From: Brendan Hansen Date: Thu, 23 Jul 2020 18:09:46 +0000 (-0500) Subject: Added bitwise operations X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=c3a337635370abe3a33912f981958fcf6aa85c70;p=onyx.git Added bitwise operations --- diff --git a/docs/plan b/docs/plan index 091acd8b..b9e23256 100644 --- a/docs/plan +++ b/docs/plan @@ -108,10 +108,14 @@ HOW: [X] Logical boolean operators - [ ] Bitwise operators + [X] Bitwise operators + + [ ] Dead code elimination [ ] Enum types + [ ] Static pointers to sized data + [ ] Start work on evaluating compile time known values. - An expression marked COMPTIME will be reduced to its value in the parse tree. diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 3b46add3..164fb0d8 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -146,18 +146,31 @@ typedef enum BinaryOp { Binary_Op_Greater = 9, Binary_Op_Greater_Equal = 10, - Binary_Op_Bool_And = 11, - Binary_Op_Bool_Or = 12, - Binary_Op_Bool_Xor = 13, - - Binary_Op_Assign_Start = 14, - Binary_Op_Assign = 15, - Binary_Op_Assign_Add = 16, - Binary_Op_Assign_Minus = 17, - Binary_Op_Assign_Multiply = 18, - Binary_Op_Assign_Divide = 19, - Binary_Op_Assign_Modulus = 20, - Binary_Op_Assign_End = 21, + Binary_Op_And = 11, + Binary_Op_Or = 12, + Binary_Op_Xor = 13, + Binary_Op_Shl = 14, + Binary_Op_Shr = 15, + Binary_Op_Sar = 16, + + Binary_Op_Bool_And = 17, + Binary_Op_Bool_Or = 18, + Binary_Op_Bool_Xor = 19, + + Binary_Op_Assign_Start = 20, + Binary_Op_Assign = 21, + Binary_Op_Assign_Add = 22, + Binary_Op_Assign_Minus = 23, + Binary_Op_Assign_Multiply = 24, + Binary_Op_Assign_Divide = 25, + Binary_Op_Assign_Modulus = 26, + Binary_Op_Assign_And = 27, + Binary_Op_Assign_Or = 28, + Binary_Op_Assign_Xor = 29, + Binary_Op_Assign_Shl = 30, + Binary_Op_Assign_Shr = 31, + Binary_Op_Assign_Sar = 32, + Binary_Op_Assign_End = 33, } BinaryOp; typedef enum OnyxIntrinsic { diff --git a/include/onyxlex.h b/include/onyxlex.h index 7909d530..913c48a0 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -39,17 +39,26 @@ typedef enum TokenType { Token_Type_Star_Equal = 283, Token_Type_Fslash_Equal = 284, Token_Type_Percent_Equal = 285, - Token_Type_And_And = 286, - Token_Type_Or_Or = 287, - Token_Type_Xor_Xor = 288, - - Token_Type_Symbol = 289, - Token_Type_Literal_String = 290, - Token_Type_Literal_Numeric = 291, - Token_Type_Literal_True = 292, - Token_Type_Literal_False = 293, - - Token_Type_Count = 294, + Token_Type_And_Equal = 286, + Token_Type_Or_Equal = 287, + Token_Type_Xor_Equal = 288, + Token_Type_And_And = 289, + Token_Type_Or_Or = 290, + Token_Type_Xor_Xor = 291, + Token_Type_Shift_Left = 292, + Token_Type_Shift_Right = 293, + Token_Type_Shift_Arith_Right = 294, + Token_Type_Shl_Equal = 295, + Token_Type_Shr_Equal = 296, + Token_Type_Sar_Equal = 297, + + Token_Type_Symbol = 298, + Token_Type_Literal_String = 299, + Token_Type_Literal_Numeric = 300, + Token_Type_Literal_True = 301, + Token_Type_Literal_False = 302, + + Token_Type_Count = 303, } TokenType; typedef struct OnyxFilePos { diff --git a/onyx b/onyx index 0449ac05..d2b55da7 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/ufc.onyx b/progs/ufc.onyx index ce5af6de..2a0103ed 100644 --- a/progs/ufc.onyx +++ b/progs/ufc.onyx @@ -84,4 +84,11 @@ proc #export "main" { v3.z = 13.0f; print(v3.magnitude()); + + foo := 5; + foo <<= 2; + foo &= 6; + foo |= 5; + foo >>= 1; + print(foo); } \ No newline at end of file diff --git a/src/onyxchecker.c b/src/onyxchecker.c index b8f19192..4ed68de1 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -381,6 +381,12 @@ CHECK(binaryop, AstBinaryOp* binop, b32 assignment_is_ok) { else if (binop->operation == Binary_Op_Assign_Multiply) binop_node->operation = Binary_Op_Multiply; else if (binop->operation == Binary_Op_Assign_Divide) binop_node->operation = Binary_Op_Divide; else if (binop->operation == Binary_Op_Assign_Modulus) binop_node->operation = Binary_Op_Modulus; + else if (binop->operation == Binary_Op_Assign_And) binop_node->operation = Binary_Op_And; + else if (binop->operation == Binary_Op_Assign_Or) binop_node->operation = Binary_Op_Or; + else if (binop->operation == Binary_Op_Assign_Xor) binop_node->operation = Binary_Op_Xor; + else if (binop->operation == Binary_Op_Assign_Shl) binop_node->operation = Binary_Op_Shl; + else if (binop->operation == Binary_Op_Assign_Shr) binop_node->operation = Binary_Op_Shr; + else if (binop->operation == Binary_Op_Assign_Sar) binop_node->operation = Binary_Op_Sar; binop->right = (AstTyped *) binop_node; binop->operation = Binary_Op_Assign; @@ -430,7 +436,7 @@ CHECK(binaryop, AstBinaryOp* binop, b32 assignment_is_ok) { } binop->type = &basic_types[Basic_Kind_Bool]; - + } else if (binop->operation >= Binary_Op_Equal && binop->operation <= Binary_Op_Greater_Equal) { binop->type = &basic_types[Basic_Kind_Bool]; diff --git a/src/onyxlex.c b/src/onyxlex.c index f1015a3e..3baef1cc 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -152,6 +152,15 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { LITERAL_TOKEN("&&", 0, Token_Type_And_And); LITERAL_TOKEN("||", 0, Token_Type_Or_Or); LITERAL_TOKEN("^^", 0, Token_Type_Xor_Xor); + LITERAL_TOKEN(">>>=", 0, Token_Type_Sar_Equal); + LITERAL_TOKEN(">>=", 0, Token_Type_Shr_Equal); + LITERAL_TOKEN("<<=", 0, Token_Type_Shl_Equal); + LITERAL_TOKEN(">>>", 0, Token_Type_Shift_Arith_Right); + LITERAL_TOKEN(">>", 0, Token_Type_Shift_Right); + LITERAL_TOKEN("<<", 0, Token_Type_Shift_Left); + LITERAL_TOKEN("&=", 0, Token_Type_And_Equal); + LITERAL_TOKEN("|=", 0, Token_Type_Or_Equal); + LITERAL_TOKEN("^=", 0, Token_Type_Xor_Equal); LITERAL_TOKEN("<=", 0, Token_Type_Less_Equal); LITERAL_TOKEN(">=", 0, Token_Type_Greater_Equal); LITERAL_TOKEN("==", 0, Token_Type_Equal_Equal); diff --git a/src/onyxparser.c b/src/onyxparser.c index c12a1a61..9dd5874a 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -330,6 +330,12 @@ static inline i32 get_precedence(BinaryOp kind) { case Binary_Op_Assign_Multiply: return 1; case Binary_Op_Assign_Divide: return 1; case Binary_Op_Assign_Modulus: return 1; + case Binary_Op_Assign_And: return 1; + case Binary_Op_Assign_Or: return 1; + case Binary_Op_Assign_Xor: return 1; + case Binary_Op_Assign_Shl: return 1; + case Binary_Op_Assign_Shr: return 1; + case Binary_Op_Assign_Sar: return 1; case Binary_Op_Bool_And: return 2; case Binary_Op_Bool_Or: return 2; @@ -343,13 +349,17 @@ static inline i32 get_precedence(BinaryOp kind) { case Binary_Op_Greater_Equal: return 4; case Binary_Op_Greater: return 4; - case Binary_Op_Add: return 5; - case Binary_Op_Minus: return 5; + case Binary_Op_And: return 5; + case Binary_Op_Or: return 5; + case Binary_Op_Xor: return 5; - case Binary_Op_Multiply: return 6; - case Binary_Op_Divide: return 6; + case Binary_Op_Add: return 6; + case Binary_Op_Minus: return 6; - case Binary_Op_Modulus: return 7; + case Binary_Op_Multiply: return 7; + case Binary_Op_Divide: return 7; + + case Binary_Op_Modulus: return 8; default: return -1; } @@ -389,29 +399,42 @@ static AstTyped* parse_expression(OnyxParser* parser) { while (1) { bin_op_kind = -1; switch ((u16) parser->curr->type) { - case Token_Type_Equal_Equal: bin_op_kind = Binary_Op_Equal; break; - case Token_Type_Not_Equal: bin_op_kind = Binary_Op_Not_Equal; break; - case Token_Type_Less_Equal: bin_op_kind = Binary_Op_Less_Equal; break; - case Token_Type_Greater_Equal: bin_op_kind = Binary_Op_Greater_Equal; break; - case '<': bin_op_kind = Binary_Op_Less; break; - case '>': bin_op_kind = Binary_Op_Greater; break; - - case '+': bin_op_kind = Binary_Op_Add; break; - case '-': bin_op_kind = Binary_Op_Minus; break; - case '*': bin_op_kind = Binary_Op_Multiply; break; - case '/': bin_op_kind = Binary_Op_Divide; break; - case '%': bin_op_kind = Binary_Op_Modulus; break; - - case Token_Type_And_And: bin_op_kind = Binary_Op_Bool_And; break; - case Token_Type_Or_Or: bin_op_kind = Binary_Op_Bool_Or; break; - case Token_Type_Xor_Xor: bin_op_kind = Binary_Op_Bool_Xor; break; - - case '=': bin_op_kind = Binary_Op_Assign; break; - case Token_Type_Plus_Equal: bin_op_kind = Binary_Op_Assign_Add; break; - case Token_Type_Minus_Equal: bin_op_kind = Binary_Op_Assign_Minus; break; - case Token_Type_Star_Equal: bin_op_kind = Binary_Op_Assign_Multiply; break; - case Token_Type_Fslash_Equal: bin_op_kind = Binary_Op_Assign_Divide; break; - case Token_Type_Percent_Equal: bin_op_kind = Binary_Op_Assign_Modulus; break; + case Token_Type_Equal_Equal: bin_op_kind = Binary_Op_Equal; break; + case Token_Type_Not_Equal: bin_op_kind = Binary_Op_Not_Equal; break; + case Token_Type_Less_Equal: bin_op_kind = Binary_Op_Less_Equal; break; + case Token_Type_Greater_Equal: bin_op_kind = Binary_Op_Greater_Equal; break; + case '<': bin_op_kind = Binary_Op_Less; break; + case '>': bin_op_kind = Binary_Op_Greater; break; + + case '+': bin_op_kind = Binary_Op_Add; break; + case '-': bin_op_kind = Binary_Op_Minus; break; + case '*': bin_op_kind = Binary_Op_Multiply; break; + case '/': bin_op_kind = Binary_Op_Divide; break; + case '%': bin_op_kind = Binary_Op_Modulus; break; + + case '&': bin_op_kind = Binary_Op_And; break; + case '|': bin_op_kind = Binary_Op_Or; break; + case '^': bin_op_kind = Binary_Op_Xor; break; + case Token_Type_Shift_Left: bin_op_kind = Binary_Op_Shl; break; + case Token_Type_Shift_Right: bin_op_kind = Binary_Op_Shr; break; + case Token_Type_Shift_Arith_Right: bin_op_kind = Binary_Op_Sar; break; + + case Token_Type_And_And: bin_op_kind = Binary_Op_Bool_And; break; + case Token_Type_Or_Or: bin_op_kind = Binary_Op_Bool_Or; break; + case Token_Type_Xor_Xor: bin_op_kind = Binary_Op_Bool_Xor; break; + + case '=': bin_op_kind = Binary_Op_Assign; break; + case Token_Type_Plus_Equal: bin_op_kind = Binary_Op_Assign_Add; break; + case Token_Type_Minus_Equal: bin_op_kind = Binary_Op_Assign_Minus; break; + case Token_Type_Star_Equal: bin_op_kind = Binary_Op_Assign_Multiply; break; + case Token_Type_Fslash_Equal: bin_op_kind = Binary_Op_Assign_Divide; break; + case Token_Type_Percent_Equal: bin_op_kind = Binary_Op_Assign_Modulus; break; + case Token_Type_And_Equal: bin_op_kind = Binary_Op_Assign_And; break; + case Token_Type_Or_Equal: bin_op_kind = Binary_Op_Assign_Or; break; + case Token_Type_Xor_Equal: bin_op_kind = Binary_Op_Assign_Xor; break; + case Token_Type_Shl_Equal: bin_op_kind = Binary_Op_Assign_Shl; break; + case Token_Type_Shr_Equal: bin_op_kind = Binary_Op_Assign_Shr; break; + case Token_Type_Sar_Equal: bin_op_kind = Binary_Op_Assign_Sar; break; default: goto expression_done; } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 6acc2d91..517cd8e9 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -574,22 +574,29 @@ COMPILE_FUNC(for, AstFor* for_node) { // the OnyxBinaryOp enum static const WasmInstructionType binop_map[][4] = { // I32 I64 F32 F64 - /* ADD */ { WI_I32_ADD, WI_I64_ADD, WI_F32_ADD, WI_F64_ADD }, - /* SUB */ { WI_I32_SUB, WI_I64_SUB, WI_F32_SUB, WI_F64_SUB }, - /* MUL */ { WI_I32_MUL, WI_I64_MUL, WI_F32_MUL, WI_F64_MUL }, - /* DIV */ { WI_I32_DIV_S, WI_I64_DIV_S, WI_F32_DIV, WI_F64_DIV }, - /* REM */ { WI_I32_REM_S, WI_I64_REM_S, WI_NOP, WI_NOP }, - - /* EQ */ { WI_I32_EQ, WI_I64_EQ, WI_F32_EQ, WI_F64_EQ }, - /* NEQ */ { WI_I32_NE, WI_I64_NE, WI_F32_NE , WI_F64_NE }, - /* LT */ { WI_I32_LT_S, WI_I64_LT_S, WI_F32_LT, WI_F64_LT }, - /* LTE */ { WI_I32_LE_S, WI_I64_LE_S, WI_F32_LE, WI_F64_LE }, - /* GT */ { WI_I32_GT_S, WI_I64_GT_S, WI_F32_GT, WI_F64_GT }, - /* GTE */ { WI_I32_GE_S, WI_I64_GE_S, WI_F32_GE, WI_F64_GE }, - - /* AND */ { WI_I32_AND, WI_I64_AND, WI_NOP, WI_NOP }, - /* OR */ { WI_I32_OR, WI_I64_OR, WI_NOP, WI_NOP }, - /* XOR */ { WI_I32_XOR, WI_I64_XOR, WI_NOP, WI_NOP }, + /* ADD */ { WI_I32_ADD, WI_I64_ADD, WI_F32_ADD, WI_F64_ADD }, + /* SUB */ { WI_I32_SUB, WI_I64_SUB, WI_F32_SUB, WI_F64_SUB }, + /* MUL */ { WI_I32_MUL, WI_I64_MUL, WI_F32_MUL, WI_F64_MUL }, + /* DIV */ { WI_I32_DIV_S, WI_I64_DIV_S, WI_F32_DIV, WI_F64_DIV }, + /* REM */ { WI_I32_REM_S, WI_I64_REM_S, WI_NOP, WI_NOP }, + + /* EQ */ { WI_I32_EQ, WI_I64_EQ, WI_F32_EQ, WI_F64_EQ }, + /* NEQ */ { WI_I32_NE, WI_I64_NE, WI_F32_NE , WI_F64_NE }, + /* LT */ { WI_I32_LT_S, WI_I64_LT_S, WI_F32_LT, WI_F64_LT }, + /* LTE */ { WI_I32_LE_S, WI_I64_LE_S, WI_F32_LE, WI_F64_LE }, + /* GT */ { WI_I32_GT_S, WI_I64_GT_S, WI_F32_GT, WI_F64_GT }, + /* GTE */ { WI_I32_GE_S, WI_I64_GE_S, WI_F32_GE, WI_F64_GE }, + + /* AND */ { WI_I32_AND, WI_I64_AND, WI_NOP, WI_NOP }, + /* OR */ { WI_I32_OR, WI_I64_OR, WI_NOP, WI_NOP }, + /* XOR */ { WI_I32_XOR, WI_I64_XOR, WI_NOP, WI_NOP }, + /* SHL */ { WI_I32_SHL, WI_I64_SHL, WI_NOP, WI_NOP }, + /* SHR */ { WI_I32_SHR_U, WI_I64_SHR_U, WI_NOP, WI_NOP }, + /* SAR */ { WI_I32_SHR_S, WI_I64_SHR_S, WI_NOP, WI_NOP }, + + /* BAND */ { WI_I32_AND, WI_I64_AND, WI_NOP, WI_NOP }, + /* BOR */ { WI_I32_OR, WI_I64_OR, WI_NOP, WI_NOP }, + /* BXOR */ { WI_I32_XOR, WI_I64_XOR, WI_NOP, WI_NOP }, }; COMPILE_FUNC(binop, AstBinaryOp* binop) {