TRM in APL
Larry Moss and some others have created an interesting little machine
for teaching certain courses. This little machine is an interesting one where each instructions is a series of 1's followed by a series of #'s. The 1's are an argument indicating either a register or some value, in either case the value is the number of 1's that is in the instruction. The number of #'s indicates the instruction:
# | Add 1 to register |
## | Add # to register |
### | Goto instruction ahead |
#### | Goto instruction behind |
##### | Pop character from word in register and jump ahead 1 if empty, two if 1, and three if #. |
I figured that I would implement a simple interpreter for this machine in APL really quickly, and it was a very quick program. Here's the result:
∇ R←N EVAL P;PC;I;V [1] R←N ⋄ PC←1 ⋄ EM←'IMPROPER HALT' ⍝ Set Init State and Program Count [2] P←(⊃'1#'∨.=⊂P)/P ⍝ Strip whitespace [3] P←↑(('1'=P)∧1,2≠/P)⊂P ⍝ Partition into instructions [4] P←(+/'#'=P),[1.5]+/'1'=P ⍝ Reformat instructions to integer [5] LP:→(PC=1+⊃⍴P)/0 ⍝ Check for halt [6] EM⎕SIGNAL((PC<1)∨pc>1+⊃⍴P)/90 ⍝ Exception on bad halt [7] (I V)←PC⌷P ⍝ I→Instruction V→Register/Count [8] →I⌷(ADD ADD GO GO CASE) ⍝ Case on instruction [9] ADD:R[V],←I⌷'1#' ⋄ PC+←1 ⋄ →LP ⍝ Add elem, increment, go [10] GO:PC+←V×(I-2)⌷1 ¯1 ⋄ →LP ⍝ Step forward/backward, go [11] CASE:PC+←('1#'⍳1↑⊃V⌷R)⌷2 3 1 ⍝ Step forward correct amount [12] R[V]←⊂1↓⊃V⌷R ⋄ →LP ⍝ Drop from register and go ∇ 1)∨pc>