Skip to content

Commit 6b10f03

Browse files
committed
Fixes and simplifications for stage 1 parser
1 parent bcf4d20 commit 6b10f03

File tree

3 files changed

+31
-59
lines changed

3 files changed

+31
-59
lines changed

src/ir.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5433,10 +5433,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
54335433
add_node_error(irb->codegen, variable_declaration->section_expr,
54345434
buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
54355435
}
5436-
if (variable_declaration->threadlocal_tok != nullptr) {
5437-
add_token_error(irb->codegen, node->owner, variable_declaration->threadlocal_tok,
5438-
buf_sprintf("function-local variable '%s' cannot be threadlocal", buf_ptr(variable_declaration->symbol)));
5439-
}
5436+
5437+
// Parser should ensure that this never happens
5438+
assert(variable_declaration->threadlocal_tok == nullptr);
54405439

54415440
// Temporarily set the name of the IrExecutable to the VariableDeclaration
54425441
// so that the struct or enum from the init expression inherits the name.

src/parser.cpp

Lines changed: 28 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
577577

578578
// TopLevelDecl
579579
// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
580-
// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl
580+
// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
581581
// / KEYWORD_use Expr SEMICOLON
582582
static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
583583
Token *first = eat_token_if(pc, TokenIdKeywordExport);
@@ -632,13 +632,18 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
632632
ast_invalid_token_error(pc, peek_token(pc));
633633
}
634634

635+
Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
635636
AstNode *var_decl = ast_parse_var_decl(pc);
636637
if (var_decl != nullptr) {
637638
assert(var_decl->type == NodeTypeVariableDeclaration);
638639
var_decl->data.variable_declaration.visib_mod = visib_mod;
640+
var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
639641
return var_decl;
640642
}
641643

644+
if (thread_local_kw != nullptr)
645+
put_back_token(pc);
646+
642647
AstNode *fn_proto = ast_parse_fn_proto(pc);
643648
if (fn_proto != nullptr) {
644649
AstNode *body = ast_parse_block(pc);
@@ -741,17 +746,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
741746

742747
// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
743748
static AstNode *ast_parse_var_decl(ParseContext *pc) {
744-
Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
745749
Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);
746750
if (mut_kw == nullptr)
747751
mut_kw = eat_token_if(pc, TokenIdKeywordVar);
748-
if (mut_kw == nullptr) {
749-
if (thread_local_kw == nullptr) {
750-
return nullptr;
751-
} else {
752-
ast_invalid_token_error(pc, peek_token(pc));
753-
}
754-
}
752+
if (mut_kw == nullptr)
753+
return nullptr;
754+
755755
Token *identifier = expect_token(pc, TokenIdSymbol);
756756
AstNode *type_expr = nullptr;
757757
if (eat_token_if(pc, TokenIdColon) != nullptr)
@@ -766,7 +766,6 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
766766
expect_token(pc, TokenIdSemicolon);
767767

768768
AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
769-
res->data.variable_declaration.threadlocal_tok = thread_local_kw;
770769
res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;
771770
res->data.variable_declaration.symbol = token_buf(identifier);
772771
res->data.variable_declaration.type = type_expr;
@@ -952,30 +951,22 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
952951

953952
// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
954953
static AstNode *ast_parse_loop_statement(ParseContext *pc) {
955-
Token *label = ast_parse_block_label(pc);
956-
Token *first = label;
957-
958954
Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);
959-
if (first == nullptr)
960-
first = inline_token;
961-
962955
AstNode *for_statement = ast_parse_for_statement(pc);
963956
if (for_statement != nullptr) {
964957
assert(for_statement->type == NodeTypeForExpr);
965-
for_statement->data.for_expr.name = token_buf(label);
966958
for_statement->data.for_expr.is_inline = inline_token != nullptr;
967959
return for_statement;
968960
}
969961

970962
AstNode *while_statement = ast_parse_while_statement(pc);
971963
if (while_statement != nullptr) {
972964
assert(while_statement->type == NodeTypeWhileExpr);
973-
while_statement->data.while_expr.name = token_buf(label);
974965
while_statement->data.while_expr.is_inline = inline_token != nullptr;
975966
return while_statement;
976967
}
977968

978-
if (first != nullptr)
969+
if (inline_token != nullptr)
979970
ast_invalid_token_error(pc, peek_token(pc));
980971
return nullptr;
981972
}
@@ -1117,7 +1108,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc) {
11171108

11181109
// CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
11191110
static 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);
11211112
}
11221113

11231114
// BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
@@ -1246,11 +1237,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
12461237
}
12471238

12481239
AstNode *block = ast_parse_block(pc);
1249-
if (block != nullptr) {
1250-
assert(block->type == NodeTypeBlock);
1251-
block->data.block.name = token_buf(label);
1240+
if (block != nullptr)
12521241
return block;
1253-
}
12541242

12551243
AstNode *curly_suffix = ast_parse_curly_suffix_expr(pc);
12561244
if (curly_suffix != nullptr)
@@ -1672,32 +1660,26 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
16721660

16731661
// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
16741662
static AstNode *ast_parse_container_decl(ParseContext *pc) {
1675-
Token *extern_token = eat_token_if(pc, TokenIdKeywordExtern);
1676-
if (extern_token != nullptr) {
1677-
AstNode *res = ast_parse_container_decl_auto(pc);
1678-
if (res == nullptr) {
1679-
put_back_token(pc);
1680-
return nullptr;
1681-
}
1663+
Token *layout_token = eat_token_if(pc, TokenIdKeywordExtern);
1664+
if (layout_token == nullptr)
1665+
layout_token = eat_token_if(pc, TokenIdKeywordPacked);
16821666

1683-
assert(res->type == NodeTypeContainerDecl);
1684-
res->line = extern_token->start_line;
1685-
res->column = extern_token->start_column;
1686-
res->data.container_decl.layout = ContainerLayoutExtern;
1687-
return res;
1667+
AstNode *res = ast_parse_container_decl_auto(pc);
1668+
if (res == nullptr) {
1669+
if (layout_token != nullptr)
1670+
put_back_token(pc);
1671+
return nullptr;
16881672
}
16891673

1690-
Token *packed_token = eat_token_if(pc, TokenIdKeywordPacked);
1691-
if (packed_token != nullptr) {
1692-
AstNode *res = ast_expect(pc, ast_parse_container_decl_auto);
1693-
assert(res->type == NodeTypeContainerDecl);
1694-
res->line = packed_token->start_line;
1695-
res->column = packed_token->start_column;
1696-
res->data.container_decl.layout = ContainerLayoutPacked;
1697-
return res;
1674+
assert(res->type == NodeTypeContainerDecl);
1675+
if (layout_token != nullptr) {
1676+
res->line = layout_token->start_line;
1677+
res->column = layout_token->start_column;
1678+
res->data.container_decl.layout = layout_token->id == TokenIdKeywordExtern
1679+
? ContainerLayoutExtern
1680+
: ContainerLayoutPacked;
16981681
}
1699-
1700-
return ast_parse_container_decl_auto(pc);
1682+
return res;
17011683
}
17021684

17031685
// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE

test/compile_errors.zig

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -587,15 +587,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
587587
"tmp.zig:1:13: error: threadlocal variable cannot be constant",
588588
);
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-
599590
cases.add(
600591
"@bitCast same size but bit count mismatch",
601592
\\export fn entry(byte: u8) void {

0 commit comments

Comments
 (0)