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() { Literals

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 `} - - Destructuring -

- // TODO: Variable declaration via destructuring is not yet implemented -

@@ -88,6 +83,7 @@ export default function DocumentationPage() { Int[][] // eg. [[1, 2], [3, 4]] `} + Option Type

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. +

@@ -149,7 +165,7 @@ export default function DocumentationPage() { // The above function could also be written like this, omitting the return // type annotation and condensing the function body into a single expression func greaterThan(num1: Int, num2: Int) = num1 > num2 - `} + `}

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 - `} + `} Calling Functions @@ -195,9 +211,58 @@ export default function DocumentationPage() { // To help reduce ambiguity ("did the firstName parameter come first, or the // lastName?"), you can use named-arguments getFullName(firstName: "Turanga", lastName: "Leela") - `} + `} + + + Lambda Functions +

+ 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 + `} + Recursive Functions

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) } } - `} + `}