authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-11-29 14:46:05-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-11-29 14:46:05-07:00
log9a014b52ccc22d7ec24804f90993cfe08e3d20c4
treee7e90f22ed9ad940cb3c22b6d02d70bcb2b7dd96
parent4466a4533c0f1ba33143bfead7ba99910d331531

flatten expression ast to hide operator precedence


3 files changed, 230 insertions(+), 421 deletions(-)

src/codegen.cpp+94-132
......@@ -305,17 +305,9 @@ static void find_declarations(CodeGen *g, AstNode *node) {
305305 case NodeTypeReturnExpr:
306306 case NodeTypeRoot:
307307 case NodeTypeBlock:
308 case NodeTypeBoolOrExpr:
308 case NodeTypeBinOpExpr:
309309 case NodeTypeFnCall:
310310 case NodeTypeRootExportDecl:
311 case NodeTypeBoolAndExpr:
312 case NodeTypeComparisonExpr:
313 case NodeTypeBinOrExpr:
314 case NodeTypeBinXorExpr:
315 case NodeTypeBinAndExpr:
316 case NodeTypeBitShiftExpr:
317 case NodeTypeAddExpr:
318 case NodeTypeMultExpr:
319311 case NodeTypeCastExpr:
320312 case NodeTypePrimaryExpr:
321313 case NodeTypeGroupedExpr:
......@@ -481,10 +473,9 @@ static void analyze_node(CodeGen *g, AstNode *node) {
481473 analyze_node(g, node->data.return_expr.expr);
482474 }
483475 break;
484 case NodeTypeBoolOrExpr:
485 analyze_node(g, node->data.bool_or_expr.op1);
486 if (node->data.bool_or_expr.op2)
487 analyze_node(g, node->data.bool_or_expr.op2);
476 case NodeTypeBinOpExpr:
477 analyze_node(g, node->data.bin_op_expr.op1);
478 analyze_node(g, node->data.bin_op_expr.op2);
488479 break;
489480 case NodeTypeFnCall:
490481 {
......@@ -515,30 +506,6 @@ static void analyze_node(CodeGen *g, AstNode *node) {
515506 case NodeTypeDirective:
516507 // we looked at directives in the parent node
517508 break;
518 case NodeTypeBoolAndExpr:
519 zig_panic("TODO");
520 break;
521 case NodeTypeComparisonExpr:
522 zig_panic("TODO");
523 break;
524 case NodeTypeBinOrExpr:
525 zig_panic("TODO");
526 break;
527 case NodeTypeBinXorExpr:
528 zig_panic("TODO");
529 break;
530 case NodeTypeBinAndExpr:
531 zig_panic("TODO");
532 break;
533 case NodeTypeBitShiftExpr:
534 zig_panic("TODO");
535 break;
536 case NodeTypeAddExpr:
537 zig_panic("TODO");
538 break;
539 case NodeTypeMultExpr:
540 zig_panic("TODO");
541 break;
542509 case NodeTypeCastExpr:
543510 zig_panic("TODO");
544511 break;
......@@ -752,168 +719,138 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
752719}
753720
754721static LLVMValueRef gen_mult_expr(CodeGen *g, AstNode *node) {
755 assert(node->type == NodeTypeMultExpr);
756
757 LLVMValueRef val1 = gen_cast_expr(g, node->data.mult_expr.op1);
758
759 if (!node->data.mult_expr.op2)
760 return val1;
722 assert(node->type == NodeTypeBinOpExpr);
761723
762 LLVMValueRef val2 = gen_cast_expr(g, node->data.mult_expr.op2);
724 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
725 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
763726
764 switch (node->data.mult_expr.mult_op) {
765 case MultOpMult:
727 switch (node->data.bin_op_expr.bin_op) {
728 case BinOpTypeMult:
766729 // TODO types so we know float vs int
767730 add_debug_source_node(g, node);
768731 return LLVMBuildMul(g->builder, val1, val2, "");
769 case MultOpDiv:
732 case BinOpTypeDiv:
770733 // TODO types so we know float vs int and signed vs unsigned
771734 add_debug_source_node(g, node);
772735 return LLVMBuildSDiv(g->builder, val1, val2, "");
773 case MultOpMod:
736 case BinOpTypeMod:
774737 // TODO types so we know float vs int and signed vs unsigned
775738 add_debug_source_node(g, node);
776739 return LLVMBuildSRem(g->builder, val1, val2, "");
777 case MultOpInvalid:
740 default:
778741 zig_unreachable();
779742 }
780743 zig_unreachable();
781744}
782745
783746static LLVMValueRef gen_add_expr(CodeGen *g, AstNode *node) {
784 assert(node->type == NodeTypeAddExpr);
785
786 LLVMValueRef val1 = gen_mult_expr(g, node->data.add_expr.op1);
787
788 if (!node->data.add_expr.op2)
789 return val1;
747 assert(node->type == NodeTypeBinOpExpr);
790748
791 LLVMValueRef val2 = gen_mult_expr(g, node->data.add_expr.op2);
749 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
750 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
792751
793 switch (node->data.add_expr.add_op) {
794 case AddOpAdd:
752 switch (node->data.bin_op_expr.bin_op) {
753 case BinOpTypeAdd:
795754 add_debug_source_node(g, node);
796755 return LLVMBuildAdd(g->builder, val1, val2, "");
797 case AddOpSub:
756 case BinOpTypeSub:
798757 add_debug_source_node(g, node);
799758 return LLVMBuildSub(g->builder, val1, val2, "");
800 case AddOpInvalid:
759 default:
801760 zig_unreachable();
802761 }
803762 zig_unreachable();
804763}
805764
806765static LLVMValueRef gen_bit_shift_expr(CodeGen *g, AstNode *node) {
807 assert(node->type == NodeTypeBitShiftExpr);
808
809 LLVMValueRef val1 = gen_add_expr(g, node->data.bit_shift_expr.op1);
810
811 if (!node->data.bit_shift_expr.op2)
812 return val1;
766 assert(node->type == NodeTypeBinOpExpr);
813767
814 LLVMValueRef val2 = gen_add_expr(g, node->data.bit_shift_expr.op2);
768 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
769 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
815770
816 switch (node->data.bit_shift_expr.bit_shift_op) {
817 case BitShiftOpLeft:
771 switch (node->data.bin_op_expr.bin_op) {
772 case BinOpTypeBitShiftLeft:
818773 add_debug_source_node(g, node);
819774 return LLVMBuildShl(g->builder, val1, val2, "");
820 case BitShiftOpRight:
775 case BinOpTypeBitShiftRight:
821776 // TODO implement type system so that we know whether to do
822777 // logical or arithmetic shifting here.
823778 // signed -> arithmetic, unsigned -> logical
824779 add_debug_source_node(g, node);
825780 return LLVMBuildLShr(g->builder, val1, val2, "");
826 case BitShiftOpInvalid:
781 default:
827782 zig_unreachable();
828783 }
829784 zig_unreachable();
830785}
831786
832787static LLVMValueRef gen_bin_and_expr(CodeGen *g, AstNode *node) {
833 assert(node->type == NodeTypeBinAndExpr);
834
835 LLVMValueRef val1 = gen_bit_shift_expr(g, node->data.bin_and_expr.op1);
836
837 if (!node->data.bin_and_expr.op2)
838 return val1;
788 assert(node->type == NodeTypeBinOpExpr);
839789
840 LLVMValueRef val2 = gen_bit_shift_expr(g, node->data.bin_and_expr.op2);
790 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
791 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
841792
842793 add_debug_source_node(g, node);
843794 return LLVMBuildAnd(g->builder, val1, val2, "");
844795}
845796
846797static LLVMValueRef gen_bin_xor_expr(CodeGen *g, AstNode *node) {
847 assert(node->type == NodeTypeBinXorExpr);
798 assert(node->type == NodeTypeBinOpExpr);
848799
849 LLVMValueRef val1 = gen_bin_and_expr(g, node->data.bin_xor_expr.op1);
850
851 if (!node->data.bin_xor_expr.op2)
852 return val1;
853
854 LLVMValueRef val2 = gen_bin_and_expr(g, node->data.bin_xor_expr.op2);
800 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
801 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
855802
856803 add_debug_source_node(g, node);
857804 return LLVMBuildXor(g->builder, val1, val2, "");
858805}
859806
860807static LLVMValueRef gen_bin_or_expr(CodeGen *g, AstNode *node) {
861 assert(node->type == NodeTypeBinOrExpr);
862
863 LLVMValueRef val1 = gen_bin_xor_expr(g, node->data.bin_or_expr.op1);
808 assert(node->type == NodeTypeBinOpExpr);
864809
865 if (!node->data.bin_or_expr.op2)
866 return val1;
867
868 LLVMValueRef val2 = gen_bin_xor_expr(g, node->data.bin_or_expr.op2);
810 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
811 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
869812
870813 add_debug_source_node(g, node);
871814 return LLVMBuildOr(g->builder, val1, val2, "");
872815}
873816
874static LLVMIntPredicate cmp_op_to_int_predicate(CmpOp cmp_op, bool is_signed) {
817static LLVMIntPredicate cmp_op_to_int_predicate(BinOpType cmp_op, bool is_signed) {
875818 switch (cmp_op) {
876 case CmpOpInvalid:
819 case BinOpTypeInvalid:
877820 zig_unreachable();
878 case CmpOpEq:
821 case BinOpTypeCmpEq:
879822 return LLVMIntEQ;
880 case CmpOpNotEq:
823 case BinOpTypeCmpNotEq:
881824 return LLVMIntNE;
882 case CmpOpLessThan:
825 case BinOpTypeCmpLessThan:
883826 return is_signed ? LLVMIntSLT : LLVMIntULT;
884 case CmpOpGreaterThan:
827 case BinOpTypeCmpGreaterThan:
885828 return is_signed ? LLVMIntSGT : LLVMIntUGT;
886 case CmpOpLessOrEq:
829 case BinOpTypeCmpLessOrEq:
887830 return is_signed ? LLVMIntSLE : LLVMIntULE;
888 case CmpOpGreaterOrEq:
831 case BinOpTypeCmpGreaterOrEq:
889832 return is_signed ? LLVMIntSGE : LLVMIntUGE;
833 default:
834 zig_unreachable();
890835 }
891 zig_unreachable();
892836}
893837
894838static LLVMValueRef gen_cmp_expr(CodeGen *g, AstNode *node) {
895 assert(node->type == NodeTypeComparisonExpr);
896
897 LLVMValueRef val1 = gen_bin_or_expr(g, node->data.comparison_expr.op1);
898
899 if (!node->data.comparison_expr.op2)
900 return val1;
839 assert(node->type == NodeTypeBinOpExpr);
901840
902 LLVMValueRef val2 = gen_bin_or_expr(g, node->data.comparison_expr.op2);
841 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
842 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
903843
904844 // TODO implement type system so that we know whether to do signed or unsigned comparison here
905 LLVMIntPredicate pred = cmp_op_to_int_predicate(node->data.comparison_expr.cmp_op, true);
845 LLVMIntPredicate pred = cmp_op_to_int_predicate(node->data.bin_op_expr.bin_op, true);
906846 add_debug_source_node(g, node);
907847 return LLVMBuildICmp(g->builder, pred, val1, val2, "");
908848}
909849
910850static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
911 assert(node->type == NodeTypeBoolAndExpr);
851 assert(node->type == NodeTypeBinOpExpr);
912852
913 LLVMValueRef val1 = gen_cmp_expr(g, node->data.bool_and_expr.op1);
914
915 if (!node->data.bool_and_expr.op2)
916 return val1;
853 LLVMValueRef val1 = gen_expr(g, node->data.bin_op_expr.op1);
917854
918855 // block for when val1 == true
919856 LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn, "BoolAndTrue");
......@@ -926,7 +863,7 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
926863 LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
927864
928865 LLVMPositionBuilderAtEnd(g->builder, true_block);
929 LLVMValueRef val2 = gen_cmp_expr(g, node->data.bool_and_expr.op2);
866 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
930867 add_debug_source_node(g, node);
931868 LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
932869
......@@ -942,12 +879,9 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
942879}
943880
944881static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
945 assert(expr_node->type == NodeTypeBoolOrExpr);
946
947 LLVMValueRef val1 = gen_bool_and_expr(g, expr_node->data.bool_or_expr.op1);
882 assert(expr_node->type == NodeTypeBinOpExpr);
948883
949 if (!expr_node->data.bool_or_expr.op2)
950 return val1;
884 LLVMValueRef val1 = gen_expr(g, expr_node->data.bin_op_expr.op1);
951885
952886 // block for when val1 == false
953887 LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn, "BoolOrFalse");
......@@ -960,7 +894,7 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
960894 LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
961895
962896 LLVMPositionBuilderAtEnd(g->builder, false_block);
963 LLVMValueRef val2 = gen_bool_and_expr(g, expr_node->data.bool_or_expr.op2);
897 LLVMValueRef val2 = gen_expr(g, expr_node->data.bin_op_expr.op2);
964898 add_debug_source_node(g, expr_node);
965899 LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
966900
......@@ -975,6 +909,41 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
975909 return phi;
976910}
977911
912static LLVMValueRef gen_bin_op_expr(CodeGen *g, AstNode *node) {
913 switch (node->data.bin_op_expr.bin_op) {
914 case BinOpTypeInvalid:
915 zig_unreachable();
916 case BinOpTypeBoolOr:
917 return gen_bool_or_expr(g, node);
918 case BinOpTypeBoolAnd:
919 return gen_bool_and_expr(g, node);
920 case BinOpTypeCmpEq:
921 case BinOpTypeCmpNotEq:
922 case BinOpTypeCmpLessThan:
923 case BinOpTypeCmpGreaterThan:
924 case BinOpTypeCmpLessOrEq:
925 case BinOpTypeCmpGreaterOrEq:
926 return gen_cmp_expr(g, node);
927 case BinOpTypeBinOr:
928 return gen_bin_or_expr(g, node);
929 case BinOpTypeBinXor:
930 return gen_bin_xor_expr(g, node);
931 case BinOpTypeBinAnd:
932 return gen_bin_and_expr(g, node);
933 case BinOpTypeBitShiftLeft:
934 case BinOpTypeBitShiftRight:
935 return gen_bit_shift_expr(g, node);
936 case BinOpTypeAdd:
937 case BinOpTypeSub:
938 return gen_add_expr(g, node);
939 case BinOpTypeMult:
940 case BinOpTypeDiv:
941 case BinOpTypeMod:
942 return gen_mult_expr(g, node);
943 }
944 zig_unreachable();
945}
946
978947static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
979948 assert(node->type == NodeTypeReturnExpr);
980949 AstNode *param_node = node->data.return_expr.expr;
......@@ -993,10 +962,12 @@ Expression : BoolOrExpression | ReturnExpression
993962*/
994963static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
995964 switch (node->type) {
996 case NodeTypeBoolOrExpr:
997 return gen_bool_or_expr(g, node);
965 case NodeTypeBinOpExpr:
966 return gen_bin_op_expr(g, node);
998967 case NodeTypeReturnExpr:
999968 return gen_return_expr(g, node);
969 case NodeTypeCastExpr:
970 return gen_cast_expr(g, node);
1000971 case NodeTypeRoot:
1001972 case NodeTypeRootExportDecl:
1002973 case NodeTypeFnProto:
......@@ -1008,15 +979,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
1008979 case NodeTypeFnCall:
1009980 case NodeTypeExternBlock:
1010981 case NodeTypeDirective:
1011 case NodeTypeBoolAndExpr:
1012 case NodeTypeComparisonExpr:
1013 case NodeTypeBinOrExpr:
1014 case NodeTypeBinXorExpr:
1015 case NodeTypeBinAndExpr:
1016 case NodeTypeBitShiftExpr:
1017 case NodeTypeAddExpr:
1018 case NodeTypeMultExpr:
1019 case NodeTypeCastExpr:
1020982 case NodeTypePrimaryExpr:
1021983 return gen_primary_expr(g, node);
1022984 case NodeTypeGroupedExpr:
src/parser.cpp+109-188
......@@ -10,43 +10,27 @@
1010#include <stdarg.h>
1111#include <stdio.h>
1212
13static const char *mult_op_str(MultOp mult_op) {
14 switch (mult_op) {
15 case MultOpInvalid: return "(invalid)";
16 case MultOpMult: return "*";
17 case MultOpDiv: return "/";
18 case MultOpMod: return "%";
19 }
20 zig_unreachable();
21}
22
23static const char *add_op_str(AddOp add_op) {
24 switch (add_op) {
25 case AddOpInvalid: return "(invalid)";
26 case AddOpAdd: return "+";
27 case AddOpSub: return "-";
28 }
29 zig_unreachable();
30}
31
32static const char *bit_shift_op_str(BitShiftOp bit_shift_op) {
33 switch (bit_shift_op) {
34 case BitShiftOpInvalid: return "(invalid)";
35 case BitShiftOpLeft: return "<<";
36 case BitShiftOpRight: return ">>";
37 }
38 zig_unreachable();
39}
40
41static const char *cmp_op_str(CmpOp cmp_op) {
42 switch (cmp_op) {
43 case CmpOpInvalid: return "(invalid)";
44 case CmpOpEq: return "=";
45 case CmpOpNotEq: return "!=";
46 case CmpOpLessThan: return "<";
47 case CmpOpGreaterThan: return ">";
48 case CmpOpLessOrEq: return "<=";
49 case CmpOpGreaterOrEq: return ">=";
13static const char *bin_op_str(BinOpType bin_op) {
14 switch (bin_op) {
15 case BinOpTypeInvalid: return "(invalid)";
16 case BinOpTypeBoolOr: return "||";
17 case BinOpTypeBoolAnd: return "&&";
18 case BinOpTypeCmpEq: return "==";
19 case BinOpTypeCmpNotEq: return "!=";
20 case BinOpTypeCmpLessThan: return "<";
21 case BinOpTypeCmpGreaterThan: return ">";
22 case BinOpTypeCmpLessOrEq: return "<=";
23 case BinOpTypeCmpGreaterOrEq: return ">=";
24 case BinOpTypeBinOr: return "|";
25 case BinOpTypeBinXor: return "^";
26 case BinOpTypeBinAnd: return "&";
27 case BinOpTypeBitShiftLeft: return "<<";
28 case BinOpTypeBitShiftRight: return ">>";
29 case BinOpTypeAdd: return "+";
30 case BinOpTypeSub: return "-";
31 case BinOpTypeMult: return "*";
32 case BinOpTypeDiv: return "/";
33 case BinOpTypeMod: return "%";
5034 }
5135 zig_unreachable();
5236}
......@@ -84,8 +68,8 @@ const char *node_type_str(NodeType node_type) {
8468 return "Type";
8569 case NodeTypeBlock:
8670 return "Block";
87 case NodeTypeBoolOrExpr:
88 return "BoolOrExpr";
71 case NodeTypeBinOpExpr:
72 return "BinOpExpr";
8973 case NodeTypeFnCall:
9074 return "FnCall";
9175 case NodeTypeExternBlock:
......@@ -94,22 +78,6 @@ const char *node_type_str(NodeType node_type) {
9478 return "Directive";
9579 case NodeTypeReturnExpr:
9680 return "ReturnExpr";
97 case NodeTypeBoolAndExpr:
98 return "BoolAndExpr";
99 case NodeTypeComparisonExpr:
100 return "ComparisonExpr";
101 case NodeTypeBinOrExpr:
102 return "BinOrExpr";
103 case NodeTypeBinXorExpr:
104 return "BinXorExpr";
105 case NodeTypeBinAndExpr:
106 return "BinAndExpr";
107 case NodeTypeBitShiftExpr:
108 return "BitShiftExpr";
109 case NodeTypeAddExpr:
110 return "AddExpr";
111 case NodeTypeMultExpr:
112 return "MultExpr";
11381 case NodeTypeCastExpr:
11482 return "CastExpr";
11583 case NodeTypePrimaryExpr:
......@@ -214,11 +182,11 @@ void ast_print(AstNode *node, int indent) {
214182 fprintf(stderr, "%s\n", node_type_str(node->type));
215183 ast_print(node->data.fn_decl.fn_proto, indent + 2);
216184 break;
217 case NodeTypeBoolOrExpr:
218 fprintf(stderr, "%s\n", node_type_str(node->type));
219 ast_print(node->data.bool_or_expr.op1, indent + 2);
220 if (node->data.bool_or_expr.op2)
221 ast_print(node->data.bool_or_expr.op2, indent + 2);
185 case NodeTypeBinOpExpr:
186 fprintf(stderr, "%s %s\n", node_type_str(node->type),
187 bin_op_str(node->data.bin_op_expr.bin_op));
188 ast_print(node->data.bin_op_expr.op1, indent + 2);
189 ast_print(node->data.bin_op_expr.op2, indent + 2);
222190 break;
223191 case NodeTypeFnCall:
224192 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.fn_call.name));
......@@ -230,58 +198,6 @@ void ast_print(AstNode *node, int indent) {
230198 case NodeTypeDirective:
231199 fprintf(stderr, "%s\n", node_type_str(node->type));
232200 break;
233 case NodeTypeBoolAndExpr:
234 fprintf(stderr, "%s\n", node_type_str(node->type));
235 ast_print(node->data.bool_and_expr.op1, indent + 2);
236 if (node->data.bool_and_expr.op2)
237 ast_print(node->data.bool_and_expr.op2, indent + 2);
238 break;
239 case NodeTypeComparisonExpr:
240 fprintf(stderr, "%s %s\n", node_type_str(node->type),
241 cmp_op_str(node->data.comparison_expr.cmp_op));
242 ast_print(node->data.comparison_expr.op1, indent + 2);
243 if (node->data.comparison_expr.op2)
244 ast_print(node->data.comparison_expr.op2, indent + 2);
245 break;
246 case NodeTypeBinOrExpr:
247 fprintf(stderr, "%s\n", node_type_str(node->type));
248 ast_print(node->data.bin_or_expr.op1, indent + 2);
249 if (node->data.bin_or_expr.op2)
250 ast_print(node->data.bin_or_expr.op2, indent + 2);
251 break;
252 case NodeTypeBinXorExpr:
253 fprintf(stderr, "%s\n", node_type_str(node->type));
254 ast_print(node->data.bin_xor_expr.op1, indent + 2);
255 if (node->data.bin_xor_expr.op2)
256 ast_print(node->data.bin_xor_expr.op2, indent + 2);
257 break;
258 case NodeTypeBinAndExpr:
259 fprintf(stderr, "%s\n", node_type_str(node->type));
260 ast_print(node->data.bin_and_expr.op1, indent + 2);
261 if (node->data.bin_and_expr.op2)
262 ast_print(node->data.bin_and_expr.op2, indent + 2);
263 break;
264 case NodeTypeBitShiftExpr:
265 fprintf(stderr, "%s %s\n", node_type_str(node->type),
266 bit_shift_op_str(node->data.bit_shift_expr.bit_shift_op));
267 ast_print(node->data.bit_shift_expr.op1, indent + 2);
268 if (node->data.bit_shift_expr.op2)
269 ast_print(node->data.bit_shift_expr.op2, indent + 2);
270 break;
271 case NodeTypeAddExpr:
272 fprintf(stderr, "%s %s\n", node_type_str(node->type),
273 add_op_str(node->data.add_expr.add_op));
274 ast_print(node->data.add_expr.op1, indent + 2);
275 if (node->data.add_expr.op2)
276 ast_print(node->data.add_expr.op2, indent + 2);
277 break;
278 case NodeTypeMultExpr:
279 fprintf(stderr, "%s %s\n", node_type_str(node->type),
280 mult_op_str(node->data.mult_expr.mult_op));
281 ast_print(node->data.mult_expr.op1, indent + 2);
282 if (node->data.mult_expr.op2)
283 ast_print(node->data.mult_expr.op2, indent + 2);
284 break;
285201 case NodeTypeCastExpr:
286202 fprintf(stderr, "%s\n", node_type_str(node->type));
287203 ast_print(node->data.cast_expr.primary_expr, indent + 2);
......@@ -709,26 +625,26 @@ static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bo
709625 return node;
710626}
711627
712static MultOp tok_to_mult_op(Token *token) {
628static BinOpType tok_to_mult_op(Token *token) {
713629 switch (token->id) {
714 case TokenIdStar: return MultOpMult;
715 case TokenIdSlash: return MultOpDiv;
716 case TokenIdPercent: return MultOpMod;
717 default: return MultOpInvalid;
630 case TokenIdStar: return BinOpTypeMult;
631 case TokenIdSlash: return BinOpTypeDiv;
632 case TokenIdPercent: return BinOpTypeMod;
633 default: return BinOpTypeInvalid;
718634 }
719635}
720636
721637/*
722638MultiplyOperator : token(Star) | token(Slash) | token(Percent)
723639*/
724static MultOp ast_parse_mult_op(ParseContext *pc, int *token_index, bool mandatory) {
640static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mandatory) {
725641 Token *token = &pc->tokens->at(*token_index);
726 MultOp result = tok_to_mult_op(token);
727 if (result == MultOpInvalid) {
642 BinOpType result = tok_to_mult_op(token);
643 if (result == BinOpTypeInvalid) {
728644 if (mandatory) {
729645 ast_invalid_token_error(pc, token);
730646 } else {
731 return MultOpInvalid;
647 return BinOpTypeInvalid;
732648 }
733649 }
734650 *token_index += 1;
......@@ -744,39 +660,39 @@ static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool man
744660 return nullptr;
745661
746662 Token *token = &pc->tokens->at(*token_index);
747 MultOp mult_op = ast_parse_mult_op(pc, token_index, false);
748 if (mult_op == MultOpInvalid)
663 BinOpType mult_op = ast_parse_mult_op(pc, token_index, false);
664 if (mult_op == BinOpTypeInvalid)
749665 return operand_1;
750666
751667 AstNode *operand_2 = ast_parse_cast_expression(pc, token_index, true);
752668
753 AstNode *node = ast_create_node(NodeTypeMultExpr, token);
754 node->data.mult_expr.op1 = operand_1;
755 node->data.mult_expr.mult_op = mult_op;
756 node->data.mult_expr.op2 = operand_2;
669 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
670 node->data.bin_op_expr.op1 = operand_1;
671 node->data.bin_op_expr.bin_op = mult_op;
672 node->data.bin_op_expr.op2 = operand_2;
757673
758674 return node;
759675}
760676
761static AddOp tok_to_add_op(Token *token) {
677static BinOpType tok_to_add_op(Token *token) {
762678 switch (token->id) {
763 case TokenIdPlus: return AddOpAdd;
764 case TokenIdDash: return AddOpSub;
765 default: return AddOpInvalid;
679 case TokenIdPlus: return BinOpTypeAdd;
680 case TokenIdDash: return BinOpTypeSub;
681 default: return BinOpTypeInvalid;
766682 }
767683}
768684
769685/*
770686AdditionOperator : token(Plus) | token(Minus)
771687*/
772static AddOp ast_parse_add_op(ParseContext *pc, int *token_index, bool mandatory) {
688static BinOpType ast_parse_add_op(ParseContext *pc, int *token_index, bool mandatory) {
773689 Token *token = &pc->tokens->at(*token_index);
774 AddOp result = tok_to_add_op(token);
775 if (result == AddOpInvalid) {
690 BinOpType result = tok_to_add_op(token);
691 if (result == BinOpTypeInvalid) {
776692 if (mandatory) {
777693 ast_invalid_token_error(pc, token);
778694 } else {
779 return AddOpInvalid;
695 return BinOpTypeInvalid;
780696 }
781697 }
782698 *token_index += 1;
......@@ -792,39 +708,39 @@ static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mand
792708 return nullptr;
793709
794710 Token *token = &pc->tokens->at(*token_index);
795 AddOp add_op = ast_parse_add_op(pc, token_index, false);
796 if (add_op == AddOpInvalid)
711 BinOpType add_op = ast_parse_add_op(pc, token_index, false);
712 if (add_op == BinOpTypeInvalid)
797713 return operand_1;
798714
799715 AstNode *operand_2 = ast_parse_mult_expr(pc, token_index, true);
800716
801 AstNode *node = ast_create_node(NodeTypeAddExpr, token);
802 node->data.add_expr.op1 = operand_1;
803 node->data.add_expr.add_op = add_op;
804 node->data.add_expr.op2 = operand_2;
717 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
718 node->data.bin_op_expr.op1 = operand_1;
719 node->data.bin_op_expr.bin_op = add_op;
720 node->data.bin_op_expr.op2 = operand_2;
805721
806722 return node;
807723}
808724
809static BitShiftOp tok_to_bit_shift_op(Token *token) {
725static BinOpType tok_to_bit_shift_op(Token *token) {
810726 switch (token->id) {
811 case TokenIdBitShiftLeft: return BitShiftOpLeft;
812 case TokenIdBitShiftRight: return BitShiftOpRight;
813 default: return BitShiftOpInvalid;
727 case TokenIdBitShiftLeft: return BinOpTypeBitShiftLeft;
728 case TokenIdBitShiftRight: return BinOpTypeBitShiftRight;
729 default: return BinOpTypeInvalid;
814730 }
815731}
816732
817733/*
818734BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)
819735*/
820static BitShiftOp ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) {
736static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) {
821737 Token *token = &pc->tokens->at(*token_index);
822 BitShiftOp result = tok_to_bit_shift_op(token);
823 if (result == BitShiftOpInvalid) {
738 BinOpType result = tok_to_bit_shift_op(token);
739 if (result == BinOpTypeInvalid) {
824740 if (mandatory) {
825741 ast_invalid_token_error(pc, token);
826742 } else {
827 return BitShiftOpInvalid;
743 return BinOpTypeInvalid;
828744 }
829745 }
830746 *token_index += 1;
......@@ -840,16 +756,16 @@ static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, boo
840756 return nullptr;
841757
842758 Token *token = &pc->tokens->at(*token_index);
843 BitShiftOp bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);
844 if (bit_shift_op == BitShiftOpInvalid)
759 BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);
760 if (bit_shift_op == BinOpTypeInvalid)
845761 return operand_1;
846762
847763 AstNode *operand_2 = ast_parse_add_expr(pc, token_index, true);
848764
849 AstNode *node = ast_create_node(NodeTypeBitShiftExpr, token);
850 node->data.bit_shift_expr.op1 = operand_1;
851 node->data.bit_shift_expr.bit_shift_op = bit_shift_op;
852 node->data.bit_shift_expr.op2 = operand_2;
765 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
766 node->data.bin_op_expr.op1 = operand_1;
767 node->data.bin_op_expr.bin_op = bit_shift_op;
768 node->data.bin_op_expr.op2 = operand_2;
853769
854770 return node;
855771}
......@@ -870,9 +786,10 @@ static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool
870786
871787 AstNode *operand_2 = ast_parse_bit_shift_expr(pc, token_index, true);
872788
873 AstNode *node = ast_create_node(NodeTypeBinAndExpr, token);
874 node->data.bin_and_expr.op1 = operand_1;
875 node->data.bin_and_expr.op2 = operand_2;
789 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
790 node->data.bin_op_expr.op1 = operand_1;
791 node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;
792 node->data.bin_op_expr.op2 = operand_2;
876793
877794 return node;
878795}
......@@ -892,9 +809,10 @@ static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool
892809
893810 AstNode *operand_2 = ast_parse_bin_and_expr(pc, token_index, true);
894811
895 AstNode *node = ast_create_node(NodeTypeBinXorExpr, token);
896 node->data.bin_xor_expr.op1 = operand_1;
897 node->data.bin_xor_expr.op2 = operand_2;
812 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
813 node->data.bin_op_expr.op1 = operand_1;
814 node->data.bin_op_expr.bin_op = BinOpTypeBinXor;
815 node->data.bin_op_expr.op2 = operand_2;
898816
899817 return node;
900818}
......@@ -914,33 +832,34 @@ static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool m
914832
915833 AstNode *operand_2 = ast_parse_bin_xor_expr(pc, token_index, true);
916834
917 AstNode *node = ast_create_node(NodeTypeBinOrExpr, token);
918 node->data.bin_or_expr.op1 = operand_1;
919 node->data.bin_or_expr.op2 = operand_2;
835 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
836 node->data.bin_op_expr.op1 = operand_1;
837 node->data.bin_op_expr.bin_op = BinOpTypeBinOr;
838 node->data.bin_op_expr.op2 = operand_2;
920839
921840 return node;
922841}
923842
924static CmpOp tok_to_cmp_op(Token *token) {
843static BinOpType tok_to_cmp_op(Token *token) {
925844 switch (token->id) {
926 case TokenIdCmpEq: return CmpOpEq;
927 case TokenIdCmpNotEq: return CmpOpNotEq;
928 case TokenIdCmpLessThan: return CmpOpLessThan;
929 case TokenIdCmpGreaterThan: return CmpOpGreaterThan;
930 case TokenIdCmpLessOrEq: return CmpOpLessOrEq;
931 case TokenIdCmpGreaterOrEq: return CmpOpGreaterOrEq;
932 default: return CmpOpInvalid;
845 case TokenIdCmpEq: return BinOpTypeCmpEq;
846 case TokenIdCmpNotEq: return BinOpTypeCmpNotEq;
847 case TokenIdCmpLessThan: return BinOpTypeCmpLessThan;
848 case TokenIdCmpGreaterThan: return BinOpTypeCmpGreaterThan;
849 case TokenIdCmpLessOrEq: return BinOpTypeCmpLessOrEq;
850 case TokenIdCmpGreaterOrEq: return BinOpTypeCmpGreaterOrEq;
851 default: return BinOpTypeInvalid;
933852 }
934853}
935854
936static CmpOp ast_parse_comparison_operator(ParseContext *pc, int *token_index, bool mandatory) {
855static BinOpType ast_parse_comparison_operator(ParseContext *pc, int *token_index, bool mandatory) {
937856 Token *token = &pc->tokens->at(*token_index);
938 CmpOp result = tok_to_cmp_op(token);
939 if (result == CmpOpInvalid) {
857 BinOpType result = tok_to_cmp_op(token);
858 if (result == BinOpTypeInvalid) {
940859 if (mandatory) {
941860 ast_invalid_token_error(pc, token);
942861 } else {
943 return CmpOpInvalid;
862 return BinOpTypeInvalid;
944863 }
945864 }
946865 *token_index += 1;
......@@ -956,16 +875,16 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo
956875 return nullptr;
957876
958877 Token *token = &pc->tokens->at(*token_index);
959 CmpOp cmp_op = ast_parse_comparison_operator(pc, token_index, false);
960 if (cmp_op == CmpOpInvalid)
878 BinOpType cmp_op = ast_parse_comparison_operator(pc, token_index, false);
879 if (cmp_op == BinOpTypeInvalid)
961880 return operand_1;
962881
963882 AstNode *operand_2 = ast_parse_bin_or_expr(pc, token_index, true);
964883
965 AstNode *node = ast_create_node(NodeTypeComparisonExpr, token);
966 node->data.comparison_expr.op1 = operand_1;
967 node->data.comparison_expr.cmp_op = cmp_op;
968 node->data.comparison_expr.op2 = operand_2;
884 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
885 node->data.bin_op_expr.op1 = operand_1;
886 node->data.bin_op_expr.bin_op = cmp_op;
887 node->data.bin_op_expr.op2 = operand_2;
969888
970889 return node;
971890}
......@@ -985,9 +904,10 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool
985904
986905 AstNode *operand_2 = ast_parse_comparison_expr(pc, token_index, true);
987906
988 AstNode *node = ast_create_node(NodeTypeBoolAndExpr, token);
989 node->data.bool_and_expr.op1 = operand_1;
990 node->data.bool_and_expr.op2 = operand_2;
907 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
908 node->data.bin_op_expr.op1 = operand_1;
909 node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;
910 node->data.bin_op_expr.op2 = operand_2;
991911
992912 return node;
993913}
......@@ -1024,9 +944,10 @@ static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool
1024944
1025945 AstNode *operand_2 = ast_parse_bool_and_expr(pc, token_index, true);
1026946
1027 AstNode *node = ast_create_node(NodeTypeBoolOrExpr, token);
1028 node->data.bool_or_expr.op1 = operand_1;
1029 node->data.bool_or_expr.op2 = operand_2;
947 AstNode *node = ast_create_node(NodeTypeBinOpExpr, token);
948 node->data.bin_op_expr.op1 = operand_1;
949 node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;
950 node->data.bin_op_expr.op2 = operand_2;
1030951
1031952 return node;
1032953}
src/parser.hpp+27-101
......@@ -28,15 +28,7 @@ enum NodeType {
2828 NodeTypeExternBlock,
2929 NodeTypeDirective,
3030 NodeTypeReturnExpr,
31 NodeTypeBoolOrExpr,
32 NodeTypeBoolAndExpr,
33 NodeTypeComparisonExpr,
34 NodeTypeBinOrExpr,
35 NodeTypeBinXorExpr,
36 NodeTypeBinAndExpr,
37 NodeTypeBitShiftExpr,
38 NodeTypeAddExpr,
39 NodeTypeMultExpr,
31 NodeTypeBinOpExpr,
4032 NodeTypeCastExpr,
4133 NodeTypePrimaryExpr,
4234 NodeTypeGroupedExpr,
......@@ -96,9 +88,32 @@ struct AstNodeReturnExpr {
9688 AstNode *expr;
9789};
9890
99struct AstNodeBoolOrExpr {
91enum BinOpType {
92 BinOpTypeInvalid,
93 // TODO: include assignment?
94 BinOpTypeBoolOr,
95 BinOpTypeBoolAnd,
96 BinOpTypeCmpEq,
97 BinOpTypeCmpNotEq,
98 BinOpTypeCmpLessThan,
99 BinOpTypeCmpGreaterThan,
100 BinOpTypeCmpLessOrEq,
101 BinOpTypeCmpGreaterOrEq,
102 BinOpTypeBinOr,
103 BinOpTypeBinXor,
104 BinOpTypeBinAnd,
105 BinOpTypeBitShiftLeft,
106 BinOpTypeBitShiftRight,
107 BinOpTypeAdd,
108 BinOpTypeSub,
109 BinOpTypeMult,
110 BinOpTypeDiv,
111 BinOpTypeMod,
112};
113
114struct AstNodeBinOpExpr {
100115 AstNode *op1;
101 // if op2 is non-null, do boolean or, otherwise nothing
116 BinOpType bin_op;
102117 AstNode *op2;
103118};
104119
......@@ -122,87 +137,6 @@ struct AstNodeRootExportDecl {
122137 Buf name;
123138};
124139
125struct AstNodeBoolAndExpr {
126 AstNode *op1;
127 // if op2 is non-null, do boolean and, otherwise nothing
128 AstNode *op2;
129};
130
131enum CmpOp {
132 CmpOpInvalid,
133 CmpOpEq,
134 CmpOpNotEq,
135 CmpOpLessThan,
136 CmpOpGreaterThan,
137 CmpOpLessOrEq,
138 CmpOpGreaterOrEq,
139};
140
141struct AstNodeComparisonExpr {
142 AstNode *op1;
143 CmpOp cmp_op;
144 // if op2 is non-null, do cmp_op, otherwise nothing
145 AstNode *op2;
146};
147
148struct AstNodeBinOrExpr {
149 AstNode *op1;
150 // if op2 is non-null, do binary or, otherwise nothing
151 AstNode *op2;
152};
153
154struct AstNodeBinXorExpr {
155 AstNode *op1;
156 // if op2 is non-null, do binary xor, otherwise nothing
157 AstNode *op2;
158};
159
160struct AstNodeBinAndExpr {
161 AstNode *op1;
162 // if op2 is non-null, do binary and, otherwise nothing
163 AstNode *op2;
164};
165
166enum BitShiftOp {
167 BitShiftOpInvalid,
168 BitShiftOpLeft,
169 BitShiftOpRight,
170};
171
172struct AstNodeBitShiftExpr {
173 AstNode *op1;
174 BitShiftOp bit_shift_op;
175 // if op2 is non-null, do bit_shift_op, otherwise nothing
176 AstNode *op2;
177};
178
179enum AddOp {
180 AddOpInvalid,
181 AddOpAdd,
182 AddOpSub,
183};
184
185struct AstNodeAddExpr {
186 AstNode *op1;
187 AddOp add_op;
188 // if op2 is non-null, do add_op, otherwise nothing
189 AstNode *op2;
190};
191
192enum MultOp {
193 MultOpInvalid,
194 MultOpMult,
195 MultOpDiv,
196 MultOpMod,
197};
198
199struct AstNodeMultExpr {
200 AstNode *op1;
201 MultOp mult_op;
202 // if op2 is non-null, do mult_op, otherwise nothing
203 AstNode *op2;
204};
205
206140struct AstNodeCastExpr {
207141 AstNode *primary_expr;
208142 // if type is non-null, do cast, otherwise nothing
......@@ -249,18 +183,10 @@ struct AstNode {
249183 AstNodeParamDecl param_decl;
250184 AstNodeBlock block;
251185 AstNodeReturnExpr return_expr;
252 AstNodeBoolOrExpr bool_or_expr;
186 AstNodeBinOpExpr bin_op_expr;
253187 AstNodeFnCall fn_call;
254188 AstNodeExternBlock extern_block;
255189 AstNodeDirective directive;
256 AstNodeBoolAndExpr bool_and_expr;
257 AstNodeComparisonExpr comparison_expr;
258 AstNodeBinOrExpr bin_or_expr;
259 AstNodeBinXorExpr bin_xor_expr;
260 AstNodeBinAndExpr bin_and_expr;
261 AstNodeBitShiftExpr bit_shift_expr;
262 AstNodeAddExpr add_expr;
263 AstNodeMultExpr mult_expr;
264190 AstNodeCastExpr cast_expr;
265191 AstNodePrimaryExpr primary_expr;
266192 AstNodeGroupedExpr grouped_expr;