| ... | @@ -345,7 +345,10 @@ static void check_type_compatibility(CodeGen *g, AstNode *node, TypeTableEntry * | ... | @@ -345,7 +345,10 @@ static void check_type_compatibility(CodeGen *g, AstNode *node, TypeTableEntry * |
| 345 | return; // TODO: is this true? | 345 | return; // TODO: is this true? |
| 346 | | 346 | |
| 347 | // TODO better error message | 347 | // TODO better error message |
| 348 | add_node_error(g, node, buf_sprintf("type mismatch. expected %s. got %s", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name))); | 348 | add_node_error(g, node, |
| | 349 | buf_sprintf("type mismatch. expected %s. got %s", |
| | 350 | buf_ptr(&expected_type->name), |
| | 351 | buf_ptr(&actual_type->name))); |
| 349 | } | 352 | } |
| 350 | | 353 | |
| 351 | static BlockContext *new_block_context(AstNode *node, BlockContext *parent) { | 354 | static BlockContext *new_block_context(AstNode *node, BlockContext *parent) { |
| ... | @@ -434,8 +437,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -434,8 +437,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 434 | | 437 | |
| 435 | LocalVariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol); | 438 | LocalVariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol); |
| 436 | if (existing_variable) { | 439 | if (existing_variable) { |
| 437 | add_node_error(g, node, buf_sprintf("redeclaration of variable '%s'.", | 440 | add_node_error(g, node, |
| 438 | buf_ptr(&variable_declaration->symbol))); | 441 | buf_sprintf("redeclaration of variable '%s'.", buf_ptr(&variable_declaration->symbol))); |
| 439 | } else { | 442 | } else { |
| 440 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); | 443 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); |
| 441 | buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol); | 444 | buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol); |
| ... | @@ -596,12 +599,11 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -596,12 +599,11 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 596 | case NodeTypeSymbol: | 599 | case NodeTypeSymbol: |
| 597 | { | 600 | { |
| 598 | Buf *symbol_name = &node->data.symbol; | 601 | Buf *symbol_name = &node->data.symbol; |
| 599 | FnTableEntry *fn_table_entry = get_context_fn_entry(context); | 602 | LocalVariableTableEntry *local_variable = find_local_variable(context, symbol_name); |
| 600 | auto table_entry = fn_table_entry->symbol_table.maybe_get(symbol_name); | 603 | if (local_variable) { |
| 601 | if (table_entry) { | 604 | return_type = local_variable->type; |
| 602 | SymbolTableEntry *symbol_entry = table_entry->value; | | |
| 603 | return_type = symbol_entry->type_entry; | | |
| 604 | } else { | 605 | } else { |
| | 606 | // TODO: check global variables also |
| 605 | add_node_error(g, node, | 607 | add_node_error(g, node, |
| 606 | buf_sprintf("use of undeclared identifier '%s'", buf_ptr(symbol_name))); | 608 | buf_sprintf("use of undeclared identifier '%s'", buf_ptr(symbol_name))); |
| 607 | return_type = g->builtin_types.entry_invalid; | 609 | return_type = g->builtin_types.entry_invalid; |
| ... | @@ -718,8 +720,8 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, | ... | @@ -718,8 +720,8 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, |
| 718 | // unique definition | 720 | // unique definition |
| 719 | context->variable_table.put(&variable_entry->name, variable_entry); | 721 | context->variable_table.put(&variable_entry->name, variable_entry); |
| 720 | } else { | 722 | } else { |
| 721 | add_node_error(g, node, buf_sprintf("redeclaration of parameter '%s'.", | 723 | add_node_error(g, node, |
| 722 | buf_ptr(&existing_entry->name))); | 724 | buf_sprintf("redeclaration of parameter '%s'.", buf_ptr(&existing_entry->name))); |
| 723 | if (existing_entry->type == variable_entry->type) { | 725 | if (existing_entry->type == variable_entry->type) { |
| 724 | // types agree, so the type is probably good enough for the rest of analysis | 726 | // types agree, so the type is probably good enough for the rest of analysis |
| 725 | } else { | 727 | } else { |