added some more array functionality
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 16 Apr 2021 03:10:17 +0000 (22:10 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 16 Apr 2021 03:10:17 +0000 (22:10 -0500)
core/array.onyx
examples/17_operator_overload.onyx [new file with mode: 0644]

index da19673215bb181e311b14906d3938f0b5245562..20f5ac38ea21fe5907f0d223734eeebbf87d76b2 100644 (file)
@@ -127,16 +127,39 @@ fast_delete :: (arr: ^[..] $T, idx: u32) {
     arr.count -= 1;
 }
 
-contains :: (arr: ^[..] $T, x: T) -> bool {
-    for it: *arr do if it == x do return true;
-    return false;
-}
-
 pop :: (arr: ^[..] $T) -> T {
     arr.count -= 1;
     return arr.data[arr.count];
 }
 
+// Uses '==' to compare for equality.
+contains :: proc {
+    (arr: ^[..] $T, x: T) -> bool {
+        for it: *arr do if it == x do return true;
+        return false;
+    },
+
+    (arr: [] $T, x: T) -> bool {
+        for it: arr do if it == x do return true;
+        return false;
+    }
+}
+
+// Uses '+' to sum.
+sum :: proc {
+    (arr: ^[..] $T, start: T = 0) -> T {
+        sum := start;
+        for it: *arr do sum += it;
+        return sum;
+    },
+
+    (arr: [] $T, start: T = 0) -> T {
+        sum := start;
+        for it: arr do sum += it;
+        return sum;
+    }
+}
+
 average :: (arr: ^[..] $T) -> T {
     sum := cast(T) 0;
     for it: *arr do sum += it;
@@ -181,17 +204,12 @@ fold :: proc {
 }
 
 map :: proc {
-    (arr: ^[..] $T, f: (T) -> T) {
-        for ^it: *arr do *it = f(*it);
-    },
-
-    (arr: ^[..] $T, f: (^T) -> void) {
-        for ^it: *arr do f(it);
-    },
-
-    (arr: ^[..] $T, data: $R, f: (T, R) -> T) {
-        for ^it: *arr do *it = f(*it, data);
-    },
+    (arr: ^[..] $T, f: (^T) -> void)          do for ^it: *arr do f(it);,
+    (arr: ^[..] $T, f: (T) -> T)              do for ^it: *arr do *it = f(*it);,
+    (arr: ^[..] $T, data: $R, f: (T, R) -> T) do for ^it: *arr do *it = f(*it, data);,
+    (arr: [] $T, f: (^T) -> void)             do for ^it:  arr do f(it);,
+    (arr: [] $T, f: (T) -> T)                 do for ^it:  arr do *it = f(*it);,
+    (arr: [] $T, data: $R, f: (T, R) -> T)    do for ^it:  arr do *it = f(*it, data);,
 }
 
 #private_file
diff --git a/examples/17_operator_overload.onyx b/examples/17_operator_overload.onyx
new file mode 100644 (file)
index 0000000..49f5e30
--- /dev/null
@@ -0,0 +1,44 @@
+#load "core/std"
+use package core
+
+// Operator overloading allows you to define what it means to perform
+// a binary operation between two types. In Onyx, they are defined in
+// the following way:
+//
+// #operator <op> <overload>
+//
+// where <op> is the binary operator, and <overload> is an expression
+// that should be a procedure that will be used for the overload.
+//
+
+// Take this example. Note, DO NOT actually use this exact implementation
+// because it leaks memory all over the place. Especially because with
+// a binary operator, you cannot pass a custom allocator.
+
+#operator + (x: str, y: str) -> str {
+    return string.concat(x, y); 
+}
+
+main :: (args: [] cstr) {
+    // Now we can say "+" between two strings. Also, we can use it
+    // to give us access to more features like array.sum which adds
+    // everything in the array together using the '+' operator.
+    // Since '+' is concatenate, array.sum will join all the strings
+    // into one, in one of the most inefficient ways possible.
+
+    test := "Hello, " + "World!";
+    println(test);
+
+    strings := str.[ "This ", "is ", "a ", "test." ];
+    result  := array.sum(cast([] str) strings, start="");
+    println(result);
+
+    // As a side note, '==' is already overloaded for strings in the
+    // standard library, so you can do this:
+    
+    if array.contains(cast([] str) strings, "is ") {
+        println("The array contains 'is '.");
+    } else {
+        println("The array does NOT contain 'is '.");
+    }
+}