Recursion
Our current language can either add or multiply two numbers. However, the result of an addition can not be used in a multiplication and vice-versa, since the arguments of both functions are primitive numbers. We also can't add or multiply using Pi.
> add pi 1
Error: Unexpected token "pi" at index 1 for type <p.number>
We can change this by changing the arguments of add
and mul
to value
, making them recursive.
Func("add")
.arg(value)
.arg(value)
.setExec((left, right) => left + right),
However, we now have a new problem, as we can only use recursion.
> add 1 2
Error: Unexpected token "1" at index 1 for type <t.value>
> add pi pi
6.28
We could solve this problem using a separate function, for example im
for immediate, but this is annoying to use.
Func("im")
.arg(primitives.number)
.setExec((val) => val),
> add im 5 im 10
15
Instead, value
has an optional default expression, which will be parsed if none of its functions matched the input.
value.setDefault(primitives.number);
This gives the desired functionality:
> add 5 mul 6 7
47
> 5
5
Notice that a single number is now also a valid program. We can see this in the updated grammar.
l.calc:
| <t.value> EOI
t.value:
| "add" <t.value> <t.value>
| "mul" <t.value> <t.value>
| "pi"
| <p.number>