diff options
-rw-r--r-- | examples/main.pipa | 6 | ||||
-rw-r--r-- | src/ast.c | 27 | ||||
-rw-r--r-- | src/ast.h | 16 | ||||
-rw-r--r-- | src/ast_pretty_printer.c | 5 | ||||
-rw-r--r-- | src/gas_assembly_generator.c | 13 | ||||
-rw-r--r-- | src/parser.c | 22 |
6 files changed, 83 insertions, 6 deletions
diff --git a/examples/main.pipa b/examples/main.pipa index 2da2231..5ea0077 100644 --- a/examples/main.pipa +++ b/examples/main.pipa @@ -1,3 +1,7 @@ -fn main(): i32 { +fn give_me_the_number(): i32 { return 69; } + +fn main(): i32 { + return give_me_the_number(); +} @@ -72,6 +72,7 @@ ast_node_destroy(ast_node_t *node) case AST_LITERAL: case AST_UNKOWN_NODE: case AST_VARIABLE: + case AST_FUNCTION_CALL: break; } free(node); @@ -276,6 +277,20 @@ ast_node_new_variable(ast_identifier_t *identifier, type_t result_type) } ast_node_t * +ast_node_new_function_call(ast_identifier_t *identifier, type_t result_type) +{ + ast_node_t *node = ast_node_new(); + + *node = (ast_node_t){ + .kind = AST_FUNCTION_CALL, + .result_type = result_type, + .data = { .function_call = { .identifier = identifier } }, + }; + + return node; +} + +ast_node_t * ast_node_ns_get_function_node_by_sv(ast_node_t *ns, string_view_t name) { assert(ns->kind == AST_NAMESPACE); @@ -296,6 +311,18 @@ ast_node_ns_get_function_node_by_name(ast_node_t *ns, char *function_name) return ast_node_ns_get_function_node_by_sv(ns, string_view_from_str(function_name)); } +bool +ast_node_is_variable_declaration(ast_node_t *node) +{ + return node->kind == AST_VARIABLE_DECLARATION; +} + +bool +ast_node_is_function_declaration(ast_node_t *node) +{ + return node->kind == AST_FUNCTION_DECLARATION; +} + char * ast_type_to_str(type_t type) { @@ -54,6 +54,11 @@ typedef struct ast_variable_t ast_identifier_t *identifier; } ast_variable_t; +typedef struct ast_function_call_t +{ + ast_identifier_t *identifier; +} ast_function_call_t; + typedef struct ast_function_declaration_t { ast_identifier_t identifier; @@ -128,6 +133,7 @@ typedef enum AST_BINARY_OPERATION, AST_BLOCK, AST_FUNCTION_DECLARATION, + AST_FUNCTION_CALL, AST_LITERAL, AST_RETURN_STMT, AST_IF_STMT, @@ -142,6 +148,7 @@ typedef union ast_namespace_t ns; ast_binary_operation_t binary_operation; ast_function_declaration_t function; + ast_function_call_t function_call; ast_literal_t literal; ast_block_t block; ast_if_stmt_t if_stmt; @@ -183,6 +190,9 @@ ast_node_t * ast_node_new_function_declaration(string_view_t function_name, type_t return_type, ast_node_t *body); ast_node_t * +ast_node_new_function_call(ast_identifier_t *identifier, type_t result_type); + +ast_node_t * ast_node_new_return_stmt(ast_node_t *argument); ast_node_t * @@ -212,4 +222,10 @@ ast_node_ns_get_function_node_by_sv(ast_node_t *ns, string_view_t name); ast_node_t * ast_node_ns_get_function_node_by_name(ast_node_t *ns, char *function_name); +bool +ast_node_is_variable_declaration(ast_node_t *node); + +bool +ast_node_is_function_declaration(ast_node_t *node); + #endif /* AST_H */ diff --git a/src/ast_pretty_printer.c b/src/ast_pretty_printer.c index f5fcf70..0d8b66c 100644 --- a/src/ast_pretty_printer.c +++ b/src/ast_pretty_printer.c @@ -155,6 +155,11 @@ ast_pretty_printer_print_ast(ast_pretty_printer_t *printer, ast_node_t *ast) } break; } + case AST_FUNCTION_CALL: { + ast_function_call_t var = ast->data.function_call; + ast_pretty_printer_printf(printer, "FunctionCall name='" SVFMT "'\n", SVARG(&var.identifier->name)); + break; + } case AST_BLOCK: { ast_pretty_printer_printf(printer, "Block\n"); ast_pretty_printer_add_indentation(printer); diff --git a/src/gas_assembly_generator.c b/src/gas_assembly_generator.c index 4326b27..2d6b993 100644 --- a/src/gas_assembly_generator.c +++ b/src/gas_assembly_generator.c @@ -29,6 +29,9 @@ static void gas_assembly_generator_compile_function(gas_assembly_generator_t *gen, ast_function_declaration_t *func); static void +gas_assembly_generator_compile_function_call(gas_assembly_generator_t *gen, ast_function_call_t *func_call); + +static void gas_assembly_generator_compile_literal(gas_assembly_generator_t *gen, ast_literal_t *literal); static void @@ -156,6 +159,9 @@ gas_assembly_generator_compile(gas_assembly_generator_t *gen, ast_node_t *ast) case AST_FUNCTION_DECLARATION: gas_assembly_generator_compile_function(gen, &ast->data.function); break; + case AST_FUNCTION_CALL: + gas_assembly_generator_compile_function_call(gen, &ast->data.function_call); + break; case AST_LITERAL: gas_assembly_generator_compile_literal(gen, &ast->data.literal); break; @@ -211,6 +217,13 @@ gas_assembly_generator_compile_function(gas_assembly_generator_t *gen, ast_funct gen->return_label_index = previous_index; } +static void +gas_assembly_generator_compile_function_call(gas_assembly_generator_t *gen, ast_function_call_t *func_call) +{ + fprintf(gen->stream, " call " SVFMT "\n", SVARG(&func_call->identifier->name)); + gas_assembly_generator_set_latest_evaluation_to_rax(gen); +} + void gas_assembly_generator_compile_linux_main(gas_assembly_generator_t *gen, ast_node_t *ns) { diff --git a/src/parser.c b/src/parser.c index b94087f..578514c 100644 --- a/src/parser.c +++ b/src/parser.c @@ -339,10 +339,9 @@ parser_parse_factor(parser_t *parser) return expression; } case TOKEN_NAME: { - // TODO: Check node kind, today accepts only variables - ast_node_t *var_node = scope_get(parser->scope, token.value); + ast_node_t *referenced_node = scope_get(parser->scope, token.value); - if (var_node == NULL) { + if (referenced_node == NULL) { parser_error_t error; error.token = token; sprintf(error.message, "identifier '" SVFMT "' not defined", SVARG(&token.value)); @@ -350,8 +349,21 @@ parser_parse_factor(parser_t *parser) return NULL; } - return ast_node_new_variable(&var_node->data.variable_declaration.identifier, - var_node->data.variable_declaration.type); + if (referenced_node->kind == AST_VARIABLE_DECLARATION) { + return ast_node_new_variable(&referenced_node->data.variable_declaration.identifier, + referenced_node->data.variable_declaration.type); + } + + // Parse function parameters + if (!drop_expected_token(parser, TOKEN_OPAREN)) { + return NULL; + } + if (!drop_expected_token(parser, TOKEN_CPAREN)) { + return NULL; + } + + return ast_node_new_function_call(&referenced_node->data.function.identifier, + referenced_node->data.function.return_type); } default: { parser_error_t error; |