for loops can iterate over integers as a shorthand for starting from 0
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 21 Jan 2021 04:40:21 +0000 (22:40 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 21 Jan 2021 04:40:21 +0000 (22:40 -0600)
bin/onyx
core/memory.onyx
examples/03_basics.onyx
include/onyxastnodes.h
onyx.exe
src/onyxastnodes.c
src/onyxchecker.c

index 53b33bfd8278737cec253aea134b5cc1bde479ad..273da230c2535210567e80f0cc4f32db2135427d 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 6502d264b9fbbefd5aac59dc64ddf7800434748c..cfa5eb5b9a56187b20b759f4684b7d328f8cf267 100644 (file)
@@ -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
index 0f5e5b49c2356bb05dd6a45e293d02bfb89028c4..6e709572a9c1a871e79fc26e87ffe2120c4bc325 100644 (file)
@@ -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 ^<type>. This is read as 'a pointer to a <type>'.
-    // 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
index cd46af0544953f6d3251e9f47fbc090c253ed8eb..06664d9ecc8228c21fd28347823818a92bc7e9cd 100644 (file)
@@ -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);
index 995887b0b13e11caaf84ed15e0a372ea2e56769e..9c28c097f0b3fc68d380018add75cd4cd31b88e0 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index ef1c3e06bc3aaa501c1b333a93034fcfb8e2cdee..479b4456245e0564732d8e3917cb3f8281ea8bda 100644 (file)
@@ -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;
index 6a06008a25a418e74275f644370453dd0a568e0e..51b6b7d21907d6b5f0f098a8b745722f3388051b 100644 (file)
@@ -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));