| author | |
| committer | |
| log | c1d77f2a231461d88ad493c92079cc571e565f87 |
| tree | 8a85649f49e567f796445d751052fbd4b105fa7c |
| parent | 918e7641fcaa79f75a365751de571807578ae503 |
4 files changed, 99 insertions(+), 96 deletions(-)
README.md+4-4| ... | @@ -88,6 +88,8 @@ ExternBlock : many(Directive) token(Extern) token(LBrace) many(FnDecl) token(RBr | ... | @@ -88,6 +88,8 @@ ExternBlock : many(Directive) token(Extern) token(LBrace) many(FnDecl) token(RBr |
| 88 | 88 | ||
| 89 | FnProto : many(Directive) option(FnVisibleMod) token(Fn) token(Symbol) ParamDeclList option(token(Arrow) Type) | 89 | FnProto : many(Directive) option(FnVisibleMod) token(Fn) token(Symbol) ParamDeclList option(token(Arrow) Type) |
| 90 | 90 | ||
| 91 | Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen) | ||
| 92 | |||
| 91 | FnVisibleMod : token(Pub) | token(Export) | 93 | FnVisibleMod : token(Pub) | token(Export) |
| 92 | 94 | ||
| 93 | FnDecl : FnProto token(Semicolon) | 95 | FnDecl : FnProto token(Semicolon) |
| ... | @@ -142,15 +144,13 @@ CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression | ... | @@ -142,15 +144,13 @@ CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression |
| 142 | 144 | ||
| 143 | PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression | 145 | PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression |
| 144 | 146 | ||
| 145 | FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | 147 | FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression |
| 146 | 148 | ||
| 147 | PrefixOp : token(Not) | token(Dash) | token(Tilde) | 149 | PrefixOp : token(Not) | token(Dash) | token(Tilde) |
| 148 | 150 | ||
| 149 | PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | 151 | PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | token(Symbol) |
| 150 | 152 | ||
| 151 | GroupedExpression : token(LParen) Expression token(RParen) | 153 | GroupedExpression : token(LParen) Expression token(RParen) |
| 152 | |||
| 153 | Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen) | ||
| 154 | ``` | 154 | ``` |
| 155 | 155 | ||
| 156 | ### Operator Precedence | 156 | ### Operator Precedence |
src/codegen.cpp+49-39| ... | @@ -306,7 +306,7 @@ static void find_declarations(CodeGen *g, AstNode *node) { | ... | @@ -306,7 +306,7 @@ static void find_declarations(CodeGen *g, AstNode *node) { |
| 306 | case NodeTypeRoot: | 306 | case NodeTypeRoot: |
| 307 | case NodeTypeBlock: | 307 | case NodeTypeBlock: |
| 308 | case NodeTypeBoolOrExpr: | 308 | case NodeTypeBoolOrExpr: |
| 309 | case NodeTypeFnCall: | 309 | case NodeTypeFnCallExpr: |
| 310 | case NodeTypeRootExportDecl: | 310 | case NodeTypeRootExportDecl: |
| 311 | case NodeTypeBoolAndExpr: | 311 | case NodeTypeBoolAndExpr: |
| 312 | case NodeTypeComparisonExpr: | 312 | case NodeTypeComparisonExpr: |
| ... | @@ -378,6 +378,14 @@ static void check_fn_def_control_flow(CodeGen *g, AstNode *node) { | ... | @@ -378,6 +378,14 @@ static void check_fn_def_control_flow(CodeGen *g, AstNode *node) { |
| 378 | } | 378 | } |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | static Buf *hack_get_fn_call_name(CodeGen *g, AstNode *node) { | ||
| 382 | // Assume that the expression evaluates to a simple name and return the buf | ||
| 383 | // TODO after type checking works we should be able to remove this hack | ||
| 384 | assert(node->type == NodeTypePrimaryExpr); | ||
| 385 | assert(node->data.primary_expr.type == PrimaryExprTypeSymbol); | ||
| 386 | return &node->data.primary_expr.data.symbol; | ||
| 387 | } | ||
| 388 | |||
| 381 | static void analyze_node(CodeGen *g, AstNode *node) { | 389 | static void analyze_node(CodeGen *g, AstNode *node) { |
| 382 | switch (node->type) { | 390 | switch (node->type) { |
| 383 | case NodeTypeRoot: | 391 | case NodeTypeRoot: |
| ... | @@ -487,9 +495,9 @@ static void analyze_node(CodeGen *g, AstNode *node) { | ... | @@ -487,9 +495,9 @@ static void analyze_node(CodeGen *g, AstNode *node) { |
| 487 | if (node->data.bool_or_expr.op2) | 495 | if (node->data.bool_or_expr.op2) |
| 488 | analyze_node(g, node->data.bool_or_expr.op2); | 496 | analyze_node(g, node->data.bool_or_expr.op2); |
| 489 | break; | 497 | break; |
| 490 | case NodeTypeFnCall: | 498 | case NodeTypeFnCallExpr: |
| 491 | { | 499 | { |
| 492 | Buf *name = &node->data.fn_call.name; | 500 | Buf *name = hack_get_fn_call_name(g, node->data.fn_call_expr.fn_ref_expr); |
| 493 | 501 | ||
| 494 | auto entry = g->fn_table.maybe_get(name); | 502 | auto entry = g->fn_table.maybe_get(name); |
| 495 | if (!entry) { | 503 | if (!entry) { |
| ... | @@ -499,7 +507,7 @@ static void analyze_node(CodeGen *g, AstNode *node) { | ... | @@ -499,7 +507,7 @@ static void analyze_node(CodeGen *g, AstNode *node) { |
| 499 | FnTableEntry *fn_table_entry = entry->value; | 507 | FnTableEntry *fn_table_entry = entry->value; |
| 500 | assert(fn_table_entry->proto_node->type == NodeTypeFnProto); | 508 | assert(fn_table_entry->proto_node->type == NodeTypeFnProto); |
| 501 | int expected_param_count = fn_table_entry->proto_node->data.fn_proto.params.length; | 509 | int expected_param_count = fn_table_entry->proto_node->data.fn_proto.params.length; |
| 502 | int actual_param_count = node->data.fn_call.params.length; | 510 | int actual_param_count = node->data.fn_call_expr.params.length; |
| 503 | if (expected_param_count != actual_param_count) { | 511 | if (expected_param_count != actual_param_count) { |
| 504 | add_node_error(g, node, | 512 | add_node_error(g, node, |
| 505 | buf_sprintf("wrong number of arguments. Expected %d, got %d.", | 513 | buf_sprintf("wrong number of arguments. Expected %d, got %d.", |
| ... | @@ -507,8 +515,8 @@ static void analyze_node(CodeGen *g, AstNode *node) { | ... | @@ -507,8 +515,8 @@ static void analyze_node(CodeGen *g, AstNode *node) { |
| 507 | } | 515 | } |
| 508 | } | 516 | } |
| 509 | 517 | ||
| 510 | for (int i = 0; i < node->data.fn_call.params.length; i += 1) { | 518 | for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) { |
| 511 | AstNode *child = node->data.fn_call.params.at(i); | 519 | AstNode *child = node->data.fn_call_expr.params.at(i); |
| 512 | analyze_node(g, child); | 520 | analyze_node(g, child); |
| 513 | } | 521 | } |
| 514 | break; | 522 | break; |
| ... | @@ -551,11 +559,9 @@ static void analyze_node(CodeGen *g, AstNode *node) { | ... | @@ -551,11 +559,9 @@ static void analyze_node(CodeGen *g, AstNode *node) { |
| 551 | case PrimaryExprTypeNumber: | 559 | case PrimaryExprTypeNumber: |
| 552 | case PrimaryExprTypeString: | 560 | case PrimaryExprTypeString: |
| 553 | case PrimaryExprTypeUnreachable: | 561 | case PrimaryExprTypeUnreachable: |
| 562 | case PrimaryExprTypeSymbol: | ||
| 554 | // nothing to do | 563 | // nothing to do |
| 555 | break; | 564 | break; |
| 556 | case PrimaryExprTypeFnCall: | ||
| 557 | analyze_node(g, node->data.primary_expr.data.fn_call); | ||
| 558 | break; | ||
| 559 | case PrimaryExprTypeGroupedExpr: | 565 | case PrimaryExprTypeGroupedExpr: |
| 560 | analyze_node(g, node->data.primary_expr.data.grouped_expr); | 566 | analyze_node(g, node->data.primary_expr.data.grouped_expr); |
| 561 | break; | 567 | break; |
| ... | @@ -662,33 +668,6 @@ static void add_debug_source_node(CodeGen *g, AstNode *node) { | ... | @@ -662,33 +668,6 @@ static void add_debug_source_node(CodeGen *g, AstNode *node) { |
| 662 | g->block_scopes.last())); | 668 | g->block_scopes.last())); |
| 663 | } | 669 | } |
| 664 | 670 | ||
| 665 | static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) { | ||
| 666 | assert(fn_call_node->type == NodeTypeFnCall); | ||
| 667 | |||
| 668 | Buf *name = &fn_call_node->data.fn_call.name; | ||
| 669 | FnTableEntry *fn_table_entry = g->fn_table.get(name); | ||
| 670 | assert(fn_table_entry->proto_node->type == NodeTypeFnProto); | ||
| 671 | int expected_param_count = fn_table_entry->proto_node->data.fn_proto.params.length; | ||
| 672 | int actual_param_count = fn_call_node->data.fn_call.params.length; | ||
| 673 | assert(expected_param_count == actual_param_count); | ||
| 674 | |||
| 675 | LLVMValueRef *param_values = allocate<LLVMValueRef>(actual_param_count); | ||
| 676 | for (int i = 0; i < actual_param_count; i += 1) { | ||
| 677 | AstNode *expr_node = fn_call_node->data.fn_call.params.at(i); | ||
| 678 | param_values[i] = gen_expr(g, expr_node); | ||
| 679 | } | ||
| 680 | |||
| 681 | add_debug_source_node(g, fn_call_node); | ||
| 682 | LLVMValueRef result = LLVMZigBuildCall(g->builder, fn_table_entry->fn_value, | ||
| 683 | param_values, actual_param_count, fn_table_entry->calling_convention, ""); | ||
| 684 | |||
| 685 | if (type_is_unreachable(fn_table_entry->proto_node->data.fn_proto.return_type)) { | ||
| 686 | return LLVMBuildUnreachable(g->builder); | ||
| 687 | } else { | ||
| 688 | return result; | ||
| 689 | } | ||
| 690 | } | ||
| 691 | |||
| 692 | static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) { | 671 | static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) { |
| 693 | auto entry = g->str_table.maybe_get(str); | 672 | auto entry = g->str_table.maybe_get(str); |
| 694 | if (entry) { | 673 | if (entry) { |
| ... | @@ -733,17 +712,47 @@ static LLVMValueRef gen_primary_expr(CodeGen *g, AstNode *node) { | ... | @@ -733,17 +712,47 @@ static LLVMValueRef gen_primary_expr(CodeGen *g, AstNode *node) { |
| 733 | case PrimaryExprTypeUnreachable: | 712 | case PrimaryExprTypeUnreachable: |
| 734 | add_debug_source_node(g, node); | 713 | add_debug_source_node(g, node); |
| 735 | return LLVMBuildUnreachable(g->builder); | 714 | return LLVMBuildUnreachable(g->builder); |
| 736 | case PrimaryExprTypeFnCall: | ||
| 737 | return gen_fn_call(g, prim_expr->data.fn_call); | ||
| 738 | case PrimaryExprTypeGroupedExpr: | 715 | case PrimaryExprTypeGroupedExpr: |
| 739 | return gen_expr(g, prim_expr->data.grouped_expr); | 716 | return gen_expr(g, prim_expr->data.grouped_expr); |
| 740 | case PrimaryExprTypeBlock: | 717 | case PrimaryExprTypeBlock: |
| 718 | zig_panic("TODO block in expression"); | ||
| 719 | break; | ||
| 720 | case PrimaryExprTypeSymbol: | ||
| 721 | zig_panic("TODO variable reference"); | ||
| 741 | break; | 722 | break; |
| 742 | } | 723 | } |
| 743 | 724 | ||
| 744 | zig_unreachable(); | 725 | zig_unreachable(); |
| 745 | } | 726 | } |
| 746 | 727 | ||
| 728 | static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { | ||
| 729 | assert(node->type == NodeTypeFnCallExpr); | ||
| 730 | |||
| 731 | Buf *name = hack_get_fn_call_name(g, node->data.fn_call_expr.fn_ref_expr); | ||
| 732 | |||
| 733 | FnTableEntry *fn_table_entry = g->fn_table.get(name); | ||
| 734 | assert(fn_table_entry->proto_node->type == NodeTypeFnProto); | ||
| 735 | int expected_param_count = fn_table_entry->proto_node->data.fn_proto.params.length; | ||
| 736 | int actual_param_count = node->data.fn_call_expr.params.length; | ||
| 737 | assert(expected_param_count == actual_param_count); | ||
| 738 | |||
| 739 | LLVMValueRef *param_values = allocate<LLVMValueRef>(actual_param_count); | ||
| 740 | for (int i = 0; i < actual_param_count; i += 1) { | ||
| 741 | AstNode *expr_node = node->data.fn_call_expr.params.at(i); | ||
| 742 | param_values[i] = gen_expr(g, expr_node); | ||
| 743 | } | ||
| 744 | |||
| 745 | add_debug_source_node(g, node); | ||
| 746 | LLVMValueRef result = LLVMZigBuildCall(g->builder, fn_table_entry->fn_value, | ||
| 747 | param_values, actual_param_count, fn_table_entry->calling_convention, ""); | ||
| 748 | |||
| 749 | if (type_is_unreachable(fn_table_entry->proto_node->data.fn_proto.return_type)) { | ||
| 750 | return LLVMBuildUnreachable(g->builder); | ||
| 751 | } else { | ||
| 752 | return result; | ||
| 753 | } | ||
| 754 | } | ||
| 755 | |||
| 747 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | 756 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 748 | assert(node->type == NodeTypePrefixOpExpr); | 757 | assert(node->type == NodeTypePrefixOpExpr); |
| 749 | assert(node->data.prefix_op_expr.primary_expr); | 758 | assert(node->data.prefix_op_expr.primary_expr); |
| ... | @@ -1028,6 +1037,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | ... | @@ -1028,6 +1037,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 1028 | return gen_return_expr(g, node); | 1037 | return gen_return_expr(g, node); |
| 1029 | case NodeTypePrefixOpExpr: | 1038 | case NodeTypePrefixOpExpr: |
| 1030 | return gen_prefix_op_expr(g, node); | 1039 | return gen_prefix_op_expr(g, node); |
| 1040 | case NodeTypeFnCallExpr: | ||
| 1041 | return gen_fn_call_expr(g, node); | ||
| 1031 | case NodeTypeRoot: | 1042 | case NodeTypeRoot: |
| 1032 | case NodeTypeRootExportDecl: | 1043 | case NodeTypeRootExportDecl: |
| 1033 | case NodeTypeFnProto: | 1044 | case NodeTypeFnProto: |
| ... | @@ -1036,7 +1047,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | ... | @@ -1036,7 +1047,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 1036 | case NodeTypeParamDecl: | 1047 | case NodeTypeParamDecl: |
| 1037 | case NodeTypeType: | 1048 | case NodeTypeType: |
| 1038 | case NodeTypeBlock: | 1049 | case NodeTypeBlock: |
| 1039 | case NodeTypeFnCall: | ||
| 1040 | case NodeTypeExternBlock: | 1050 | case NodeTypeExternBlock: |
| 1041 | case NodeTypeDirective: | 1051 | case NodeTypeDirective: |
| 1042 | case NodeTypeBoolAndExpr: | 1052 | case NodeTypeBoolAndExpr: |
src/parser.cpp+40-47| ... | @@ -96,8 +96,8 @@ const char *node_type_str(NodeType node_type) { | ... | @@ -96,8 +96,8 @@ const char *node_type_str(NodeType node_type) { |
| 96 | return "Block"; | 96 | return "Block"; |
| 97 | case NodeTypeBoolOrExpr: | 97 | case NodeTypeBoolOrExpr: |
| 98 | return "BoolOrExpr"; | 98 | return "BoolOrExpr"; |
| 99 | case NodeTypeFnCall: | 99 | case NodeTypeFnCallExpr: |
| 100 | return "FnCall"; | 100 | return "FnCallExpr"; |
| 101 | case NodeTypeExternBlock: | 101 | case NodeTypeExternBlock: |
| 102 | return "ExternBlock"; | 102 | return "ExternBlock"; |
| 103 | case NodeTypeDirective: | 103 | case NodeTypeDirective: |
| ... | @@ -232,10 +232,11 @@ void ast_print(AstNode *node, int indent) { | ... | @@ -232,10 +232,11 @@ void ast_print(AstNode *node, int indent) { |
| 232 | if (node->data.bool_or_expr.op2) | 232 | if (node->data.bool_or_expr.op2) |
| 233 | ast_print(node->data.bool_or_expr.op2, indent + 2); | 233 | ast_print(node->data.bool_or_expr.op2, indent + 2); |
| 234 | break; | 234 | break; |
| 235 | case NodeTypeFnCall: | 235 | case NodeTypeFnCallExpr: |
| 236 | fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.fn_call.name)); | 236 | fprintf(stderr, "%s\n", node_type_str(node->type)); |
| 237 | for (int i = 0; i < node->data.fn_call.params.length; i += 1) { | 237 | ast_print(node->data.fn_call_expr.fn_ref_expr, indent + 2); |
| 238 | AstNode *child = node->data.fn_call.params.at(i); | 238 | for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) { |
| 239 | AstNode *child = node->data.fn_call_expr.params.at(i); | ||
| 239 | ast_print(child, indent + 2); | 240 | ast_print(child, indent + 2); |
| 240 | } | 241 | } |
| 241 | break; | 242 | break; |
| ... | @@ -318,10 +319,6 @@ void ast_print(AstNode *node, int indent) { | ... | @@ -318,10 +319,6 @@ void ast_print(AstNode *node, int indent) { |
| 318 | case PrimaryExprTypeUnreachable: | 319 | case PrimaryExprTypeUnreachable: |
| 319 | fprintf(stderr, "PrimaryExpr Unreachable\n"); | 320 | fprintf(stderr, "PrimaryExpr Unreachable\n"); |
| 320 | break; | 321 | break; |
| 321 | case PrimaryExprTypeFnCall: | ||
| 322 | fprintf(stderr, "PrimaryExpr FnCall\n"); | ||
| 323 | ast_print(node->data.primary_expr.data.fn_call, indent + 2); | ||
| 324 | break; | ||
| 325 | case PrimaryExprTypeGroupedExpr: | 322 | case PrimaryExprTypeGroupedExpr: |
| 326 | fprintf(stderr, "PrimaryExpr GroupedExpr\n"); | 323 | fprintf(stderr, "PrimaryExpr GroupedExpr\n"); |
| 327 | ast_print(node->data.primary_expr.data.grouped_expr, indent + 2); | 324 | ast_print(node->data.primary_expr.data.grouped_expr, indent + 2); |
| ... | @@ -330,6 +327,10 @@ void ast_print(AstNode *node, int indent) { | ... | @@ -330,6 +327,10 @@ void ast_print(AstNode *node, int indent) { |
| 330 | fprintf(stderr, "PrimaryExpr Block\n"); | 327 | fprintf(stderr, "PrimaryExpr Block\n"); |
| 331 | ast_print(node->data.primary_expr.data.block, indent + 2); | 328 | ast_print(node->data.primary_expr.data.block, indent + 2); |
| 332 | break; | 329 | break; |
| 330 | case PrimaryExprTypeSymbol: | ||
| 331 | fprintf(stderr, "PrimaryExpr Symbol %s\n", | ||
| 332 | buf_ptr(&node->data.primary_expr.data.symbol)); | ||
| 333 | break; | ||
| 333 | } | 334 | } |
| 334 | break; | 335 | break; |
| 335 | case NodeTypeGroupedExpr: | 336 | case NodeTypeGroupedExpr: |
| ... | @@ -626,32 +627,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, int *token_index, bool | ... | @@ -626,32 +627,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, int *token_index, bool |
| 626 | } | 627 | } |
| 627 | 628 | ||
| 628 | /* | 629 | /* |
| 629 | FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen) ; | 630 | PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | token(Symbol) |
| 630 | */ | ||
| 631 | static AstNode *ast_parse_fn_call(ParseContext *pc, int *token_index, bool mandatory) { | ||
| 632 | Token *fn_name = &pc->tokens->at(*token_index); | ||
| 633 | if (fn_name->id != TokenIdSymbol) { | ||
| 634 | if (mandatory) { | ||
| 635 | ast_invalid_token_error(pc, fn_name); | ||
| 636 | } else { | ||
| 637 | return nullptr; | ||
| 638 | } | ||
| 639 | } | ||
| 640 | |||
| 641 | *token_index += 1; | ||
| 642 | |||
| 643 | AstNode *node = ast_create_node(NodeTypeFnCall, fn_name); | ||
| 644 | |||
| 645 | |||
| 646 | ast_buf_from_token(pc, fn_name, &node->data.fn_call.name); | ||
| 647 | |||
| 648 | ast_parse_fn_call_param_list(pc, *token_index, token_index, &node->data.fn_call.params); | ||
| 649 | |||
| 650 | return node; | ||
| 651 | } | ||
| 652 | |||
| 653 | /* | ||
| 654 | PrimaryExpression : token(Number) | token(String) | token(Unreachable) | FnCall | GroupedExpression | Block | ||
| 655 | */ | 631 | */ |
| 656 | static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { | 632 | static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 657 | Token *token = &pc->tokens->at(*token_index); | 633 | Token *token = &pc->tokens->at(*token_index); |
| ... | @@ -673,6 +649,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool | ... | @@ -673,6 +649,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool |
| 673 | node->data.primary_expr.type = PrimaryExprTypeUnreachable; | 649 | node->data.primary_expr.type = PrimaryExprTypeUnreachable; |
| 674 | *token_index += 1; | 650 | *token_index += 1; |
| 675 | return node; | 651 | return node; |
| 652 | } else if (token->id == TokenIdSymbol) { | ||
| 653 | AstNode *node = ast_create_node(NodeTypePrimaryExpr, token); | ||
| 654 | node->data.primary_expr.type = PrimaryExprTypeSymbol; | ||
| 655 | ast_buf_from_token(pc, token, &node->data.primary_expr.data.symbol); | ||
| 656 | *token_index += 1; | ||
| 657 | return node; | ||
| 676 | } | 658 | } |
| 677 | 659 | ||
| 678 | AstNode *block_node = ast_parse_block(pc, token_index, false); | 660 | AstNode *block_node = ast_parse_block(pc, token_index, false); |
| ... | @@ -691,20 +673,31 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool | ... | @@ -691,20 +673,31 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool |
| 691 | return node; | 673 | return node; |
| 692 | } | 674 | } |
| 693 | 675 | ||
| 694 | AstNode *fn_call_node = ast_parse_fn_call(pc, token_index, false); | ||
| 695 | if (fn_call_node) { | ||
| 696 | AstNode *node = ast_create_node(NodeTypePrimaryExpr, token); | ||
| 697 | node->data.primary_expr.type = PrimaryExprTypeFnCall; | ||
| 698 | node->data.primary_expr.data.fn_call = fn_call_node; | ||
| 699 | return node; | ||
| 700 | } | ||
| 701 | |||
| 702 | if (!mandatory) | 676 | if (!mandatory) |
| 703 | return nullptr; | 677 | return nullptr; |
| 704 | 678 | ||
| 705 | ast_invalid_token_error(pc, token); | 679 | ast_invalid_token_error(pc, token); |
| 706 | } | 680 | } |
| 707 | 681 | ||
| 682 | /* | ||
| 683 | FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression | ||
| 684 | */ | ||
| 685 | static AstNode *ast_parse_fn_call_expr(ParseContext *pc, int *token_index, bool mandatory) { | ||
| 686 | AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory); | ||
| 687 | if (!primary_expr) | ||
| 688 | return nullptr; | ||
| 689 | |||
| 690 | Token *l_paren = &pc->tokens->at(*token_index); | ||
| 691 | if (l_paren->id != TokenIdLParen) | ||
| 692 | return primary_expr; | ||
| 693 | |||
| 694 | AstNode *node = ast_create_node_with_node(NodeTypeFnCallExpr, primary_expr); | ||
| 695 | node->data.fn_call_expr.fn_ref_expr = primary_expr; | ||
| 696 | ast_parse_fn_call_param_list(pc, *token_index, token_index, &node->data.fn_call_expr.params); | ||
| 697 | |||
| 698 | return node; | ||
| 699 | } | ||
| 700 | |||
| 708 | static PrefixOp tok_to_prefix_op(Token *token) { | 701 | static PrefixOp tok_to_prefix_op(Token *token) { |
| 709 | switch (token->id) { | 702 | switch (token->id) { |
| 710 | case TokenIdBang: return PrefixOpBoolNot; | 703 | case TokenIdBang: return PrefixOpBoolNot; |
| ... | @@ -732,15 +725,15 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man | ... | @@ -732,15 +725,15 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man |
| 732 | } | 725 | } |
| 733 | 726 | ||
| 734 | /* | 727 | /* |
| 735 | PrefixOpExpression : PrefixOp PrimaryExpression | PrimaryExpression | 728 | PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression |
| 736 | */ | 729 | */ |
| 737 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) { | 730 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 738 | Token *token = &pc->tokens->at(*token_index); | 731 | Token *token = &pc->tokens->at(*token_index); |
| 739 | PrefixOp prefix_op = ast_parse_prefix_op(pc, token_index, false); | 732 | PrefixOp prefix_op = ast_parse_prefix_op(pc, token_index, false); |
| 740 | if (prefix_op == PrefixOpInvalid) | 733 | if (prefix_op == PrefixOpInvalid) |
| 741 | return ast_parse_primary_expr(pc, token_index, mandatory); | 734 | return ast_parse_fn_call_expr(pc, token_index, mandatory); |
| 742 | 735 | ||
| 743 | AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, true); | 736 | AstNode *primary_expr = ast_parse_fn_call_expr(pc, token_index, true); |
| 744 | AstNode *node = ast_create_node(NodeTypePrefixOpExpr, token); | 737 | AstNode *node = ast_create_node(NodeTypePrefixOpExpr, token); |
| 745 | node->data.prefix_op_expr.primary_expr = primary_expr; | 738 | node->data.prefix_op_expr.primary_expr = primary_expr; |
| 746 | node->data.prefix_op_expr.prefix_op = prefix_op; | 739 | node->data.prefix_op_expr.prefix_op = prefix_op; |
src/parser.hpp+6-6| ... | @@ -24,7 +24,6 @@ enum NodeType { | ... | @@ -24,7 +24,6 @@ enum NodeType { |
| 24 | NodeTypeParamDecl, | 24 | NodeTypeParamDecl, |
| 25 | NodeTypeType, | 25 | NodeTypeType, |
| 26 | NodeTypeBlock, | 26 | NodeTypeBlock, |
| 27 | NodeTypeFnCall, | ||
| 28 | NodeTypeExternBlock, | 27 | NodeTypeExternBlock, |
| 29 | NodeTypeDirective, | 28 | NodeTypeDirective, |
| 30 | NodeTypeReturnExpr, | 29 | NodeTypeReturnExpr, |
| ... | @@ -41,6 +40,7 @@ enum NodeType { | ... | @@ -41,6 +40,7 @@ enum NodeType { |
| 41 | NodeTypePrimaryExpr, | 40 | NodeTypePrimaryExpr, |
| 42 | NodeTypeGroupedExpr, | 41 | NodeTypeGroupedExpr, |
| 43 | NodeTypePrefixOpExpr, | 42 | NodeTypePrefixOpExpr, |
| 43 | NodeTypeFnCallExpr, | ||
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | struct AstNodeRoot { | 46 | struct AstNodeRoot { |
| ... | @@ -103,8 +103,8 @@ struct AstNodeBoolOrExpr { | ... | @@ -103,8 +103,8 @@ struct AstNodeBoolOrExpr { |
| 103 | AstNode *op2; | 103 | AstNode *op2; |
| 104 | }; | 104 | }; |
| 105 | 105 | ||
| 106 | struct AstNodeFnCall { | 106 | struct AstNodeFnCallExpr { |
| 107 | Buf name; | 107 | AstNode *fn_ref_expr; |
| 108 | ZigList<AstNode *> params; | 108 | ZigList<AstNode *> params; |
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| ... | @@ -214,9 +214,9 @@ enum PrimaryExprType { | ... | @@ -214,9 +214,9 @@ enum PrimaryExprType { |
| 214 | PrimaryExprTypeNumber, | 214 | PrimaryExprTypeNumber, |
| 215 | PrimaryExprTypeString, | 215 | PrimaryExprTypeString, |
| 216 | PrimaryExprTypeUnreachable, | 216 | PrimaryExprTypeUnreachable, |
| 217 | PrimaryExprTypeFnCall, | ||
| 218 | PrimaryExprTypeGroupedExpr, | 217 | PrimaryExprTypeGroupedExpr, |
| 219 | PrimaryExprTypeBlock, | 218 | PrimaryExprTypeBlock, |
| 219 | PrimaryExprTypeSymbol, | ||
| 220 | }; | 220 | }; |
| 221 | 221 | ||
| 222 | struct AstNodePrimaryExpr { | 222 | struct AstNodePrimaryExpr { |
| ... | @@ -224,7 +224,7 @@ struct AstNodePrimaryExpr { | ... | @@ -224,7 +224,7 @@ struct AstNodePrimaryExpr { |
| 224 | union { | 224 | union { |
| 225 | Buf number; | 225 | Buf number; |
| 226 | Buf string; | 226 | Buf string; |
| 227 | AstNode *fn_call; | 227 | Buf symbol; |
| 228 | AstNode *grouped_expr; | 228 | AstNode *grouped_expr; |
| 229 | AstNode *block; | 229 | AstNode *block; |
| 230 | } data; | 230 | } data; |
| ... | @@ -263,7 +263,6 @@ struct AstNode { | ... | @@ -263,7 +263,6 @@ struct AstNode { |
| 263 | AstNodeBlock block; | 263 | AstNodeBlock block; |
| 264 | AstNodeReturnExpr return_expr; | 264 | AstNodeReturnExpr return_expr; |
| 265 | AstNodeBoolOrExpr bool_or_expr; | 265 | AstNodeBoolOrExpr bool_or_expr; |
| 266 | AstNodeFnCall fn_call; | ||
| 267 | AstNodeExternBlock extern_block; | 266 | AstNodeExternBlock extern_block; |
| 268 | AstNodeDirective directive; | 267 | AstNodeDirective directive; |
| 269 | AstNodeBoolAndExpr bool_and_expr; | 268 | AstNodeBoolAndExpr bool_and_expr; |
| ... | @@ -278,6 +277,7 @@ struct AstNode { | ... | @@ -278,6 +277,7 @@ struct AstNode { |
| 278 | AstNodePrimaryExpr primary_expr; | 277 | AstNodePrimaryExpr primary_expr; |
| 279 | AstNodeGroupedExpr grouped_expr; | 278 | AstNodeGroupedExpr grouped_expr; |
| 280 | AstNodePrefixOpExpr prefix_op_expr; | 279 | AstNodePrefixOpExpr prefix_op_expr; |
| 280 | AstNodeFnCallExpr fn_call_expr; | ||
| 281 | } data; | 281 | } data; |
| 282 | }; | 282 | }; |
| 283 | 283 |