| ... | ... | @@ -583,6 +583,40 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m |
| 583 | 583 | return node; |
| 584 | 584 | } |
| 585 | 585 | |
| 586 | /* |
| 587 | GotoExpression = option("inline") "goto" Symbol |
| 588 | */ |
| 589 | static AstNode *ast_parse_goto_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 590 | Token *first_token = &pc->tokens->at(*token_index); |
| 591 | Token *goto_token; |
| 592 | bool is_inline; |
| 593 | if (first_token->id == TokenIdKeywordInline) { |
| 594 | is_inline = true; |
| 595 | goto_token = &pc->tokens->at(*token_index + 1); |
| 596 | if (goto_token->id == TokenIdKeywordGoto) { |
| 597 | *token_index += 2; |
| 598 | } else if (mandatory) { |
| 599 | ast_expect_token(pc, first_token, TokenIdKeywordGoto); |
| 600 | } else { |
| 601 | return nullptr; |
| 602 | } |
| 603 | } else if (first_token->id == TokenIdKeywordGoto) { |
| 604 | goto_token = first_token; |
| 605 | is_inline = false; |
| 606 | *token_index += 1; |
| 607 | } else if (mandatory) { |
| 608 | ast_expect_token(pc, first_token, TokenIdKeywordGoto); |
| 609 | } else { |
| 610 | return nullptr; |
| 611 | } |
| 612 | |
| 613 | AstNode *node = ast_create_node(pc, NodeTypeGoto, goto_token); |
| 614 | |
| 615 | Token *dest_symbol = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 616 | node->data.goto_expr.name = token_buf(dest_symbol); |
| 617 | node->data.goto_expr.is_inline = is_inline; |
| 618 | return node; |
| 619 | } |
| 586 | 620 | /* |
| 587 | 621 | PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol") |
| 588 | 622 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this" |
| ... | ... | @@ -672,18 +706,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo |
| 672 | 706 | AstNode *node = ast_create_node(pc, NodeTypeSymbol, token); |
| 673 | 707 | node->data.symbol_expr.symbol = token_buf(token); |
| 674 | 708 | return node; |
| 675 | | } else if (token->id == TokenIdKeywordGoto) { |
| 676 | | AstNode *node = ast_create_node(pc, NodeTypeGoto, token); |
| 677 | | *token_index += 1; |
| 678 | | |
| 679 | | Token *dest_symbol = &pc->tokens->at(*token_index); |
| 680 | | *token_index += 1; |
| 681 | | ast_expect_token(pc, dest_symbol, TokenIdSymbol); |
| 682 | | |
| 683 | | node->data.goto_expr.name = token_buf(dest_symbol); |
| 684 | | return node; |
| 685 | 709 | } |
| 686 | 710 | |
| 711 | AstNode *goto_node = ast_parse_goto_expr(pc, token_index, false); |
| 712 | if (goto_node) |
| 713 | return goto_node; |
| 714 | |
| 687 | 715 | AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false); |
| 688 | 716 | if (grouped_expr_node) { |
| 689 | 717 | return grouped_expr_node; |