authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-29 14:39:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-29 14:39:11-07:00
logc1d77f2a231461d88ad493c92079cc571e565f87
tree8a85649f49e567f796445d751052fbd4b105fa7c
parent918e7641fcaa79f75a365751de571807578ae503

function call names are expressions


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
8888
8989FnProto : many(Directive) option(FnVisibleMod) token(Fn) token(Symbol) ParamDeclList option(token(Arrow) Type)
9090
91Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen)
92
9193FnVisibleMod : token(Pub) | token(Export)
9294
9395FnDecl : FnProto token(Semicolon)
......@@ -142,15 +144,13 @@ CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
142144
143145PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression
144146
145FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen)
147FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression
146148
147149PrefixOp : token(Not) | token(Dash) | token(Tilde)
148150
149PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block
151PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | token(Symbol)
150152
151153GroupedExpression : token(LParen) Expression token(RParen)
152
153Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen)
154154```
155155
156156### Operator Precedence
src/codegen.cpp+49-39
......@@ -306,7 +306,7 @@ static void find_declarations(CodeGen *g, AstNode *node) {
306306 case NodeTypeRoot:
307307 case NodeTypeBlock:
308308 case NodeTypeBoolOrExpr:
309 case NodeTypeFnCall:
309 case NodeTypeFnCallExpr:
310310 case NodeTypeRootExportDecl:
311311 case NodeTypeBoolAndExpr:
312312 case NodeTypeComparisonExpr:
......@@ -378,6 +378,14 @@ static void check_fn_def_control_flow(CodeGen *g, AstNode *node) {
378378 }
379379}
380380
381static 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
381389static void analyze_node(CodeGen *g, AstNode *node) {
382390 switch (node->type) {
383391 case NodeTypeRoot:
......@@ -487,9 +495,9 @@ static void analyze_node(CodeGen *g, AstNode *node) {
487495 if (node->data.bool_or_expr.op2)
488496 analyze_node(g, node->data.bool_or_expr.op2);
489497 break;
490 case NodeTypeFnCall:
498 case NodeTypeFnCallExpr:
491499 {
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);
493501
494502 auto entry = g->fn_table.maybe_get(name);
495503 if (!entry) {
......@@ -499,7 +507,7 @@ static void analyze_node(CodeGen *g, AstNode *node) {
499507 FnTableEntry *fn_table_entry = entry->value;
500508 assert(fn_table_entry->proto_node->type == NodeTypeFnProto);
501509 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;
503511 if (expected_param_count != actual_param_count) {
504512 add_node_error(g, node,
505513 buf_sprintf("wrong number of arguments. Expected %d, got %d.",
......@@ -507,8 +515,8 @@ static void analyze_node(CodeGen *g, AstNode *node) {
507515 }
508516 }
509517
510 for (int i = 0; i < node->data.fn_call.params.length; i += 1) {
511 AstNode *child = node->data.fn_call.params.at(i);
518 for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
519 AstNode *child = node->data.fn_call_expr.params.at(i);
512520 analyze_node(g, child);
513521 }
514522 break;
......@@ -551,11 +559,9 @@ static void analyze_node(CodeGen *g, AstNode *node) {
551559 case PrimaryExprTypeNumber:
552560 case PrimaryExprTypeString:
553561 case PrimaryExprTypeUnreachable:
562 case PrimaryExprTypeSymbol:
554563 // nothing to do
555564 break;
556 case PrimaryExprTypeFnCall:
557 analyze_node(g, node->data.primary_expr.data.fn_call);
558 break;
559565 case PrimaryExprTypeGroupedExpr:
560566 analyze_node(g, node->data.primary_expr.data.grouped_expr);
561567 break;
......@@ -662,33 +668,6 @@ static void add_debug_source_node(CodeGen *g, AstNode *node) {
662668 g->block_scopes.last()));
663669}
664670
665static 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
692671static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) {
693672 auto entry = g->str_table.maybe_get(str);
694673 if (entry) {
......@@ -733,17 +712,47 @@ static LLVMValueRef gen_primary_expr(CodeGen *g, AstNode *node) {
733712 case PrimaryExprTypeUnreachable:
734713 add_debug_source_node(g, node);
735714 return LLVMBuildUnreachable(g->builder);
736 case PrimaryExprTypeFnCall:
737 return gen_fn_call(g, prim_expr->data.fn_call);
738715 case PrimaryExprTypeGroupedExpr:
739716 return gen_expr(g, prim_expr->data.grouped_expr);
740717 case PrimaryExprTypeBlock:
718 zig_panic("TODO block in expression");
719 break;
720 case PrimaryExprTypeSymbol:
721 zig_panic("TODO variable reference");
741722 break;
742723 }
743724
744725 zig_unreachable();
745726}
746727
728static 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
747756static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
748757 assert(node->type == NodeTypePrefixOpExpr);
749758 assert(node->data.prefix_op_expr.primary_expr);
......@@ -1028,6 +1037,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
10281037 return gen_return_expr(g, node);
10291038 case NodeTypePrefixOpExpr:
10301039 return gen_prefix_op_expr(g, node);
1040 case NodeTypeFnCallExpr:
1041 return gen_fn_call_expr(g, node);
10311042 case NodeTypeRoot:
10321043 case NodeTypeRootExportDecl:
10331044 case NodeTypeFnProto:
......@@ -1036,7 +1047,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
10361047 case NodeTypeParamDecl:
10371048 case NodeTypeType:
10381049 case NodeTypeBlock:
1039 case NodeTypeFnCall:
10401050 case NodeTypeExternBlock:
10411051 case NodeTypeDirective:
10421052 case NodeTypeBoolAndExpr:
src/parser.cpp+40-47
......@@ -96,8 +96,8 @@ const char *node_type_str(NodeType node_type) {
9696 return "Block";
9797 case NodeTypeBoolOrExpr:
9898 return "BoolOrExpr";
99 case NodeTypeFnCall:
100 return "FnCall";
99 case NodeTypeFnCallExpr:
100 return "FnCallExpr";
101101 case NodeTypeExternBlock:
102102 return "ExternBlock";
103103 case NodeTypeDirective:
......@@ -232,10 +232,11 @@ void ast_print(AstNode *node, int indent) {
232232 if (node->data.bool_or_expr.op2)
233233 ast_print(node->data.bool_or_expr.op2, indent + 2);
234234 break;
235 case NodeTypeFnCall:
236 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.fn_call.name));
237 for (int i = 0; i < node->data.fn_call.params.length; i += 1) {
238 AstNode *child = node->data.fn_call.params.at(i);
235 case NodeTypeFnCallExpr:
236 fprintf(stderr, "%s\n", node_type_str(node->type));
237 ast_print(node->data.fn_call_expr.fn_ref_expr, indent + 2);
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);
239240 ast_print(child, indent + 2);
240241 }
241242 break;
......@@ -318,10 +319,6 @@ void ast_print(AstNode *node, int indent) {
318319 case PrimaryExprTypeUnreachable:
319320 fprintf(stderr, "PrimaryExpr Unreachable\n");
320321 break;
321 case PrimaryExprTypeFnCall:
322 fprintf(stderr, "PrimaryExpr FnCall\n");
323 ast_print(node->data.primary_expr.data.fn_call, indent + 2);
324 break;
325322 case PrimaryExprTypeGroupedExpr:
326323 fprintf(stderr, "PrimaryExpr GroupedExpr\n");
327324 ast_print(node->data.primary_expr.data.grouped_expr, indent + 2);
......@@ -330,6 +327,10 @@ void ast_print(AstNode *node, int indent) {
330327 fprintf(stderr, "PrimaryExpr Block\n");
331328 ast_print(node->data.primary_expr.data.block, indent + 2);
332329 break;
330 case PrimaryExprTypeSymbol:
331 fprintf(stderr, "PrimaryExpr Symbol %s\n",
332 buf_ptr(&node->data.primary_expr.data.symbol));
333 break;
333334 }
334335 break;
335336 case NodeTypeGroupedExpr:
......@@ -626,32 +627,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, int *token_index, bool
626627}
627628
628629/*
629FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen) ;
630*/
631static 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/*
654PrimaryExpression : token(Number) | token(String) | token(Unreachable) | FnCall | GroupedExpression | Block
630PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | token(Symbol)
655631*/
656632static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
657633 Token *token = &pc->tokens->at(*token_index);
......@@ -673,6 +649,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
673649 node->data.primary_expr.type = PrimaryExprTypeUnreachable;
674650 *token_index += 1;
675651 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;
676658 }
677659
678660 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
691673 return node;
692674 }
693675
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
702676 if (!mandatory)
703677 return nullptr;
704678
705679 ast_invalid_token_error(pc, token);
706680}
707681
682/*
683FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression
684*/
685static 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
708701static PrefixOp tok_to_prefix_op(Token *token) {
709702 switch (token->id) {
710703 case TokenIdBang: return PrefixOpBoolNot;
......@@ -732,15 +725,15 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man
732725}
733726
734727/*
735PrefixOpExpression : PrefixOp PrimaryExpression | PrimaryExpression
728PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression
736729*/
737730static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {
738731 Token *token = &pc->tokens->at(*token_index);
739732 PrefixOp prefix_op = ast_parse_prefix_op(pc, token_index, false);
740733 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);
742735
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);
744737 AstNode *node = ast_create_node(NodeTypePrefixOpExpr, token);
745738 node->data.prefix_op_expr.primary_expr = primary_expr;
746739 node->data.prefix_op_expr.prefix_op = prefix_op;
src/parser.hpp+6-6
......@@ -24,7 +24,6 @@ enum NodeType {
2424 NodeTypeParamDecl,
2525 NodeTypeType,
2626 NodeTypeBlock,
27 NodeTypeFnCall,
2827 NodeTypeExternBlock,
2928 NodeTypeDirective,
3029 NodeTypeReturnExpr,
......@@ -41,6 +40,7 @@ enum NodeType {
4140 NodeTypePrimaryExpr,
4241 NodeTypeGroupedExpr,
4342 NodeTypePrefixOpExpr,
43 NodeTypeFnCallExpr,
4444};
4545
4646struct AstNodeRoot {
......@@ -103,8 +103,8 @@ struct AstNodeBoolOrExpr {
103103 AstNode *op2;
104104};
105105
106struct AstNodeFnCall {
107 Buf name;
106struct AstNodeFnCallExpr {
107 AstNode *fn_ref_expr;
108108 ZigList<AstNode *> params;
109109};
110110
......@@ -214,9 +214,9 @@ enum PrimaryExprType {
214214 PrimaryExprTypeNumber,
215215 PrimaryExprTypeString,
216216 PrimaryExprTypeUnreachable,
217 PrimaryExprTypeFnCall,
218217 PrimaryExprTypeGroupedExpr,
219218 PrimaryExprTypeBlock,
219 PrimaryExprTypeSymbol,
220220};
221221
222222struct AstNodePrimaryExpr {
......@@ -224,7 +224,7 @@ struct AstNodePrimaryExpr {
224224 union {
225225 Buf number;
226226 Buf string;
227 AstNode *fn_call;
227 Buf symbol;
228228 AstNode *grouped_expr;
229229 AstNode *block;
230230 } data;
......@@ -263,7 +263,6 @@ struct AstNode {
263263 AstNodeBlock block;
264264 AstNodeReturnExpr return_expr;
265265 AstNodeBoolOrExpr bool_or_expr;
266 AstNodeFnCall fn_call;
267266 AstNodeExternBlock extern_block;
268267 AstNodeDirective directive;
269268 AstNodeBoolAndExpr bool_and_expr;
......@@ -278,6 +277,7 @@ struct AstNode {
278277 AstNodePrimaryExpr primary_expr;
279278 AstNodeGroupedExpr grouped_expr;
280279 AstNodePrefixOpExpr prefix_op_expr;
280 AstNodeFnCallExpr fn_call_expr;
281281 } data;
282282};
283283