/*create a function and add it into function list *the function is defined by an extdef node in syntax tree*/ struct func_descriptor* create_function(struct tree_node* specifier_node, struct tree_node* fundec_node){ char* func_name = fundec_node -> child -> unit_value; if(find_func(func_table_head, func_name) != NULL){ printf("Error type 4 at line %d: Function \'%s\'redifine\n", fundec_node -> lineno, func_name); semantic_error_flag = true; return NULL; } if(is_struct_type(specifier_node) && is_struct_definition(specifier_node -> child)){ printf("Warnning: struct defined inside return field of function \'%s\'\n", func_name); } /*handle return type*/ struct type_descriptor* return_type = create_type(specifier_node); /*create func descriptor and add into list*/ struct func_descriptor* new_func_descriptor = create_func_descriptor(func_name, return_type, 0); add_func(func_table_head, new_func_descriptor); /*handle params*/ if(fundec_node -> child -> sibling -> sibling -> unit_code == VarList){ struct tree_node* varlist_node = fundec_node -> child -> sibling -> sibling; new_func_descriptor -> param_num = init_param_list(new_func_descriptor -> param_list_head, varlist_node); } return new_func_descriptor; }
void parse_param_list(token tag_name, param *param_list, token end_token) { param *param_ptr; int param_index; char old_name[256]; // Initialise the parameter list. init_param_list(); // Parse the parameter list. while ((param_ptr = parse_next_param(param_list)) != NULL) { switch (param_ptr->value_type) { case VALUE_BLOCK_NAME: parse_string(old_name, 256); if (!parse_name(old_name, (char *)param_ptr->variable_ptr, false)) file_error("Expected a valid block name rather than '%s'", old_name); break; case VALUE_BLOCK_TYPE: *(blocktype *)param_ptr->variable_ptr = parse_block_type(); break; case VALUE_BOOL: *(bool *)param_ptr->variable_ptr = parse_bool(); break; case VALUE_CHAR: *(char *)param_ptr->variable_ptr = parse_char(); break; case VALUE_DEGREES: *(double *)param_ptr->variable_ptr = parse_degrees(); break; case VALUE_DOUBLE: *(double *)param_ptr->variable_ptr = parse_double(); break; case VALUE_INTEGER: *(int *)param_ptr->variable_ptr = parse_integer(); break; case VALUE_PART_NAME: parse_string(old_name, 256); if (!parse_name(old_name, (char *)param_ptr->variable_ptr, false)) file_error("Expected a valid part name rather than '%s'", old_name); break; case VALUE_PERCENTAGE: *(double *)param_ptr->variable_ptr = parse_percentage(); break; case VALUE_REF_LIST: parse_ref_list((ref_list *)param_ptr->variable_ptr); break; case VALUE_RGB: *(RGBcolour *)param_ptr->variable_ptr = parse_RGB(); break; case VALUE_STRING: parse_string((char *)param_ptr->variable_ptr, 256); break; case VALUE_TEXCOORDS_LIST: parse_texcoords_list((texcoords_list *)param_ptr->variable_ptr); break; case VALUE_TEXTURE_STYLE: *(texstyle *)param_ptr->variable_ptr = parse_texture_style(); break; case VALUE_VERTEX_COORDS: *(vertex *)param_ptr->variable_ptr = parse_vertex_coordinates(); break; default: file_error("internal error--unrecognised parameter value type"); } } // If an end_token was specified, then verify that the end token parsed // matches it. if (end_token != TOKEN_NONE && file_token != end_token) expected_token(get_token_str(end_token)); // If there was a parameter list, verify that all required parameters were // parsed. if (param_list) { param_index = 0; while (param_list[param_index].param_name != TOKEN_NONE) { if (param_list[param_index].required && !matched_param[param_index]) file_error("parameter '%s' is missing from tag '%s'", get_token_str(param_list[param_index].param_name), get_token_str(tag_name)); param_index++; } } }