See this page, "URM is BF-complete" for more details about the Universal Register Machine.
Psh is used as the Push interpreter.
The interpreter accepts an URM program encoded as follows:
URM Symbol | Encoding |
---|---|
. | 0 |
a | -1 |
s | -2 |
( | -3 |
) | -4 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 4 |
5 | 5 |
The first line represents the registers, and the second line contains the encoded URM program. The first register is not addressable but is included to maintain 0-based indexing.
The memory is organized as follows (purpose and inclusive ranges): [REGISTERS: 0–5][CODE: 6–59][VARIABLES: 60–61]
.
The code of the URM interpreter in Push with a sample URM program that multiplies register 3 to register 2:
(
0 0 6 3 0 0
-3 -1 4 -1 5 -2 2 -4 2 -3 -3 -1 2 -2 4 -4 4 -2 3 -3 -1 1 -1 4 -2 5 -4 5 -3 -1 5 -2 1 -4 1 -4 3 0
integer.stackdepth 62 integer.swap integer.-
exec.do*times 0
integer.stackdepth exec.do*count
(
integer.yank
)
exec.y
(
60 integer.yankdup
(6 integer.+) integer.yankdup
integer.dup
(0 integer.=) exec.if
(
integer.pop
exec.flush
) ()
integer.dup
(-1 integer.=) exec.if
(
(1 60 integer.+) integer.yank
1 integer.+
(1 60 integer.+) integer.shove
1 60 integer.+ integer.yankdup
1 (6 integer.+) integer.+ integer.yankdup
integer.dup
(2 integer.+) integer.yank
1 integer.+
integer.swap
(1 integer.+) integer.shove
) ()
integer.dup
(-2 integer.=) exec.if
(
(1 60 integer.+) integer.yank
1 integer.+
(1 60 integer.+) integer.shove
1 60 integer.+ integer.yankdup
1 (6 integer.+) integer.+ integer.yankdup
integer.dup
(2 integer.+) integer.yank
-1 integer.+
integer.swap
(1 integer.+) integer.shove
) ()
integer.dup
(-3 integer.=) exec.if
(
(1 61 integer.+) integer.yank
1 integer.+
(1 61 integer.+) integer.shove
exec.y
(
(1 61 integer.+) integer.yankdup
0 integer.>
exec.if
(
(1 60 integer.+) integer.yank
1 integer.+
(1 60 integer.+) integer.shove
1 60 integer.+ integer.yankdup
1 (6 integer.+) integer.+ integer.yankdup
integer.dup
(-3 integer.=) exec.if
(
(2 61 integer.+) integer.yank
1 integer.+
(2 61 integer.+) integer.shove
) ()
integer.dup
(-4 integer.=) exec.if
(
(2 61 integer.+) integer.yank
-1 integer.+
(2 61 integer.+) integer.shove
) ()
integer.pop
) exec.pop
)
(1 60 integer.+) integer.yank
-1 integer.+
(1 60 integer.+) integer.shove
) ()
integer.dup
(-4 integer.=) exec.if
(
1 60 integer.+ integer.yankdup
2 (6 integer.+) integer.+ integer.yankdup
(1 integer.+) integer.yankdup
(0 integer.>) exec.if
(
(1 61 integer.+) integer.yank
1 integer.+
(1 61 integer.+) integer.shove
exec.y
(
(1 61 integer.+) integer.yankdup
0 integer.>
exec.if
(
(1 60 integer.+) integer.yank
-1 integer.+
(1 60 integer.+) integer.shove
1 60 integer.+ integer.yankdup
1 (6 integer.+) integer.+ integer.yankdup
integer.dup
(-4 integer.=) exec.if
(
(2 61 integer.+) integer.yank
1 integer.+
(2 61 integer.+) integer.shove
) ()
integer.dup
(-3 integer.=) exec.if
(
(2 61 integer.+) integer.yank
-1 integer.+
(2 61 integer.+) integer.shove
) ()
integer.pop
) exec.pop
)
)
(
(1 60 integer.+) integer.yank
1 integer.+
(1 60 integer.+) integer.shove
)
) ()
integer.pop
60 integer.yank
1 integer.+
60 integer.shove
)
)