authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-11-29 14:52:49-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-11-29 14:52:49-07:00
log30442ed893c4477851d37c865eb978c4bf27c814
tree406d86f58bcda7ab68affb8c37c6787854338884
parent9a014b52ccc22d7ec24804f90993cfe08e3d20c4
parentc1d77f2a231461d88ad493c92079cc571e565f87

merge conflicts


7 files changed, 228 insertions(+), 108 deletions(-)

README.md+12-6
......@@ -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)
......@@ -138,20 +140,24 @@ MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpres
138140
139141MultiplyOperator : token(Star) | token(Slash) | token(Percent)
140142
141CastExpression : PrimaryExpression token(as) Type | PrimaryExpression
143CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
142144
143PrimaryExpression : token(Number) | token(String) | token(Unreachable) | FnCall | GroupedExpression | Block
145PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression
144146
145GroupedExpression : token(LParen) Expression token(RParen)
147FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression
146148
147FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen)
149PrefixOp : token(Not) | token(Dash) | token(Tilde)
148150
149Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen)
151PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | token(Symbol)
152
153GroupedExpression : token(LParen) Expression token(RParen)
150154```
151155
152### Binary Operator Precedence
156### Operator Precedence
153157
154158```
159x()
160!x -x ~x
155161as
156162* / %
157163+ -
example/math.zig-1
......@@ -3,4 +3,3 @@ export library "math";
33export fn add(a: i32, b: i32) -> i32 {
44 return a + b;
55}
6
src/codegen.cpp+83-42
......@@ -306,9 +306,10 @@ static void find_declarations(CodeGen *g, AstNode *node) {
306306 case NodeTypeRoot:
307307 case NodeTypeBlock:
308308 case NodeTypeBinOpExpr:
309 case NodeTypeFnCall:
309 case NodeTypeFnCallExpr:
310310 case NodeTypeRootExportDecl:
311311 case NodeTypeCastExpr:
312 case NodeTypePrefixOpExpr:
312313 case NodeTypePrimaryExpr:
313314 case NodeTypeGroupedExpr:
314315 zig_unreachable();
......@@ -369,6 +370,14 @@ static void check_fn_def_control_flow(CodeGen *g, AstNode *node) {
369370 }
370371}
371372
373static Buf *hack_get_fn_call_name(CodeGen *g, AstNode *node) {
374 // Assume that the expression evaluates to a simple name and return the buf
375 // TODO after type checking works we should be able to remove this hack
376 assert(node->type == NodeTypePrimaryExpr);
377 assert(node->data.primary_expr.type == PrimaryExprTypeSymbol);
378 return &node->data.primary_expr.data.symbol;
379}
380
372381static void analyze_node(CodeGen *g, AstNode *node) {
373382 switch (node->type) {
374383 case NodeTypeRoot:
......@@ -477,9 +486,9 @@ static void analyze_node(CodeGen *g, AstNode *node) {
477486 analyze_node(g, node->data.bin_op_expr.op1);
478487 analyze_node(g, node->data.bin_op_expr.op2);
479488 break;
480 case NodeTypeFnCall:
489 case NodeTypeFnCallExpr:
481490 {
482 Buf *name = &node->data.fn_call.name;
491 Buf *name = hack_get_fn_call_name(g, node->data.fn_call_expr.fn_ref_expr);
483492
484493 auto entry = g->fn_table.maybe_get(name);
485494 if (!entry) {
......@@ -489,7 +498,7 @@ static void analyze_node(CodeGen *g, AstNode *node) {
489498 FnTableEntry *fn_table_entry = entry->value;
490499 assert(fn_table_entry->proto_node->type == NodeTypeFnProto);
491500 int expected_param_count = fn_table_entry->proto_node->data.fn_proto.params.length;
492 int actual_param_count = node->data.fn_call.params.length;
501 int actual_param_count = node->data.fn_call_expr.params.length;
493502 if (expected_param_count != actual_param_count) {
494503 add_node_error(g, node,
495504 buf_sprintf("wrong number of arguments. Expected %d, got %d.",
......@@ -497,8 +506,8 @@ static void analyze_node(CodeGen *g, AstNode *node) {
497506 }
498507 }
499508
500 for (int i = 0; i < node->data.fn_call.params.length; i += 1) {
501 AstNode *child = node->data.fn_call.params.at(i);
509 for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
510 AstNode *child = node->data.fn_call_expr.params.at(i);
502511 analyze_node(g, child);
503512 }
504513 break;
......@@ -509,16 +518,17 @@ static void analyze_node(CodeGen *g, AstNode *node) {
509518 case NodeTypeCastExpr:
510519 zig_panic("TODO");
511520 break;
521 case NodeTypePrefixOpExpr:
522 zig_panic("TODO");
523 break;
512524 case NodeTypePrimaryExpr:
513525 switch (node->data.primary_expr.type) {
514526 case PrimaryExprTypeNumber:
515527 case PrimaryExprTypeString:
516528 case PrimaryExprTypeUnreachable:
529 case PrimaryExprTypeSymbol:
517530 // nothing to do
518531 break;
519 case PrimaryExprTypeFnCall:
520 analyze_node(g, node->data.primary_expr.data.fn_call);
521 break;
522532 case PrimaryExprTypeGroupedExpr:
523533 analyze_node(g, node->data.primary_expr.data.grouped_expr);
524534 break;
......@@ -625,33 +635,6 @@ static void add_debug_source_node(CodeGen *g, AstNode *node) {
625635 g->block_scopes.last()));
626636}
627637
628static LLVMValueRef gen_fn_call(CodeGen *g, AstNode *fn_call_node) {
629 assert(fn_call_node->type == NodeTypeFnCall);
630
631 Buf *name = &fn_call_node->data.fn_call.name;
632 FnTableEntry *fn_table_entry = g->fn_table.get(name);
633 assert(fn_table_entry->proto_node->type == NodeTypeFnProto);
634 int expected_param_count = fn_table_entry->proto_node->data.fn_proto.params.length;
635 int actual_param_count = fn_call_node->data.fn_call.params.length;
636 assert(expected_param_count == actual_param_count);
637
638 LLVMValueRef *param_values = allocate<LLVMValueRef>(actual_param_count);
639 for (int i = 0; i < actual_param_count; i += 1) {
640 AstNode *expr_node = fn_call_node->data.fn_call.params.at(i);
641 param_values[i] = gen_expr(g, expr_node);
642 }
643
644 add_debug_source_node(g, fn_call_node);
645 LLVMValueRef result = LLVMZigBuildCall(g->builder, fn_table_entry->fn_value,
646 param_values, actual_param_count, fn_table_entry->calling_convention, "");
647
648 if (type_is_unreachable(fn_table_entry->proto_node->data.fn_proto.return_type)) {
649 return LLVMBuildUnreachable(g->builder);
650 } else {
651 return result;
652 }
653}
654
655638static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) {
656639 auto entry = g->str_table.maybe_get(str);
657640 if (entry) {
......@@ -696,21 +679,76 @@ static LLVMValueRef gen_primary_expr(CodeGen *g, AstNode *node) {
696679 case PrimaryExprTypeUnreachable:
697680 add_debug_source_node(g, node);
698681 return LLVMBuildUnreachable(g->builder);
699 case PrimaryExprTypeFnCall:
700 return gen_fn_call(g, prim_expr->data.fn_call);
701682 case PrimaryExprTypeGroupedExpr:
702683 return gen_expr(g, prim_expr->data.grouped_expr);
703684 case PrimaryExprTypeBlock:
685 zig_panic("TODO block in expression");
704686 break;
687 case PrimaryExprTypeSymbol:
688 zig_panic("TODO variable reference");
689 break;
690 }
691
692 zig_unreachable();
693}
694
695static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
696 assert(node->type == NodeTypeFnCallExpr);
697
698 Buf *name = hack_get_fn_call_name(g, node->data.fn_call_expr.fn_ref_expr);
699
700 FnTableEntry *fn_table_entry = g->fn_table.get(name);
701 assert(fn_table_entry->proto_node->type == NodeTypeFnProto);
702 int expected_param_count = fn_table_entry->proto_node->data.fn_proto.params.length;
703 int actual_param_count = node->data.fn_call_expr.params.length;
704 assert(expected_param_count == actual_param_count);
705
706 LLVMValueRef *param_values = allocate<LLVMValueRef>(actual_param_count);
707 for (int i = 0; i < actual_param_count; i += 1) {
708 AstNode *expr_node = node->data.fn_call_expr.params.at(i);
709 param_values[i] = gen_expr(g, expr_node);
705710 }
706711
712 add_debug_source_node(g, node);
713 LLVMValueRef result = LLVMZigBuildCall(g->builder, fn_table_entry->fn_value,
714 param_values, actual_param_count, fn_table_entry->calling_convention, "");
715
716 if (type_is_unreachable(fn_table_entry->proto_node->data.fn_proto.return_type)) {
717 return LLVMBuildUnreachable(g->builder);
718 } else {
719 return result;
720 }
721}
722
723static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
724 assert(node->type == NodeTypePrefixOpExpr);
725 assert(node->data.prefix_op_expr.primary_expr);
726
727 LLVMValueRef expr = gen_expr(g, node->data.prefix_op_expr.primary_expr);
728
729 switch (node->data.prefix_op_expr.prefix_op) {
730 case PrefixOpNegation:
731 add_debug_source_node(g, node);
732 return LLVMBuildNeg(g->builder, expr, "");
733 case PrefixOpBoolNot:
734 {
735 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
736 add_debug_source_node(g, node);
737 return LLVMBuildICmp(g->builder, LLVMIntEQ, expr, zero, "");
738 }
739 case PrefixOpBinNot:
740 add_debug_source_node(g, node);
741 return LLVMBuildNot(g->builder, expr, "");
742 case PrefixOpInvalid:
743 zig_unreachable();
744 }
707745 zig_unreachable();
708746}
709747
710748static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
711749 assert(node->type == NodeTypeCastExpr);
712750
713 LLVMValueRef expr = gen_primary_expr(g, node->data.cast_expr.primary_expr);
751 LLVMValueRef expr = gen_expr(g, node->data.cast_expr.prefix_op_expr);
714752
715753 if (!node->data.cast_expr.type)
716754 return expr;
......@@ -968,6 +1006,12 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
9681006 return gen_return_expr(g, node);
9691007 case NodeTypeCastExpr:
9701008 return gen_cast_expr(g, node);
1009 case NodeTypePrefixOpExpr:
1010 return gen_prefix_op_expr(g, node);
1011 case NodeTypeFnCallExpr:
1012 return gen_fn_call_expr(g, node);
1013 case NodeTypePrimaryExpr:
1014 return gen_primary_expr(g, node);
9711015 case NodeTypeRoot:
9721016 case NodeTypeRootExportDecl:
9731017 case NodeTypeFnProto:
......@@ -976,11 +1020,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
9761020 case NodeTypeParamDecl:
9771021 case NodeTypeType:
9781022 case NodeTypeBlock:
979 case NodeTypeFnCall:
9801023 case NodeTypeExternBlock:
9811024 case NodeTypeDirective:
982 case NodeTypePrimaryExpr:
983 return gen_primary_expr(g, node);
9841025 case NodeTypeGroupedExpr:
9851026 zig_unreachable();
9861027 }
src/parser.cpp+103-49
......@@ -35,6 +35,16 @@ static const char *bin_op_str(BinOpType bin_op) {
3535 zig_unreachable();
3636}
3737
38static const char *prefix_op_str(PrefixOp prefix_op) {
39 switch (prefix_op) {
40 case PrefixOpInvalid: return "(invalid)";
41 case PrefixOpNegation: return "-";
42 case PrefixOpBoolNot: return "!";
43 case PrefixOpBinNot: return "~";
44 }
45 zig_unreachable();
46}
47
3848__attribute__ ((format (printf, 2, 3)))
3949__attribute__ ((noreturn))
4050static void ast_error(Token *token, const char *format, ...) {
......@@ -70,8 +80,8 @@ const char *node_type_str(NodeType node_type) {
7080 return "Block";
7181 case NodeTypeBinOpExpr:
7282 return "BinOpExpr";
73 case NodeTypeFnCall:
74 return "FnCall";
83 case NodeTypeFnCallExpr:
84 return "FnCallExpr";
7585 case NodeTypeExternBlock:
7686 return "ExternBlock";
7787 case NodeTypeDirective:
......@@ -84,6 +94,8 @@ const char *node_type_str(NodeType node_type) {
8494 return "PrimaryExpr";
8595 case NodeTypeGroupedExpr:
8696 return "GroupedExpr";
97 case NodeTypePrefixOpExpr:
98 return "PrefixOpExpr";
8799 }
88100 zig_unreachable();
89101}
......@@ -188,10 +200,11 @@ void ast_print(AstNode *node, int indent) {
188200 ast_print(node->data.bin_op_expr.op1, indent + 2);
189201 ast_print(node->data.bin_op_expr.op2, indent + 2);
190202 break;
191 case NodeTypeFnCall:
192 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.fn_call.name));
193 for (int i = 0; i < node->data.fn_call.params.length; i += 1) {
194 AstNode *child = node->data.fn_call.params.at(i);
203 case NodeTypeFnCallExpr:
204 fprintf(stderr, "%s\n", node_type_str(node->type));
205 ast_print(node->data.fn_call_expr.fn_ref_expr, indent + 2);
206 for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
207 AstNode *child = node->data.fn_call_expr.params.at(i);
195208 ast_print(child, indent + 2);
196209 }
197210 break;
......@@ -200,10 +213,15 @@ void ast_print(AstNode *node, int indent) {
200213 break;
201214 case NodeTypeCastExpr:
202215 fprintf(stderr, "%s\n", node_type_str(node->type));
203 ast_print(node->data.cast_expr.primary_expr, indent + 2);
216 ast_print(node->data.cast_expr.prefix_op_expr, indent + 2);
204217 if (node->data.cast_expr.type)
205218 ast_print(node->data.cast_expr.type, indent + 2);
206219 break;
220 case NodeTypePrefixOpExpr:
221 fprintf(stderr, "%s %s\n", node_type_str(node->type),
222 prefix_op_str(node->data.prefix_op_expr.prefix_op));
223 ast_print(node->data.prefix_op_expr.primary_expr, indent + 2);
224 break;
207225 case NodeTypePrimaryExpr:
208226 switch (node->data.primary_expr.type) {
209227 case PrimaryExprTypeNumber:
......@@ -217,10 +235,6 @@ void ast_print(AstNode *node, int indent) {
217235 case PrimaryExprTypeUnreachable:
218236 fprintf(stderr, "PrimaryExpr Unreachable\n");
219237 break;
220 case PrimaryExprTypeFnCall:
221 fprintf(stderr, "PrimaryExpr FnCall\n");
222 ast_print(node->data.primary_expr.data.fn_call, indent + 2);
223 break;
224238 case PrimaryExprTypeGroupedExpr:
225239 fprintf(stderr, "PrimaryExpr GroupedExpr\n");
226240 ast_print(node->data.primary_expr.data.grouped_expr, indent + 2);
......@@ -229,6 +243,10 @@ void ast_print(AstNode *node, int indent) {
229243 fprintf(stderr, "PrimaryExpr Block\n");
230244 ast_print(node->data.primary_expr.data.block, indent + 2);
231245 break;
246 case PrimaryExprTypeSymbol:
247 fprintf(stderr, "PrimaryExpr Symbol %s\n",
248 buf_ptr(&node->data.primary_expr.data.symbol));
249 break;
232250 }
233251 break;
234252 case NodeTypeGroupedExpr:
......@@ -525,32 +543,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, int *token_index, bool
525543}
526544
527545/*
528FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen) ;
529*/
530static AstNode *ast_parse_fn_call(ParseContext *pc, int *token_index, bool mandatory) {
531 Token *fn_name = &pc->tokens->at(*token_index);
532 if (fn_name->id != TokenIdSymbol) {
533 if (mandatory) {
534 ast_invalid_token_error(pc, fn_name);
535 } else {
536 return nullptr;
537 }
538 }
539
540 *token_index += 1;
541
542 AstNode *node = ast_create_node(NodeTypeFnCall, fn_name);
543
544
545 ast_buf_from_token(pc, fn_name, &node->data.fn_call.name);
546
547 ast_parse_fn_call_param_list(pc, *token_index, token_index, &node->data.fn_call.params);
548
549 return node;
550}
551
552/*
553PrimaryExpression : token(Number) | token(String) | token(Unreachable) | FnCall | GroupedExpression | Block
546PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | token(Symbol)
554547*/
555548static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
556549 Token *token = &pc->tokens->at(*token_index);
......@@ -572,6 +565,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
572565 node->data.primary_expr.type = PrimaryExprTypeUnreachable;
573566 *token_index += 1;
574567 return node;
568 } else if (token->id == TokenIdSymbol) {
569 AstNode *node = ast_create_node(NodeTypePrimaryExpr, token);
570 node->data.primary_expr.type = PrimaryExprTypeSymbol;
571 ast_buf_from_token(pc, token, &node->data.primary_expr.data.symbol);
572 *token_index += 1;
573 return node;
575574 }
576575
577576 AstNode *block_node = ast_parse_block(pc, token_index, false);
......@@ -590,14 +589,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
590589 return node;
591590 }
592591
593 AstNode *fn_call_node = ast_parse_fn_call(pc, token_index, false);
594 if (fn_call_node) {
595 AstNode *node = ast_create_node(NodeTypePrimaryExpr, token);
596 node->data.primary_expr.type = PrimaryExprTypeFnCall;
597 node->data.primary_expr.data.fn_call = fn_call_node;
598 return node;
599 }
600
601592 if (!mandatory)
602593 return nullptr;
603594
......@@ -605,20 +596,83 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
605596}
606597
607598/*
608CastExpression : PrimaryExpression token(As) Type | PrimaryExpression
599FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression
609600*/
610static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bool mandatory) {
601static AstNode *ast_parse_fn_call_expr(ParseContext *pc, int *token_index, bool mandatory) {
611602 AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory);
612603 if (!primary_expr)
613604 return nullptr;
614605
606 Token *l_paren = &pc->tokens->at(*token_index);
607 if (l_paren->id != TokenIdLParen)
608 return primary_expr;
609
610 AstNode *node = ast_create_node_with_node(NodeTypeFnCallExpr, primary_expr);
611 node->data.fn_call_expr.fn_ref_expr = primary_expr;
612 ast_parse_fn_call_param_list(pc, *token_index, token_index, &node->data.fn_call_expr.params);
613
614 return node;
615}
616
617static PrefixOp tok_to_prefix_op(Token *token) {
618 switch (token->id) {
619 case TokenIdBang: return PrefixOpBoolNot;
620 case TokenIdDash: return PrefixOpNegation;
621 case TokenIdTilde: return PrefixOpBinNot;
622 default: return PrefixOpInvalid;
623 }
624}
625
626/*
627PrefixOp : token(Not) | token(Dash) | token(Tilde)
628*/
629static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool mandatory) {
630 Token *token = &pc->tokens->at(*token_index);
631 PrefixOp result = tok_to_prefix_op(token);
632 if (result == PrefixOpInvalid) {
633 if (mandatory) {
634 ast_invalid_token_error(pc, token);
635 } else {
636 return PrefixOpInvalid;
637 }
638 }
639 *token_index += 1;
640 return result;
641}
642
643/*
644PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression
645*/
646static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {
647 Token *token = &pc->tokens->at(*token_index);
648 PrefixOp prefix_op = ast_parse_prefix_op(pc, token_index, false);
649 if (prefix_op == PrefixOpInvalid)
650 return ast_parse_fn_call_expr(pc, token_index, mandatory);
651
652 AstNode *primary_expr = ast_parse_fn_call_expr(pc, token_index, true);
653 AstNode *node = ast_create_node(NodeTypePrefixOpExpr, token);
654 node->data.prefix_op_expr.primary_expr = primary_expr;
655 node->data.prefix_op_expr.prefix_op = prefix_op;
656
657 return node;
658}
659
660
661/*
662CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
663*/
664static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bool mandatory) {
665 AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory);
666 if (!prefix_op_expr)
667 return nullptr;
668
615669 Token *as_kw = &pc->tokens->at(*token_index);
616670 if (as_kw->id != TokenIdKeywordAs)
617 return primary_expr;
671 return prefix_op_expr;
618672 *token_index += 1;
619673
620674 AstNode *node = ast_create_node(NodeTypeCastExpr, as_kw);
621 node->data.cast_expr.primary_expr = primary_expr;
675 node->data.cast_expr.prefix_op_expr = prefix_op_expr;
622676
623677 node->data.cast_expr.type = ast_parse_type(pc, *token_index, token_index);
624678
src/parser.hpp+21-7
......@@ -24,7 +24,6 @@ enum NodeType {
2424 NodeTypeParamDecl,
2525 NodeTypeType,
2626 NodeTypeBlock,
27 NodeTypeFnCall,
2827 NodeTypeExternBlock,
2928 NodeTypeDirective,
3029 NodeTypeReturnExpr,
......@@ -32,6 +31,8 @@ enum NodeType {
3231 NodeTypeCastExpr,
3332 NodeTypePrimaryExpr,
3433 NodeTypeGroupedExpr,
34 NodeTypePrefixOpExpr,
35 NodeTypeFnCallExpr,
3536};
3637
3738struct AstNodeRoot {
......@@ -117,8 +118,8 @@ struct AstNodeBinOpExpr {
117118 AstNode *op2;
118119};
119120
120struct AstNodeFnCall {
121 Buf name;
121struct AstNodeFnCallExpr {
122 AstNode *fn_ref_expr;
122123 ZigList<AstNode *> params;
123124};
124125
......@@ -138,7 +139,7 @@ struct AstNodeRootExportDecl {
138139};
139140
140141struct AstNodeCastExpr {
141 AstNode *primary_expr;
142 AstNode *prefix_op_expr;
142143 // if type is non-null, do cast, otherwise nothing
143144 AstNode *type;
144145};
......@@ -147,9 +148,9 @@ enum PrimaryExprType {
147148 PrimaryExprTypeNumber,
148149 PrimaryExprTypeString,
149150 PrimaryExprTypeUnreachable,
150 PrimaryExprTypeFnCall,
151151 PrimaryExprTypeGroupedExpr,
152152 PrimaryExprTypeBlock,
153 PrimaryExprTypeSymbol,
153154};
154155
155156struct AstNodePrimaryExpr {
......@@ -157,7 +158,7 @@ struct AstNodePrimaryExpr {
157158 union {
158159 Buf number;
159160 Buf string;
160 AstNode *fn_call;
161 Buf symbol;
161162 AstNode *grouped_expr;
162163 AstNode *block;
163164 } data;
......@@ -167,6 +168,18 @@ struct AstNodeGroupedExpr {
167168 AstNode *expr;
168169};
169170
171enum PrefixOp {
172 PrefixOpInvalid,
173 PrefixOpBoolNot,
174 PrefixOpBinNot,
175 PrefixOpNegation,
176};
177
178struct AstNodePrefixOpExpr {
179 PrefixOp prefix_op;
180 AstNode *primary_expr;
181};
182
170183struct AstNode {
171184 enum NodeType type;
172185 AstNode *parent;
......@@ -184,12 +197,13 @@ struct AstNode {
184197 AstNodeBlock block;
185198 AstNodeReturnExpr return_expr;
186199 AstNodeBinOpExpr bin_op_expr;
187 AstNodeFnCall fn_call;
188200 AstNodeExternBlock extern_block;
189201 AstNodeDirective directive;
190202 AstNodeCastExpr cast_expr;
191203 AstNodePrimaryExpr primary_expr;
192204 AstNodeGroupedExpr grouped_expr;
205 AstNodePrefixOpExpr prefix_op_expr;
206 AstNodeFnCallExpr fn_call_expr;
193207 } data;
194208};
195209
src/tokenizer.cpp+7-2
......@@ -249,6 +249,10 @@ ZigList<Token> *tokenize(Buf *buf) {
249249 begin_token(&t, TokenIdPlus);
250250 end_token(&t);
251251 break;
252 case '~':
253 begin_token(&t, TokenIdTilde);
254 end_token(&t);
255 break;
252256 case '-':
253257 begin_token(&t, TokenIdDash);
254258 t.state = TokenizeStateSawDash;
......@@ -278,7 +282,7 @@ ZigList<Token> *tokenize(Buf *buf) {
278282 t.state = TokenizeStateEq;
279283 break;
280284 case '!':
281 begin_token(&t, TokenIdNot);
285 begin_token(&t, TokenIdBang);
282286 t.state = TokenizeStateBang;
283287 break;
284288 case '<':
......@@ -578,7 +582,8 @@ static const char * token_name(Token *token) {
578582 case TokenIdBoolOr: return "BoolOr";
579583 case TokenIdBoolAnd: return "BoolAnd";
580584 case TokenIdEq: return "Eq";
581 case TokenIdNot: return "Not";
585 case TokenIdBang: return "Bang";
586 case TokenIdTilde: return "Tilde";
582587 case TokenIdCmpEq: return "CmpEq";
583588 case TokenIdCmpNotEq: return "CmpNotEq";
584589 case TokenIdCmpLessThan: return "CmpLessThan";
src/tokenizer.hpp+2-1
......@@ -43,7 +43,8 @@ enum TokenId {
4343 TokenIdBinXor,
4444 TokenIdEq,
4545 TokenIdCmpEq,
46 TokenIdNot,
46 TokenIdBang,
47 TokenIdTilde,
4748 TokenIdCmpNotEq,
4849 TokenIdCmpLessThan,
4950 TokenIdCmpGreaterThan,