diff --git a/compiler/CMakeLists.txt b/compiler/CMakeLists.txt index 5202c8b..384c8ed 100644 --- a/compiler/CMakeLists.txt +++ b/compiler/CMakeLists.txt @@ -6,5 +6,5 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/y.tab.c COMMAND yacc -d -o ${CMAKE_CURRENT_SOURCE_DIR}/y.tab.c ${CMAKE_CURRENT_SOURCE_DIR}/grammar.y ) -add_library(COMPILER lex.yy.c y.tab.c codegen.c disassemble.c create.c error.c fix_tree.c opcode.c string.c compiler.c) +add_library(COMPILER lex.yy.c y.tab.c codegen.c disassemble.c create.c error.c fix_tree.c opcode.c string.c compiler.c util.c) target_include_directories(COMPILER INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/compiler/create.c b/compiler/create.c index 4088e87..7346e95 100644 --- a/compiler/create.c +++ b/compiler/create.c @@ -1,5 +1,6 @@ #include #include +#include "error.h" #include "summoner.h" static int current_line_number() @@ -280,6 +281,14 @@ ParameterList *chain_parameter(ParameterList *list, ParameterList *parameter) FuncDefinition *alloc_func_definition(char *name, ParameterList *parameters, TypeSpecifier *return_type, Block *block) { + if (search_function(name) || search_declaration(name, NULL)) + { + compile_error(get_current_compiler()->current_line_number, + FUNCTION_MULTIPLE_DEFINE_ERR, + STRING_MESSAGE_ARGUMENT, "name", name, + MESSAGE_ARGUMENT_END); + } + FuncDefinition *func_d = (FuncDefinition *)malloc(sizeof(FuncDefinition)); func_d->name = name; func_d->parameters = parameters; diff --git a/compiler/fix_tree.c b/compiler/fix_tree.c index bbe6a86..9e0ccc1 100644 --- a/compiler/fix_tree.c +++ b/compiler/fix_tree.c @@ -9,52 +9,6 @@ extern BuiltinFun *search_builtin_function(char *name); static Expression *fix_expression(Block *current_block, Expression *expr); static void fix_statement_list(Block *current_block, StatementList *list, FuncDefinition *fd); -Declaration *search_declaration_in_current_block(char *identifier, Block *block) -{ - if (!block) - { - return NULL; - } - - Declaration *d_pos; - for (d_pos = block->declaration_list; d_pos; d_pos = d_pos->next) - { - if (!strcmp(identifier, d_pos->name)) - { - return d_pos; - } - } - return NULL; -} - -Declaration *search_declaration(char *identifier, Block *block) -{ - Block *b_pos; - Declaration *d_pos; - Compiler *compiler; - - for (b_pos = block; b_pos; b_pos = b_pos->outer_block) - { - for (d_pos = b_pos->declaration_list; d_pos; d_pos = d_pos->next) - { - if (!strcmp(identifier, d_pos->name)) - { - return d_pos; - } - } - } - - compiler = get_current_compiler(); - for (d_pos = compiler->declaration_list; d_pos; d_pos = d_pos->next) - { - if (!strcmp(identifier, d_pos->name)) - { - return d_pos; - } - } - return NULL; -} - static Expression * fix_identifier_expression(Block *current_block, Expression *expr) { diff --git a/compiler/grammar.y b/compiler/grammar.y index a0a6895..204cce2 100644 --- a/compiler/grammar.y +++ b/compiler/grammar.y @@ -145,14 +145,12 @@ return_stmt: ; if_stmt: - IF bool_expr block { $$ = alloc_if_stmt($2, $3, NULL, NULL); } - | IF bool_expr block ELSE block { $$ = alloc_if_stmt($2, $3, NULL, $5); } - | IF bool_expr block elseif_list { $$ = alloc_if_stmt($2, $3, $4, NULL); } + IF bool_expr block elseif_list { $$ = alloc_if_stmt($2, $3, $4, NULL); } | IF bool_expr block elseif_list ELSE block { $$ = alloc_if_stmt($2, $3, $4, $6); } ; elseif_list: - elseif + { $$ = NULL; } | elseif_list elseif { $$ = chain_else_if_list($1, $2); } ; diff --git a/compiler/summoner.h b/compiler/summoner.h index 9d510d9..b0eb960 100644 --- a/compiler/summoner.h +++ b/compiler/summoner.h @@ -370,4 +370,9 @@ SVM_Executable *smc_code_gen(Compiler *compiler); int svm_dump_instruction(FILE *fp, SVM_Byte *code, int index); void svm_disassemble(SVM_Executable *exe); +/** util.c */ +Declaration *search_declaration(char *identifier, Block *block); +Declaration *search_declaration_in_current_block(char *identifier, Block *block); +FuncDefinition *search_function(char *name); + #endif diff --git a/compiler/util.c b/compiler/util.c new file mode 100644 index 0000000..1ea10ff --- /dev/null +++ b/compiler/util.c @@ -0,0 +1,62 @@ +#include +#include "summoner.h" + +Declaration *search_declaration_in_current_block(char *identifier, Block *block) +{ + if (!block) + { + return NULL; + } + + Declaration *d_pos; + for (d_pos = block->declaration_list; d_pos; d_pos = d_pos->next) + { + if (!strcmp(identifier, d_pos->name)) + { + return d_pos; + } + } + return NULL; +} + +Declaration *search_declaration(char *identifier, Block *block) +{ + Block *b_pos; + Declaration *d_pos; + Compiler *compiler; + + for (b_pos = block; b_pos; b_pos = b_pos->outer_block) + { + for (d_pos = b_pos->declaration_list; d_pos; d_pos = d_pos->next) + { + if (!strcmp(identifier, d_pos->name)) + { + return d_pos; + } + } + } + + compiler = get_current_compiler(); + for (d_pos = compiler->declaration_list; d_pos; d_pos = d_pos->next) + { + if (!strcmp(identifier, d_pos->name)) + { + return d_pos; + } + } + return NULL; +} + +FuncDefinition *search_function(char *name) +{ + Compiler *compiler; + FuncDefinition *func_pos; + + compiler = get_current_compiler(); + for (func_pos = compiler->func_definition_list; func_pos; func_pos = func_pos->next) { + if (!strcmp(func_pos->name, name)) { + return func_pos; + } + } + return NULL; +}