Overview
Underload is a Turing-complete stack based programming language. Elements on the stack are of variable length and manipulated by a set of eight instructions.
Instruction set
Instruction | Description |
---|---|
~ | exchange the top two elements |
: | duplicate the top element |
! | discard the top element |
* | concatenate the top element to the end of the second element |
a | enclose the top element in parentheses |
S | output the top element then discard it |
^ | remove the top element then execute it |
( ) | add a new element containing everything between the parentheses |
Example Programs
Hello, World!
A simple program to demonstrate output in Underload:
(Hello, World!)S
First (Hello, World!)
adds a new element containing
“Hello, World!” to the stack. Next, S
displays
and discards the element.
Quine
A quine is a program which outputs its own source code:
(:aSS):aSS
First (:aSS)
adds a new element containing “:aSS”
to the stack:
:aSS |
Then :
duplicates the top element. The new top element is
to the right:
:aSS | :aSS |
Next a
encloses the top element in parentheses:
:aSS | (:aSS) |
Finally SS
will display and discard the top two elements.
Implemention in Redcode
org underl
stack equ (ip-1)
ip dat prog, prog
exec mov >ip, <stack ; ^
jmn exec, @stack
add #1, stack
efind jmn efind, >stack
mov.ba stack, stack
sub.a #1, stack
mov #prog-ip, ip
mov.a #prog-ip, ip
ecopy mov {stack, }ip
jmn ecopy, *stack
jmp underl
enclose sub #2, stack ; a
mov.ba stack, stack
mov #41, *stack
eloop add.a #2, stack
mov *stack, {stack
jmn eloop, *stack
mov #40, *stack
jmp underl
swap jmn swap, }stack ; ~
sfinda jmn sfinda, }stack
mov {stack, <stack
scopy mov {stack, <stack
jmn scopy, @stack
mov.ab stack, stack
add #1, stack
sfindb jmn sfindb, >stack
sub #1, stack
scopyb mov {stack, <stack
jmn scopyb, @stack
jmp dcopy
push nop <stack, >pcount ; ()
pcopy mov >ip, <stack
sne #41, @stack
sub #1, pcount
sne #40, @stack
jmp pcopy, >pcount
pcount jmn pcopy, #0
jmp underl, >stack
concat jmn concat, >stack ; *
cloop sub #2, stack
mov >stack, @stack
jmn cloop, @stack
jmp underl, >stack
output sne #0, >stack ; S
jmp underl
ofind jmn ofind, >stack
mov.ba stack, stack
sub.a #2, stack
oloop sts *stack, 0
jmn oloop, {stack
jmp underl
duplic jmn duplic, }stack ; :
mov {stack, <stack
dcopy mov {stack, <stack
jmn dcopy, @stack
drop jmn drop, >stack ; !
underl sne #33, @ip
jmp drop, >ip
sne #94, @ip
jmp exec, >ip
seq #97, @ip
sne #65, @ip
jmp enclose, >ip
mov.ba stack, stack
sne #58, @ip
jmp duplic, >ip
sne #126, @ip
jmp swap, >ip
mov #0, <stack
add #1, stack
sne #40, @ip
jmp push, >ip
sne #42, @ip
jmp concat, >ip
seq #115, @ip
sne #83, @ip
jmp output, >ip
prog