fix a + b + c and similar

fix || and &&

closes #17
This commit is contained in:
Josh Wolfe 2015-12-12 17:03:44 -07:00
parent 38f12adbda
commit 64dd0b8d95
6 changed files with 193 additions and 147 deletions

View File

@ -92,7 +92,7 @@ AssignmentExpression : BoolOrExpression token(Equal) BoolOrExpression | BoolOrEx
BlockExpression : IfExpression | Block
BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression
BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression
ReturnExpression : token(Return) option(Expression)
@ -102,33 +102,33 @@ ElseIf : token(Else) IfExpression
Else : token(Else) Block
BoolAndExpression : ComparisonExpression token(BoolAnd) ComparisonExpression | ComparisonExpression
BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression
ComparisonExpression : BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression
ComparisonOperator : token(BoolEq) | token(BoolNotEq) | token(BoolLessThan) | token(BoolGreaterThan) | token(BoolLessEqual) | token(BoolGreaterEqual)
BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryXorExpression | BinaryXorExpression
BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryOrExpression | BinaryXorExpression
BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryAndExpression | BinaryAndExpression
BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryXorExpression | BinaryAndExpression
BinaryAndExpression : BitShiftExpression token(BinAnd) BitShiftExpression | BitShiftExpression
BinaryAndExpression : BitShiftExpression token(BinAnd) BinaryAndExpression | BitShiftExpression
BitShiftExpression : AdditionExpression BitShiftOperator AdditionExpression | AdditionExpression
BitShiftExpression : AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)
BitShiftOperator : token(BitShiftLeft) | token(BitShiftRight)
AdditionExpression : MultiplyExpression AdditionOperator MultiplyExpression | MultiplyExpression
AdditionExpression : MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
AdditionOperator : token(Plus) | token(Minus)
MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpression
MultiplyExpression : CastExpression MultiplyOperator MultiplyExpression | CastExpression
MultiplyOperator : token(Star) | token(Slash) | token(Percent)
CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
CastExpression : CastExpression token(as) Type | PrefixOpExpression
PrefixOpExpression : PrefixOp SuffixOpExpression | SuffixOpExpression
PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression)

View File

@ -894,20 +894,24 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
return_type = g->builtin_types.entry_bool;
break;
case BinOpTypeBinOr:
zig_panic("TODO bin or type");
break;
case BinOpTypeBinXor:
zig_panic("TODO bin xor type");
break;
case BinOpTypeBinAnd:
zig_panic("TODO bin and type");
break;
{
// TODO: don't require i32
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op1);
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op2);
return_type = g->builtin_types.entry_i32;
break;
}
case BinOpTypeBitShiftLeft:
zig_panic("TODO bit shift left type");
break;
case BinOpTypeBitShiftRight:
zig_panic("TODO bit shift right type");
break;
{
// TODO: don't require i32
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op1);
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op2);
return_type = g->builtin_types.entry_i32;
break;
}
case BinOpTypeAdd:
case BinOpTypeSub:
// TODO think how should type checking for these work?
@ -918,14 +922,15 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
return_type = g->builtin_types.entry_i32;
break;
case BinOpTypeMult:
zig_panic("TODO mult type");
break;
case BinOpTypeDiv:
zig_panic("TODO div type");
break;
case BinOpTypeMod:
zig_panic("TODO modulus type");
break;
{
// TODO: don't require i32
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op1);
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.bin_op_expr.op2);
return_type = g->builtin_types.entry_i32;
break;
}
case BinOpTypeInvalid:
zig_unreachable();
}
@ -1081,11 +1086,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
return_type = g->builtin_types.entry_bool;
break;
case PrefixOpBinNot:
zig_panic("TODO type check bin not");
break;
{
// TODO: don't require i32
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.prefix_op_expr.primary_expr);
return_type = g->builtin_types.entry_i32;
break;
}
case PrefixOpNegation:
zig_panic("TODO type check negation");
break;
{
// TODO: don't require i32
analyze_expression(g, import, context, g->builtin_types.entry_i32, node->data.prefix_op_expr.primary_expr);
return_type = g->builtin_types.entry_i32;
break;
}
case PrefixOpInvalid:
zig_unreachable();
}

View File

