summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/main.pipa6
-rw-r--r--src/ast.c27
-rw-r--r--src/ast.h16
-rw-r--r--src/ast_pretty_printer.c5
-rw-r--r--src/gas_assembly_generator.c13
-rw-r--r--src/parser.c22
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();
+}
diff --git a/src/ast.c b/src/ast.c
index 47d658d..e9aa677 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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)
{
diff --git a/src/ast.h b/src/ast.h
index 7d2d2f1..315de1e 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -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;