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>