diff options
author | Carlos Maniero <carlos@maniero.me> | 2023-05-10 22:24:14 -0300 |
---|---|---|
committer | Carlos Maniero <carlos@maniero.me> | 2023-05-10 22:45:31 -0300 |
commit | 5042a4ffc1363d6f0f99a3afd79f76cf2da738d6 (patch) | |
tree | 90c31d77ddf6b9051669fafdc6dfe0fc3b1f35eb /src/ast.c | |
parent | 6f187a71cbe3aa4ebb32ba287c75562d96c7a3f4 (diff) |
gas: implement function calls
For now function calls are following the C's calling convention, which
means they are using the following registers to pass functions'
arguments:
rdi, rsi, rdx, rcx, r8, r9
If a function has more then 6 parameters, the compilation will fail.
To enable function with more than 6 parameters we will need to save the
extra arguments on stack.
Naming:
parameters: function parameters are the variables a function receives.
arguments: Arguments are the values passed to a function when calling
it.
Calling mechanism:
When a function is called, all the expressions passed as argument are
evaluated, after the evaluation, the result is stored on the register
that represents its argument position, the first argument will be
stored on rdi, the second on rsi and so on.
Receiving mechanism:
When a function starts, the first thing it does is store all the
registers onto the stack. So rdi will be stored on -8(rbp), rsi on
-16(rbp) and so on. And, a ref_entry is created making the
relationship parameter-stack_offset.
Signed-off-by: Carlos Maniero <carlos@maniero.me>
Diffstat (limited to 'src/ast.c')
-rw-r--r-- | src/ast.c | 54 |
1 files changed, 48 insertions, 6 deletions
@@ -49,6 +49,7 @@ ast_node_destroy(ast_node_t *node) break; case AST_FUNCTION_DECLARATION: ast_node_destroy(node->data.function.body); + ast_node_destroy_vector(node->data.function.prototype.parameters); break; case AST_IF_STMT: ast_node_destroy(node->data.if_stmt.condition); @@ -69,6 +70,7 @@ ast_node_destroy(ast_node_t *node) break; case AST_VARIABLE_ASSIGNMENT: ast_node_destroy(node->data.variable_assignment.expression); + case AST_FUNCTION_PARAMETER: case AST_LITERAL: case AST_UNKOWN_NODE: case AST_VARIABLE: @@ -93,7 +95,30 @@ ast_node_new_return_stmt(ast_node_t *argument) } ast_node_t * -ast_node_new_function_declaration(string_view_t function_name, type_t return_type, ast_node_t *body) +ast_node_new_function_parameter(string_view_t name, type_t type) +{ + ast_node_t *node = ast_node_new(); + + *node = (ast_node_t){ + .kind = AST_FUNCTION_PARAMETER, + .data = { + .function_parameter = { + .identifier = { + .name = name, + }, + .type = type, + }, + }, + }; + + return node; +} + +ast_node_t * +ast_node_new_function_declaration(string_view_t function_name, + type_t return_type, + vector_t *parameters, + ast_node_t *body) { ast_node_t *node = ast_node_new(); @@ -101,8 +126,11 @@ ast_node_new_function_declaration(string_view_t function_name, type_t return_typ .kind = AST_FUNCTION_DECLARATION, .data = { .function = { - .identifier = { .name = function_name }, - .return_type = return_type, + .prototype = { + .identifier = { .name = function_name }, + .return_type = return_type, + .parameters = parameters, + }, .body = body, } }, @@ -277,14 +305,14 @@ 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_new_function_call(ast_identifier_t *identifier, type_t result_type, vector_t *arguments) { ast_node_t *node = ast_node_new(); *node = (ast_node_t){ .kind = AST_FUNCTION_CALL, .result_type = result_type, - .data = { .function_call = { .identifier = identifier } }, + .data = { .function_call = { .identifier = identifier, .arguments = arguments } }, }; return node; @@ -298,7 +326,7 @@ ast_node_ns_get_function_node_by_sv(ast_node_t *ns, string_view_t name) for (size_t i = 0; i < ns->data.ns.nodes->size; i++) { ast_node_t *node = vector_at(ns->data.ns.nodes, i); - if (node->kind == AST_FUNCTION_DECLARATION && string_view_eq(node->data.function.identifier.name, name)) { + if (node->kind == AST_FUNCTION_DECLARATION && string_view_eq(node->data.function.prototype.identifier.name, name)) { return node; } } @@ -323,6 +351,20 @@ ast_node_is_function_declaration(ast_node_t *node) return node->kind == AST_FUNCTION_DECLARATION; } +ast_identifier_t * +ast_node_function_declaration_identifier(ast_node_t *node) +{ + assert(node->kind == AST_FUNCTION_DECLARATION); + + return &node->data.function.prototype.identifier; +} + +string_view_t +ast_node_function_declaration_name(ast_node_t *node) +{ + return ast_node_function_declaration_identifier(node)->name; +} + char * ast_type_to_str(type_t type) { |