things of struct type now work as lvalues
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 13 Aug 2020 16:07:22 +0000 (11:07 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 13 Aug 2020 16:07:22 +0000 (11:07 -0500)
include/onyxtypes.h
onyx
progs/stack_based.onyx
src/onyxchecker.c
src/onyxtypes.c
src/onyxwasm.c

index ce7e9d0cd87a6a9035f52fb475724005f49ee383..27cd1a9d16954bf10fd8e1ca3b700c399c7763d9 100644 (file)
@@ -120,6 +120,7 @@ b32 type_struct_lookup_member(Type* type, char* member, StructMember* smem);
 b32 type_struct_is_simple(Type* type);
 
 b32 type_is_pointer(Type* type);
+b32 type_is_rawptr(Type* type);
 b32 type_is_array(Type* tyoe);
 b32 type_is_struct(Type* type);
 b32 type_is_bool(Type* type);
diff --git a/onyx b/onyx
index 1d3ffad0b2d7fcb3ba9294343118b8a8df8058f3..301d6b49f82c296dcde8f67fb7b90fe4a27bc3cb 100755 (executable)
Binary files a/onyx and b/onyx differ
index b0ac4c35b1880bb0458ff7586ee0860ccacdeb14..d3801d6cc90ffbdcd6da69644eb9a0a49da1b5f6 100644 (file)
@@ -142,9 +142,22 @@ start :: proc #export {
 
     stupid_idea(1234)() |> print();
 
-    v : [5] Vec3;
-    v[2].x = 4;
-    v[2].y = 5;
-    v[2].z = 6;
-    mag_squared(v[2]) |> print();
+    varr : [5] Vec3;
+    varr[2].x = 4;
+    varr[2].y = 5;
+    varr[2].z = 6;
+    mag_squared(varr[2]) |> print();
+
+    v1 : Vec3;
+    v1.x = 1;
+    v1.y = 2;
+    v1.z = 4;
+
+    v2 := ^v1;
+
+    v3 : Vec3;
+    vec_add(v1, *v2, ^v3);
+    print(v3.x);
+    print(v3.y);
+    print(v3.z);
 }
\ No newline at end of file
index a19999476b946d7f2f20a8e3d872f184b1711f65..c0b50b8d96611dc8ccc0b12688d465694f115496 100644 (file)
@@ -428,6 +428,20 @@ CHECK(binaryop_compare, AstBinaryOp** pbinop) {
         return 1;
     }
 
