Rejoyce is a purely functional, persistent, concatenative language
It maintains an In queue and an Out stackThe In queue represents code yet to be executed, and is initially populated with the program to run
The Out stack represents data to be manipulated, and is initially empty
The two record the complete state of execution at any time
To evaluate a token, Rejoyce returns a completely new In and Out stack
A token can be a literal value, like 5
Or a word, like range
Or a quotation of literals and words, like [dup last 0 <=]
Or maps of words to definitions like { vec/wrap [[] swap conj] }
Literals, quotations, and maps are moved to the stack unmodified
Words are looked up on the stack for definitions, and are replaced by the first definition found
Words can produce new Out stacks, In queues, or both
Formally, every token in Rejoyce is a function of (In,Out) → (In',Out')
The eval.joy represents the complete evaluation of the code 5 range
Everything to the right of the ◆ is the In queue
Everything to the left of the ◆ is the Out stack
Every new line is the next step in the evaluation
Every line is a completely new In queue and Out stack
The core library maps, where the definitions of e.g. dup
and <=
are, are left out for brevity
They are at the bottom of the Out stack initially
The range.joy
map is left out for brevity
It is at the top of the Out stack initially
Note evaluating a quotation happens by 'unwrapping it' and prepending it to the In queue
Note line 2 → 3, range
is looked up and replaced in the In queue with its definition from range.joy
Note line 9 → 10, until
loops by expanding to an unless
with another until
inside it's body
Note line 16 → 17, unless
evaluates the quotation at the top of the stack if the boolean beneath it is false
This is the map with the range
function and its helpers
The /
in vec/wrap
is meant to simulate namespaces
When these words are looked up in eval.joy
, the contents of their quotations are prepended to the In queue