From: Brendan Hansen Date: Thu, 21 Jan 2021 04:40:21 +0000 (-0600) Subject: for loops can iterate over integers as a shorthand for starting from 0 X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=b7f19c1215b1a6730e80ce1ea11bacdf0d58f41d;p=onyx.git for loops can iterate over integers as a shorthand for starting from 0 --- diff --git a/bin/onyx b/bin/onyx index 53b33bfd..273da230 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/memory.onyx b/core/memory.onyx index 6502d264..cfa5eb5b 100644 --- a/core/memory.onyx +++ b/core/memory.onyx @@ -11,14 +11,14 @@ set :: proc (start: rawptr, length: u32, value: u8) { for i: 0 .. length do s[i] = value; } -alloc_slice :: proc (sl: ^[] $T, count: i32) { - sl.data = calloc(sizeof T * count); +alloc_slice :: proc (sl: ^[] $T, count: i32, allocator := context.allocator) { + sl.data = raw_alloc(allocator, sizeof T * count); sl.count = count; } -make_slice :: proc ($T: type_expr, count: i32) -> [] T { +make_slice :: proc ($T: type_expr, count: i32, allocator := context.allocator) -> [] T { return <[] T>.{ - data = calloc(sizeof T * count), + data = raw_alloc(allocator, sizeof T * count), count = count }; } \ No newline at end of file diff --git a/examples/03_basics.onyx b/examples/03_basics.onyx index 0f5e5b49..6e709572 100644 --- a/examples/03_basics.onyx +++ b/examples/03_basics.onyx @@ -22,9 +22,10 @@ main :: proc (args: [] cstr) { // of these types in terms of other types. Let's look at some of those types. // A pointer in Onyx is written as ^. This is read as 'a pointer to a '. - // I will not type to explain what a pointer is here, but it is something to note - // that pointers in Onyx are only 4-bytes instead of 8-bytes, since Onyx's compile - // target is WASM32. + // I will not try to explain what a pointer is here, but something to note is that + // pointers in Onyx are 8-bytes in size, but only have their lower 4-bytes used, + // since Onyx's compile target is WASM32. This way, when WASM64 is standardized, + // pointer will not cause any issues when moving over code to 64-bit. // // Here foo is an i32. The unary prefix ^ operator takes the address of a value. // The type of foo_ptr is ^i32, or a pointer to an i32. Another example of a pointer diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index cd46af05..06664d9e 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1045,6 +1045,7 @@ char* get_function_name(AstFunction* func); AstNumLit* make_int_literal(bh_allocator a, i64 value); AstNumLit* make_float_literal(bh_allocator a, f64 value); +AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high); AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right); AstArgument* make_argument(bh_allocator a, AstTyped* value); AstFieldAccess* make_field_access(bh_allocator a, AstTyped* node, char* field); diff --git a/onyx.exe b/onyx.exe index 995887b0..9c28c097 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index ef1c3e06..479b4456 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -630,6 +630,14 @@ AstNumLit* make_float_literal(bh_allocator a, f64 d) { return num; } +AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high) { + AstRangeLiteral* rl = onyx_ast_node_new(a, sizeof(AstRangeLiteral), Ast_Kind_Range_Literal); + rl->type = builtin_range_type_type; + rl->low = low; + rl->high = high; + return rl; +} + AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right) { AstBinaryOp* binop_node = onyx_ast_node_new(a, sizeof(AstBinaryOp), Ast_Kind_Binary_Op); binop_node->left = left; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 6a06008a..51b6b7d2 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -148,17 +148,30 @@ CheckStatus check_while(AstIfWhile* whilenode) { CheckStatus check_for(AstFor* fornode) { CHECK(expression, &fornode->iter); - fornode->loop_type = For_Loop_Invalid; + resolve_expression_type(fornode->iter); Type* iter_type = fornode->iter->type; - b32 can_iterate = 0; - if (types_are_compatible(iter_type, builtin_range_type_type)) { + fornode->loop_type = For_Loop_Invalid; + if (types_are_compatible(iter_type, &basic_types[Basic_Kind_I32])) { if (fornode->by_pointer) { onyx_report_error(fornode->var->token->pos, "Cannot iterate by pointer over a range."); return Check_Error; } - can_iterate = 1; + AstNumLit* low_0 = make_int_literal(context.ast_alloc, 0); + AstRangeLiteral* rl = make_range_literal(context.ast_alloc, (AstTyped *) low_0, fornode->iter); + CHECK(range_literal, &rl); + fornode->iter = (AstTyped *) rl; + + fornode->var->type = builtin_range_type_type->Struct.memarr[0]->type; + fornode->var->flags |= Ast_Flag_Cannot_Take_Addr; + fornode->loop_type = For_Loop_Range; + } + else if (types_are_compatible(iter_type, builtin_range_type_type)) { + if (fornode->by_pointer) { + onyx_report_error(fornode->var->token->pos, "Cannot iterate by pointer over a range."); + return Check_Error; + } // NOTE: Blindly copy the first range member's type which will // be the low value. - brendanfh 2020/09/04 @@ -168,16 +181,12 @@ CheckStatus check_for(AstFor* fornode) { } else if (iter_type->kind == Type_Kind_Array) { - can_iterate = 1; - if (fornode->by_pointer) fornode->var->type = type_make_pointer(context.ast_alloc, iter_type->Array.elem); else fornode->var->type = iter_type->Array.elem; fornode->loop_type = For_Loop_Array; } else if (iter_type->kind == Type_Kind_Slice) { - can_iterate = 1; - if (fornode->by_pointer) fornode->var->type = iter_type->Slice.ptr_to_data; else fornode->var->type = iter_type->Slice.ptr_to_data->Pointer.elem; @@ -190,16 +199,12 @@ CheckStatus check_for(AstFor* fornode) { return Check_Error; } - can_iterate = 1; - fornode->var->type = iter_type->VarArgs.ptr_to_data->Pointer.elem; // NOTE: Slices are VarArgs are being treated the same here. fornode->loop_type = For_Loop_Slice; } else if (iter_type->kind == Type_Kind_DynArray) { - can_iterate = 1; - if (fornode->by_pointer) fornode->var->type = iter_type->DynArray.ptr_to_data; else fornode->var->type = iter_type->DynArray.ptr_to_data->Pointer.elem; @@ -209,7 +214,7 @@ CheckStatus check_for(AstFor* fornode) { if (fornode->by_pointer) fornode->var->flags |= Ast_Flag_Cannot_Take_Addr; - if (!can_iterate) { + if (fornode->loop_type == For_Loop_Invalid) { onyx_report_error(fornode->iter->token->pos, "Cannot iterate over a '%s'.", type_get_name(iter_type));