Typed uxntal is an inference system based on routine definitions.
Type inference in Uxntal is done by checking the stack effect declarations of words before they can be run, against the cumulative stack state of each item in the definition of each word.
- ( a -- b ) Normal
- ( a -> b ) Vector
- ( a -+ b ) Fallthrough
- ( a ~- b ) Normal Branch
- ( a ~> b ) Vector Branch
- ( a ~+ b ) Fallthrough Branch
- ( a -: b ) Unsafe
@routine ( a b -- c ) Ok. MUL JMP2r
The simplest case is when a piece of code does not have any branches or recursion, and just pushes literals and calls words. Pushing a literal has stack effect
( -- x ). The stack effect of most words is always known statically from the declaration.
@add ( a* b* -- c* ) Warning: Imbalance in @add of +2 DUP2 ADD2 JMP2r
Words that do not pass the stack-checker are generating a warning, and so essentially this defines a very simple and permissive type system that nevertheless catches some invalid programs and enables compiler optimizations.
@routine ( a -- ) Ok. #01 ?&branch POP JMP2r &branch ( a ~- ) POP JMP2r
The tail-less fall-through type allows for routine to not return, and check the stack balance including that of the next routine in memory.
@falling ( a b c -+ c ) POP @next-routine ( a b -- res ) ADD JMP2r
Passing items to a branch through the return-stack, is done by prefixing the definition with a backtick.
@routine ( a -- b ) STHk DUP #01 EQU ?&branch POPr JMP2r &branch ( a `a ~- b ) POP STHr JMP2r
- Uxnbal, Source