@ -485,22 +485,18 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
// block for when val1 == false (don't even evaluate the second part)
LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolAndFalse");
LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(val1));
add_debug_source_node(g, node);
LLVMValueRef val1_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, zero, "");
LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
LLVMBuildCondBr(g->builder, val1, true_block, false_block);
LLVMPositionBuilderAtEnd(g->builder, true_block);
LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
add_debug_source_node(g, node);
LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
LLVMBuildBr(g->builder, false_block);
LLVMPositionBuilderAtEnd(g->builder, false_block);
add_debug_source_node(g, node);
LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
LLVMValueRef one_i1 = LLVMConstAllOnes(LLVMInt1Type());
LLVMValueRef incoming_values[2] = {one_i1, val2_i1};
LLVMValueRef incoming_values[2] = {val1, val2};
LLVMBasicBlockRef incoming_blocks[2] = {orig_block, true_block};
LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
@ -519,22 +515,18 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
// block for when val1 == true (don't even evaluate the second part)
LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolOrTrue");
LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(val1));
add_debug_source_node(g, expr_node);
LLVMValueRef val1_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, zero, "");
LLVMBuildCondBr(g->builder, val1_i1, false_block, true_block);
LLVMBuildCondBr(g->builder, val1, true_block, false_block);
LLVMPositionBuilderAtEnd(g->builder, false_block);
LLVMValueRef val2 = gen_expr(g, expr_node->data.bin_op_expr.op2);
add_debug_source_node(g, expr_node);
LLVMValueRef val2_i1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
LLVMBuildBr(g->builder, true_block);
LLVMPositionBuilderAtEnd(g->builder, true_block);
add_debug_source_node(g, expr_node);
LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
LLVMValueRef one_i1 = LLVMConstAllOnes(LLVMInt1Type());
LLVMValueRef incoming_values[2] = {one_i1, val2_i1};
LLVMValueRef incoming_values[2] = {val1, val2};
LLVMBasicBlockRef incoming_blocks[2] = {orig_block, false_block};
LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);

View File

