Although the Parser can handle functions, it cannot handle function calls. Therefore, a new token called func_call_st was created. The expected grammar for a function call is the function name followed by parameters contained within parenthesis:
// Update to code in Parser.y
statement:
return_st { $$ = $1; }
| declaration_st SEMI { $$ = $1; }
| func_call_st SEMI { $$ = $1; }
| expression SEMI { $$ = $1; }
;
func_call_st:
ID OP_PAR call_parameters CL_PAR {
$$ = new_ast_func_call_node($1, $3);
}
;
See below for the code added to create function call nodes in the abstract syntax tree:
// Update to code in ast.h
typedef struct AST_Node_Func_Call_t {
Node_Type type;
char* funcname;
AST_Node* param_list;
scope_t* scope;
} AST_Node_Func_Call;
// Update to code in ast.c
AST_Node* new_ast_func_call_node(char* fname, AST_Node* param_list) {
AST_Node_Func_Call* node = malloc(sizeof(AST_Node_Func_Call));
node->type = FUNC_CALL_NODE;
node->funcname = _strdup(fname);
node->param_list = param_list;
node->scope = current_scope;
return (AST_Node*)node;
}
Note that another new token besides func_call_st is used, called call_parameters. Although the parameters token was created previously, it cannot be reused as parameters in function calls do not include the variable type. Due to this, the call_parameters/call_parameter tokens were created the same as the parameters/parameter tokens except variable types weren’t included:
// Update to code in Parser.y
call_parameters:
call_parameters call_parameter {
AST_Node_ParamList* temp_paramlist = (AST_Node_ParamList*) $1;
$$ = new_ast_paramlist_node($1, $2, temp_paramlist->param_cnt + 1);
}
| call_parameter { $$ = new_ast_paramlist_node(NULL, $1, 1); }
| VOID { $$ = NULL; }
| { $$ = NULL; } /*No paramters passed*/
;
call_parameter:
variable COMMA { $$ = new_ast_call_param_node($1); }
| variable { $$ = new_ast_call_param_node($1); }
;
The parameter list node created for the parameters token is reused (list to store an unknown amount of parameters for a function or function call); however, a new abstract syntax tree node was created for call parameters (same as parameter nodes, except variable type is not stored):
// Update to code in ast.h
typedef struct AST_Node_Call_Param_t {
Node_Type type;
AST_Node* ID;
} AST_Node_Call_Param;
// Update to code in ast.c
AST_Node* new_ast_call_param_node(AST_Node* ID) {
AST_Node_Call_Param* node = malloc(sizeof(AST_Node_Call_Param));
node->type = CALL_PARAM_NODE;
node->ID = ID;
return (AST_Node*)node;
}
Code to insert call parameters into the symbol table will need to be added in the future for the Complier to be able to access the parameters when generating assembly code.