From: Brendan Hansen Date: Thu, 5 Aug 2021 03:24:37 +0000 (-0500) Subject: updated examples; type creation bugfix X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3875e0aadc68284f8268216e1248f02d2e0629b2;p=onyx.git updated examples; type creation bugfix --- diff --git a/bin/onyx b/bin/onyx index e51b1df8..8ce676ff 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/examples/05_slices.onyx b/examples/05_slices.onyx index d9046a39..1cc792ad 100644 --- a/examples/05_slices.onyx +++ b/examples/05_slices.onyx @@ -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 diff --git a/examples/07_structs.onyx b/examples/07_structs.onyx index 0d1acc55..4cf1593d 100644 --- a/examples/07_structs.onyx +++ b/examples/07_structs.onyx @@ -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"); diff --git a/examples/09_for_loops.onyx b/examples/09_for_loops.onyx index 28560ac6..efa0ce65 100644 --- a/examples/09_for_loops.onyx +++ b/examples/09_for_loops.onyx @@ -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 ^? : @@ -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); + } + } } diff --git a/examples/11_map.onyx b/examples/11_map.onyx index e8467669..94e9d984 100644 --- a/examples/11_map.onyx +++ b/examples/11_map.onyx @@ -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"); diff --git a/src/onyxparser.c b/src/onyxparser.c index 2ae6c8d4..0b796c01 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -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); diff --git a/src/onyxtypes.c b/src/onyxtypes.c index edd1c609..70098f3f 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -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); diff --git a/src/onyxutils.c b/src/onyxutils.c index 64c5691c..2fddfdb5 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -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 });