aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorhryx <codroid@gmail.com>2019-05-12 02:00:49 -0700
committerhryx <codroid@gmail.com>2019-05-12 02:00:49 -0700
commit3787f3428625e830fd852a8f5a40c7d8a2d429f6 (patch)
tree23fb493b9d2f07c7abe57955874682959936319a /src/parser.cpp
parent16aee1f58a80295f7599a8290d764a5c7040c373 (diff)
parentedcc7c72d1a684a8a16ca23ad26689f2cce4e803 (diff)
downloadzig-3787f3428625e830fd852a8f5a40c7d8a2d429f6.tar.gz
zig-3787f3428625e830fd852a8f5a40c7d8a2d429f6.zip
Merge branch 'master' into rebased
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp114
1 files changed, 57 insertions, 57 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 9172e21b92..583accfd72 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -577,7 +577,7 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
// TopLevelDecl
// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
-// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl
+// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
// / KEYWORD_use Expr SEMICOLON
static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
Token *first = eat_token_if(pc, TokenIdKeywordExport);
@@ -591,17 +591,22 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
lib_name = eat_token_if(pc, TokenIdStringLiteral);
if (first->id != TokenIdKeywordInline) {
+ Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
AstNode *var_decl = ast_parse_var_decl(pc);
if (var_decl != nullptr) {
assert(var_decl->type == NodeTypeVariableDeclaration);
var_decl->line = first->start_line;
var_decl->column = first->start_column;
+ var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
var_decl->data.variable_declaration.visib_mod = visib_mod;
var_decl->data.variable_declaration.is_extern = first->id == TokenIdKeywordExtern;
var_decl->data.variable_declaration.is_export = first->id == TokenIdKeywordExport;
var_decl->data.variable_declaration.lib_name = token_buf(lib_name);
return var_decl;
}
+
+ if (thread_local_kw != nullptr)
+ put_back_token(pc);
}
AstNode *fn_proto = ast_parse_fn_proto(pc);
@@ -632,13 +637,18 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
ast_invalid_token_error(pc, peek_token(pc));
}
+ Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
AstNode *var_decl = ast_parse_var_decl(pc);
if (var_decl != nullptr) {
assert(var_decl->type == NodeTypeVariableDeclaration);
var_decl->data.variable_declaration.visib_mod = visib_mod;
+ var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
return var_decl;
}
+ if (thread_local_kw != nullptr)
+ put_back_token(pc);
+
AstNode *fn_proto = ast_parse_fn_proto(pc);
if (fn_proto != nullptr) {
AstNode *body = ast_parse_block(pc);
@@ -741,17 +751,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
static AstNode *ast_parse_var_decl(ParseContext *pc) {
- Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);
if (mut_kw == nullptr)
mut_kw = eat_token_if(pc, TokenIdKeywordVar);
- if (mut_kw == nullptr) {
- if (thread_local_kw == nullptr) {
- return nullptr;
- } else {
- ast_invalid_token_error(pc, peek_token(pc));
- }
- }
+ if (mut_kw == nullptr)
+ return nullptr;
+
Token *identifier = expect_token(pc, TokenIdSymbol);
AstNode *type_expr = nullptr;
if (eat_token_if(pc, TokenIdColon) != nullptr)
@@ -766,7 +771,6 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
expect_token(pc, TokenIdSemicolon);
AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
- res->data.variable_declaration.threadlocal_tok = thread_local_kw;
res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;
res->data.variable_declaration.symbol = token_buf(identifier);
res->data.variable_declaration.type = type_expr;
@@ -952,17 +956,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
static AstNode *ast_parse_loop_statement(ParseContext *pc) {
- Token *label = ast_parse_block_label(pc);
- Token *first = label;
-
Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);
- if (first == nullptr)
- first = inline_token;
-
AstNode *for_statement = ast_parse_for_statement(pc);
if (for_statement != nullptr) {
assert(for_statement->type == NodeTypeForExpr);
- for_statement->data.for_expr.name = token_buf(label);
for_statement->data.for_expr.is_inline = inline_token != nullptr;
return for_statement;
}
@@ -970,12 +967,11 @@ static AstNode *ast_parse_loop_statement(ParseContext *pc) {
AstNode *while_statement = ast_parse_while_statement(pc);
if (while_statement != nullptr) {
assert(while_statement->type == NodeTypeWhileExpr);
- while_statement->data.while_expr.name = token_buf(label);
while_statement->data.while_expr.is_inline = inline_token != nullptr;
return while_statement;
}
- if (first != nullptr)
+ if (inline_token != nullptr)
ast_invalid_token_error(pc, peek_token(pc));
return nullptr;
}
@@ -1117,7 +1113,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc) {
// CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
static AstNode *ast_parse_compare_expr(ParseContext *pc) {
- return ast_parse_bin_op_expr(pc, BinOpChainInf, ast_parse_compare_op, ast_parse_bitwise_expr);
+ return ast_parse_bin_op_expr(pc, BinOpChainOnce, ast_parse_compare_op, ast_parse_bitwise_expr);
}
// BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
@@ -1162,10 +1158,6 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
// / Block
// / CurlySuffixExpr
static AstNode *ast_parse_primary_expr(ParseContext *pc) {
- AstNode *enum_lit = ast_parse_enum_lit(pc);
- if (enum_lit != nullptr)
- return enum_lit;
-
AstNode *asm_expr = ast_parse_asm_expr(pc);
if (asm_expr != nullptr)
return asm_expr;
@@ -1246,11 +1238,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
}
AstNode *block = ast_parse_block(pc);
- if (block != nullptr) {
- assert(block->type == NodeTypeBlock);
- block->data.block.name = token_buf(label);
+ if (block != nullptr)
return block;
- }
AstNode *curly_suffix = ast_parse_curly_suffix_expr(pc);
if (curly_suffix != nullptr)
@@ -1503,6 +1492,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
// <- BUILTINIDENTIFIER FnCallArguments
// / CHAR_LITERAL
// / ContainerDecl
+// / DOT IDENTIFIER
// / ErrorSetDecl
// / FLOAT
// / FnProto
@@ -1563,6 +1553,10 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
if (container_decl != nullptr)
return container_decl;
+ AstNode *enum_lit = ast_parse_enum_lit(pc);
+ if (enum_lit != nullptr)
+ return enum_lit;
+
AstNode *error_set_decl = ast_parse_error_set_decl(pc);
if (error_set_decl != nullptr)
return error_set_decl;
@@ -1672,32 +1666,26 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
static AstNode *ast_parse_container_decl(ParseContext *pc) {
- Token *extern_token = eat_token_if(pc, TokenIdKeywordExtern);
- if (extern_token != nullptr) {
- AstNode *res = ast_parse_container_decl_auto(pc);
- if (res == nullptr) {
- put_back_token(pc);
- return nullptr;
- }
+ Token *layout_token = eat_token_if(pc, TokenIdKeywordExtern);
+ if (layout_token == nullptr)
+ layout_token = eat_token_if(pc, TokenIdKeywordPacked);
- assert(res->type == NodeTypeContainerDecl);
- res->line = extern_token->start_line;
- res->column = extern_token->start_column;
- res->data.container_decl.layout = ContainerLayoutExtern;
- return res;
+ AstNode *res = ast_parse_container_decl_auto(pc);
+ if (res == nullptr) {
+ if (layout_token != nullptr)
+ put_back_token(pc);
+ return nullptr;
}
- Token *packed_token = eat_token_if(pc, TokenIdKeywordPacked);
- if (packed_token != nullptr) {
- AstNode *res = ast_expect(pc, ast_parse_container_decl_auto);
- assert(res->type == NodeTypeContainerDecl);
- res->line = packed_token->start_line;
- res->column = packed_token->start_column;
- res->data.container_decl.layout = ContainerLayoutPacked;
- return res;
+ assert(res->type == NodeTypeContainerDecl);
+ if (layout_token != nullptr) {
+ res->line = layout_token->start_line;
+ res->column = layout_token->start_column;
+ res->data.container_decl.layout = layout_token->id == TokenIdKeywordExtern
+ ? ContainerLayoutExtern
+ : ContainerLayoutPacked;
}
-
- return ast_parse_container_decl_auto(pc);
+ return res;
}
// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
@@ -1971,7 +1959,14 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {
return nullptr;
Token *name = expect_token(pc, TokenIdSymbol);
- expect_token(pc, TokenIdEq);
+ if (eat_token_if(pc, TokenIdEq) == nullptr) {
+ // Because ".Name" can also be intepreted as an enum literal, we should put back
+ // those two tokens again so that the parser can try to parse them as the enum
+ // literal later.
+ put_back_token(pc);
+ put_back_token(pc);
+ return nullptr;
+ }
AstNode *expr = ast_expect(pc, ast_parse_expr);
AstNode *res = ast_create_node(pc, NodeTypeStructValueField, first);
@@ -2750,12 +2745,19 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
}
// ContainerDeclType
-// <- (KEYWORD_struct / KEYWORD_enum) (LPAREN Expr RPAREN)?
+// <- KEYWORD_struct
+// / KEYWORD_enum (LPAREN Expr RPAREN)?
// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
Token *first = eat_token_if(pc, TokenIdKeywordStruct);
- if (first == nullptr)
- first = eat_token_if(pc, TokenIdKeywordEnum);
+ if (first != nullptr) {
+ AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
+ res->data.container_decl.init_arg_expr = nullptr;
+ res->data.container_decl.kind = ContainerKindStruct;
+ return res;
+ }
+
+ first = eat_token_if(pc, TokenIdKeywordEnum);
if (first != nullptr) {
AstNode *init_arg_expr = nullptr;
if (eat_token_if(pc, TokenIdLParen) != nullptr) {
@@ -2764,9 +2766,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
}
AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
res->data.container_decl.init_arg_expr = init_arg_expr;
- res->data.container_decl.kind = first->id == TokenIdKeywordStruct
- ? ContainerKindStruct
- : ContainerKindEnum;
+ res->data.container_decl.kind = ContainerKindEnum;
return res;
}