diff --git a/abra_wasm/abra_wasm.js b/abra_wasm/abra_wasm.js
index 71d9dc1..8e6d2dd 100644
--- a/abra_wasm/abra_wasm.js
+++ b/abra_wasm/abra_wasm.js
@@ -1,26 +1,6 @@
let wasm;
-const heap = new Array(32).fill(undefined);
-
-heap.push(undefined, null, true, false);
-
-function getObject(idx) { return heap[idx]; }
-
-let heap_next = heap.length;
-
-function dropObject(idx) {
- if (idx < 36) return;
- heap[idx] = heap_next;
- heap_next = idx;
-}
-
-function takeObject(idx) {
- const ret = getObject(idx);
- dropObject(idx);
- return ret;
-}
-
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
cachedTextDecoder.decode();
@@ -37,6 +17,12 @@ function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
+const heap = new Array(32).fill(undefined);
+
+heap.push(undefined, null, true, false);
+
+let heap_next = heap.length;
+
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
@@ -46,6 +32,20 @@ function addHeapObject(obj) {
return idx;
}
+function getObject(idx) { return heap[idx]; }
+
+function dropObject(idx) {
+ if (idx < 36) return;
+ heap[idx] = heap_next;
+ heap_next = idx;
+}
+
+function takeObject(idx) {
+ const ret = getObject(idx);
+ dropObject(idx);
+ return ret;
+}
+
function makeMutClosure(arg0, arg1, dtor, f) {
const state = { a: arg0, b: arg1, cnt: 1 };
const real = (...args) => {
@@ -213,6 +213,10 @@ async function init(input) {
}
const imports = {};
imports.wbg = {};
+ imports.wbg.__wbindgen_json_parse = function(arg0, arg1) {
+ var ret = JSON.parse(getStringFromWasm0(arg0, arg1));
+ return addHeapObject(ret);
+ };
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
@@ -223,10 +227,6 @@ async function init(input) {
imports.wbg.__wbg_log_022eb750364e566f = function(arg0, arg1) {
console.log(getStringFromWasm0(arg0, arg1));
};
- imports.wbg.__wbindgen_json_parse = function(arg0, arg1) {
- var ret = JSON.parse(getStringFromWasm0(arg0, arg1));
- return addHeapObject(ret);
- };
imports.wbg.__wbindgen_cb_drop = function(arg0) {
const obj = takeObject(arg0).original;
if (obj.cnt-- == 1) {
@@ -273,8 +273,8 @@ async function init(input) {
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
- imports.wbg.__wbindgen_closure_wrapper653 = function(arg0, arg1, arg2) {
- var ret = makeMutClosure(arg0, arg1, 187, __wbg_adapter_12);
+ imports.wbg.__wbindgen_closure_wrapper702 = function(arg0, arg1, arg2) {
+ var ret = makeMutClosure(arg0, arg1, 159, __wbg_adapter_12);
return addHeapObject(ret);
};
diff --git a/abra_wasm/abra_wasm_bg.wasm b/abra_wasm/abra_wasm_bg.wasm
index 667236b..13b803d 100644
Binary files a/abra_wasm/abra_wasm_bg.wasm and b/abra_wasm/abra_wasm_bg.wasm differ
diff --git a/public/abra_wasm/abra_wasm_bg.wasm b/public/abra_wasm/abra_wasm_bg.wasm
index 667236b..13b803d 100644
Binary files a/public/abra_wasm/abra_wasm_bg.wasm and b/public/abra_wasm/abra_wasm_bg.wasm differ
diff --git a/src/pages/Documentation.tsx b/src/pages/Documentation.tsx
index 74d29db..ee7ebd6 100644
--- a/src/pages/Documentation.tsx
+++ b/src/pages/Documentation.tsx
@@ -11,7 +11,7 @@ export default function DocumentationPage() {
Abra has all the literal types you'd expect: integer and floating-point numbers, booleans, strings, and - arrays. (Objects are not yet implemented!). + arrays.
{`
@@ -63,11 +63,6 @@ export default function DocumentationPage() {
favoriteColor = "purple" // This works just fine
`}
-
-
- // TODO: Variable declaration via destructuring is not yet implemented
-
There's another special type in Abra called the Option
type, which is denoted with the
question-mark (?
) suffix. This represents a value that may contain a value of that type,
@@ -108,10 +104,9 @@ export default function DocumentationPage() {
existed at such an index, and some languages throw an exception and give up.
- Abra takes the middle
- road: an array indexing operation will always succeed and will always return a "box", which may or may not
- contain a value. One way to "unbox" this value is to use the coalescing operator (?:
),
- also called the "Elvis operator" in some languages. This operator will either unbox
+ Abra takes the middle road: an array indexing operation will always succeed and will always return a
+ "box", which may or may not contain a value. One way to "unbox" this value is to use the coalescing
+ operator (?:
), also called the "Elvis operator" in some languages. This operator will either unbox
the Optional
and return what's inside, or will provide a given fallback.
@@ -125,6 +120,27 @@ export default function DocumentationPage() {
"hello" ?: "world" // Type error, since the left-hand side "hello" is not an Optional
`}
+
+ There's another operator that makes it convenient to work with Optional
types: the ?.
+ operator. This allows for an Optional
-safe way of accessing properties of variables without manually
+ "unwrapping" the value. For example, if we wanted to get the length of a string contained within an array:
+
+ {`
+ val names = ["Brian", "Ken", "Meg"]
+
+ val brian: String? = names[0] // The type of brian is an Optional String
+ val wrongLength = brian.length // Type error, since the property "length" does not exist on String?
+ val rightLength = brian?.length // This is correct
+ `}
+
+
+ The rightLength
variable will be of type Int?
. Essentially, what happens here is
+ this: since the code can't be sure if the variable brian
holds a value or not, we can use the
+ Optional
-safe operator (?.
) to access its length
property. If the variable
+ holds a value, it will get the length
property off of the variable; if it does not hold a
+ value, it will just short-circuit and produce the value of None
.
+
Functions can also be declared with default argument values. This makes those parameters optional when
@@ -170,7 +186,7 @@ export default function DocumentationPage() {
func add2(a: Int, b = 2, c: Int) = a + b + c
// This is an error here ^ since required params
// cannot come after optional ones
- `}
+ `}
+ There's also a syntax for anonymous lambda functions in Abra, which follows after Typescript's arrow
+ function syntax. Arguments are in parentheses followed by their type annotations, then an arrow (=>
)
+ and then either a single expression or a block.
+
+ {`
+ val add = (a: Int, b: Int) => a + b
+ val mult = (a: Int, b: Int) => {
+ var product = a
+ for i in range(0, b) {
+ product = product + a
+ }
+ product
+ }
+ `}
+
+ + Functions in Abra are first-class citizens, so they can be passed as arguments to other functions. When + passing lambdas as arguments, the type annotations for arguments are optional. +
++ It's also important to note that regular named functions can also be passed as parameters! +
+
+ {`
+ func call(fn: (Int) => Int, number: Int) = fn(number)
+
+ call(x => x + 1, 23) // Returns 24
+
+ func increment(value: Int) = value + 1
+ call(increment, 23) // Also returns 24
+ `}
+
+ + A function will satisfy a function type signature if all of its required arguments match; any optional + arguments are not typechecked against the type signature: +
+
+ {`
+ func call(fn: (Int) => Int, number: Int) = fn(number)
+
+ call((x, y = 1) => x + y + 1, 22) // Returns 24
+ // ^ The argument y will always be set to the default value
+ `}
+ Abra has support for recursive functions, but the function must have an explicit return type annotation. @@ -215,7 +280,7 @@ export default function DocumentationPage() { fib(n - 2) + fib(n - 1) } } - `} + `}