From: Brendan Hansen Date: Tue, 15 Dec 2020 01:32:13 +0000 (-0600) Subject: better error reporting for invalid binary operations X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3c3b7d0d99780682acd5e2339cd4852f87fba9fe;p=onyx.git better error reporting for invalid binary operations --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index c752c68d..d331f280 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -240,6 +240,8 @@ typedef enum BinaryOp { Binary_Op_Pipe = 33, Binary_Op_Range = 34, + + Binary_Op_Count } BinaryOp; typedef enum OnyxIntrinsic { diff --git a/onyx b/onyx index 82f9930c..8f9659c1 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 98133c32..01c95e42 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -796,8 +796,64 @@ b32 check_binaryop(AstBinaryOp** pbinop, b32 assignment_is_ok) { } } + static const u8 binop_allowed[Binary_Op_Count] = { + /* Add */ Basic_Flag_Numeric | Basic_Flag_Pointer, + /* Minus */ Basic_Flag_Numeric | Basic_Flag_Pointer, + /* Multiply */ Basic_Flag_Numeric, + /* Divide */ Basic_Flag_Numeric, + /* Modulus */ Basic_Flag_Integer, + + /* Equal */ Basic_Flag_Ordered, + /* Not_Equal */ Basic_Flag_Ordered, + /* Less */ Basic_Flag_Ordered, + /* Less_Equal */ Basic_Flag_Ordered, + /* Greater */ Basic_Flag_Ordered, + /* Greater_Equal */ Basic_Flag_Ordered, + + /* And */ Basic_Flag_Integer, + /* Or */ Basic_Flag_Integer, + /* Xor */ Basic_Flag_Integer, + /* Shl */ Basic_Flag_Integer, + /* Shr */ Basic_Flag_Integer, + /* Sar */ Basic_Flag_Integer, + + /* Bool_And */ Basic_Flag_Boolean, + /* Bool_Or */ Basic_Flag_Boolean, + + /* Assign_Start */ 0, + /* Assign */ 0, + /* Assign_Add */ 0, + /* Assign_Minus */ 0, + /* Assign_Multiply */ 0, + /* Assign_Divide */ 0, + /* Assign_Modulus */ 0, + /* Assign_And */ 0, + /* Assign_Or */ 0, + /* Assign_Xor */ 0, + /* Assign_Shl */ 0, + /* Assign_Shr */ 0, + /* Assign_Sar */ 0, + /* Assign_End */ 0, + + /* Pipe */ 0, + /* Range */ 0, + }; + binop->type = binop->left->type; + enum BasicFlag effective_flags = 0; + switch (binop->type->kind) { + case Type_Kind_Basic: effective_flags = binop->type->Basic.flags; break; + case Type_Kind_Pointer: effective_flags = Basic_Flag_Pointer; break; + case Type_Kind_Enum: effective_flags = Basic_Flag_Integer; break; + } + + if ((binop_allowed[binop->operation] & effective_flags) == 0) { + onyx_report_error(binop->token->pos, "Binary operator not allowed for arguments of type '%s'.", + type_get_name(binop->type)); + return 1; + } + if (binop->flags & Ast_Flag_Comptime) { // NOTE: Not a binary op *pbinop = (AstBinaryOp *) ast_reduce(semstate.node_allocator, (AstTyped *) binop); diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 894c4b4e..be107baf 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1230,9 +1230,7 @@ EMIT_FUNC(binop, AstBinaryOp* binop) { WasmInstructionType binop_instr = binop_map[(i32) binop->operation][optype]; - if (binop_instr == WI_NOP) { - assert(("Invalid type and operation", 0)); - } + assert(binop_instr != WI_NOP); // NOTE: Use unsigned variant if needed // Unsigned instructions are always right after