added 'using' struct members
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 8 Sep 2020 13:23:47 +0000 (08:23 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 8 Sep 2020 13:23:47 +0000 (08:23 -0500)
12 files changed:
.vimspector.json
core/stdio.onyx
core/string.onyx
docs/plan
include/onyxastnodes.h
onyx
progs/odin_example.onyx
progs/poly_test.onyx
src/onyxchecker.c
src/onyxparser.c
src/onyxsymres.c
src/onyxtypes.c

index 899b511c32ce13ca2eeb9c41aa3d9b9a230d0e77..bf221152ebc25a86b65cb47f8b5eb9d759a91372 100644 (file)
@@ -6,7 +6,7 @@
                 "type": "cppdbg",
                 "request": "launch",
                 "program": "${workspaceFolder}/onyx",
-                "args": ["-verbose", "progs/poly_test.onyx"],
+                "args": ["-verbose", "progs/odin_example.onyx"],
                 "stopAtEntry": true,
                 "cwd": "${workspaceFolder}",
                 "environment": [],
index 2c74f7a36929627e1d96465413280daf582b5545..3b84e9e79c7ae395ca168e0baee21b0d5bbb9239 100644 (file)
@@ -20,7 +20,7 @@ print_cstring :: proc (s: cstring) do string_builder_append(^print_buffer, s);
 print_i64     :: proc (n: i64, base := 10l) do string_builder_append(^print_buffer, n, base);
 print_i32     :: proc (n: i32, base := 10)  do string_builder_append(^print_buffer, cast(i64) n, cast(u64) base);
 print_bool    :: proc (b: bool) do string_builder_append(^print_buffer, b);
-print_ptr     :: proc (p: rawptr) do string_builder_append(^print_buffer, cast(i64) p, 16l);
+print_ptr     :: proc (p: ^void) do string_builder_append(^print_buffer, cast(i64) p, 16l);
 
 print_range :: proc (r: range, sep := " ") {
     for i: r {
index 6e073198c9107e09891702bda85cd678c6be9faf..405ede87214c53a5543bf9fd419944dfc6a10bc1 100644 (file)
@@ -77,7 +77,7 @@ string_substr :: proc (str: string, sub: string) -> string {
 }
 
 string_contains :: proc (str: string, c: u8) -> bool {
-    for i: 0 .. str.count do if str[i] == c do return true;
+    for ch: str do if ch == c do return true;
     return false;
 }
 
index 604acdcf40eec9d0ba0a35f11aac6faee3f55926..04eadb19412ecc9be696c974dd959172d81fff60 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -275,6 +275,7 @@ HOW:
         [ ] look into creating a source map
             - first-look looks really gross
             - whoever came up with the source map spec should be fired... why are people so afraid of binary files??
+            - DWARF looks like it might be easier, but it still doesn't look fun.
 
         [ ] convert to using an 'atom' like table
             - All identifier tokens are given a unique atom ptr, up to string equality.
index c0bda21051d8051c5a40860ffdcf6c0fb0509100..d58a3df7aa953f1b159d11866ed9429b2a8da2ab 100644 (file)
@@ -183,6 +183,8 @@ typedef enum AstFlags {
     Ast_Flag_Cannot_Take_Addr  = BH_BIT(19),
 
     Ast_Flag_Arg_Is_VarArg     = BH_BIT(20),
+
+    Ast_Flag_Struct_Mem_Used   = BH_BIT(21),
 } AstFlags;
 
 typedef enum UnaryOp {
@@ -666,6 +668,7 @@ static inline CallingConvention type_function_get_cc(Type* type) {
     if (type->kind != Type_Kind_Function) return CC_Undefined;
     if (type->Function.return_type->kind == Type_Kind_Struct) return CC_Return_Stack;
     if (type->Function.return_type->kind == Type_Kind_Slice) return CC_Return_Stack;
+    if (type->Function.return_type->kind == Type_Kind_DynArray) return CC_Return_Stack;
     return CC_Return_Wasm;
 }
 
diff --git a/onyx b/onyx
index 4f86f2c14aad708e0fc8c7dd3d15225d78378bf0..8338bfe5fdb70ee372bd3e6f7222d4c62cabe05b 100755 (executable)
Binary files a/onyx and b/onyx differ
index 24c29d1fa226c9db35d30a26ab0d5070733195f2..7fc7dbcd9361368af8640e79479f4ff4d94cd1ca 100644 (file)
@@ -2,7 +2,68 @@
 
 use package core
 
+
+Foo :: struct {
+    data1 : i32;
+    data2 : f32;
+}
+
+Bar :: struct {
+    use foo : Foo;
+    bar_data : string;
+    // bar_data2 : cstring;
+}
+
+// BUG: This should cause some kind of error since this should be
+// infinite in size, but it doesn't so... fix that.
+//                                      - brendanfh   2020/09/08
+// Link :: struct {
+//     data : i32;
+//     next : Link;
+// }
+
+
+// bar : Bar;
+// bar.data1 = 123;
+// bar.data2 = 524782.1f;
+
+// asdf :: proc (f: Foo) -> ...
+// asdf(bar.foo);
+
+print_foo :: proc (f: ^Foo) {
+    print("Foo: \n");
+    print(f.data1);
+    print("\n");
+    print(cast(i32) f.data2);
+    print("\n");
+}
+
+print_bar :: proc (bar: ^Bar) {
+    print(bar.data1);
+    print("\n");
+    print(cast(i32) bar.data2);
+    print("\n");
+    print(bar.bar_data);
+    print("\n");
+}
+
+make_bar :: proc -> Bar {
+    bar : Bar;
+    bar.data1 = 1234;
+    bar.data2 = 12.34f;
+    bar.bar_data = "This is a test";
+
+    return bar;
+}
+
 main :: proc (args: [] cstring) {
+    bar := make_bar();
+
+    print(sizeof Bar);
+    print("\n");
+    print_bar(^bar);
+    print_foo(^bar.foo);
+
     program := "+ + * s - /";
     accumulator := 0;
 
index eff90783e71414964d00da9443124892e22fbba7..fe7285681559071fd37950ca876626859cb4e253 100644 (file)
@@ -134,6 +134,10 @@ print_strings :: proc (ss: ..string) {
 }
 
 multi_max :: proc (nums: ..$T) -> T {
+    print("Got this many args: ");
+    print(nums.count);
+    print("\n");
+
     max := nums[0];
     for num: nums do if num > max do max = num;
     return max;
index 42781cd1cc824e2ae161a0bbcd48f2dc59c2a0e8..d8862bd0cbb6311074443949fa6883117b3c3d66 100644 (file)
@@ -584,7 +584,7 @@ b32 check_binop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) {
         if (check_binaryop(&binop_node, 0)) return 1;
     }
 
-    if (!types_are_compatible(binop->right->type, binop->right->type)) {
+    if (!types_are_compatible(binop->right->type, binop->left->type)) {
         onyx_report_error(binop->token->pos,
                 "Cannot assign value of type '%s' to a '%s'.",
                 type_get_name(binop->right->type),
@@ -819,8 +819,8 @@ b32 check_struct_literal(AstStructLiteral* sl) {
         onyx_report_error(sl->token->pos,
                 "'%s' expects %d values, given %d.",
                 type_get_name(sl->type),
-                bh_arr_length(sl->values),
-                mem_count);
+                mem_count,
+                bh_arr_length(sl->values));
         return 1;
     }
 
index 1bfd8aa2030c35eb6a0e834602e67a03680bdea6..67a9c17a5b0b3a90c19b06baef2756afc44b7851 100644 (file)
@@ -1359,6 +1359,11 @@ static AstStructType* parse_struct(OnyxParser* parser) {
 
         AstStructMember* mem = make_node(AstStructMember, Ast_Kind_Struct_Member);
 
+        if (parser->curr->type == Token_Type_Keyword_Use) {
+            consume_token(parser);
+            mem->flags |= Ast_Flag_Struct_Mem_Used;
+        }
+
         mem->token = expect_token(parser, Token_Type_Symbol);
         expect_token(parser, ':');
         mem->type_node = parse_type(parser);
index 55bdd862e5326ab153130293a68e62e736614933..987aab01e480f8d13dec4795ac0514674844dde2 100644 (file)
@@ -89,10 +89,27 @@ static AstType* symres_type(AstType* type) {
 
         s_node->flags |= Ast_Flag_Type_Is_Resolved;
 
-        bh_arr_each(AstStructMember *, member, s_node->members) {
-            (*member)->type_node = symres_type((*member)->type_node);
-            if ((*member)->initial_value != NULL) {
-                symres_expression(&(*member)->initial_value);
+        fori (i, 0, bh_arr_length(s_node->members)) {
+            AstStructMember *member = s_node->members[i];
+            member->type_node = symres_type(member->type_node);
+
+            if (member->flags & Ast_Flag_Struct_Mem_Used) {
+                if (member->type_node->kind != Ast_Kind_Struct_Type) {
+                    onyx_report_error(member->token->pos,
+                            "Can only 'use' members of struct type.");
+                }
+
+                AstStructType *used = (AstStructType *) member->type_node;
+
+                bh_arr_insertn(s_node->members, i, bh_arr_length(used->members));
+
+                fori (j, 0, bh_arr_length(used->members)) {
+                    s_node->members[i + j + 1] = used->members[j];
+                }
+            }
+
+            if (member->initial_value != NULL) {
+                symres_expression(&member->initial_value);
             }
         }
 
index 21908b522f1ac45ffff54a83b13fb70a06c62b12..0b4e0be63c96eef610b4afc0c69258652280780f 100644 (file)
@@ -139,6 +139,8 @@ b32 types_are_compatible(Type* t1, Type* t2) {
                 return types_are_compatible(t1->Pointer.elem, t2->Pointer.elem);
             }
 
+            if (t2->kind == Type_Kind_Basic && t2->Basic.kind == Basic_Kind_Rawptr) return 1;
+
             break;
         }
 
@@ -341,17 +343,24 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
                 token_toggle_end((*member)->token);
 
                 u32 type_size = type_size_of((*member)->type);
-                if (!is_union) offset += type_size;
-                if (!is_union)   size += type_size;
-                else             size =  bh_max(size, type_size);
+                if (((*member)->flags & Ast_Flag_Struct_Mem_Used) == 0) {
+                    if (!is_union) offset += type_size;
+                    if (!is_union) size += type_size;
+                    else           size =  bh_max(size, type_size);
 
-                idx++;
+                    idx++;
+                }
             }
 
             // NOTE: Need to do a second pass because the references to the
             // elements of the table may change if the internal arrays of the
             // table need to be resized.
+            s_type->Struct.mem_count = 0;
             bh_arr_each(AstStructMember *, member, s_node->members) {
+                if ((*member)->flags & Ast_Flag_Struct_Mem_Used) continue;
+
+                s_type->Struct.mem_count++;
+
                 token_toggle_end((*member)->token);
                 bh_arr_push(s_type->Struct.memarr, &bh_table_get(StructMember, s_type->Struct.members, (*member)->token->text));
                 token_toggle_end((*member)->token);
@@ -637,13 +646,15 @@ b32 type_struct_is_simple(Type* type) {
     if (type->kind != Type_Kind_Struct) return 0;
 
     b32 is_simple = 1;
-    bh_table_each_start(StructMember, type->Struct.members);
-        if (value.type->kind == Type_Kind_Struct
-            || value.type->kind == Type_Kind_Array) {
+    bh_arr_each(StructMember *, mem, type->Struct.memarr) {
+        if ((*mem)->type->kind == Type_Kind_Struct
+            || (*mem)->type->kind == Type_Kind_Array
+            || (*mem)->type->kind == Type_Kind_Slice
+            || (*mem)->type->kind == Type_Kind_DynArray) {
             is_simple = 0;
             break;
         }
-    bh_table_each_end;
+    }
 
     return is_simple;
 }