bugfix: numerous symbol related core library bugs
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 3 Apr 2023 02:44:42 +0000 (21:44 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 3 Apr 2023 02:44:42 +0000 (21:44 -0500)
core/alloc/alloc.onyx
core/alloc/gc.onyx
core/builtin.onyx
core/container/array.onyx
core/container/map.onyx
core/container/set.onyx
core/misc/method_ops.onyx

index f08b305878d49081e01136f19c6382c8032d6c50..e6147409acda56ed92fcbc8487e70ec9ad6adb31 100644 (file)
@@ -45,6 +45,8 @@ array_from_stack :: macro ($T: type_expr, size: u32) -> [] T {
         }
 """
 on_heap :: macro (v: $V) -> &V {
+    use core
+
     out := cast(&V) raw_alloc(context.allocator, sizeof V);
     core.memory.set(out, 0, sizeof V);
     *out = v;
@@ -55,6 +57,8 @@ on_heap :: macro (v: $V) -> &V {
     Like `alloc.on_heap`, but allocates on the temporary allocator.
 """
 on_temp :: macro (v: $V) -> &V {
+    use core
+
     out := cast(&V) raw_alloc(context.temp_allocator, sizeof V);
     core.memory.set(out, 0, sizeof V);
     *out = v;
index 293222b8755a8205beed9cc44964a497c2659053..01ad229f5e93b41016c2b744ad504686a39fc7e9 100644 (file)
@@ -16,7 +16,7 @@ package core.alloc.gc
 //       // Every allocation here will automatically be freed
 //   }
 
-use core
+use core {package, *}
 
 GCState :: struct {
     backing_allocator: Allocator;
@@ -60,11 +60,11 @@ make_allocator :: (hs: &GCState) -> Allocator {
 
 auto :: #match {
     macro () {
-        use core.alloc {gc}
+        use core.alloc {package, gc}
         
         gcs := gc.make();
         old_allocator := context.allocator;
-        context.allocator = core.alloc.as_allocator(&gcs);
+        context.allocator = alloc.as_allocator(&gcs);
         defer {
             gc.clear(&gcs);
             context.allocator = old_allocator;
index 0b90dcd1c672794dc2adacfb7d18fe78c93fea3f..abe73849a07e254001ae16f5d867fee7a8bf6f7a 100644 (file)
@@ -448,23 +448,6 @@ any :: struct {
 Code :: struct {_:i32;}
 
 
-#doc """
-    Define aliases for common datastructures in the core library, if the core library is available.
-    I'm on the fence about keeping this, as the programmer may want to use these names for their own
-    structures, but for the moment I don't see any harm. I'm also thinking about removing the '[..]'
-    syntax for dynamic arrays and just make them like Map's and Set's, i.e. Array(T). This would
-    remove some confusion around the 3 different array types as dynamic arrays would clearly just be
-    normal structures. With the recent addition of macros and iterators, there really wouldn't be much
-    difference anyway.
-"""
-#if #defined(core.map.Map) {
-    Map :: core.map.Map;
-}
-
-#if #defined(core.set.Set) {
-    Set :: core.set.Set;
-}
-
 
 #doc """
     This procedure is a special compiler generated procedure that initializes all the data segments
index fd19385b0f2775a71bc06a21053d7a5433b99902..1613b5f5b59ae54a935c0a9862e951e4c8bc334f 100644 (file)
@@ -14,8 +14,16 @@ use core
 // ---------------------------------
 //           Dynamic Arrays
 // ---------------------------------
+
+#doc """
+    Creates a new dynamic array.
+"""
 make :: #match #local {}
 
+#doc """
+    Creates a dynamic array of type `T` with an initial capacity of `capacity`,
+    from the `allocator`.
+"""
 #overload
 make :: ($T: type_expr, capacity := 4, allocator := context.allocator) -> [..] T {
     arr : [..] T;
@@ -23,6 +31,9 @@ make :: ($T: type_expr, capacity := 4, allocator := context.allocator) -> [..] T
     return arr;
 }
 
+#doc """
+    Creates a new dynamic array as a *copy* of the provided array.
+"""
 #overload
 make :: (base: [] $T, allocator := context.allocator) -> [..] T {
     arr: [..] T;
@@ -41,6 +52,7 @@ __make_overload :: macro (_: &[..] $T, capacity: u32, allocator := context.alloc
     return #this_package.make(T, capacity, allocator);
 }
 
+#doc "Initializes a dynamic array."
 init :: (arr: &[..] $T, capacity := 4, allocator := context.allocator) {
     arr.count = 0;
     arr.capacity = capacity;
@@ -48,6 +60,7 @@ init :: (arr: &[..] $T, capacity := 4, allocator := context.allocator) {
     arr.data = raw_alloc(allocator, sizeof T * arr.capacity);
 }
 
+#doc "Frees a dynamic array."
 free :: (arr: &[..] $T) {
     arr.count = 0;
     arr.capacity = 0;
@@ -78,6 +91,13 @@ copy :: #match #locked {
     }
 }
 
+#doc """
+    Copies a sub-array of a dynamic-array.
+
+        arr := array.make(.[ 2, 3, 5, 7, 11 ]);
+        sub := array.copy_range(&arr, 2 .. 5);
+        println(sub); // 5, 7, 11
+"""
 copy_range :: (arr: &[..] $T, r: range, allocator := context.allocator) -> [..] T {
     new_arr : [..] T;
     init(&new_arr, r.high - r.low, allocator);
@@ -87,10 +107,20 @@ copy_range :: (arr: &[..] $T, r: range, allocator := context.allocator) -> [..]
     return new_arr;
 }
 
+#doc """
+    Clears a dynamic array.
+
+    Note: This does not clear or free the memory for the dynamic array.
+"""
 clear :: (arr: &[..] $T) {
     arr.count = 0;
 }
 
+#doc """
+    Resizes a dynamic array if it does not have enough capacity.
+
+    If this procedure returns `true`, `arr.capacity` will be greater than or equal to `capacity`.
+"""
 ensure_capacity :: (arr: &[..] $T, capacity: u32) -> bool {
     if arr.capacity >= capacity do return true;
     if arr.data == null do init(arr);
@@ -102,12 +132,18 @@ ensure_capacity :: (arr: &[..] $T, capacity: u32) -> bool {
     return true;
 }
 
+#doc """
+    Appends a zeroed-element to the end of the array, and returns a pointer to it.
+"""
 alloc_one :: (arr: &[..] $T) -> &T {
     if !ensure_capacity(arr, arr.count + 1) do return null;
     arr.count += 1;
     return &arr.data[arr.count - 1];
 }
 
+#doc """
+    Appends `x` to the end of the array.
+"""
 push :: (arr: &[..] $T, x: T) -> bool {
     if !ensure_capacity(arr, arr.count + 1) do return false;
     arr.data[arr.count] = x;
@@ -118,6 +154,12 @@ push :: (arr: &[..] $T, x: T) -> bool {
 // Semi-useful shortcut for adding something to an array.
 #operator << macro (arr: [..] $T, v: T) do #this_package.push(&arr, v);
 
+
+#doc """
+    Inserts element(s) into the middle of the array at `idx`.
+
+    If `idx >= arr.count`, nothing happens.
+"""
 insert :: #match #local {}
 
 #overload
@@ -152,7 +194,11 @@ insert :: (arr: &[..] $T, idx: u32, new_arr: [] T) -> bool {
     return true;
 }
 
+#doc """
+    Inserts a zeroed-element at `idx`.
+"""
 insert_empty :: (arr: &[..] $T, idx: u32) -> bool {
+    if idx >= arr.count do return false;
     if !ensure_capacity(arr, arr.count + 1) do return false;
 
     arr.count += 1;
@@ -164,6 +210,11 @@ insert_empty :: (arr: &[..] $T, idx: u32) -> bool {
     return true;
 }
 
+#doc """
+    Removes all instances of `elem` from the array.
+
+    Uses `==` to test for equality.
+"""
 remove :: (arr: &[..] $T, elem: T) {
     move := 0;
 
@@ -177,6 +228,11 @@ remove :: (arr: &[..] $T, elem: T) {
     arr.count -= move;
 }
 
+#doc """
+    Removes the element at index `idx` from the array and returns it.
+
+    Maintains order of the array.
+"""
 delete :: (arr: &[..] $T, idx: u32) -> T {
     if idx >= arr.count do return .{};
 
@@ -189,6 +245,11 @@ delete :: (arr: &[..] $T, idx: u32) -> T {
     return to_return;
 }
 
+#doc """
+    Removes the element at index `idx` from the array and returns it.
+
+    Order is not guaranteed to be preserved.
+"""
 fast_delete :: (arr: &[..] $T, idx: u32) -> T {
     if idx >= arr.count do return .{};
 
@@ -199,6 +260,11 @@ fast_delete :: (arr: &[..] $T, idx: u32) -> T {
     return to_return;
 }
 
+#doc """
+    Removes `n` elements from the end of the array.
+
+    `n` by default is 1.
+"""
 pop :: (arr: &[..] $T, n := 1) -> T {
     if arr.count == 0 do return .{};
 
@@ -207,6 +273,10 @@ pop :: (arr: &[..] $T, n := 1) -> T {
     return arr.data[arr.count];
 }
 
+
+#doc """
+    Appends elements from another array or iterator to the end of the array.
+"""
 concat :: #match #local {}
 
 #overload
@@ -224,6 +294,15 @@ concat :: (arr: &[..] $T, other: Iterator(T)) {
     }
 }
 
+#doc """
+    Removes all elements for which the given predicate does not hold.
+
+    Use `it` to refer to the current element being tested.
+
+        arr := array.make(.[ 1, 2, 3, 4, 5 ]);
+        array.filter(&arr, #(it % 2 == 0));
+        println(arr); // 2, 4
+"""
 filter :: macro (arr: &[..] $T, body: Code) {
     move := 0;
 
index 9edcaa308a1caa59af5729517279a1d28d94415d..afaece43de27857289661ce00642782ed387f378 100644 (file)
@@ -58,6 +58,10 @@ Map :: struct (Key_Type: type_expr, Value_Type: type_expr) where ValidKey(Key_Ty
     as_iter :: as_iter
 }
 
+#inject builtin {
+    Map :: Map;
+}
+
 
 #doc """
    Allows for creation of a Map using make().
index 71f41fc832c624f97a3002afc319ce69564a39d1..942ddd5795b7c197b0083c444cb46951fd9d289d 100644 (file)
@@ -42,6 +42,10 @@ Set :: struct (Elem_Type: type_expr) where SetValue(Elem_Type) {
     as_iter  :: as_iter
 }
 
+#inject builtin {
+    Set :: Set;
+}
+
 make :: ($T: type_expr, default := T.{}, allocator := context.allocator) -> Set(T) {
     set : Set(T);
     init(&set, default=default, allocator=allocator);
index 1e347dec8bf8adeb0a87b3c30ba549a2e9b2e80d..48e2fd53f9028f9bd9d554dddc7e93aec53e0546 100644 (file)
@@ -1,5 +1,7 @@
 package core
 
+use runtime
+
 //
 // This file defines an optional language feature called method operators.
 // Instead of defining an operator overload using the #operator directive,