Added bitwise operations
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 23 Jul 2020 18:09:46 +0000 (13:09 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 23 Jul 2020 18:09:46 +0000 (13:09 -0500)
docs/plan
include/onyxastnodes.h
include/onyxlex.h
onyx
progs/ufc.onyx
src/onyxchecker.c
src/onyxlex.c
src/onyxparser.c
src/onyxwasm.c

index 091acd8b3c407d9efadc226ba57b53e698e95c14..b9e23256c24e76a94ef47c58ddc0ff5001dab74b 100644 (file)
--- 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.
 
index 3b46add3bd02afc4c6c14bccf51eef18cd328484..164fb0d88a6e836433b13705e02c936221b42619 100644 (file)
@@ -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 {
index 7909d53099fbcf80522f38cc635f94d7e9fc7b97..913c48a0f8191204f441955e249b8e0ae0f512b4 100644 (file)
@@ -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 0449ac056154b8f57265a5bd4bc80e11b9d46a7f..d2b55da7adf36d2013726b73a2a8bc3c9355aed2 100755 (executable)
Binary files a/onyx and b/onyx differ
index ce5af6de76d9d67f9afee36436ef5a8f1d57ca01..2a0103ed6d8b963cdb559248767dedb90b2c2b11 100644 (file)
@@ -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
index b8f19192995e298868b9ccd9e8b0bd17785f18b4..4ed68de1686835daf2867362e4da4cf2fc73bbb8 100644 (file)
@@ -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];
index f1015a3eb5abacf81f256fad6c1da934bc3e3b2f..3baef1cc85ffbcf25838708283b1f1cc6c99fdee 100644 (file)
@@ -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);
index c12a1a61ccbc046dc49e5c0ade2ce13d6d3a04d4..9dd5874af59ff25a289cede23962ac8c3ca67bce 100644 (file)
@@ -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;
         }
 
index 6acc2d9166a06164c8914b83d3a6776c21106b57..517cd8e91ff78b4e937c733252cb6d17f63df58c 100644 (file)
@@ -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) {