updated examples; type creation bugfix
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 5 Aug 2021 03:24:37 +0000 (22:24 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 5 Aug 2021 03:24:37 +0000 (22:24 -0500)
bin/onyx
examples/05_slices.onyx
examples/07_structs.onyx
examples/09_for_loops.onyx
examples/11_map.onyx
src/onyxparser.c
src/onyxtypes.c
src/onyxutils.c

index e51b1df8f55dba6658cf25ac742e7f846caf8787..8ce676ff2e15c3b515b8dac99265da83c2afdff1 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index d9046a39ec6e574fba2d4de277b4ef51939c674a..1cc792ade6a3e54464dc68ee27f16766504f116f 100644 (file)
@@ -23,7 +23,7 @@ main :: (args: [] cstr) {
     slice.count = 4;
 
     // You can iterate over slices directly using a for-loop.
-    for elem: slice do printf("%i ", elem);
+    for elem: slice do printf("{} ", elem);
     print("\n");
 
     // Another equivalent way of writing lines 22 and 23 is to
@@ -33,7 +33,7 @@ main :: (args: [] cstr) {
     slice = arr[3 .. 7];
 
     // Printing it out to verify it is the same.
-    for elem: slice do printf("%i ", elem);
+    for elem: slice do printf("{} ", elem);
     print("\n");
 
     // Since strings are represented as slices in Onyx, substrings
index 0d1acc55c1cbdb0124ce4e701d57f5adea4b9e4a..4cf1593defbc346808124f74ed7ab01d4c2caff8 100644 (file)
@@ -21,7 +21,10 @@ main :: (args: [] cstr) {
 
     // Structs can be passed by value to procedures.
     print_person :: (person: Person) {
-        printf("Person(%s, %i, %i)\n", person.name, person.age, person.height);
+        printf("Person({}, {}, {})\n", person.name, person.age, person.height);
+
+        // Structs can also be printed using a single '{}' in printf.
+        printf("{}\n", person);
     }
 
     // This is the verbose way to declare a local variable with a struct
@@ -60,7 +63,7 @@ main :: (args: [] cstr) {
     }
 
     print_vector2f :: (vec: Vector2f) {
-        printf("Vector2f(%f, %f)", vec.x, vec.y);
+        printf("{}", vec);
     }
 
     // This does initialize the members to their defaults.
@@ -81,7 +84,7 @@ main :: (args: [] cstr) {
 
     fiu : FloatIntUnion;
     fiu.f = 0.5f;
-    printf("Integer representation of 0.5: %p\n", fiu.i);
+    printf("Integer representation of 0.5: {}\n", fiu.i);
 
 
 
@@ -121,14 +124,14 @@ main :: (args: [] cstr) {
         another_data_member = 1234,
     };
 
-    printf("%s, (%f, %f)\n", thing.name, thing.velocity.x, thing.velocity.y);
+    printf("{}, ({}, {})\n", thing.name, thing.velocity.x, thing.velocity.y);
 
     // This is very useful in many different situtations. Another useful feature is an implicit
     // pointer conversion between two structs, A and B, if A is the first member of B, and is used.
     // For example, we can pass `thing` to this procedure, even though it is not a ComponentOne.
     // The first member is a ComponentOne and is used, so a implicit pointer conversion is always safe.
     do_something_with_component_one :: (c: ^ComponentOne) {
-        printf("ComponentOne's name is %s.\n", c.name);
+        printf("ComponentOne's name is {}.\n", c.name);
     }
 
     do_something_with_component_one(^thing);
@@ -155,7 +158,7 @@ main :: (args: [] cstr) {
 
     println("param_struct_instance values:");
     println(param_struct_instance.t_member);
-    for elem: param_struct_instance.array_of_T do printf("%f ", elem);
+    for elem: param_struct_instance.array_of_T do printf("{} ", elem);
     print("\n");
 
 
index 28560ac64a72a92c9f455643f62a620645c73823..efa0ce65ba28340c58cbfe6fa543df8abdb03cb5 100644 (file)
@@ -9,11 +9,12 @@
 use package core
 
 main :: (args: [] cstr) {
-    // Currently, for loops can iterate over four kinds of data structures in Onyx:
+    // Currently, for loops can iterate over five kinds of data structures in Onyx:
     //      * Ranges
     //      * Fixed arrays
     //      * Slices
     //      * Dynamic arrays
+    //      * Custom iterators
 
     // The syntax of for loops is very simple:
     // for ^? <iteration variable>: <iterator> <block>
@@ -40,11 +41,37 @@ main :: (args: [] cstr) {
     print("Doubled primes: ");
     print_array(primes);
 
-    // Currently, there is not support for defining custom iterators for for-loops.
-    // At the moment, this pattern is the best for that purpose:
+    // There is also support for custom iterators using the built-in Iterator type.
+    // You have to specify a next, close, and data member. The semantics are roughly
+    // as follows:
     //
-    //  while it := iterator_create(...); !iterator_done(^it) {
-    //      defer iterator_next(^it);
-    //      ...
-    //  }
+    //     1. next is called to get two values: the next iteration value, and a
+    //        continuation flag. If the continuation flag is true, then the iteration
+    //        will continue for another iteration. If the continuation flag is false
+    //        the iteration immediately terminates and the iteration value will be
+    //        ignored.
+    //
+    //     2. close is called whenever the for-loop exits in any manner (finished,
+    //        break, return).
+
+    {
+        value: i32 = 10;
+
+        //       This is pointer provided to the iterator structure.
+        next :: (v: ^i32) -> (i32, bool) {
+            defer *v -= 1;
+            return *v, *v >= 0;
+        }
+
+        close :: (v: ^i32) {
+            println("Closing the iterator.");
+        }
+
+        iterator: Iterator(i32) = .{ data = ^value, next = next, close = close };
+
+        // Simply use the iterator.
+        for v: iterator {
+            println(v);
+        }
+    }
 }
index e84676691662f8194ff05519fee5b1fc664357fa..94e9d984b4ac0a8b554fcb8450c88ca3ce24fc09 100644 (file)
@@ -31,7 +31,7 @@ main ::  (args: [] cstr) {
     // To retrieve an entry's value, use the map.get procedure.
     print_age :: (ages: ^map.Map(str, u32), name: str) {
         age := map.get(ages, name);
-        printf("%s's age is %i.\n", name, age);
+        printf("{}'s age is {}.\n", name, age);
     }
 
     print_age(^ages, "Dwight");
index 2ae6c8d48b4d1a97e987e434f9b0fac8d6e2bade..0b796c01edebd9a85f268d248f106034a3bd4f55 100644 (file)
@@ -605,8 +605,8 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                 retval = (AstTyped *) defined;
                 break;
             }
-            else if (next_tokens_are(parser, 2, '#', '{')) {
-                OnyxToken* code_token = expect_token(parser, '#');
+            else if (parse_possible_directive(parser, "code")) {
+                OnyxToken* code_token = parser->curr - 1;
                 // expect_token(parser, '{');
 
                 AstCodeBlock* code_block = make_node(AstCodeBlock, Ast_Kind_Code_Block);
index edd1c6095cff9eae4f73b5955c6a00e81903b767..70098f3f5a855611f975dcebf9df752c4ea0914d 100644 (file)
@@ -44,6 +44,13 @@ static bh_imap type_slice_map;
 static bh_imap type_dynarr_map;
 static bh_imap type_vararg_map;
 
+static Type* type_create(TypeKind kind, bh_allocator a, u32 extra_type_pointer_count) {
+    Type* type = bh_alloc(a, sizeof(Type) + sizeof(Type *) * extra_type_pointer_count);
+    type->kind = kind;
+    type->ast_type = NULL;
+    return type;
+}
+
 static void type_register(Type* type) {
     static u32 next_unique_id = 1;
     type->id = next_unique_id++;
@@ -240,9 +247,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             Type* return_type = type_build_from_ast(alloc, ftype_node->return_type);
             if (return_type == NULL) return NULL;
 
-            Type* func_type = bh_alloc(alloc, sizeof(Type) + sizeof(Type *) * param_count);
-
-            func_type->kind = Type_Kind_Function;
+            Type* func_type = type_create(Type_Kind_Function, alloc, param_count);
             func_type->ast_type = type_node;
             func_type->Function.param_count = param_count;
             func_type->Function.needed_param_count = param_count;
@@ -264,9 +269,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
         case Ast_Kind_Array_Type: {
             AstArrayType* a_node = (AstArrayType *) type_node;
 
-            Type* a_type = bh_alloc(alloc, sizeof(Type));
-            a_type->kind = Type_Kind_Array;
-            a_type->ast_type = type_node;
+            Type* a_type = type_create(Type_Kind_Array, alloc, 0);
             a_type->Array.elem = type_build_from_ast(alloc, a_node->elem);
 
             u32 count = 0;
@@ -304,10 +307,9 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
 
             Type* s_type;
             if (s_node->stcache == NULL) {
-                s_type = bh_alloc(alloc, sizeof(Type));
+                s_type = type_create(Type_Kind_Struct, alloc, 0);
                 s_node->stcache = s_type;
 
-                s_type->kind = Type_Kind_Struct;
                 s_type->ast_type = type_node;
                 s_type->Struct.name = s_node->name;
                 s_type->Struct.mem_count = bh_arr_length(s_node->members);
@@ -433,10 +435,9 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             if (enum_node->etcache) return enum_node->etcache;
             if (enum_node->backing_type == NULL) return NULL;
 
-            Type* enum_type = bh_alloc(alloc, sizeof(Type));
+            Type* enum_type = type_create(Type_Kind_Enum, alloc, 0);
             enum_node->etcache = enum_type;
 
-            enum_type->kind = Type_Kind_Enum;
             enum_type->ast_type = type_node;
             enum_type->Enum.backing = enum_node->backing_type;
             enum_type->Enum.name = enum_node->name;
@@ -534,8 +535,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
 
             i64 type_count = bh_arr_length(ctype->types);
 
-            Type* comp_type = bh_alloc(alloc, sizeof(Type) + sizeof(Type *) * type_count);
-            comp_type->kind = Type_Kind_Compound;
+            Type* comp_type = type_create(Type_Kind_Compound, alloc, type_count);
             comp_type->Compound.size = 0;
             comp_type->Compound.count = type_count;
 
@@ -575,9 +575,7 @@ Type* type_build_function_type(bh_allocator alloc, AstFunction* func) {
     Type* return_type = type_build_from_ast(alloc, func->return_type);
     if (return_type == NULL) return NULL;
 
-    Type* func_type = bh_alloc(alloc, sizeof(Type) + sizeof(Type *) * param_count);
-
-    func_type->kind = Type_Kind_Function;
+    Type* func_type = type_create(Type_Kind_Function, alloc, param_count);
     func_type->Function.param_count = param_count;
     func_type->Function.needed_param_count = 0;
     func_type->Function.vararg_arg_pos = -1;
@@ -606,8 +604,7 @@ Type* type_build_compound_type(bh_allocator alloc, AstCompound* compound) {
         if (compound->exprs[i]->type == NULL) return NULL;
     }
 
-    Type* comp_type = bh_alloc(alloc, sizeof(Type) + sizeof(Type *) * expr_count);
-    comp_type->kind = Type_Kind_Compound;
+    Type* comp_type = type_create(Type_Kind_Compound, alloc, expr_count);
     comp_type->Compound.size = 0;
     comp_type->Compound.count = expr_count;
 
@@ -637,9 +634,7 @@ Type* type_make_pointer(bh_allocator alloc, Type* to) {
         return ptr_type;
 
     } else {
-        Type* ptr_type = bh_alloc_item(alloc, Type);
-
-        ptr_type->kind = Type_Kind_Pointer;
+        Type* ptr_type = type_create(Type_Kind_Pointer, alloc, 0);
         ptr_type->Pointer.base.flags |= Basic_Flag_Pointer;
         ptr_type->Pointer.base.size = 8;
         ptr_type->Pointer.elem = to;
@@ -654,9 +649,7 @@ Type* type_make_pointer(bh_allocator alloc, Type* to) {
 Type* type_make_array(bh_allocator alloc, Type* to, u32 count) {
     if (to == NULL) return NULL;
 
-    Type* arr_type = bh_alloc_item(alloc, Type);
-
-    arr_type->kind = Type_Kind_Array;
+    Type* arr_type = type_create(Type_Kind_Array, alloc, 0);
     arr_type->Array.count = count;
     arr_type->Array.elem = to;
     arr_type->Array.size = count * type_size_of(to);
@@ -676,8 +669,7 @@ Type* type_make_slice(bh_allocator alloc, Type* of) {
         return slice_type;
 
     } else {
-        Type* slice_type = bh_alloc(alloc, sizeof(Type));
-        slice_type->kind = Type_Kind_Slice;
+        Type* slice_type = type_create(Type_Kind_Slice, alloc, 0);
         type_register(slice_type);
         bh_imap_put(&type_slice_map, of->id, slice_type->id);
 
@@ -697,8 +689,7 @@ Type* type_make_dynarray(bh_allocator alloc, Type* of) {
         return dynarr;
 
     } else {
-        Type* dynarr = bh_alloc(alloc, sizeof(Type));
-        dynarr->kind = Type_Kind_DynArray;
+        Type* dynarr = type_create(Type_Kind_DynArray, alloc, 0);
         type_register(dynarr);
         bh_imap_put(&type_dynarr_map, of->id, dynarr->id);
 
@@ -718,8 +709,7 @@ Type* type_make_varargs(bh_allocator alloc, Type* of) {
         return va_type;
 
     } else {
-        Type* va_type = bh_alloc(alloc, sizeof(Type));
-        va_type->kind = Type_Kind_VarArgs;
+        Type* va_type = type_create(Type_Kind_VarArgs, alloc, 0);
         type_register(va_type);
         bh_imap_put(&type_vararg_map, of->id, va_type->id);
 
index 64c5691c47311773f861db4bd2d1b04d33d9b73f..2fddfdb531f68ebfd6ea65f171fc12312900573c 100644 (file)
@@ -33,6 +33,7 @@ Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_al
 
         char* pac_name = bh_alloc_array(alloc, char, strlen(package_name) + 1);
         memcpy(pac_name, package_name, strlen(package_name) + 1);
+        pac_name[strlen(package_name)] = '\0';
 
         package->name = pac_name;
         package->scope = scope_create(alloc, parent_scope, (OnyxFilePos) { 0 });