From: Brendan Hansen Date: Thu, 23 Jul 2020 17:22:39 +0000 (-0500) Subject: Added boolean logical operators X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=0ca39e43765090cd310ac610937fd878a44207d1;p=onyx.git Added boolean logical operators --- diff --git a/docs/plan b/docs/plan index 91f99cf7..091acd8b 100644 --- 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 diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 8d6d42fe..3b46add3 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -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 { diff --git a/include/onyxlex.h b/include/onyxlex.h index a8726ec5..7909d530 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -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 2b68828b..0449ac05 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/structs.onyx b/progs/structs.onyx index bfe93372..687a16ec 100644 --- a/progs/structs.onyx +++ b/progs/structs.onyx @@ -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 index 00000000..ce5af6de --- /dev/null +++ b/progs/ufc.onyx @@ -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 diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 44dbd8a8..b8f19192 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -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; } diff --git a/src/onyxlex.c b/src/onyxlex.c index 6db48c72..f1015a3e 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -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); diff --git a/src/onyxparser.c b/src/onyxparser.c index ee617e42..c12a1a61 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -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; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 35053e65..6acc2d91 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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) {