From: Brendan Hansen Date: Thu, 13 Aug 2020 16:07:22 +0000 (-0500) Subject: things of struct type now work as lvalues X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=efa435e651a923f3268f9f1d41950d08a46a159f;p=onyx.git things of struct type now work as lvalues --- diff --git a/include/onyxtypes.h b/include/onyxtypes.h index ce7e9d0c..27cd1a9d 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -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 1d3ffad0..301d6b49 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx index b0ac4c35..d3801d6c 100644 --- a/progs/stack_based.onyx +++ b/progs/stack_based.onyx @@ -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 diff --git a/src/onyxchecker.c b/src/onyxchecker.c index a1999947..c0b50b8d 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -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, diff --git a/src/onyxtypes.c b/src/onyxtypes.c index a70fc5f4..34f6c5ee 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -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; } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 3d3e9074..34f0d74c 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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;