@ -944,7 +944,7 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man
}
/*
PrefixOpExpression : PrefixOp SuffixOpExpression | SuffixOpExpression
PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
*/
static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
@ -952,7 +952,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo
if (prefix_op == PrefixOpInvalid)
return ast_parse_suffix_op_expr(pc, token_index, mandatory);
AstNode *prefix_op_expr = ast_parse_suffix_op_expr(pc, token_index, true);
AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
node->data.prefix_op_expr.primary_expr = prefix_op_expr;
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
/*
CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
CastExpression : CastExpression token(as) Type | PrefixOpExpression
*/
static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory);
if (!prefix_op_expr)
AstNode *operand_1 = ast_parse_prefix_op_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *as_kw = &pc->tokens->at(*token_index);
if (as_kw->id != TokenIdKeywordAs)
return prefix_op_expr;
*token_index += 1;
while (true) {
Token *as_kw = &pc->tokens->at(*token_index);
if (as_kw->id != TokenIdKeywordAs)
return operand_1;
*token_index += 1;
AstNode *node = ast_create_node(pc, NodeTypeCastExpr, as_kw);
node->data.cast_expr.expr = prefix_op_expr;
AstNode *node = ast_create_node(pc, NodeTypeCastExpr, as_kw);
node->data.cast_expr.expr = operand_1;
node->data.cast_expr.type = ast_parse_type(pc, *token_index, token_index);
node->data.cast_expr.type = ast_parse_type(pc, *token_index, token_index);
return node;
operand_1 = node;
}
}
static BinOpType tok_to_mult_op(Token *token) {
@ -1009,26 +1011,28 @@ static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mand
}
/*
MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpression
MultiplyExpression : CastExpression MultiplyOperator MultiplyExpression | CastExpression
*/
static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_cast_expression(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
BinOpType mult_op = ast_parse_mult_op(pc, token_index, false);
if (mult_op == BinOpTypeInvalid)
return operand_1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
BinOpType mult_op = ast_parse_mult_op(pc, token_index, false);
if (mult_op == BinOpTypeInvalid)
return operand_1;
AstNode *operand_2 = ast_parse_cast_expression(pc, token_index, true);
AstNode *operand_2 = ast_parse_cast_expression(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = mult_op;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = mult_op;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
static BinOpType tok_to_add_op(Token *token) {
@ -1057,26 +1061,28 @@ static BinOpType ast_parse_add_op(ParseContext *pc, int *token_index, bool manda
}
/*
AdditionExpression : MultiplyExpression AdditionOperator MultiplyExpression | MultiplyExpression
AdditionExpression : MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
*/
static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_mult_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
BinOpType add_op = ast_parse_add_op(pc, token_index, false);
if (add_op == BinOpTypeInvalid)
return operand_1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
BinOpType add_op = ast_parse_add_op(pc, token_index, false);
if (add_op == BinOpTypeInvalid)
return operand_1;
AstNode *operand_2 = ast_parse_mult_expr(pc, token_index, true);
AstNode *operand_2 = ast_parse_mult_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = add_op;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = add_op;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
static BinOpType tok_to_bit_shift_op(Token *token) {
@ -1088,7 +1094,7 @@ static BinOpType tok_to_bit_shift_op(Token *token) {
}
/*
BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)
BitShiftOperator : token(BitShiftLeft) | token(BitShiftRight)
*/
static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
@ -1105,96 +1111,104 @@ static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool
}
/*
BitShiftExpression : AdditionExpression BitShiftOperator AdditionExpression | AdditionExpression
BitShiftExpression : AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
*/
static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_add_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);
if (bit_shift_op == BinOpTypeInvalid)
return operand_1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false);
if (bit_shift_op == BinOpTypeInvalid)
return operand_1;
AstNode *operand_2 = ast_parse_add_expr(pc, token_index, true);
AstNode *operand_2 = ast_parse_add_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = bit_shift_op;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = bit_shift_op;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
/*
BinaryAndExpression : BitShiftExpression token(BinAnd) BitShiftExpression | BitShiftExpression
BinaryAndExpression : BitShiftExpression token(BinAnd) BinaryAndExpression | BitShiftExpression
*/
static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_bit_shift_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBinAnd)
return operand_1;
*token_index += 1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBinAnd)
return operand_1;
*token_index += 1;
AstNode *operand_2 = ast_parse_bit_shift_expr(pc, token_index, true);
AstNode *operand_2 = ast_parse_bit_shift_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
/*
BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryAndExpression | BinaryAndExpression
BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryXorExpression | BinaryAndExpression
*/
static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_bin_and_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBinXor)
return operand_1;
*token_index += 1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBinXor)
return operand_1;
*token_index += 1;
AstNode *operand_2 = ast_parse_bin_and_expr(pc, token_index, true);
AstNode *operand_2 = ast_parse_bin_and_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBinXor;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBinXor;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
/*
BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryXorExpression | BinaryXorExpression
BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryOrExpression | BinaryXorExpression
*/
static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_bin_xor_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBinOr)
return operand_1;
*token_index += 1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBinOr)
return operand_1;
*token_index += 1;
AstNode *operand_2 = ast_parse_bin_xor_expr(pc, token_index, true);
AstNode *operand_2 = ast_parse_bin_xor_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBinOr;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBinOr;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
static BinOpType tok_to_cmp_op(Token *token) {
@ -1247,26 +1261,28 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo
}
/*
BoolAndExpression : ComparisonExpression token(BoolAnd) ComparisonExpression | ComparisonExpression
BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression
*/
static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_comparison_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBoolAnd)
return operand_1;
*token_index += 1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBoolAnd)
return operand_1;
*token_index += 1;
AstNode *operand_2 = ast_parse_comparison_expr(pc, token_index, true);
AstNode *operand_2 = ast_parse_comparison_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
/*
@ -1382,26 +1398,28 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token
}
/*
BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression
BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression
*/
static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool mandatory) {
AstNode *operand_1 = ast_parse_bool_and_expr(pc, token_index, mandatory);
if (!operand_1)
return nullptr;
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBoolOr)
return operand_1;
*token_index += 1;
while (true) {
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdBoolOr)
return operand_1;
*token_index += 1;
AstNode *operand_2 = ast_parse_bool_and_expr(pc, token_index, true);
AstNode *operand_2 = ast_parse_bool_and_expr(pc, token_index, true);
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;
node->data.bin_op_expr.op2 = operand_2;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = operand_1;
node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;
node->data.bin_op_expr.op2 = operand_2;
return node;
operand_1 = node;
}
}
/*

View File

@ -478,9 +478,10 @@ void tokenize(Buf *buf, Tokenization *out) {
t.multi_line_comment_count = 1;
break;
default:
t.pos -= 1;
end_token(&t);
t.state = TokenizeStateStart;
break;
continue;
}
break;
case TokenizeStateLineComment:
@ -592,9 +593,10 @@ void tokenize(Buf *buf, Tokenization *out) {
t.state = TokenizeStateStart;
break;
default:
t.pos -= 1;
end_token(&t);
t.state = TokenizeStateStart;
break;
continue;
}
break;
}

View File

@ -409,6 +409,27 @@ export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {
)SOURCE", "Hello, world!\n");
add_simple_case("a + b + c", R"SOURCE(
use "std.zig";
export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {
if false || false || false { print_str("BAD 1\n" as string); }
if true && true && false { print_str("BAD 2\n" as string); }
if 1 | 2 | 4 != 7 { print_str("BAD 3\n" as string); }
if 3 ^ 6 ^ 8 != 13 { print_str("BAD 4\n" as string); }
if 7 & 14 & 28 != 4 { print_str("BAD 5\n" as string); }
if 9 << 1 << 2 != 9 << 3 { print_str("BAD 6\n" as string); }
if 90 >> 1 >> 2 != 90 >> 3 { print_str("BAD 7\n" as string); }
if 100 - 1 + 1000 != 1099 { print_str("BAD 8\n" as string); }
if 5 * 4 / 2 % 3 != 1 { print_str("BAD 9\n" as string); }
if 5 as i32 as i32 != 5 { print_str("BAD 10\n" as string); }
if !!false { print_str("BAD 11\n" as string); }
if 7 != --7 { print_str("BAD 12\n" as string); }
print_str("OK\n" as string);
return 0;
}
)SOURCE", "OK\n");
}