authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2019-05-10 16:09:58+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2019-05-10 16:09:58+02:00
log6b10f03b4a868cc02fc0535193ea0108c77ddd1f
tree6e3a295a21e89dbc55eea9432f575c4f584bfc92
parentbcf4d20289bfb062aa7e4fadd900c9a247feb3e8

Fixes and simplifications for stage 1 parser


3 files changed, 31 insertions(+), 59 deletions(-)

src/ir.cpp+3-4
...@@ -5433,10 +5433,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5433,10 +5433,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
5433 add_node_error(irb->codegen, variable_declaration->section_expr,5433 add_node_error(irb->codegen, variable_declaration->section_expr,
5434 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));5434 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
5435 }5435 }
5436 if (variable_declaration->threadlocal_tok != nullptr) {5436
5437 add_token_error(irb->codegen, node->owner, variable_declaration->threadlocal_tok,5437 // Parser should ensure that this never happens
5438 buf_sprintf("function-local variable '%s' cannot be threadlocal", buf_ptr(variable_declaration->symbol)));5438 assert(variable_declaration->threadlocal_tok == nullptr);
5439 }
54405439
5441 // Temporarily set the name of the IrExecutable to the VariableDeclaration5440 // Temporarily set the name of the IrExecutable to the VariableDeclaration
5442 // so that the struct or enum from the init expression inherits the name.5441 // so that the struct or enum from the init expression inherits the name.
src/parser.cpp+28-46
...@@ -577,7 +577,7 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {...@@ -577,7 +577,7 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
577577
578// TopLevelDecl578// TopLevelDecl
579// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)579// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
580// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl580// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
581// / KEYWORD_use Expr SEMICOLON581// / KEYWORD_use Expr SEMICOLON
582static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {582static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
583 Token *first = eat_token_if(pc, TokenIdKeywordExport);583 Token *first = eat_token_if(pc, TokenIdKeywordExport);
...@@ -632,13 +632,18 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {...@@ -632,13 +632,18 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
632 ast_invalid_token_error(pc, peek_token(pc));632 ast_invalid_token_error(pc, peek_token(pc));
633 }633 }
634634
635 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
635 AstNode *var_decl = ast_parse_var_decl(pc);636 AstNode *var_decl = ast_parse_var_decl(pc);
636 if (var_decl != nullptr) {637 if (var_decl != nullptr) {
637 assert(var_decl->type == NodeTypeVariableDeclaration);638 assert(var_decl->type == NodeTypeVariableDeclaration);
638 var_decl->data.variable_declaration.visib_mod = visib_mod;639 var_decl->data.variable_declaration.visib_mod = visib_mod;
640 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
639 return var_decl;641 return var_decl;
640 }642 }
641643
644 if (thread_local_kw != nullptr)
645 put_back_token(pc);
646
642 AstNode *fn_proto = ast_parse_fn_proto(pc);647 AstNode *fn_proto = ast_parse_fn_proto(pc);
643 if (fn_proto != nullptr) {648 if (fn_proto != nullptr) {
644 AstNode *body = ast_parse_block(pc);649 AstNode *body = ast_parse_block(pc);
...@@ -741,17 +746,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -741,17 +746,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
741746
742// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON747// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
743static AstNode *ast_parse_var_decl(ParseContext *pc) {748static AstNode *ast_parse_var_decl(ParseContext *pc) {
744 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
745 Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);749 Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);
746 if (mut_kw == nullptr)750 if (mut_kw == nullptr)
747 mut_kw = eat_token_if(pc, TokenIdKeywordVar);751 mut_kw = eat_token_if(pc, TokenIdKeywordVar);
748 if (mut_kw == nullptr) {752 if (mut_kw == nullptr)
749 if (thread_local_kw == nullptr) {753 return nullptr;
750 return nullptr;754
751 } else {
752 ast_invalid_token_error(pc, peek_token(pc));
753 }
754 }
755 Token *identifier = expect_token(pc, TokenIdSymbol);755 Token *identifier = expect_token(pc, TokenIdSymbol);
756 AstNode *type_expr = nullptr;756 AstNode *type_expr = nullptr;
757 if (eat_token_if(pc, TokenIdColon) != nullptr)757 if (eat_token_if(pc, TokenIdColon) != nullptr)
...@@ -766,7 +766,6 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {...@@ -766,7 +766,6 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
766 expect_token(pc, TokenIdSemicolon);766 expect_token(pc, TokenIdSemicolon);
767767
768 AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);768 AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
769 res->data.variable_declaration.threadlocal_tok = thread_local_kw;
770 res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;769 res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;
771 res->data.variable_declaration.symbol = token_buf(identifier);770 res->data.variable_declaration.symbol = token_buf(identifier);
772 res->data.variable_declaration.type = type_expr;771 res->data.variable_declaration.type = type_expr;
...@@ -952,17 +951,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {...@@ -952,17 +951,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
952951
953// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)952// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
954static AstNode *ast_parse_loop_statement(ParseContext *pc) {953static AstNode *ast_parse_loop_statement(ParseContext *pc) {
955 Token *label = ast_parse_block_label(pc);
956 Token *first = label;
957
958 Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);954 Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);
959 if (first == nullptr)
960 first = inline_token;
961
962 AstNode *for_statement = ast_parse_for_statement(pc);955 AstNode *for_statement = ast_parse_for_statement(pc);
963 if (for_statement != nullptr) {956 if (for_statement != nullptr) {
964 assert(for_statement->type == NodeTypeForExpr);957 assert(for_statement->type == NodeTypeForExpr);
965 for_statement->data.for_expr.name = token_buf(label);
966 for_statement->data.for_expr.is_inline = inline_token != nullptr;958 for_statement->data.for_expr.is_inline = inline_token != nullptr;
967 return for_statement;959 return for_statement;
968 }960 }
...@@ -970,12 +962,11 @@ static AstNode *ast_parse_loop_statement(ParseContext *pc) {...@@ -970,12 +962,11 @@ static AstNode *ast_parse_loop_statement(ParseContext *pc) {
970 AstNode *while_statement = ast_parse_while_statement(pc);962 AstNode *while_statement = ast_parse_while_statement(pc);
971 if (while_statement != nullptr) {963 if (while_statement != nullptr) {
972 assert(while_statement->type == NodeTypeWhileExpr);964 assert(while_statement->type == NodeTypeWhileExpr);
973 while_statement->data.while_expr.name = token_buf(label);
974 while_statement->data.while_expr.is_inline = inline_token != nullptr;965 while_statement->data.while_expr.is_inline = inline_token != nullptr;
975 return while_statement;966 return while_statement;
976 }967 }
977968
978 if (first != nullptr)969 if (inline_token != nullptr)
979 ast_invalid_token_error(pc, peek_token(pc));970 ast_invalid_token_error(pc, peek_token(pc));
980 return nullptr;971 return nullptr;
981}972}
...@@ -1117,7 +1108,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc) {...@@ -1117,7 +1108,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc) {
11171108
1118// CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?1109// CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
1119static AstNode *ast_parse_compare_expr(ParseContext *pc) {1110static AstNode *ast_parse_compare_expr(ParseContext *pc) {
1120 return ast_parse_bin_op_expr(pc, BinOpChainInf, ast_parse_compare_op, ast_parse_bitwise_expr);1111 return ast_parse_bin_op_expr(pc, BinOpChainOnce, ast_parse_compare_op, ast_parse_bitwise_expr);
1121}1112}
11221113
1123// BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*1114// BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
...@@ -1246,11 +1237,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {...@@ -1246,11 +1237,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
1246 }1237 }
12471238
1248 AstNode *block = ast_parse_block(pc);1239 AstNode *block = ast_parse_block(pc);
1249 if (block != nullptr) {1240 if (block != nullptr)
1250 assert(block->type == NodeTypeBlock);
1251 block->data.block.name = token_buf(label);
1252 return block;1241 return block;
1253 }
12541242
1255 AstNode *curly_suffix = ast_parse_curly_suffix_expr(pc);1243 AstNode *curly_suffix = ast_parse_curly_suffix_expr(pc);
1256 if (curly_suffix != nullptr)1244 if (curly_suffix != nullptr)
...@@ -1672,32 +1660,26 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {...@@ -1672,32 +1660,26 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
16721660
1673// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto1661// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
1674static AstNode *ast_parse_container_decl(ParseContext *pc) {1662static AstNode *ast_parse_container_decl(ParseContext *pc) {
1675 Token *extern_token = eat_token_if(pc, TokenIdKeywordExtern);1663 Token *layout_token = eat_token_if(pc, TokenIdKeywordExtern);
1676 if (extern_token != nullptr) {1664 if (layout_token == nullptr)
1677 AstNode *res = ast_parse_container_decl_auto(pc);1665 layout_token = eat_token_if(pc, TokenIdKeywordPacked);
1678 if (res == nullptr) {
1679 put_back_token(pc);
1680 return nullptr;
1681 }
16821666
1683 assert(res->type == NodeTypeContainerDecl);1667 AstNode *res = ast_parse_container_decl_auto(pc);
1684 res->line = extern_token->start_line;1668 if (res == nullptr) {
1685 res->column = extern_token->start_column;1669 if (layout_token != nullptr)
1686 res->data.container_decl.layout = ContainerLayoutExtern;1670 put_back_token(pc);
1687 return res;1671 return nullptr;
1688 }1672 }
16891673
1690 Token *packed_token = eat_token_if(pc, TokenIdKeywordPacked);1674 assert(res->type == NodeTypeContainerDecl);
1691 if (packed_token != nullptr) {1675 if (layout_token != nullptr) {
1692 AstNode *res = ast_expect(pc, ast_parse_container_decl_auto);1676 res->line = layout_token->start_line;
1693 assert(res->type == NodeTypeContainerDecl);1677 res->column = layout_token->start_column;
1694 res->line = packed_token->start_line;1678 res->data.container_decl.layout = layout_token->id == TokenIdKeywordExtern
1695 res->column = packed_token->start_column;1679 ? ContainerLayoutExtern
1696 res->data.container_decl.layout = ContainerLayoutPacked;1680 : ContainerLayoutPacked;
1697 return res;
1698 }1681 }
16991682 return res;
1700 return ast_parse_container_decl_auto(pc);
1701}1683}
17021684
1703// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE1685// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
test/compile_errors.zig-9
...@@ -587,15 +587,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -587,15 +587,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
587 "tmp.zig:1:13: error: threadlocal variable cannot be constant",587 "tmp.zig:1:13: error: threadlocal variable cannot be constant",
588 );588 );
589589
590 cases.add(
591 "threadlocal qualifier on local variable",
592 \\export fn entry() void {
593 \\ threadlocal var x: i32 = 1234;
594 \\}
595 ,
596 "tmp.zig:2:5: error: function-local variable 'x' cannot be threadlocal",
597 );
598
599 cases.add(590 cases.add(
600 "@bitCast same size but bit count mismatch",591 "@bitCast same size but bit count mismatch",
601 \\export fn entry(byte: u8) void {592 \\export fn entry(byte: u8) void {