| author | |
| committer | |
| log | c7615c1a8055effe5e29bc2329278ca41a258804 |
| tree | 6705ba3000e3816ad1b8f29f466a152f881c1723 |
| parent | 139e5ca08f3b15cf900be7096d7be0db4e0eced8 |
4 files changed, 27 insertions(+), 18 deletions(-)
README.md-1| ... | ... | @@ -43,7 +43,6 @@ make |
| 43 | 43 | ## Roadmap |
| 44 | 44 | |
| 45 | 45 | * parseh: unreachable <--> noreturn attribute |
| 46 | * error for extern function with void parameter | |
| 47 | 46 | * unused label error |
| 48 | 47 | * loops |
| 49 | 48 | * structs |
src/analyze.cpp+14-10| ... | ... | @@ -115,7 +115,16 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t |
| 115 | 115 | for (int i = 0; i < node->data.fn_proto.params.length; i += 1) { |
| 116 | 116 | AstNode *child = node->data.fn_proto.params.at(i); |
| 117 | 117 | assert(child->type == NodeTypeParamDecl); |
| 118 | resolve_type(g, child->data.param_decl.type); | |
| 118 | TypeTableEntry *type_entry = resolve_type(g, child->data.param_decl.type); | |
| 119 | if (type_entry == g->builtin_types.entry_unreachable) { | |
| 120 | add_node_error(g, child->data.param_decl.type, | |
| 121 | buf_sprintf("parameter of type 'unreachable' not allowed")); | |
| 122 | } else if (type_entry == g->builtin_types.entry_void) { | |
| 123 | if (node->data.fn_proto.visib_mod == FnProtoVisibModExport) { | |
| 124 | add_node_error(g, child->data.param_decl.type, | |
| 125 | buf_sprintf("parameter of type 'void' not allowed on exported functions")); | |
| 126 | } | |
| 127 | } | |
| 119 | 128 | } |
| 120 | 129 | |
| 121 | 130 | resolve_type(g, node->data.fn_proto.return_type); |
| ... | ... | @@ -423,18 +432,18 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 423 | 432 | resolve_type(g, variable_declaration->type) : nullptr; |
| 424 | 433 | if (explicit_type == g->builtin_types.entry_unreachable) { |
| 425 | 434 | add_node_error(g, variable_declaration->type, |
| 426 | buf_sprintf("variable of type 'unreachable' is not allowed.")); | |
| 435 | buf_sprintf("variable of type 'unreachable' not allowed")); | |
| 427 | 436 | } |
| 428 | 437 | |
| 429 | 438 | TypeTableEntry *implicit_type = variable_declaration->expr != nullptr ? |
| 430 | 439 | analyze_expression(g, import, context, explicit_type, variable_declaration->expr) : nullptr; |
| 431 | 440 | if (implicit_type == g->builtin_types.entry_unreachable) { |
| 432 | 441 | add_node_error(g, node, |
| 433 | buf_sprintf("variable initialization is unreachable.")); | |
| 442 | buf_sprintf("variable initialization is unreachable")); | |
| 434 | 443 | } |
| 435 | 444 | |
| 436 | 445 | if (implicit_type == nullptr) { |
| 437 | add_node_error(g, node, buf_sprintf("initial values are required for variable declaration.")); | |
| 446 | add_node_error(g, node, buf_sprintf("initial values are required for variable declaration")); | |
| 438 | 447 | } |
| 439 | 448 | |
| 440 | 449 | TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type; |
| ... | ... | @@ -443,7 +452,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 443 | 452 | LocalVariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol); |
| 444 | 453 | if (existing_variable) { |
| 445 | 454 | add_node_error(g, node, |
| 446 | buf_sprintf("redeclaration of variable '%s'.", buf_ptr(&variable_declaration->symbol))); | |
| 455 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(&variable_declaration->symbol))); | |
| 447 | 456 | } else { |
| 448 | 457 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); |
| 449 | 458 | buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol); |
| ... | ... | @@ -723,11 +732,6 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, |
| 723 | 732 | assert(param_decl->type->type == NodeTypeType); |
| 724 | 733 | TypeTableEntry *type = param_decl->type->codegen_node->data.type_node.entry; |
| 725 | 734 | |
| 726 | if (type == g->builtin_types.entry_unreachable) { | |
| 727 | add_node_error(g, param_decl->type, | |
| 728 | buf_sprintf("parameter of type 'unreachable' is not allowed.")); | |
| 729 | } | |
| 730 | ||
| 731 | 735 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); |
| 732 | 736 | buf_init_from_buf(&variable_entry->name, &param_decl->name); |
| 733 | 737 | variable_entry->type = type; |
src/errmsg.cpp+3-1| ... | ... | @@ -19,7 +19,9 @@ void print_err_msg(ErrorMsg *err, ErrColor color) { |
| 19 | 19 | assert(err->line_offsets); |
| 20 | 20 | |
| 21 | 21 | int line_start_offset = err->line_offsets->at(err->line_start); |
| 22 | int line_end_offset = err->line_offsets->at(err->line_start + 1); | |
| 22 | int end_line = err->line_start + 1; | |
| 23 | int line_end_offset = (end_line >= err->line_offsets->length) ? | |
| 24 | buf_len(err->source) : err->line_offsets->at(err->line_start + 1); | |
| 23 | 25 | |
| 24 | 26 | fwrite(buf_ptr(err->source) + line_start_offset, 1, line_end_offset - line_start_offset - 1, stderr); |
| 25 | 27 | fprintf(stderr, "\n"); |
test/run_tests.cpp+10-6| ... | ... | @@ -418,20 +418,20 @@ fn b() {} |
| 418 | 418 | add_compile_fail_case("parameter redeclaration", R"SOURCE( |
| 419 | 419 | fn f(a : i32, a : i32) { |
| 420 | 420 | } |
| 421 | )SOURCE", 1, ".tmp_source.zig:2:1: error: redeclaration of parameter 'a'."); | |
| 421 | )SOURCE", 1, ".tmp_source.zig:2:1: error: redeclaration of parameter 'a'"); | |
| 422 | 422 | |
| 423 | 423 | add_compile_fail_case("local variable redeclaration", R"SOURCE( |
| 424 | 424 | fn f() { |
| 425 | 425 | let a : i32 = 0; |
| 426 | 426 | let a = 0; |
| 427 | 427 | } |
| 428 | )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'."); | |
| 428 | )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'"); | |
| 429 | 429 | |
| 430 | 430 | add_compile_fail_case("local variable redeclares parameter", R"SOURCE( |
| 431 | 431 | fn f(a : i32) { |
| 432 | 432 | let a = 0; |
| 433 | 433 | } |
| 434 | )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'."); | |
| 434 | )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'"); | |
| 435 | 435 | |
| 436 | 436 | add_compile_fail_case("variable has wrong type", R"SOURCE( |
| 437 | 437 | fn f() -> i32 { |
| ... | ... | @@ -450,17 +450,21 @@ fn f() { |
| 450 | 450 | fn f() { |
| 451 | 451 | let a = return; |
| 452 | 452 | } |
| 453 | )SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable."); | |
| 453 | )SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable"); | |
| 454 | 454 | |
| 455 | 455 | add_compile_fail_case("unreachable variable", R"SOURCE( |
| 456 | 456 | fn f() { |
| 457 | 457 | let a : unreachable = return; |
| 458 | 458 | } |
| 459 | )SOURCE", 1, ".tmp_source.zig:3:13: error: variable of type 'unreachable' is not allowed."); | |
| 459 | )SOURCE", 1, ".tmp_source.zig:3:13: error: variable of type 'unreachable' not allowed"); | |
| 460 | 460 | |
| 461 | 461 | add_compile_fail_case("unreachable parameter", R"SOURCE( |
| 462 | 462 | fn f(a : unreachable) {} |
| 463 | )SOURCE", 1, ".tmp_source.zig:2:10: error: parameter of type 'unreachable' is not allowed."); | |
| 463 | )SOURCE", 1, ".tmp_source.zig:2:10: error: parameter of type 'unreachable' not allowed"); | |
| 464 | ||
| 465 | add_compile_fail_case("exporting a void parameter", R"SOURCE( | |
| 466 | export fn f(a : void) {} | |
| 467 | )SOURCE", 1, ".tmp_source.zig:2:17: error: parameter of type 'void' not allowed on exported functions"); | |
| 464 | 468 | |
| 465 | 469 | } |
| 466 | 470 |