Updated Developer's Notes on Implementing Unlambda (markdown)

CismonX 2020-02-11 00:31:01 +08:00
parent 80d1567233
commit 1929f0e045
1 changed files with 1 additions and 1 deletions

@ -28,7 +28,7 @@ After each (1), continuously pop instructions from the stack and append it to th
As you may have noticed, there's an obvious flaw in the said compilation rules - the special behaviour of function `d` wasn't taken into consideration. According to the Unlambda language specs, whenever an "operator" (the left child of an internal AST node) evaluates to function `d`, evaluation of the "operand" (its right sibling) is postponed and saved to a "promise", which may evaluate further in the future.
For rule (2), the compiler knows whether X is function `d`. When it is `d`, every instruction between the `NOP` and `APP d, acc` should be skipped, thus it compiles to `DEL offset`, where the "offset" points to the instruction next to the `APP d, acc`. The offset of the instruction next to `DEL offset` should be stored into the promise, so that the skipped instructions can execute in the future. Meanwhile, `APP d, acc` will never happen, so we change it into `AD` and introduce an internal function `f` ("finalize"), which applies the argument to the element popped from the stack, and restores the instruction pointed it saved. The function `f` is pushed to the runtime stack whenever the promise is applied to an argument, which should be pushed to the stack beforehand.
For rule (2), the compiler knows whether X is function `d`. When it is `d`, every instruction between the `NOP` and `APP d, acc` should be skipped, thus it compiles to `DEL offset`, where the "offset" points to the instruction next to the `APP d, acc`. The offset of the instruction next to `DEL offset` should be stored into the promise, so that the skipped instructions can execute in the future. Meanwhile, `APP d, acc` will never happen, so we change it into `LA` and introduce an internal function `f` ("finalize"), which applies the argument to the element popped from the stack, and restores the instruction pointed it saved. The function `f` is pushed to the runtime stack whenever the promise is applied to an argument, which should be pushed to the stack beforehand.
For rule (4), the left child may evaluate to `d`. If not, `SA` behaves normally (saves accumulator), otherwise, it behaves like `DEL`, which requires it to take an offset as operand as well.