aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-11-23 04:45:35 -0500
committerAndrew Kelley <andrew@ziglang.org>2019-11-23 04:45:35 -0500
commit7597735badd1f6aa6750f354a7e9c85fec705c55 (patch)
tree69e5e1b3795afcf065b0a40203ba4f678a4532d7 /src/parser.cpp
parent6b623b5ea2a811b54a2391f17081a8981fa733a5 (diff)
downloadzig-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.cpp184
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;