+    if (binop->left->type->kind == Type_Kind_Struct) {
+        onyx_message_add(Msg_Type_Literal,
+                binop->token->pos,
+                "invalid type for left side of binary operator");
+        return 1;
+    }
+
+    if (binop->right->type->kind == Type_Kind_Struct) {
+        onyx_message_add(Msg_Type_Literal,
+                binop->token->pos,
+                "invalid type for right side of binary operator");
+        return 1;
+    }
+
     if (!types_are_compatible(binop->left->type, binop->right->type)) {
         onyx_message_add(Msg_Type_Binop_Mismatch,
                 binop->token->pos,
index a70fc5f48c3f089a72fcca6ed87dd4c4315c18f4..34f6c5ee95e9d18d1d96c3352452f5d1c2771e67 100644 (file)
@@ -450,6 +450,10 @@ b32 type_is_pointer(Type* type) {
         || (type->kind == Type_Kind_Array);
 }
 
+b32 type_is_rawptr(Type* type) {
+    return type->kind == Type_Kind_Basic && type->Basic.kind == Basic_Kind_Rawptr;
+}
+
 b32 type_is_array(Type* type) {
     return type->kind == Type_Kind_Array;
 }
index 3d3e9074e94570ba140b09274b26dc3eb6fbeea7..34f0d74cdba3b5af153ccf3cc1934c13a27770a6 100644 (file)
@@ -277,6 +277,19 @@ static u64 local_raw_allocate(LocalAllocator* la, WasmType wt) {
     }
 }
 
+static void local_raw_free(LocalAllocator* la, WasmType wt) {
+    i32 idx = 0;
+
+    if (wt == WASM_TYPE_INT32)   idx = 0;
+    if (wt == WASM_TYPE_INT64)   idx = 1;
+    if (wt == WASM_TYPE_FLOAT32) idx = 2;
+    if (wt == WASM_TYPE_FLOAT64) idx = 3;
+
+    assert(la->allocated[idx] > 0 && la->freed[idx] < la->allocated[idx]);
+
+    la->freed[idx]++;
+}
+
 static u64 local_allocate(LocalAllocator* la, AstLocal* local) {
     if (local_is_wasm_local(local)) {
         WasmType wt = onyx_type_to_wasm_type(local->type);
@@ -301,17 +314,8 @@ static u64 local_allocate(LocalAllocator* la, AstLocal* local) {
 
 static void local_free(LocalAllocator* la, AstLocal* local) {
     if (local_is_wasm_local(local)) {
-        i32 idx = 0;
-
         WasmType wt = onyx_type_to_wasm_type(local->type);
-        if (wt == WASM_TYPE_INT32)   idx = 0;
-        if (wt == WASM_TYPE_INT64)   idx = 1;
-        if (wt == WASM_TYPE_FLOAT32) idx = 2;
-        if (wt == WASM_TYPE_FLOAT64) idx = 3;
-
-        assert(la->allocated[idx] > 0 && la->freed[idx] < la->allocated[idx]);
-
-        la->freed[idx]++;
+        local_raw_free(la, wt);
 
     } else {
         u32 size = type_size_of(local->type);
@@ -357,6 +361,8 @@ COMPILE_FUNC(intrinsic_call,        AstIntrinsicCall* call);
 COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return);
 COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return);
 COMPILE_FUNC(local_location,        AstLocal* local, u64* offset_return);
+COMPILE_FUNC(struct_load,           AstTyped* expr);
+COMPILE_FUNC(struct_store,          AstTyped* lval);
 COMPILE_FUNC(expression,            AstTyped* expr);
 COMPILE_FUNC(cast,                  AstUnaryOp* cast);
 COMPILE_FUNC(return,                AstReturn* ret);
@@ -457,6 +463,14 @@ COMPILE_FUNC(statement, AstNode* stmt) {
 COMPILE_FUNC(assignment, AstBinaryOp* assign) {
     bh_arr(WasmInstruction) code = *pcode;
 
+    if (assign->right->type->kind == Type_Kind_Struct) {
+        compile_expression(mod, &code, assign->right);
+        compile_struct_store(mod, &code, assign->left);
+
+        *pcode = code;
+        return;
+    }
+
     AstTyped* lval = assign->left;
 
     if (lval->kind == Ast_Kind_Local) {
@@ -512,6 +526,8 @@ COMPILE_FUNC(assignment, AstBinaryOp* assign) {
 COMPILE_FUNC(store_instruction, Type* type, u32 offset) {
     bh_arr(WasmInstruction) code = *pcode;
 
+    assert(("Should use compile_struct_store instead", type->kind != Type_Kind_Struct));
+
     u32 alignment = type_get_alignment_log2(type);
 
     if (type->kind == Type_Kind_Enum) {
@@ -1110,6 +1126,39 @@ COMPILE_FUNC(struct_load, AstTyped* expr) {
     *pcode = code;
 }
 
+COMPILE_FUNC(struct_store, AstTyped* lval) {
+    bh_arr(WasmInstruction) code = *pcode;
+
+    assert(lval->type->kind == Type_Kind_Struct);
+
+    u64 offset = 0;
+
+    bh_arr_rev_each(StructMember *, smem, lval->type->Struct.memarr) {
+        offset = 0;
+
+        WasmType wt = onyx_type_to_wasm_type((*smem)->type);
+        u64 localidx = local_raw_allocate(mod->local_alloc, wt);
+
+        WIL(WI_LOCAL_SET, localidx);
+
+        switch (lval->kind) {
+            case Ast_Kind_Local: compile_local_location(mod, &code, (AstLocal *) lval, &offset); break;
+            case Ast_Kind_Dereference: compile_expression(mod, &code, ((AstDereference *) lval)->expr); break;
+            case Ast_Kind_Array_Access: compile_array_access_location(mod, &code, (AstArrayAccess *) lval, &offset); break;
+            case Ast_Kind_Field_Access: compile_field_access_location(mod, &code, (AstFieldAccess *) lval, &offset); break;
+
+            default: assert(0);
+        }
+        WIL(WI_LOCAL_GET, localidx);
+
+        compile_store_instruction(mod, &code, (*smem)->type, offset + (*smem)->offset);
+
+        local_raw_free(mod->local_alloc, wt);
+    }
+
+    *pcode = code;
+}
+
 COMPILE_FUNC(expression, AstTyped* expr) {
     bh_arr(WasmInstruction) code = *pcode;