Function Parameters

Using the same method as was done with declarations, the grammar for functions was updated in the Parser to account for multiple functions in a program:

functions:
functions function {
	AST_Node_StateList* temp_funclist = (AST_Node_StateList*) $1;
	$$ = new_ast_statelist_node($1, $2, temp_funclist->statement_cnt + 1); 
}
| function  { 
	incr_scope();
	$$ = new_ast_statelist_node(NULL, $1, 1); 
}
;

However, the grammar for a single function still does not account for parameters (see that the grammar only looks for an open and a close parenthesis with nothing in between):

function:
INT ID OP_PAR CL_PAR OP_BRACE statement CL_BRACE {
      $$ = new_ast_func_node($2,$6); }
;

The updated grammar for a function that accounts for parameters will look like the following with the addition of a new token called parameters:

// Additions to Parser.y
function:
var_type ID OP_PAR parameters CL_PAR OP_BRACE statements CL_BRACE {
      $$ = new_ast_func_node($2,$4,$7); }
;

This update requires the new_ast_func_node() function to now take an additional parameter for the parameters token:

// Additions to ast.c
AST_Node* new_ast_func_node(char* fname, AST_Node* param_list, AST_Node* state_list) {
	AST_Node_Func* node = malloc(sizeof(AST_Node_Func));

	node->type = FUNC_NODE;
	node->funcname = _strdup(fname);
	node->statement_list = state_list;
	node->param_list = param_list;
	node->scope = current_scope;
	return (AST_Node*)node;
}

As functions will have an unknown amount of parameters, a parameter list node is created for each function. The design of the parameter list node is the same as the previously created statement list. Function parameters in C are a variable type followed by a variable name. Therefore, the parameter nodes found within a parameter list were designed to contain the parameter type and name:

// Additions to ast.h
typedef struct AST_Node_ParamList_t {
	Node_Type type;
	AST_Node* paramlist;
	AST_Node* param;
	int param_cnt;
} AST_Node_ParamList;

typedef struct AST_Node_Param_t {
	Node_Type type;
	VariableType vartype;
	AST_Node* ID;
} AST_Node_Param;

Functions were made to create parameter list and parameter nodes:

// Additions to ast.c
AST_Node* new_ast_param_node(int vtype, AST_Node* ID) {
	AST_Node_Param* node = malloc(sizeof(AST_Node_Param));

	node->type = PARAM_NODE;
	node->ID = ID;
	node->vartype = vtype;
	return (AST_Node*)node;
}

AST_Node* new_ast_paramlist_node(AST_Node* prmlist, AST_Node* prm, int prmcnt) {
	AST_Node_ParamList* node = malloc(sizeof(AST_Node_ParamList));

	node->type = PARAMLIST_NODE;
	node->paramlist = prmlist;
	node->param = prm;
	node->param_cnt = prmcnt;
	return (AST_Node*)node;
}

A function can either have multiple parameters, a single parameter, or no parameters (marked by empty space or void). Therefore, the grammar for the parameters token was made to account for these four possibilities (note, grammar resembles that of the statements token):

parameters:
parameters parameter {
	AST_Node_ParamList* temp_paramlist = (AST_Node_ParamList*) $1;
	$$ = new_ast_paramlist_node($1, $2, temp_paramlist->param_cnt + 1); 
}
| parameter  { 	
	$$ = new_ast_paramlist_node(NULL, $1, 1); 
}
| VOID { 
	$$ = NULL; 
}
| { /*No paramters passed*/
	$$ = NULL; 
} 
;

The token parameter must account for parameters in the function. As previously mentioned, parameters in a C function are variable types followed by variable names; however, if there are multiple parameters, they will be separated with commas. The grammar for the parameter token was created to account for both parameters that aren’t and are separated by commas:

parameter:
var_type variable COMMA { 
	AST_Node_ID* temp_ID = (AST_Node_ID*) $2;
	$$ = new_ast_param_node($1, $2); 
}
| var_type variable { 
	AST_Node_ID* temp_ID = (AST_Node_ID*) $2;
	$$ = new_ast_param_node($1, $2); 
}
;

Future updates for parameters include inserting the parameters into the symbol table and accounting for function call parameters.