Execute Computer/Zero: Difference between revisions
Content added Content deleted
(Added XPL0 example.) |
|||
Line 2,183: | Line 2,183: | ||
for (prog in progs) interp.call(prog)</syntaxhighlight> |
for (prog in progs) interp.call(prog)</syntaxhighlight> |
||
{{out}} |
|||
<pre> |
|||
4 |
|||
56 |
|||
55 |
|||
6 |
|||
0 |
|||
</pre> |
|||
=={{header|XPL0}}== |
|||
Some simplifying assumptions are made. Literal addresses are used instead |
|||
of labels. The STP instruction merely stops (and displays the |
|||
accumulator) rather than allowing the program to continue after a key is |
|||
struck. This prevents the Prisoner's Dilemma from running as intended. |
|||
<syntaxhighlight lang "XPL0">def NOP=0, LDA=1, STA=2, ADD=3, SUB=4, BRZ=5, JMP=6, STP=7; |
|||
char Mem(32); |
|||
string 0; |
|||
proc Load(Prog); \Load program into memory |
|||
char Prog; |
|||
int PC, I, Ch, Hash; |
|||
func GetNum; \Return value of number |
|||
int Num; |
|||
[while Ch <= $20 do |
|||
[Ch:= Prog(I); I:= I+1]; |
|||
Num:= 0; |
|||
while Ch>=^0 and Ch<=^9 do |
|||
[Num:= Num*10 + Ch - ^0; |
|||
Ch:= Prog(I); I:= I+1; |
|||
]; |
|||
return Num; |
|||
]; |
|||
[PC:= 0; I:= 0; |
|||
repeat repeat Ch:= Prog(I); I:= I+1; until Ch > $20; |
|||
if Ch>=^0 and Ch<=^9 then |
|||
Mem(PC):= GetNum |
|||
else [Hash:= 0; |
|||
while Ch >= ^A do |
|||
[Hash:= Hash + Ch; |
|||
Ch:= Prog(I); I:= I+1; |
|||
]; |
|||
case Hash of |
|||
^N+^O+^P: Mem(PC):= NOP<<5; |
|||
^L+^D+^A: Mem(PC):= LDA<<5 + GetNum; |
|||
^S+^T+^A: Mem(PC):= STA<<5 + GetNum; |
|||
^A+^D+^D: Mem(PC):= ADD<<5 + GetNum; |
|||
^S+^U+^B: Mem(PC):= SUB<<5 + GetNum; |
|||
^B+^R+^Z: Mem(PC):= BRZ<<5 + GetNum; |
|||
^J+^M+^P: Mem(PC):= JMP<<5 + GetNum; |
|||
^S+^T+^P: Mem(PC):= STP<<5 |
|||
other [Text(0, "Bad opcode at "); IntOut(0, PC); exit]; |
|||
]; |
|||
PC:= PC+1; |
|||
until Ch = 0; |
|||
]; |
|||
proc Run(Prog); \Load and run a program |
|||
int Prog, PC, Acc, Instr, Addr; |
|||
[Load(Prog); |
|||
PC:= 0; Acc:= 0; |
|||
loop [Instr:= Mem(PC) >> 5; |
|||
Addr:= Mem(PC) & $1F; |
|||
PC:= PC+1; |
|||
case Instr of |
|||
LDA: Acc:= Mem(Addr); |
|||
STA: Mem(Addr):= Acc; |
|||
ADD: Acc:= Acc + Mem(Addr) & $FF; |
|||
SUB: Acc:= Acc - Mem(Addr) & $FF; |
|||
BRZ: if Acc = 0 then PC:= Addr; |
|||
JMP: PC:= Addr; |
|||
STP: quit |
|||
other []; \NOP |
|||
if PC > 31 then quit; |
|||
]; |
|||
IntOut(0, Acc); CrLf(0); |
|||
]; |
|||
int Progs, N; |
|||
[Progs:= [ |
|||
"LDA 3 ADD 4 STP 2 2", |
|||
"LDA 12 ADD 10 STA 12 LDA 11 SUB 13 STA 11 BRZ 8 JMP 0 LDA 12 STP 8 7 0 1", |
|||
"LDA 14 STA 15 ADD 13 STA 14 LDA 15 STA 13 LDA 16 SUB 17 BRZ 11 STA 16 JMP 0 |
|||
LDA 14 STP 1 1 0 8 1", |
|||
"LDA 13 ADD 15 STA 5 ADD 16 STA 7 NOP STA 14 NOP BRZ 11 STA 15 JMP 0 LDA 14 |
|||
STP LDA 0 0 28 1 0 0 0 6 0 2 26 5 20 3 30 1 22 4 24", |
|||
"0 0 STP NOP LDA 3 SUB 29 BRZ 18 LDA 3 STA 29 BRZ 14 LDA 1 ADD 31 STA 1 |
|||
JMP 2 LDA 0 ADD 31 STA 0 JMP 2 LDA 3 STA 29 LDA 0 ADD 30 ADD 3 STA 0 LDA 1 |
|||
ADD 30 ADD 3 STA 1 JMP 2 0 1 3"]; |
|||
for N:= 0 to 4 do Run(Progs(N)); |
|||
]</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |