authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-12 17:03:44-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-12 17:07:43-07:00
log64dd0b8d9535672484512a4a9957a63c08a32f3f
treedf77022689ae2a31f438891a6679605cba582e53
parent38f12adbda5d3b0114232fdccdbcc0b4179f9115

fix a + b + c and similar

fix || and && closes #17

6 files changed, 193 insertions(+), 147 deletions(-)

doc/langref.md+11-11
......@@ -92,7 +92,7 @@ AssignmentExpression : BoolOrExpression token(Equal) BoolOrExpression | BoolOrEx
9292
9393BlockExpression : IfExpression | Block
9494
95BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression
95BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression
9696
9797ReturnExpression : token(Return) option(Expression)
9898
......@@ -102,33 +102,33 @@ ElseIf : token(Else) IfExpression
102102
103103Else : token(Else) Block
104104
105BoolAndExpression : ComparisonExpression token(BoolAnd) ComparisonExpression | ComparisonExpression
105BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression
106106
107107ComparisonExpression : BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression
108108
109109ComparisonOperator : token(BoolEq) | token(BoolNotEq) | token(BoolLessThan) | token(BoolGreaterThan) | token(BoolLessEqual) | token(BoolGreaterEqual)
110110
111BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryXorExpression | BinaryXorExpression
111BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryOrExpression | BinaryXorExpression
112112
113BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryAndExpression | BinaryAndExpression
113BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryXorExpression | BinaryAndExpression
114114
115BinaryAndExpression : BitShiftExpression token(BinAnd) BitShiftExpression | BitShiftExpression
115BinaryAndExpression : BitShiftExpression token(BinAnd) BinaryAndExpression | BitShiftExpression
116116
117BitShiftExpression : AdditionExpression BitShiftOperator AdditionExpression | AdditionExpression
117BitShiftExpression : AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
118118
119BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)
119BitShiftOperator : token(BitShiftLeft) | token(BitShiftRight)
120120
121AdditionExpression : MultiplyExpression AdditionOperator MultiplyExpression | MultiplyExpression
121AdditionExpression : MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
122122
123123AdditionOperator : token(Plus) | token(Minus)
124124
125MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpression
125MultiplyExpression : CastExpression MultiplyOperator MultiplyExpression | CastExpression
126126
127127MultiplyOperator : token(Star) | token(Slash) | token(Percent)
128128
129CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
129CastExpression : CastExpression token(as) Type | PrefixOpExpression
130130
131PrefixOpExpression : PrefixOp SuffixOpExpression | SuffixOpExpression
131PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
132132
133133SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression)
134134
src/analyze.cpp+33-20
......@@ -894,20 +894,24 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
894894 return_type = g->builtin_types.entry_bool;
895895 break;
896896 case BinOpTypeBinOr:
897 zig_panic("TODO bin or type");
898 break;
899897 case BinOpTypeBinXor:
900 zig_panic("TODO bin xor type");
901 break;
902898 case BinOpTypeBinAnd:
903 zig_panic("TODO bin and type");
904 break;
899 {
900 // TODO: don't require i32
901 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op1);
902 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op2);
903 return_type = g->builtin_types.entry_i32;
904 break;
905 }
905906 case BinOpTypeBitShiftLeft:
906 zig_panic("TODO bit shift left type");
907 break;
908907 case BinOpTypeBitShiftRight:
909 zig_panic("TODO bit shift right type");
910 break;
908 {
909 // TODO: don't require i32
910 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op1);
911 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op2);
912 return_type = g->builtin_types.entry_i32;
913 break;
914 }
911915 case BinOpTypeAdd:
912916 case BinOpTypeSub:
913917 // TODO think how should type checking for these work?
......@@ -918,14 +922,15 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
918922 return_type = g->builtin_types.entry_i32;
919923 break;
920924 case BinOpTypeMult:
921 zig_panic("TODO mult type");
922 break;
923925 case BinOpTypeDiv:
924 zig_panic("TODO div type");
925 break;
926926 case BinOpTypeMod:
927 zig_panic("TODO modulus type");
928 break;
927 {
928 // TODO: don't require i32
929 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op1);
930 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op2);
931 return_type = g->builtin_types.entry_i32;
932 break;
933 }
929934 case BinOpTypeInvalid:
930935 zig_unreachable();
931936 }
......@@ -1081,11 +1086,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
10811086 return_type = g->builtin_types.entry_bool;
10821087 break;
10831088 case PrefixOpBinNot:
1084 zig_panic("TODO type check bin not");
1085 break;
1089 {
1090 // TODO: don't require i32
1091 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.prefix_op_expr.primary_expr);
1092 return_type = g->builtin_types.entry_i32;
1093 break;
1094 }
10861095 case PrefixOpNegation:
1087 zig_panic("TODO type check negation");
1088 break;
1096 {
1097 // TODO: don't require i32
1098 analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.prefix_op_expr.primary_expr);
1099 return_type = g->builtin_types.entry_i32;
1100 break;
1101 }
10891102 case PrefixOpInvalid:
10901103 zig_unreachable();
10911104 }
src/codegen.cpp+4-12
......@@ -485,22 +485,18 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
485485 // block for when val1 == false (don't even evaluate the second part)
486486 LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolAndFalse");
487487
488 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(val1));
489488 add_debug_source_node(g, node);
490 LLVMValueRef val1_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, zero, "");
491 LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
489 LLVMBuildCondBr(g->builder, val1, true_block, false_block);
492490
493491 LLVMPositionBuilderAtEnd(g->builder, true_block);
494492 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
495493 add_debug_source_node(g, node);
496 LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
497494 LLVMBuildBr(g->builder, false_block);
498495
499496 LLVMPositionBuilderAtEnd(g->builder, false_block);
500497 add_debug_source_node(g, node);
501498 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
502 LLVMValueRef one_i1 = LLVMConstAllOnes(LLVMInt1Type());
503 LLVMValueRef incoming_values[2] = {one_i1, val2_i1};
499 LLVMValueRef incoming_values[2] = {val1, val2};
504500 LLVMBasicBlockRef incoming_blocks[2] = {orig_block, true_block};
505501 LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
506502
......@@ -519,22 +515,18 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
519515 // block for when val1 == true (don't even evaluate the second part)
520516 LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolOrTrue");
521517
522 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(val1));
523518 add_debug_source_node(g, expr_node);
524 LLVMValueRef val1_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, zero, "");
525 LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
519 LLVMBuildCondBr(g->builder, val1, true_block, false_block);
526520
527521 LLVMPositionBuilderAtEnd(g->builder, false_block);
528522 LLVMValueRef val2 = gen_expr(g, expr_node->data.bin_op_expr.op2);
529523 add_debug_source_node(g, expr_node);
530 LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
531524 LLVMBuildBr(g->builder, true_block);
532525
533526 LLVMPositionBuilderAtEnd(g->builder, true_block);
534527 add_debug_source_node(g, expr_node);
535528 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
536 LLVMValueRef one_i1 = LLVMConstAllOnes(LLVMInt1Type());
537 LLVMValueRef incoming_values[2] = {one_i1, val2_i1};
529 LLVMValueRef incoming_values[2] = {val1, val2};
538530 LLVMBasicBlockRef incoming_blocks[2] = {orig_block, false_block};
539531 LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
540532
src/parser.cpp+120-102
......@@ -944,7 +944,7 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man
944944}
945945
946946/*
947PrefixOpExpression : PrefixOp SuffixOpExpression | SuffixOpExpression
947PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
948948*/
949949static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {
950950 Token *token = &pc->tokens->at(*token_index);
......@@ -952,7 +952,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo
952952 if (prefix_op == PrefixOpInvalid)
953953 return ast_parse_suffix_op_expr(pc, token_index, mandatory);
954954
955 AstNode *prefix_op_expr = ast_parse_suffix_op_expr(pc, token_index, true);
955 AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, true);
956956 AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
957957 node->data.prefix_op_expr.primary_expr = prefix_op_expr;
958958 node->data.prefix_op_expr.prefix_op = prefix_op;
......@@ -962,24 +962,26 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo
962962
963963
964964/*
965CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
965CastExpression : CastExpression token(as) Type | PrefixOpExpression
966966*/
967967static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bool mandatory) {
968 AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory);
969 if (!prefix_op_expr)
968 AstNode *operand_1 = ast_parse_prefix_op_expr(pc, token_index, mandatory);
969 if (!operand_1)
970970 return nullptr;
971971
972 Token *as_kw = &pc->tokens->at(*token_index);
973 if (as_kw->id != TokenIdKeywordAs)
974 return prefix_op_expr;
975 *token_index += 1;
972 while (true) {
973 Token *as_kw = &pc->tokens->at(*token_index);
974 if (as_kw->id != TokenIdKeywordAs)
975 return operand_1;
976 *token_index += 1;
976977
977 AstNode *node = ast_create_node(pc, NodeTypeCastExpr, as_kw);
978 node->data.cast_expr.expr = prefix_op_expr;
978 AstNode *node = ast_create_node(pc, NodeTypeCastExpr, as_kw);
979 node->data.cast_expr.expr = operand_1;
979980
980 node->data.cast_expr.type = ast_parse_type(pc, *token_index, token_index);
981 node->data.cast_expr.type = ast_parse_type(pc, *token_index, token_index);
981982
982 return node;
983 operand_1 = node;
984 }
983985}
984986
985987static BinOpType tok_to_mult_op(Token *token) {
......@@ -1009,26 +1011,28 @@ static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mand
10091011}
10101012
10111013/*
1012MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpression
1014MultiplyExpression : CastExpression MultiplyOperator MultiplyExpression | CastExpression
10131015*/
10141016static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool mandatory) {
10151017 AstNode *operand_1 = ast_parse_cast_expression(pc, token_index, mandatory);
10161018 if (!operand_1)
10171019 return nullptr;
10181020
1019 Token *token = &pc->tokens->at(*token_index);
1020 BinOpType mult_op = ast_parse_mult_op(pc, token_index, false);
1021 if (mult_op == BinOpTypeInvalid)
1022 return operand_1;
1021 while (true) {
1022 Token *token = &pc->tokens->at(*token_index);
1023 BinOpType mult_op = ast_parse_mult_op(pc, token_index, false);
1024 if (mult_op == BinOpTypeInvalid)
1025 return operand_1;
10231026
1024 AstNode *operand_2 = ast_parse_cast_expression(pc, token_index, true);
1027 AstNode *operand_2 = ast_parse_cast_expression(pc, token_index, true);
10251028
1026 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1027 node->data.bin_op_expr.op1 = operand_1;
1028 node->data.bin_op_expr.bin_op = mult_op;
1029 node->data.bin_op_expr.op2 = operand_2;
1029 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1030 node->data.bin_op_expr.op1 = operand_1;
1031 node->data.bin_op_expr.bin_op = mult_op;
1032 node->data.bin_op_expr.op2 = operand_2;
10301033
1031 return node;
1034 operand_1 = node;
1035 }
10321036}
10331037
10341038static BinOpType tok_to_add_op(Token *token) {
......@@ -1057,26 +1061,28 @@ static BinOpType ast_parse_add_op(ParseContext *pc, int *token_index, bool manda
10571061}
10581062
10591063/*
1060AdditionExpression : MultiplyExpression AdditionOperator MultiplyExpression | MultiplyExpression
1064AdditionExpression : MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
10611065*/
10621066static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mandatory) {
10631067 AstNode *operand_1 = ast_parse_mult_expr(pc, token_index, mandatory);
10641068 if (!operand_1)
10651069 return nullptr;
10661070
1067 Token *token = &pc->tokens->at(*token_index);
1068 BinOpType add_op = ast_parse_add_op(pc, token_index, false);
1069 if (add_op == BinOpTypeInvalid)
1070 return operand_1;
1071 while (true) {
1072 Token *token = &pc->tokens->at(*token_index);
1073 BinOpType add_op = ast_parse_add_op(pc, token_index, false);
1074 if (add_op == BinOpTypeInvalid)
1075 return operand_1;
10711076
1072 AstNode *operand_2 = ast_parse_mult_expr(pc, token_index, true);
1077 AstNode *operand_2 = ast_parse_mult_expr(pc, token_index, true);
10731078
1074 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1075 node->data.bin_op_expr.op1 = operand_1;
1076 node->data.bin_op_expr.bin_op = add_op;
1077 node->data.bin_op_expr.op2 = operand_2;
1079 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1080 node->data.bin_op_expr.op1 = operand_1;
1081 node->data.bin_op_expr.bin_op = add_op;
1082 node->data.bin_op_expr.op2 = operand_2;
10781083
1079 return node;
1084 operand_1 = node;
1085 }
10801086}
10811087
10821088static BinOpType tok_to_bit_shift_op(Token *token) {
......@@ -1088,7 +1094,7 @@ static BinOpType tok_to_bit_shift_op(Token *token) {
10881094}
10891095
10901096/*
1091BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)
1097BitShiftOperator : token(BitShiftLeft) | token(BitShiftRight)
10921098*/
10931099static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) {
10941100 Token *token = &pc->tokens->at(*token_index);
......@@ -1105,96 +1111,104 @@ static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool
11051111}
11061112
11071113/*
1108BitShiftExpression : AdditionExpression BitShiftOperator AdditionExpression | AdditionExpression
1114BitShiftExpression : AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
11091115*/
11101116static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, bool mandatory) {
11111117 AstNode *operand_1 = ast_parse_add_expr(pc, token_index, mandatory);
11121118 if (!operand_1)
11131119 return nullptr;
11141120
1115 Token *token = &pc->tokens->at(*token_index);
1116 BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);
1117 if (bit_shift_op == BinOpTypeInvalid)
1118 return operand_1;
1121 while (true) {
1122 Token *token = &pc->tokens->at(*token_index);
1123 BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);
1124 if (bit_shift_op == BinOpTypeInvalid)
1125 return operand_1;
11191126
1120 AstNode *operand_2 = ast_parse_add_expr(pc, token_index, true);
1127 AstNode *operand_2 = ast_parse_add_expr(pc, token_index, true);
11211128
1122 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1123 node->data.bin_op_expr.op1 = operand_1;
1124 node->data.bin_op_expr.bin_op = bit_shift_op;
1125 node->data.bin_op_expr.op2 = operand_2;
1129 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1130 node->data.bin_op_expr.op1 = operand_1;
1131 node->data.bin_op_expr.bin_op = bit_shift_op;
1132 node->data.bin_op_expr.op2 = operand_2;
11261133
1127 return node;
1134 operand_1 = node;
1135 }
11281136}
11291137
11301138
11311139/*
1132BinaryAndExpression : BitShiftExpression token(BinAnd) BitShiftExpression | BitShiftExpression
1140BinaryAndExpression : BitShiftExpression token(BinAnd) BinaryAndExpression | BitShiftExpression
11331141*/
11341142static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool mandatory) {
11351143 AstNode *operand_1 = ast_parse_bit_shift_expr(pc, token_index, mandatory);
11361144 if (!operand_1)
11371145 return nullptr;
11381146
1139 Token *token = &pc->tokens->at(*token_index);
1140 if (token->id != TokenIdBinAnd)
1141 return operand_1;
1142 *token_index += 1;
1147 while (true) {
1148 Token *token = &pc->tokens->at(*token_index);
1149 if (token->id != TokenIdBinAnd)
1150 return operand_1;
1151 *token_index += 1;
11431152
1144 AstNode *operand_2 = ast_parse_bit_shift_expr(pc, token_index, true);
1153 AstNode *operand_2 = ast_parse_bit_shift_expr(pc, token_index, true);
11451154
1146 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1147 node->data.bin_op_expr.op1 = operand_1;
1148 node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;
1149 node->data.bin_op_expr.op2 = operand_2;
1155 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1156 node->data.bin_op_expr.op1 = operand_1;
1157 node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;
1158 node->data.bin_op_expr.op2 = operand_2;
11501159
1151 return node;
1160 operand_1 = node;
1161 }
11521162}
11531163
11541164/*
1155BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryAndExpression | BinaryAndExpression
1165BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryXorExpression | BinaryAndExpression
11561166*/
11571167static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool mandatory) {
11581168 AstNode *operand_1 = ast_parse_bin_and_expr(pc, token_index, mandatory);
11591169 if (!operand_1)
11601170 return nullptr;
11611171
1162 Token *token = &pc->tokens->at(*token_index);
1163 if (token->id != TokenIdBinXor)
1164 return operand_1;
1165 *token_index += 1;
1172 while (true) {
1173 Token *token = &pc->tokens->at(*token_index);
1174 if (token->id != TokenIdBinXor)
1175 return operand_1;
1176 *token_index += 1;
11661177
1167 AstNode *operand_2 = ast_parse_bin_and_expr(pc, token_index, true);
1178 AstNode *operand_2 = ast_parse_bin_and_expr(pc, token_index, true);
11681179
1169 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1170 node->data.bin_op_expr.op1 = operand_1;
1171 node->data.bin_op_expr.bin_op = BinOpTypeBinXor;
1172 node->data.bin_op_expr.op2 = operand_2;
1180 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1181 node->data.bin_op_expr.op1 = operand_1;
1182 node->data.bin_op_expr.bin_op = BinOpTypeBinXor;
1183 node->data.bin_op_expr.op2 = operand_2;
11731184
1174 return node;
1185 operand_1 = node;
1186 }
11751187}
11761188
11771189/*
1178BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryXorExpression | BinaryXorExpression
1190BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryOrExpression | BinaryXorExpression
11791191*/
11801192static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool mandatory) {
11811193 AstNode *operand_1 = ast_parse_bin_xor_expr(pc, token_index, mandatory);
11821194 if (!operand_1)
11831195 return nullptr;
11841196
1185 Token *token = &pc->tokens->at(*token_index);
1186 if (token->id != TokenIdBinOr)
1187 return operand_1;
1188 *token_index += 1;
1197 while (true) {
1198 Token *token = &pc->tokens->at(*token_index);
1199 if (token->id != TokenIdBinOr)
1200 return operand_1;
1201 *token_index += 1;
11891202
1190 AstNode *operand_2 = ast_parse_bin_xor_expr(pc, token_index, true);
1203 AstNode *operand_2 = ast_parse_bin_xor_expr(pc, token_index, true);
11911204
1192 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1193 node->data.bin_op_expr.op1 = operand_1;
1194 node->data.bin_op_expr.bin_op = BinOpTypeBinOr;
1195 node->data.bin_op_expr.op2 = operand_2;
1205 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1206 node->data.bin_op_expr.op1 = operand_1;
1207 node->data.bin_op_expr.bin_op = BinOpTypeBinOr;
1208 node->data.bin_op_expr.op2 = operand_2;
11961209
1197 return node;
1210 operand_1 = node;
1211 }
11981212}
11991213
12001214static BinOpType tok_to_cmp_op(Token *token) {
......@@ -1247,26 +1261,28 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo
12471261}
12481262
12491263/*
1250BoolAndExpression : ComparisonExpression token(BoolAnd) ComparisonExpression | ComparisonExpression
1264BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression
12511265 */
12521266static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool mandatory) {
12531267 AstNode *operand_1 = ast_parse_comparison_expr(pc, token_index, mandatory);
12541268 if (!operand_1)
12551269 return nullptr;
12561270
1257 Token *token = &pc->tokens->at(*token_index);
1258 if (token->id != TokenIdBoolAnd)
1259 return operand_1;
1260 *token_index += 1;
1271 while (true) {
1272 Token *token = &pc->tokens->at(*token_index);
1273 if (token->id != TokenIdBoolAnd)
1274 return operand_1;
1275 *token_index += 1;
12611276
1262 AstNode *operand_2 = ast_parse_comparison_expr(pc, token_index, true);
1277 AstNode *operand_2 = ast_parse_comparison_expr(pc, token_index, true);
12631278
1264 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1265 node->data.bin_op_expr.op1 = operand_1;
1266 node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;
1267 node->data.bin_op_expr.op2 = operand_2;
1279 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1280 node->data.bin_op_expr.op1 = operand_1;
1281 node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;
1282 node->data.bin_op_expr.op2 = operand_2;
12681283
1269 return node;
1284 operand_1 = node;
1285 }
12701286}
12711287
12721288/*
......@@ -1382,26 +1398,28 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token
13821398}
13831399
13841400/*
1385BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression
1401BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression
13861402*/
13871403static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool mandatory) {
13881404 AstNode *operand_1 = ast_parse_bool_and_expr(pc, token_index, mandatory);
13891405 if (!operand_1)
13901406 return nullptr;
13911407
1392 Token *token = &pc->tokens->at(*token_index);
1393 if (token->id != TokenIdBoolOr)
1394 return operand_1;
1395 *token_index += 1;
1408 while (true) {
1409 Token *token = &pc->tokens->at(*token_index);
1410 if (token->id != TokenIdBoolOr)
1411 return operand_1;
1412 *token_index += 1;
13961413
1397 AstNode *operand_2 = ast_parse_bool_and_expr(pc, token_index, true);
1414 AstNode *operand_2 = ast_parse_bool_and_expr(pc, token_index, true);
13981415
1399 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1400 node->data.bin_op_expr.op1 = operand_1;
1401 node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;
1402 node->data.bin_op_expr.op2 = operand_2;
1416 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1417 node->data.bin_op_expr.op1 = operand_1;
1418 node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;
1419 node->data.bin_op_expr.op2 = operand_2;
14031420
1404 return node;
1421 operand_1 = node;
1422 }
14051423}
14061424
14071425/*
src/tokenizer.cpp+4-2
......@@ -478,9 +478,10 @@ void tokenize(Buf *buf, Tokenization *out) {
478478 t.multi_line_comment_count = 1;
479479 break;
480480 default:
481 t.pos -= 1;
481482 end_token(&t);
482483 t.state = TokenizeStateStart;
483 break;
484 continue;
484485 }
485486 break;
486487 case TokenizeStateLineComment:
......@@ -592,9 +593,10 @@ void tokenize(Buf *buf, Tokenization *out) {
592593 t.state = TokenizeStateStart;
593594 break;
594595 default:
596 t.pos -= 1;
595597 end_token(&t);
596598 t.state = TokenizeStateStart;
597 break;
599 continue;
598600 }
599601 break;
600602 }
test/run_tests.cpp+21
......@@ -409,6 +409,27 @@ export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {
409409 )SOURCE", "Hello, world!\n");
410410
411411
412 add_simple_case("a + b + c", R"SOURCE(
413use "std.zig";
414
415export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {
416 if false || false || false { print_str("BAD 1\n" as string); }
417 if true && true && false { print_str("BAD 2\n" as string); }
418 if 1 | 2 | 4 != 7 { print_str("BAD 3\n" as string); }
419 if 3 ^ 6 ^ 8 != 13 { print_str("BAD 4\n" as string); }
420 if 7 & 14 & 28 != 4 { print_str("BAD 5\n" as string); }
421 if 9 << 1 << 2 != 9 << 3 { print_str("BAD 6\n" as string); }
422 if 90 >> 1 >> 2 != 90 >> 3 { print_str("BAD 7\n" as string); }
423 if 100 - 1 + 1000 != 1099 { print_str("BAD 8\n" as string); }
424 if 5 * 4 / 2 % 3 != 1 { print_str("BAD 9\n" as string); }
425 if 5 as i32 as i32 != 5 { print_str("BAD 10\n" as string); }
426 if !!false { print_str("BAD 11\n" as string); }
427 if 7 != --7 { print_str("BAD 12\n" as string); }
428
429 print_str("OK\n" as string);
430 return 0;
431}
432 )SOURCE", "OK\n");
412433
413434}
414435