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...@@ -92,7 +92,7 @@ AssignmentExpression : BoolOrExpression token(Equal) BoolOrExpression | BoolOrEx
9292
93BlockExpression : IfExpression | Block93BlockExpression : IfExpression | Block
9494
95BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression95BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression
9696
97ReturnExpression : token(Return) option(Expression)97ReturnExpression : token(Return) option(Expression)
9898
...@@ -102,33 +102,33 @@ ElseIf : token(Else) IfExpression...@@ -102,33 +102,33 @@ ElseIf : token(Else) IfExpression
102102
103Else : token(Else) Block103Else : token(Else) Block
104104
105BoolAndExpression : ComparisonExpression token(BoolAnd) ComparisonExpression | ComparisonExpression105BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression
106106
107ComparisonExpression : BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression107ComparisonExpression : BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression
108108
109ComparisonOperator : token(BoolEq) | token(BoolNotEq) | token(BoolLessThan) | token(BoolGreaterThan) | token(BoolLessEqual) | token(BoolGreaterEqual)109ComparisonOperator : token(BoolEq) | token(BoolNotEq) | token(BoolLessThan) | token(BoolGreaterThan) | token(BoolLessEqual) | token(BoolGreaterEqual)
110110
111BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryXorExpression | BinaryXorExpression111BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryOrExpression | BinaryXorExpression
112112
113BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryAndExpression | BinaryAndExpression113BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryXorExpression | BinaryAndExpression
114114
115BinaryAndExpression : BitShiftExpression token(BinAnd) BitShiftExpression | BitShiftExpression115BinaryAndExpression : BitShiftExpression token(BinAnd) BinaryAndExpression | BitShiftExpression
116116
117BitShiftExpression : AdditionExpression BitShiftOperator AdditionExpression | AdditionExpression117BitShiftExpression : AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
118118
119BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)119BitShiftOperator : token(BitShiftLeft) | token(BitShiftRight)
120120
121AdditionExpression : MultiplyExpression AdditionOperator MultiplyExpression | MultiplyExpression121AdditionExpression : MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
122122
123AdditionOperator : token(Plus) | token(Minus)123AdditionOperator : token(Plus) | token(Minus)
124124
125MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpression125MultiplyExpression : CastExpression MultiplyOperator MultiplyExpression | CastExpression
126126
127MultiplyOperator : token(Star) | token(Slash) | token(Percent)127MultiplyOperator : token(Star) | token(Slash) | token(Percent)
128128
129CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression129CastExpression : CastExpression token(as) Type | PrefixOpExpression
130130
131PrefixOpExpression : PrefixOp SuffixOpExpression | SuffixOpExpression131PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
132132
133SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression)133SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression)
134134
src/analyze.cpp+33-20
...@@ -894,20 +894,24 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -894,20 +894,24 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
894 return_type = g->builtin_types.entry_bool;894 return_type = g->builtin_types.entry_bool;
895 break;895 break;
896 case BinOpTypeBinOr:896 case BinOpTypeBinOr:
897 zig_panic("TODO bin or type");
898 break;
899 case BinOpTypeBinXor:897 case BinOpTypeBinXor:
900 zig_panic("TODO bin xor type");
901 break;
902 case BinOpTypeBinAnd:898 case BinOpTypeBinAnd:
903 zig_panic("TODO bin and type");899 {
904 break;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 }
905 case BinOpTypeBitShiftLeft:906 case BinOpTypeBitShiftLeft:
906 zig_panic("TODO bit shift left type");
907 break;
908 case BinOpTypeBitShiftRight:907 case BinOpTypeBitShiftRight:
909 zig_panic("TODO bit shift right type");908 {
910 break;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 }
911 case BinOpTypeAdd:915 case BinOpTypeAdd:
912 case BinOpTypeSub:916 case BinOpTypeSub:
913 // TODO think how should type checking for these work?917 // TODO think how should type checking for these work?
...@@ -918,14 +922,15 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -918,14 +922,15 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
918 return_type = g->builtin_types.entry_i32;922 return_type = g->builtin_types.entry_i32;
919 break;923 break;
920 case BinOpTypeMult:924 case BinOpTypeMult:
921 zig_panic("TODO mult type");
922 break;
923 case BinOpTypeDiv:925 case BinOpTypeDiv:
924 zig_panic("TODO div type");
925 break;
926 case BinOpTypeMod:926 case BinOpTypeMod:
927 zig_panic("TODO modulus type");927 {
928 break;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 }
929 case BinOpTypeInvalid:934 case BinOpTypeInvalid:
930 zig_unreachable();935 zig_unreachable();
931 }936 }
...@@ -1081,11 +1086,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -1081,11 +1086,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
1081 return_type = g->builtin_types.entry_bool;1086 return_type = g->builtin_types.entry_bool;
1082 break;1087 break;
1083 case PrefixOpBinNot:1088 case PrefixOpBinNot:
1084 zig_panic("TODO type check bin not");1089 {
1085 break;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 }
1086 case PrefixOpNegation:1095 case PrefixOpNegation:
1087 zig_panic("TODO type check negation");1096 {
1088 break;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 }
1089 case PrefixOpInvalid:1102 case PrefixOpInvalid:
1090 zig_unreachable();1103 zig_unreachable();
1091 }1104 }
src/codegen.cpp+4-12
...@@ -485,22 +485,18 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {...@@ -485,22 +485,18 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
485 // block for when val1 == false (don't even evaluate the second part)485 // block for when val1 == false (don't even evaluate the second part)
486 LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolAndFalse");486 LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolAndFalse");
487487
488 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(val1));
489 add_debug_source_node(g, node);488 add_debug_source_node(g, node);
490 LLVMValueRef val1_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, zero, "");489 LLVMBuildCondBr(g->builder, val1, true_block, false_block);
491 LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
492490
493 LLVMPositionBuilderAtEnd(g->builder, true_block);491 LLVMPositionBuilderAtEnd(g->builder, true_block);
494 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);492 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
495 add_debug_source_node(g, node);493 add_debug_source_node(g, node);
496 LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
497 LLVMBuildBr(g->builder, false_block);494 LLVMBuildBr(g->builder, false_block);
498495
499 LLVMPositionBuilderAtEnd(g->builder, false_block);496 LLVMPositionBuilderAtEnd(g->builder, false_block);
500 add_debug_source_node(g, node);497 add_debug_source_node(g, node);
501 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");498 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
502 LLVMValueRef one_i1 = LLVMConstAllOnes(LLVMInt1Type());499 LLVMValueRef incoming_values[2] = {val1, val2};
503 LLVMValueRef incoming_values[2] = {one_i1, val2_i1};
504 LLVMBasicBlockRef incoming_blocks[2] = {orig_block, true_block};500 LLVMBasicBlockRef incoming_blocks[2] = {orig_block, true_block};
505 LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);501 LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
506502
...@@ -519,22 +515,18 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {...@@ -519,22 +515,18 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
519 // block for when val1 == true (don't even evaluate the second part)515 // block for when val1 == true (don't even evaluate the second part)
520 LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolOrTrue");516 LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolOrTrue");
521517
522 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(val1));
523 add_debug_source_node(g, expr_node);518 add_debug_source_node(g, expr_node);
524 LLVMValueRef val1_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, zero, "");519 LLVMBuildCondBr(g->builder, val1, true_block, false_block);
525 LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
526520
527 LLVMPositionBuilderAtEnd(g->builder, false_block);521 LLVMPositionBuilderAtEnd(g->builder, false_block);
528 LLVMValueRef val2 = gen_expr(g, expr_node->data.bin_op_expr.op2);522 LLVMValueRef val2 = gen_expr(g, expr_node->data.bin_op_expr.op2);
529 add_debug_source_node(g, expr_node);523 add_debug_source_node(g, expr_node);
530 LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
531 LLVMBuildBr(g->builder, true_block);524 LLVMBuildBr(g->builder, true_block);
532525
533 LLVMPositionBuilderAtEnd(g->builder, true_block);526 LLVMPositionBuilderAtEnd(g->builder, true_block);
534 add_debug_source_node(g, expr_node);527 add_debug_source_node(g, expr_node);
535 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");528 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
536 LLVMValueRef one_i1 = LLVMConstAllOnes(LLVMInt1Type());529 LLVMValueRef incoming_values[2] = {val1, val2};
537 LLVMValueRef incoming_values[2] = {one_i1, val2_i1};
538 LLVMBasicBlockRef incoming_blocks[2] = {orig_block, false_block};530 LLVMBasicBlockRef incoming_blocks[2] = {orig_block, false_block};
539 LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);531 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...@@ -944,7 +944,7 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man
944}944}
945945
946/*946/*
947PrefixOpExpression : PrefixOp SuffixOpExpression | SuffixOpExpression947PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
948*/948*/
949static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {949static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {
950 Token *token = &pc->tokens->at(*token_index);950 Token *token = &pc->tokens->at(*token_index);
...@@ -952,7 +952,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo...@@ -952,7 +952,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo
952 if (prefix_op == PrefixOpInvalid)952 if (prefix_op == PrefixOpInvalid)
953 return ast_parse_suffix_op_expr(pc, token_index, mandatory);953 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);
956 AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);956 AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
957 node->data.prefix_op_expr.primary_expr = prefix_op_expr;957 node->data.prefix_op_expr.primary_expr = prefix_op_expr;
958 node->data.prefix_op_expr.prefix_op = prefix_op;958 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...@@ -962,24 +962,26 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo
962962
963963
964/*964/*
965CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression965CastExpression : CastExpression token(as) Type | PrefixOpExpression
966*/966*/
967static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bool mandatory) {967static 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);968 AstNode *operand_1 = ast_parse_prefix_op_expr(pc, token_index, mandatory);
969 if (!prefix_op_expr)969 if (!operand_1)
970 return nullptr;970 return nullptr;
971971
972 Token *as_kw = &pc->tokens->at(*token_index);972 while (true) {
973 if (as_kw->id != TokenIdKeywordAs)973 Token *as_kw = &pc->tokens->at(*token_index);
974 return prefix_op_expr;974 if (as_kw->id != TokenIdKeywordAs)
975 *token_index += 1;975 return operand_1;
976 *token_index += 1;
976977
977 AstNode *node = ast_create_node(pc, NodeTypeCastExpr, as_kw);978 AstNode *node = ast_create_node(pc, NodeTypeCastExpr, as_kw);
978 node->data.cast_expr.expr = prefix_op_expr;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 }
983}985}
984986
985static BinOpType tok_to_mult_op(Token *token) {987static BinOpType tok_to_mult_op(Token *token) {
...@@ -1009,26 +1011,28 @@ static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mand...@@ -1009,26 +1011,28 @@ static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mand
1009}1011}
10101012
1011/*1013/*
1012MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpression1014MultiplyExpression : CastExpression MultiplyOperator MultiplyExpression | CastExpression
1013*/1015*/
1014static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool mandatory) {1016static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool mandatory) {
1015 AstNode *operand_1 = ast_parse_cast_expression(pc, token_index, mandatory);1017 AstNode *operand_1 = ast_parse_cast_expression(pc, token_index, mandatory);
1016 if (!operand_1)1018 if (!operand_1)
1017 return nullptr;1019 return nullptr;
10181020
1019 Token *token = &pc->tokens->at(*token_index);1021 while (true) {
1020 BinOpType mult_op = ast_parse_mult_op(pc, token_index, false);1022 Token *token = &pc->tokens->at(*token_index);
1021 if (mult_op == BinOpTypeInvalid)1023 BinOpType mult_op = ast_parse_mult_op(pc, token_index, false);
1022 return operand_1;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);1029 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1027 node->data.bin_op_expr.op1 = operand_1;1030 node->data.bin_op_expr.op1 = operand_1;
1028 node->data.bin_op_expr.bin_op = mult_op;1031 node->data.bin_op_expr.bin_op = mult_op;
1029 node->data.bin_op_expr.op2 = operand_2;1032 node->data.bin_op_expr.op2 = operand_2;
10301033
1031 return node;1034 operand_1 = node;
1035 }
1032}1036}
10331037
1034static BinOpType tok_to_add_op(Token *token) {1038static BinOpType tok_to_add_op(Token *token) {
...@@ -1057,26 +1061,28 @@ static BinOpType ast_parse_add_op(ParseContext *pc, int *token_index, bool manda...@@ -1057,26 +1061,28 @@ static BinOpType ast_parse_add_op(ParseContext *pc, int *token_index, bool manda
1057}1061}
10581062
1059/*1063/*
1060AdditionExpression : MultiplyExpression AdditionOperator MultiplyExpression | MultiplyExpression1064AdditionExpression : MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
1061*/1065*/
1062static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mandatory) {1066static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mandatory) {
1063 AstNode *operand_1 = ast_parse_mult_expr(pc, token_index, mandatory);1067 AstNode *operand_1 = ast_parse_mult_expr(pc, token_index, mandatory);
1064 if (!operand_1)1068 if (!operand_1)
1065 return nullptr;1069 return nullptr;
10661070
1067 Token *token = &pc->tokens->at(*token_index);1071 while (true) {
1068 BinOpType add_op = ast_parse_add_op(pc, token_index, false);1072 Token *token = &pc->tokens->at(*token_index);
1069 if (add_op == BinOpTypeInvalid)1073 BinOpType add_op = ast_parse_add_op(pc, token_index, false);
1070 return operand_1;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);1079 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1075 node->data.bin_op_expr.op1 = operand_1;1080 node->data.bin_op_expr.op1 = operand_1;
1076 node->data.bin_op_expr.bin_op = add_op;1081 node->data.bin_op_expr.bin_op = add_op;
1077 node->data.bin_op_expr.op2 = operand_2;1082 node->data.bin_op_expr.op2 = operand_2;
10781083
1079 return node;1084 operand_1 = node;
1085 }
1080}1086}
10811087
1082static BinOpType tok_to_bit_shift_op(Token *token) {1088static BinOpType tok_to_bit_shift_op(Token *token) {
...@@ -1088,7 +1094,7 @@ static BinOpType tok_to_bit_shift_op(Token *token) {...@@ -1088,7 +1094,7 @@ static BinOpType tok_to_bit_shift_op(Token *token) {
1088}1094}
10891095
1090/*1096/*
1091BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)1097BitShiftOperator : token(BitShiftLeft) | token(BitShiftRight)
1092*/1098*/
1093static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) {1099static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) {
1094 Token *token = &pc->tokens->at(*token_index);1100 Token *token = &pc->tokens->at(*token_index);
...@@ -1105,96 +1111,104 @@ static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool...@@ -1105,96 +1111,104 @@ static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool
1105}1111}
11061112
1107/*1113/*
1108BitShiftExpression : AdditionExpression BitShiftOperator AdditionExpression | AdditionExpression1114BitShiftExpression : AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
1109*/1115*/
1110static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, bool mandatory) {1116static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, bool mandatory) {
1111 AstNode *operand_1 = ast_parse_add_expr(pc, token_index, mandatory);1117 AstNode *operand_1 = ast_parse_add_expr(pc, token_index, mandatory);
1112 if (!operand_1)1118 if (!operand_1)
1113 return nullptr;1119 return nullptr;
11141120
1115 Token *token = &pc->tokens->at(*token_index);1121 while (true) {
1116 BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);1122 Token *token = &pc->tokens->at(*token_index);
1117 if (bit_shift_op == BinOpTypeInvalid)1123 BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);
1118 return operand_1;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);1129 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1123 node->data.bin_op_expr.op1 = operand_1;1130 node->data.bin_op_expr.op1 = operand_1;
1124 node->data.bin_op_expr.bin_op = bit_shift_op;1131 node->data.bin_op_expr.bin_op = bit_shift_op;
1125 node->data.bin_op_expr.op2 = operand_2;1132 node->data.bin_op_expr.op2 = operand_2;
11261133
1127 return node;1134 operand_1 = node;
1135 }
1128}1136}
11291137
11301138
1131/*1139/*
1132BinaryAndExpression : BitShiftExpression token(BinAnd) BitShiftExpression | BitShiftExpression1140BinaryAndExpression : BitShiftExpression token(BinAnd) BinaryAndExpression | BitShiftExpression
1133*/1141*/
1134static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool mandatory) {1142static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool mandatory) {
1135 AstNode *operand_1 = ast_parse_bit_shift_expr(pc, token_index, mandatory);1143 AstNode *operand_1 = ast_parse_bit_shift_expr(pc, token_index, mandatory);
1136 if (!operand_1)1144 if (!operand_1)
1137 return nullptr;1145 return nullptr;
11381146
1139 Token *token = &pc->tokens->at(*token_index);1147 while (true) {
1140 if (token->id != TokenIdBinAnd)1148 Token *token = &pc->tokens->at(*token_index);
1141 return operand_1;1149 if (token->id != TokenIdBinAnd)
1142 *token_index += 1;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);1155 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1147 node->data.bin_op_expr.op1 = operand_1;1156 node->data.bin_op_expr.op1 = operand_1;
1148 node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;1157 node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;
1149 node->data.bin_op_expr.op2 = operand_2;1158 node->data.bin_op_expr.op2 = operand_2;
11501159
1151 return node;1160 operand_1 = node;
1161 }
1152}1162}
11531163
1154/*1164/*
1155BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryAndExpression | BinaryAndExpression1165BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryXorExpression | BinaryAndExpression
1156*/1166*/
1157static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool mandatory) {1167static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool mandatory) {
1158 AstNode *operand_1 = ast_parse_bin_and_expr(pc, token_index, mandatory);1168 AstNode *operand_1 = ast_parse_bin_and_expr(pc, token_index, mandatory);
1159 if (!operand_1)1169 if (!operand_1)
1160 return nullptr;1170 return nullptr;
11611171
1162 Token *token = &pc->tokens->at(*token_index);1172 while (true) {
1163 if (token->id != TokenIdBinXor)1173 Token *token = &pc->tokens->at(*token_index);
1164 return operand_1;1174 if (token->id != TokenIdBinXor)
1165 *token_index += 1;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);1180 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1170 node->data.bin_op_expr.op1 = operand_1;1181 node->data.bin_op_expr.op1 = operand_1;
1171 node->data.bin_op_expr.bin_op = BinOpTypeBinXor;1182 node->data.bin_op_expr.bin_op = BinOpTypeBinXor;
1172 node->data.bin_op_expr.op2 = operand_2;1183 node->data.bin_op_expr.op2 = operand_2;
11731184
1174 return node;1185 operand_1 = node;
1186 }
1175}1187}
11761188
1177/*1189/*
1178BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryXorExpression | BinaryXorExpression1190BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryOrExpression | BinaryXorExpression
1179*/1191*/
1180static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool mandatory) {1192static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool mandatory) {
1181 AstNode *operand_1 = ast_parse_bin_xor_expr(pc, token_index, mandatory);1193 AstNode *operand_1 = ast_parse_bin_xor_expr(pc, token_index, mandatory);
1182 if (!operand_1)1194 if (!operand_1)
1183 return nullptr;1195 return nullptr;
11841196
1185 Token *token = &pc->tokens->at(*token_index);1197 while (true) {
1186 if (token->id != TokenIdBinOr)1198 Token *token = &pc->tokens->at(*token_index);
1187 return operand_1;1199 if (token->id != TokenIdBinOr)
1188 *token_index += 1;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);1205 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1193 node->data.bin_op_expr.op1 = operand_1;1206 node->data.bin_op_expr.op1 = operand_1;
1194 node->data.bin_op_expr.bin_op = BinOpTypeBinOr;1207 node->data.bin_op_expr.bin_op = BinOpTypeBinOr;
1195 node->data.bin_op_expr.op2 = operand_2;1208 node->data.bin_op_expr.op2 = operand_2;
11961209
1197 return node;1210 operand_1 = node;
1211 }
1198}1212}
11991213
1200static BinOpType tok_to_cmp_op(Token *token) {1214static BinOpType tok_to_cmp_op(Token *token) {
...@@ -1247,26 +1261,28 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo...@@ -1247,26 +1261,28 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo
1247}1261}
12481262
1249/*1263/*
1250BoolAndExpression : ComparisonExpression token(BoolAnd) ComparisonExpression | ComparisonExpression1264BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression
1251 */1265 */
1252static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool mandatory) {1266static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool mandatory) {
1253 AstNode *operand_1 = ast_parse_comparison_expr(pc, token_index, mandatory);1267 AstNode *operand_1 = ast_parse_comparison_expr(pc, token_index, mandatory);
1254 if (!operand_1)1268 if (!operand_1)
1255 return nullptr;1269 return nullptr;
12561270
1257 Token *token = &pc->tokens->at(*token_index);1271 while (true) {
1258 if (token->id != TokenIdBoolAnd)1272 Token *token = &pc->tokens->at(*token_index);
1259 return operand_1;1273 if (token->id != TokenIdBoolAnd)
1260 *token_index += 1;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);1279 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1265 node->data.bin_op_expr.op1 = operand_1;1280 node->data.bin_op_expr.op1 = operand_1;
1266 node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;1281 node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;
1267 node->data.bin_op_expr.op2 = operand_2;1282 node->data.bin_op_expr.op2 = operand_2;
12681283
1269 return node;1284 operand_1 = node;
1285 }
1270}1286}
12711287
1272/*1288/*
...@@ -1382,26 +1398,28 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token...@@ -1382,26 +1398,28 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token
1382}1398}
13831399
1384/*1400/*
1385BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression1401BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression
1386*/1402*/
1387static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool mandatory) {1403static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool mandatory) {
1388 AstNode *operand_1 = ast_parse_bool_and_expr(pc, token_index, mandatory);1404 AstNode *operand_1 = ast_parse_bool_and_expr(pc, token_index, mandatory);
1389 if (!operand_1)1405 if (!operand_1)
1390 return nullptr;1406 return nullptr;
13911407
1392 Token *token = &pc->tokens->at(*token_index);1408 while (true) {
1393 if (token->id != TokenIdBoolOr)1409 Token *token = &pc->tokens->at(*token_index);
1394 return operand_1;1410 if (token->id != TokenIdBoolOr)
1395 *token_index += 1;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);1416 AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
1400 node->data.bin_op_expr.op1 = operand_1;1417 node->data.bin_op_expr.op1 = operand_1;
1401 node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;1418 node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;
1402 node->data.bin_op_expr.op2 = operand_2;1419 node->data.bin_op_expr.op2 = operand_2;
14031420
1404 return node;1421 operand_1 = node;
1422 }
1405}1423}
14061424
1407/*1425/*
src/tokenizer.cpp+4-2
...@@ -478,9 +478,10 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -478,9 +478,10 @@ void tokenize(Buf *buf, Tokenization *out) {
478 t.multi_line_comment_count = 1;478 t.multi_line_comment_count = 1;
479 break;479 break;
480 default:480 default:
481 t.pos -= 1;
481 end_token(&t);482 end_token(&t);
482 t.state = TokenizeStateStart;483 t.state = TokenizeStateStart;
483 break;484 continue;
484 }485 }
485 break;486 break;
486 case TokenizeStateLineComment:487 case TokenizeStateLineComment:
...@@ -592,9 +593,10 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -592,9 +593,10 @@ void tokenize(Buf *buf, Tokenization *out) {
592 t.state = TokenizeStateStart;593 t.state = TokenizeStateStart;
593 break;594 break;
594 default:595 default:
596 t.pos -= 1;
595 end_token(&t);597 end_token(&t);
596 t.state = TokenizeStateStart;598 t.state = TokenizeStateStart;
597 break;599 continue;
598 }600 }
599 break;601 break;
600 }602 }
test/run_tests.cpp+21
...@@ -409,6 +409,27 @@ export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {...@@ -409,6 +409,27 @@ export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {
409 )SOURCE", "Hello, world!\n");409 )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
413}434}
414435