Waffle (Web assembly functional function language) is a statically typed programing language with some functional characteristics.
Defining Functions is done by writing the arguments with types in parenthesis, an arrow ->, return types in parenthesis and function body in {}.
f = (a int, b int) -> (int) {
c = 10 * 2
return a + b + c
}
If the function only has one line, that line is parsed as an return statement. As long as the function isn't recursive, specifying return types is optional in this case.
f = (a int, b int) -> { a + b * 2 }
Executing functions is done by writing ! and a variable storing the function to be executed. All expression after will be used as arguments to the function being executed.
a = !g 10 10 + 2
In this example 10 and 12 will be the value of the arguments to the function g. If you on the other hand want to add 2 to the result you can add parenthesis around the function and the arguments like this:
a = (!g 10 10) + 2
Alternatively you can do this:
a = 2 + !g 10 10
If else is only valid in expressions and functions as a ternary operator. There must be two expression between the if and else keywords. The first returning a bool deciding whether to run the true or false-expression, and the second being the true-expression. After the else keyword is the false-expression. The true and false expression must have the same return types.
f = (a int) -> { if a >= 0 a * 2 else 0 }
All elements in an array must be of the same type. Arrays can be created like this:
[10, 2, 1]
Because the compiler needs to figure out the type of the array, crating an empty array like this [] is not valid. Since there is no other way of creating an array there is currently no way to create an empty array.
Getting and setting elements in an array is done by the get and set function. The set function mutates the element specified and returns the array.
f = () -> (int) {
a = [0, 3, 5]
a = !set a 0 3
return !get a 0
}
This code creates an array with the elements 0, 3 and 5. Then it sets the 0th element of the array to 3 and returns the 0th element of the function.
These functions are added to the output wasm file when used.
Returns the length of array given
([]a) -> (int)
Creates new array copying number of elements specified. Runtime error occurs if int given is larger than the length of the array given.
([]a, int) -> ([]a)
Creates new array copying from the second element. If the length of the array given is 0 or 1, an empty array will be returned.
([]a) -> ([]a)
Assignment statements with function definition is currently the only thing valid in the global scope. Variables created in the global scope can not be mutated.
Line comments are stared with // and block comments are started with /* and ended with */
Unreachable will be caused by setting, getting or taking with an index out out of bounds.
Currently all global functions are exported in the wasm file generated by the compiler. All global functions can therefore be accessed in javascript.
main = (a int) -> { !k (!f a) (!g a) }
const run = async () => {
const buffer = readFileSync("./main.wasm")
const module = await WebAssembly.compile(buffer)
const instance = await WebAssembly.instantiate(module, {})
console.log(instance.exports.main())
}
- array functions
- make
- range
- append
- drop
- map
- reduce
- scan
- find
- takes array and element and returns true if found
- membership
- takes array and element and returns true if found
- indexIn
- takes element and array and gives the first index the element is found, -1 when not found
- Other functions
- max
- min
- random
- Math functions
- Curringish (if function miss arguments it returns a new function )
- function composition
- deallocate arrays
- add lines to ast to get better errors
- strings