diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-11-23 04:45:35 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-11-23 04:45:35 -0500 |
| commit | 7597735badd1f6aa6750f354a7e9c85fec705c55 (patch) | |
| tree | 69e5e1b3795afcf065b0a40203ba4f678a4532d7 /src/parser.cpp | |
| parent | 6b623b5ea2a811b54a2391f17081a8981fa733a5 (diff) | |
| download | zig-7597735badd1f6aa6750f354a7e9c85fec705c55.tar.gz zig-7597735badd1f6aa6750f354a7e9c85fec705c55.zip | |
update the stage1 implementation to the new proposal
See #3731
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 184 |
1 files changed, 111 insertions, 73 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index c3f719425b..61f3120d0e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1833,8 +1833,10 @@ static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) { return loop; } - if (label != nullptr) - ast_invalid_token_error(pc, peek_token(pc)); + if (label != nullptr) { + put_back_token(pc); + put_back_token(pc); + } return nullptr; } @@ -1931,15 +1933,11 @@ static AstNode *ast_parse_asm_output(ParseContext *pc) { // AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) { - Token *sym_name = eat_token_if(pc, TokenIdBracketUnderscoreBracket); - if (sym_name == nullptr) { - if (eat_token_if(pc, TokenIdLBracket) == nullptr) { - return nullptr; - } else { - sym_name = expect_token(pc, TokenIdSymbol); - expect_token(pc, TokenIdRBracket); - } - } + if (eat_token_if(pc, TokenIdLBracket) == nullptr) + return nullptr; + + Token *sym_name = expect_token(pc, TokenIdSymbol); + expect_token(pc, TokenIdRBracket); Token *str = expect_token(pc, TokenIdStringLiteral); expect_token(pc, TokenIdLParen); @@ -1954,7 +1952,7 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) { expect_token(pc, TokenIdRParen); AsmOutput *res = allocate<AsmOutput>(1); - res->asm_symbolic_name = (sym_name->id == TokenIdBracketUnderscoreBracket) ? buf_create_from_str("_") : token_buf(sym_name); + res->asm_symbolic_name = token_buf(sym_name); res->constraint = token_buf(str); res->variable_name = token_buf(var_name); res->return_type = return_type; @@ -1977,15 +1975,11 @@ static AstNode *ast_parse_asm_input(ParseContext *pc) { // AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN static AsmInput *ast_parse_asm_input_item(ParseContext *pc) { - Token *sym_name = eat_token_if(pc, TokenIdBracketUnderscoreBracket); - if (sym_name == nullptr) { - if (eat_token_if(pc, TokenIdLBracket) == nullptr) { - return nullptr; - } else { - sym_name = expect_token(pc, TokenIdSymbol); - expect_token(pc, TokenIdRBracket); - } - } + if (eat_token_if(pc, TokenIdLBracket) == nullptr) + return nullptr; + + Token *sym_name = expect_token(pc, TokenIdSymbol); + expect_token(pc, TokenIdRBracket); Token *constraint = expect_token(pc, TokenIdStringLiteral); expect_token(pc, TokenIdLParen); @@ -1993,7 +1987,7 @@ static AsmInput *ast_parse_asm_input_item(ParseContext *pc) { expect_token(pc, TokenIdRParen); AsmInput *res = allocate<AsmInput>(1); - res->asm_symbolic_name = (sym_name->id == TokenIdBracketUnderscoreBracket) ? buf_create_from_str("_") : token_buf(sym_name); + res->asm_symbolic_name = token_buf(sym_name); res->constraint = token_buf(constraint); res->expr = expr; return res; @@ -2613,42 +2607,28 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) { put_back_token(pc); } - AstNode *array = ast_parse_array_type_start(pc); - if (array != nullptr) { - assert(array->type == NodeTypeArrayType); - while (true) { - if (eat_token_if(pc, TokenIdKeywordNull) != nullptr) { - array->data.array_type.is_null_terminated = true; - continue; - } - - Token *allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero); - if (allowzero_token != nullptr) { - array->data.array_type.allow_zero_token = allowzero_token; - continue; - } - - AstNode *align_expr = ast_parse_byte_align(pc); - if (align_expr != nullptr) { - array->data.array_type.align_expr = align_expr; - continue; - } - - if (eat_token_if(pc, TokenIdKeywordConst) != nullptr) { - array->data.array_type.is_const = true; - continue; - } - - if (eat_token_if(pc, TokenIdKeywordVolatile) != nullptr) { - array->data.array_type.is_volatile = true; - continue; + Token *arr_init_lbracket = eat_token_if(pc, TokenIdLBracket); + if (arr_init_lbracket != nullptr) { + Token *underscore = eat_token_if(pc, TokenIdSymbol); + if (underscore == nullptr) { + put_back_token(pc); + } else if (!buf_eql_str(token_buf(underscore), "_")) { + put_back_token(pc); + put_back_token(pc); + } else { + AstNode *sentinel = nullptr; + Token *colon = eat_token_if(pc, TokenIdColon); + if (colon != nullptr) { + sentinel = ast_expect(pc, ast_parse_expr); } - break; + expect_token(pc, TokenIdRBracket); + AstNode *node = ast_create_node(pc, NodeTypeInferredArrayType, arr_init_lbracket); + node->data.inferred_array_type.sentinel = sentinel; + return node; } - - return array; } + AstNode *ptr = ast_parse_ptr_type_start(pc); if (ptr != nullptr) { assert(ptr->type == NodeTypePointerType); @@ -2657,11 +2637,6 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) { if (child == nullptr) child = ptr; while (true) { - if (eat_token_if(pc, TokenIdKeywordNull) != nullptr) { - child->data.pointer_type.is_null_terminated = true; - continue; - } - Token *allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero); if (allowzero_token != nullptr) { child->data.pointer_type.allow_zero_token = allowzero_token; @@ -2699,9 +2674,35 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) { return ptr; } - Token *arr_init = eat_token_if(pc, TokenIdBracketUnderscoreBracket); - if (arr_init != nullptr) { - return ast_create_node(pc, NodeTypeInferredArrayType, arr_init); + AstNode *array = ast_parse_array_type_start(pc); + if (array != nullptr) { + assert(array->type == NodeTypeArrayType); + while (true) { + Token *allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero); + if (allowzero_token != nullptr) { + array->data.array_type.allow_zero_token = allowzero_token; + continue; + } + + AstNode *align_expr = ast_parse_byte_align(pc); + if (align_expr != nullptr) { + array->data.array_type.align_expr = align_expr; + continue; + } + + if (eat_token_if(pc, TokenIdKeywordConst) != nullptr) { + array->data.array_type.is_const = true; + continue; + } + + if (eat_token_if(pc, TokenIdKeywordVolatile) != nullptr) { + array->data.array_type.is_volatile = true; + continue; + } + break; + } + + return array; } @@ -2775,9 +2776,15 @@ static AstNode *ast_parse_array_type_start(ParseContext *pc) { return nullptr; AstNode *size = ast_parse_expr(pc); + AstNode *sentinel = nullptr; + Token *colon = eat_token_if(pc, TokenIdColon); + if (colon != nullptr) { + sentinel = ast_expect(pc, ast_parse_expr); + } expect_token(pc, TokenIdRBracket); AstNode *res = ast_create_node(pc, NodeTypeArrayType, lbracket); res->data.array_type.size = size; + res->data.array_type.sentinel = sentinel; return res; } @@ -2787,35 +2794,63 @@ static AstNode *ast_parse_array_type_start(ParseContext *pc) { // / PTRUNKNOWN // / PTRC static AstNode *ast_parse_ptr_type_start(ParseContext *pc) { + AstNode *sentinel = nullptr; + Token *asterisk = eat_token_if(pc, TokenIdStar); if (asterisk != nullptr) { + Token *colon = eat_token_if(pc, TokenIdColon); + if (colon != nullptr) { + sentinel = ast_expect(pc, ast_parse_expr); + } AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk); res->data.pointer_type.star_token = asterisk; + res->data.pointer_type.sentinel = sentinel; return res; } Token *asterisk2 = eat_token_if(pc, TokenIdStarStar); if (asterisk2 != nullptr) { + Token *colon = eat_token_if(pc, TokenIdColon); + if (colon != nullptr) { + sentinel = ast_expect(pc, ast_parse_expr); + } AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk2); AstNode *res2 = ast_create_node(pc, NodeTypePointerType, asterisk2); res->data.pointer_type.star_token = asterisk2; res2->data.pointer_type.star_token = asterisk2; + res2->data.pointer_type.sentinel = sentinel; res->data.pointer_type.op_expr = res2; return res; } - Token *multptr = eat_token_if(pc, TokenIdBracketStarBracket); - if (multptr != nullptr) { - AstNode *res = ast_create_node(pc, NodeTypePointerType, multptr); - res->data.pointer_type.star_token = multptr; - return res; - } + Token *lbracket = eat_token_if(pc, TokenIdLBracket); + if (lbracket != nullptr) { + Token *star = eat_token_if(pc, TokenIdStar); + if (star == nullptr) { + put_back_token(pc); + } else { + Token *c_tok = eat_token_if(pc, TokenIdSymbol); + if (c_tok != nullptr) { + if (!buf_eql_str(token_buf(c_tok), "c")) { + put_back_token(pc); // c symbol + } else { + expect_token(pc, TokenIdRBracket); + AstNode *res = ast_create_node(pc, NodeTypePointerType, lbracket); + res->data.pointer_type.star_token = c_tok; + return res; + } + } - Token *cptr = eat_token_if(pc, TokenIdBracketStarCBracket); - if (cptr != nullptr) { - AstNode *res = ast_create_node(pc, NodeTypePointerType, cptr); - res->data.pointer_type.star_token = cptr; - return res; + Token *colon = eat_token_if(pc, TokenIdColon); + if (colon != nullptr) { + sentinel = ast_expect(pc, ast_parse_expr); + } + expect_token(pc, TokenIdRBracket); + AstNode *res = ast_create_node(pc, NodeTypePointerType, lbracket); + res->data.pointer_type.star_token = lbracket; + res->data.pointer_type.sentinel = sentinel; + return res; + } } return nullptr; @@ -3093,10 +3128,12 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont break; case NodeTypeArrayType: visit_field(&node->data.array_type.size, visit, context); + visit_field(&node->data.array_type.sentinel, visit, context); visit_field(&node->data.array_type.child_type, visit, context); visit_field(&node->data.array_type.align_expr, visit, context); break; case NodeTypeInferredArrayType: + visit_field(&node->data.array_type.sentinel, visit, context); visit_field(&node->data.array_type.child_type, visit, context); break; case NodeTypeAnyFrameType: @@ -3106,6 +3143,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont // none break; case NodeTypePointerType: + visit_field(&node->data.pointer_type.sentinel, visit, context); visit_field(&node->data.pointer_type.align_expr, visit, context); visit_field(&node->data.pointer_type.op_expr, visit, context); break; |
