update the stage1 implementation to the new proposal

See #3731
This commit is contained in:
Andrew Kelley
2019-11-23 04:45:35 -05:00
parent 6b623b5ea2
commit 7597735bad
21 changed files with 613 additions and 442 deletions

View File

@@ -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 *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);
}
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;
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;