Added boolean logical operators
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 23 Jul 2020 17:22:39 +0000 (12:22 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 23 Jul 2020 17:22:39 +0000 (12:22 -0500)
docs/plan
include/onyxastnodes.h
include/onyxlex.h
onyx
progs/structs.onyx
progs/ufc.onyx [new file with mode: 0644]
src/onyxchecker.c
src/onyxlex.c
src/onyxparser.c
src/onyxwasm.c

index 91f99cf7afe5e3dba38d9a8eca242b180450629b..091acd8b3c407d9efadc226ba57b53e698e95c14 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -102,17 +102,22 @@ HOW:
             - Literals should be placed in data section with pointers to the start.
             - Should strings be null-terminated or a length at the start of the string?
 
-        [ ] Struct splatting in arguments and parameters
+        [X] Struct splatting in arguments and parameters
 
         [X] UFC syntax for structs
 
-        [ ] Enum types
+        [X] Logical boolean operators
 
-        [ ] Procedures as arguments
+        [ ] Bitwise operators
+
+        [ ] Enum types
 
         [ ] Start work on evaluating compile time known values.
             - An expression marked COMPTIME will be reduced to its value in the parse tree.
 
+        [ ] Switch statements
+
+        [ ] Procedures as arguments
 
 
 
index 8d6d42fe02f899812bb3f0ab3c4472005bbf5295..3b46add3bd02afc4c6c14bccf51eef18cd328484 100644 (file)
@@ -146,14 +146,18 @@ typedef enum BinaryOp {
     Binary_Op_Greater         = 9,
     Binary_Op_Greater_Equal   = 10,
 
-    Binary_Op_Assign_Start    = 11,
-    Binary_Op_Assign          = 12,
-    Binary_Op_Assign_Add      = 13,
-    Binary_Op_Assign_Minus    = 14,
-    Binary_Op_Assign_Multiply = 15,
-    Binary_Op_Assign_Divide   = 16,
-    Binary_Op_Assign_Modulus  = 17,
-    Binary_Op_Assign_End      = 18,
+    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,
 } BinaryOp;
 
 typedef enum OnyxIntrinsic {
index a8726ec53b31eaa59c56ab0b38f47c366b400fc3..7909d53099fbcf80522f38cc635f94d7e9fc7b97 100644 (file)
@@ -39,14 +39,17 @@ 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               = 286,
-    Token_Type_Literal_String       = 287,
-    Token_Type_Literal_Numeric      = 288,
-    Token_Type_Literal_True         = 289,
-    Token_Type_Literal_False        = 290,
+    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                = 291,
+    Token_Type_Count                = 294,
 } TokenType;
 
 typedef struct OnyxFilePos {
diff --git a/onyx b/onyx
index 2b68828bf89f06aa5813d97f264fb8e0b9c1aff9..0449ac056154b8f57265a5bd4bc80e11b9d46a7f 100755 (executable)
Binary files a/onyx and b/onyx differ
index bfe93372ea67ebb875a5162cc3922dcbbf6bd3da..687a16ec655d2140fd0a11ad9c194cf3ff11a873 100644 (file)
@@ -121,6 +121,20 @@ minus :: proc (n: i32, k: i32) -> i32 {
     return n - k;
 }
 
+Fool :: struct {
+    bar : ^Bar;
+}
+
+Bar :: struct {
+    i: i32;
+    j: i64;
+}
+
+print_bar :: proc (bar: Bar) {
+    print(bar.i);
+    print(bar.j);
+}
+
 proc #export "main" {
     v2 := alloc(sizeof Vec2) as ^Vec2;
     v2.x = 5;
@@ -133,9 +147,16 @@ proc #export "main" {
     v3.z = 1;
     print(v3.magnitude());
 
-    vec2_splat(*v2, *v3);
+    (*v2).vec2_splat(*v3);
 
     print((1).minus(2));
+
+    foo := alloc(sizeof Fool) as ^Fool;
+    foo.bar = alloc(sizeof Bar) as ^Bar;
+    foo.bar.i = 50;
+    foo.bar.j = 70 as i64;
+
+    (*foo.bar).print_bar();
 }
 
 SOA :: struct {
@@ -149,13 +170,13 @@ vec2_set :: proc (v: ^Vec2) {
     v.y = 5678;
 }
 
-vec2_splat :: proc (vx: i32, vy: i32, other: Vec3) {
+vec2_splat :: proc (v: Vec2, other: Vec3) {
     print(other.x);
     print(other.y);
     print(other.z);
 
-    print(vx);
-    print(vy);
+    print(v.x);
+    print(v.y);
 }
 
 soa_test :: proc #export "main9" {
diff --git a/progs/ufc.onyx b/progs/ufc.onyx
new file mode 100644 (file)
index 0000000..ce5af6d
--- /dev/null
@@ -0,0 +1,87 @@
+use "progs/intrinsics"
+use "progs/print_funcs"
+
+alloc :: proc (size: u32) -> rawptr {
+    heap_u32    :: __heap_start as ^u32;
+
+    curr_offset := *heap_u32;
+    if curr_offset == 0 curr_offset = 8;
+
+    *heap_u32   = curr_offset + size;
+
+    return ((__heap_start as u32) + curr_offset) as rawptr;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Vec2 :: struct {
+       x : f32;
+       y : f32;
+}
+
+vec2_magnitude :: proc (v: ^Vec2) -> i32 {
+       return sqrt_f32(v.x * v.x + v.y * v.y) as i32;
+}
+
+Vec3 :: struct {
+       x : f32;
+       y : f32;
+       z : f32;
+}
+
+vec3_magnitude :: proc (v: ^Vec3) -> f32 {
+       return sqrt_f32(v.x * v.x + v.y * v.y + v.z * v.z);     
+}
+
+magnitude :: proc #overloaded {
+       vec2_magnitude,
+       vec3_magnitude,
+}
+
+dot :: proc (v: Vec2, u: Vec2) -> f32 {
+       return v.x * u.x + v.y * u.y;
+}
+
+proc #export "main" {
+       vec := alloc(sizeof Vec2) as ^Vec2;
+       vec.x = 5.0f;
+       vec.y = 12.0f;
+
+       print(vec.x);
+       print(vec.y);
+
+       mag :: vec.magnitude();
+
+       print(mag);
+
+       print((*vec).dot(1.0f, 1.0f));
+       print(dot(2.0f, 4.0f, -6.0f, 3.0f));
+
+
+       v3 := alloc(sizeof Vec3) as ^Vec3;
+       v3.x = 5.0f;
+       v3.y = 12.0f;
+       v3.z = 13.0f;
+
+       print(v3.magnitude());
+}
\ No newline at end of file
index 44dbd8a8a328899d461966a7d5b128be4d63f2a8..b8f19192995e298868b9ccd9e8b0bd17785f18b4 100644 (file)
@@ -198,6 +198,8 @@ CHECK(call, AstCall* call) {
                 arg->token = actual_param->token;
                 arg->next = actual_param->next;
 
+                call->arg_count++;
+
                 *prev_param = (AstNode *) arg;
                 prev_param = (AstNode **) &arg->next;
             }
@@ -417,11 +419,25 @@ CHECK(binaryop, AstBinaryOp* binop, b32 assignment_is_ok) {
         return 1;
     }
 
-    if (binop->operation >= Binary_Op_Equal
+    if (binop->operation >= Binary_Op_Bool_And
+            && binop->operation <= Binary_Op_Bool_Xor) {
+
+        if (!type_is_bool(binop->left->type) || !type_is_bool(binop->right->type)) {
+            onyx_message_add(Msg_Type_Literal,
+                    binop->token->pos,
+                    "boolean operator expects boolean types for both operands");
+            return 1;
+        }
+
+        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];
+
     } else if (binop_is_assignment(binop)) {
         binop->type = &basic_types[Basic_Kind_Void];
+
     } else {
         binop->type = binop->left->type;
     }
index 6db48c72549ac345fa1d8f04e8f05c03a9cd3bc9..f1015a3eb5abacf81f256fad6c1da934bc3e3b2f 100644 (file)
@@ -149,6 +149,9 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
     LITERAL_TOKEN("->",         0, Token_Type_Right_Arrow);
     LITERAL_TOKEN("<-",         0, Token_Type_Right_Arrow);
     LITERAL_TOKEN("---",        0, Token_Type_Empty_Block);
+    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_Less_Equal);
     LITERAL_TOKEN(">=",         0, Token_Type_Greater_Equal);
     LITERAL_TOKEN("==",         0, Token_Type_Equal_Equal);
index ee617e4220a7ae683be8e32e0e1608281c956017..c12a1a61ccbc046dc49e5c0ade2ce13d6d3a04d4 100644 (file)
@@ -324,12 +324,16 @@ static AstTyped* parse_factor(OnyxParser* parser) {
 
 static inline i32 get_precedence(BinaryOp kind) {
     switch (kind) {
-        case Binary_Op_Assign:          return 2;
-        case Binary_Op_Assign_Add:      return 2;
-        case Binary_Op_Assign_Minus:    return 2;
-        case Binary_Op_Assign_Multiply: return 2;
-        case Binary_Op_Assign_Divide:   return 2;
-        case Binary_Op_Assign_Modulus:  return 2;
+        case Binary_Op_Assign:          return 1;
+        case Binary_Op_Assign_Add:      return 1;
+        case Binary_Op_Assign_Minus:    return 1;
+        case Binary_Op_Assign_Multiply: return 1;
+        case Binary_Op_Assign_Divide:   return 1;
+        case Binary_Op_Assign_Modulus:  return 1;
+
+        case Binary_Op_Bool_And:        return 2;
+        case Binary_Op_Bool_Or:         return 2;
+        case Binary_Op_Bool_Xor:        return 2;
 
         case Binary_Op_Equal:           return 3;
         case Binary_Op_Not_Equal:       return 3;
@@ -398,6 +402,10 @@ static AstTyped* parse_expression(OnyxParser* parser) {
             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;
index 35053e65d898a3b77c2fad213da8c56c0ef6cf94..6acc2d9166a06164c8914b83d3a6776c21106b57 100644 (file)
@@ -586,6 +586,10 @@ static const WasmInstructionType binop_map[][4] = {
     /* 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 },
 };
 
 COMPILE_FUNC(binop, AstBinaryOp* binop) {