Execute Computer/Zero: Difference between revisions

Added Easylang
(J)
(Added Easylang)
 
(44 intermediate revisions by 16 users not shown)
Line 13:
 
<br><br>
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">BEGIN # execute some ComputerZero programs #
# instructions #
INT nop = 0, lda = 1, sta = 2, add = 3, sub = 4, brz = 5, jmp = 6, stp = 7;
PROC instr = ( INT op, v )INT: ( 32 * op ) + v;
OP NOP = ( INT v )INT: instr( nop, v );
OP LDA = ( INT v )INT: instr( lda, v );
OP STA = ( INT v )INT: instr( sta, v );
OP ADD = ( INT v )INT: instr( add, v );
OP SUB = ( INT v )INT: instr( sub, v );
OP BRZ = ( INT v )INT: instr( brz, v );
OP JMP = ( INT v )INT: instr( jmp, v );
OP STP = ( INT v )INT: instr( stp, v );
# executes the program named name #
PROC execute = ( STRING name, []INT program )VOID:
BEGIN
[ 0 : 31 ]INT m; # the computer 32 has bytes of memory #
FOR i FROM LWB m TO UPB m DO m[ i ] := 0 OD;
# "assemble" the program #
INT m pos := -1;
FOR i FROM LWB program TO UPB program DO
m[ m pos +:= 1 ] := program[ i ]
OD;
# execute the program #
BOOL running := TRUE;
INT pc := 0;
INT a := 0;
WHILE running DO
INT op := m[ pc ] OVER 32;
INT operand := m[ pc ] MOD 32;
pc +:= 1 MODAB 32;
IF op = nop THEN SKIP
ELIF op = lda THEN a := m[ operand ]
ELIF op = sta THEN m[ operand ] := a
ELIF op = add THEN a +:= m[ operand ] MODAB 256
ELIF op = sub THEN a -:= m[ operand ] MODAB 256
ELIF op = brz THEN IF a = 0 THEN pc := operand FI
ELIF op = jmp THEN pc := operand
ELSE # stp #
running := FALSE;
print( ( " " * ( 12 - ( ( UPB name - LWB name ) + 1 ) ) ) );
print( ( name, ": ", whole( a, -3 ), newline ) )
FI
OD
END # execute # ;
# task test programs (from the Computer Zero website) #
# the unary NOP, LDA, STA, etc. operators are used to construct the #
# instructions; as parameterless operators aren't allowed, NOP and STP #
# must have a dummy parameter #
execute( "2+2", ( LDA 3, ADD 4, STP 0, 2, 2 )
);
execute( "7*8"
, ( LDA 12, ADD 10, STA 12, LDA 11, SUB 13, STA 11, BRZ 8, JMP 0
, LDA 12, STP 0, 8, 7, 0, 1
)
);
execute( "fibonacci"
, ( 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 0, 1, 1, 0
, 8, 1
)
);
execute( "linkedList"
, ( LDA 13, ADD 15, STA 5, ADD 16, STA 7, NOP 0, STA 14, NOP 0
, BRZ 11, STA 15, JMP 0, LDA 14, STP 0, LDA 0, 0, 28
, 1, 0, 0, 0, 6, 0, 2, 26
, 5, 20, 3, 30, 1, 22, 4, 24
)
);
execute( "prisoner"
, ( NOP 0, NOP 0, STP 0, 0, 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 1, ADD 30, ADD 3, STA 1
, LDA 0, ADD 30, ADD 3, STA 0, JMP 2, 0, 1, 3
)
);
# subtractions yielding negative results #
execute( "0-255", ( LDA 3, SUB 4, STP 0, 0, 255 ) );
execute( "0-1", ( LDA 3, SUB 4, STP 0, 0, 1 ) );
# overflow on addition #
execute( "1+255", ( LDA 3, ADD 4, STP 0, 1, 255 ) )
END
</syntaxhighlight>
{{out}}
<pre>
2+2: 4
7*8: 56
fibonacci: 55
linkedList: 6
prisoner: 0
0-255: 1
0-1: 255
1+255: 0
</pre>
 
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
<syntaxhighlight lang="gwbasic"> 0 FOR P = 1 TO 5: READ S$: PRINT S$" : ";: FOR MEM = 0 TO 31: ON LEN (S$) > 0 GOSUB 90:A = VAL (S$): GOSUB 2: NEXT MEM: GOSUB 7: PRINT A: NEXT P: END
1 LET A = V: RETURN
2 LET P$ = MID$ (P$,1,MEM) + CHR$ (A) + MID$ (P$,MEM + 2,31 - MEM): PRINT MID$ ("",1 ^ FRE (0));: RETURN
3 LET A = A + V:A = A - 256 * (A > 255): RETURN
4 LET A = A - V:A = A + 256 * (A < 0): RETURN
5 IF A > 0 THEN RETURN
6 LET PC = MEM: RETURN
7 LET PC = 0
8 LET A = 0
9 FOR OP = 0 TO 7 STEP 0
10 LET PC = PC + 1 - 32 * (PC = 32)
20 LET I = ASC ( MID$ (P$,PC,1))
30 LET OP = INT (I / 32)
40 LET MEM = I - OP * 32
50 LET V = ASC ( MID$ (P$,MEM + 1,1))
60 ON OP GOSUB 1,2,3,4,5,6
70 NEXT OP
80 RETURN
90 READ S$: RETURN
100 DATA "2+2",35,100,224,2,2,
200 DATA "7*8",44,106,76,43,141,75,168,192,44,224,8,7,0,1,
300 DATA "FIBONACCI",46,79,109,78,47,77,48,145,171,80,192,46,224,1,1,0,8,1,
400 DATA "LINKED LIST",45,111,69,112,71,0,78,0,171,79,192,46,224,32,0,28,1,0,0,0,6,0,2,26,5,20,3,30,1,22,4,24
500 DATA "PRISONER",0,0,224,0,0,35,157,178,35,93,174,33,127,65,194,32,127,64,192,35,93,33,126,99,</syntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
The original version of the virtual machine has a provision of entering user choices in the Prisoner's dilema game. It works allowing the user to enter a number when executing a Stop instruction. There is no simple way to do this with Rosetta Code instructions that the program should return a value when it reaches a Stop instruction. As a result, all the versions displayed in the Rosetta Code examples, simply returns a zero when it reaches the stop instruction.
<syntaxhighlight lang="Delphi">
 
{structure that holds name of program and code}
 
type TProgram = record
Name, Code: string;
end;
 
{List of programs}
 
var ProgList: array [0..4] of TProgram =(
(Name: 'Two plus two'; Code: 'LDA 3 ADD 4 STP 2 2'),
(Name: 'Seven times eight'; Code: 'LDA 12 ADD 10 STA 12 LDA 11 SUB 13 STA 11 BRZ 8 JMP 0 LDA 12 STP 8 7 0 1'),
(Name: 'The Fibonacci sequence'; Code: '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'),
(Name: 'Linked list'; Code: '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'),
(Name: 'Prisoner’s Dilemma'; Code: '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')
);
 
{Defines opcode function call}
 
type TOpProc = function(Opcode: byte): boolean;
 
{Defines argument type for opcode}
 
type TArgType = (atNone,atAddress,atMemory);
 
{Defines Opcode information}
 
type TOpcode = record
OpCode: integer;
ArgType: TArgType;
Mnemonic: string[3];
Proc: TOpProc;
end;
 
{Simulated memory, program counter and accumulator}
 
var Memory: array [0..31] of byte;
var ProgramCounter: integer;
var Accumulator: byte;
 
{Routines to carry out actions of opcodes}
 
function DoNoOp(Operand: byte): boolean;
{ ($00) = NOP - (no operation)}
begin
Inc(ProgramCounter);
Result:=True;
end;
 
 
function DoLDA(Operand: byte): boolean;
{ ($20) LDA - (load accumulator) - a := memory [xxxxx]}
begin
Accumulator:=Memory[Operand];
Inc(ProgramCounter);
Result:=True;
end;
 
 
function DoSTA(Operand: byte): boolean;
{ ($40) STA - (store accumulator) - memory [xxxxx] := a}
begin
Memory[Operand]:=Accumulator;
Inc(ProgramCounter);
Result:=True;
end;
 
 
function DoADD(Operand: byte): boolean;
{ ($60) ADD - (add) - a := a + memory [xxxxx]}
begin
Accumulator:=Accumulator + Memory[Operand];
Inc(ProgramCounter);
Result:=True;
end;
 
 
function DoSUB(Operand: byte): boolean;
{ ($80) SUB - (subtract) - a := a – memory [xxxxx]}
begin
Accumulator:=Accumulator - Memory[Operand];
Inc(ProgramCounter);
Result:=True;
end;
 
 
function DoBRZ(Operand: byte): boolean;
{ ($A0) BRZ - (branch on zero) - if a = 0 then goto xxxxx}
begin
if Accumulator=0 then ProgramCounter:=Operand
else Inc(ProgramCounter);
Result:=True;
end;
 
 
function DoJMP(Operand: byte): boolean;
{ ($C0) JMP - (jump) - goto xxxxx}
begin
ProgramCounter:=Operand;
Result:=True;
end;
 
 
function DoSTP(Operand: byte): boolean;
{ ($E0) STP - (stop)}
begin
Result:=False;
end;
 
{Table of opcodes}
 
var OpTable: array [0..7] of TOpcode= (
(Opcode: $00; ArgType: atNone; Mnemonic: 'NOP'; Proc: DoNoOp),
(Opcode: $20; ArgType: atMemory; Mnemonic: 'LDA'; Proc: DoLDA),
(Opcode: $40; ArgType: atMemory; Mnemonic: 'STA'; Proc: DoSTA),
(Opcode: $60; ArgType: atMemory; Mnemonic: 'ADD'; Proc: DoADD),
(Opcode: $80; ArgType: atMemory; Mnemonic: 'SUB'; Proc: DoSUB),
(Opcode: $A0; ArgType: atAddress; Mnemonic: 'BRZ'; Proc: DoBRZ),
(Opcode: $C0; ArgType: atAddress; Mnemonic: 'JMP'; Proc: DoJMP),
(Opcode: $E0; ArgType: atNone; Mnemonic: 'STP'; Proc: DoSTP));
 
 
 
procedure ClearMemory;
{Set all memory locations to zero}
var I: integer;
begin
for I:=0 to High(Memory) do
Memory[I]:=0;
end;
 
 
function DecodeMnemonic(NMem: string): TOpcode;
{Convert 3-char Mnemonic to opcode info}
var I: integer;
begin
for I:=0 to High(OpTable) do
if NMem=OpTable[I].Mnemonic then
begin
Result:=OpTable[I];
exit;
end;
raise Exception.Create('Opcode Not Found');
end;
 
 
procedure AssembleProgram(Prog: string);
{Convert text source code into machine code and store in memory}
var Inx,MemInx,IntAtom,T: integer;
var Atom: string;
var OC: TOpcode;
begin
ClearMemory;
MemInx:=0;
Inx:=1;
while true do
begin
{Get one space delimited atom}
Atom:=ExtractToken(Prog,' ',Inx);
{exit if end of source code}
if Atom='' then break;
{Is the atom text (Mnemonic) or number?}
if Atom[1] in ['A'..'Z','a'..'z'] then
begin
{Convert Mnemonic to opcode info}
OC:=DecodeMnemonic(Atom);
{Get machine value of opcode}
IntAtom:=OC.OpCode;
{Is operand of of memory or address type?}
if OC.ArgType in [atMemory,atAddress] then
begin
{if so combine opcode and operand}
Atom:=ExtractToken(Prog,' ',Inx);
T:=StrToInt(Atom);
IntAtom:=IntAtom or T;
end;
end
else IntAtom:=StrToInt(Atom);
{Store machine code in memory}
Memory[MemInx]:=IntAtom;
{Point to next memory location}
Inc(MemInx);
end;
end;
 
 
function DecodeOpcode(Inst: byte; var Opcode: TOpcode): boolean;
{Convert machine instruction to opcode information}
var I: integer;
var Op: byte;
begin
Result:=True;
{Get opcode part of instruction}
Op:=$E0 and Inst;
{Look for it in table}
for I:=0 to High(OpTable) do
if OpTable[I].OpCode=Op then
begin
Opcode:=OpTable[I];
exit;
end;
Result:=False;
end;
 
 
function ExecuteInstruction(Instruct: byte): boolean;
{Execute a single instruction}
var I: integer;
var Opcode: TOpcode;
var Operand: byte;
begin
if not DecodeOpcode(Instruct,Opcode) then raise Exception.Create('Illegal Opcode');
{Separate instruction and operand}
Operand:=$1F and Instruct;
{Execute instruction}
Result:=Opcode.Proc(Operand);
end;
 
 
procedure DisplayInstruction(Memo: TMemo; PC: integer);
{Display instruction information}
var Opcode: TOpcode;
var Inst,Operand: integer;
var S: string;
begin
Inst:=Memory[PC];
if not DecodeOpcode(Inst,Opcode) then raise Exception.Create('Illegal Opcode');
Operand:=Inst and $1F;
S:=IntToStr(PC)+' $'+IntToHex(Inst,2);
S:=S+' '+Opcode.Mnemonic;
case Opcode.ArgType of
atMemory:
begin
S:=S+' Mem['+IntToStr(Operand)+']=';
S:=S+' '+IntToStr(Memory[Operand]);
end;
atAddress: S:=S+' '+IntToStr(Operand);
end;
Memo.Lines.Add(S);
end;
 
 
procedure ExecuteProgram(Memo: TMemo; Prog: TProgram);
{Executed program until stop instruction reached}
begin
Memo.Lines.Add(Prog.Name);
AssembleProgram(Prog.Code);
ProgramCounter:=0;
Accumulator:=0;
repeat
begin
DisplayInstruction(Memo,ProgramCounter);
end
until not ExecuteInstruction(Memory[ProgramCounter]);
Memo.Lines.Add('Result='+IntToStr(Accumulator));
Memo.Lines.Add('');
end;
 
 
 
procedure ShowComputerZero(Memo: TMemo);
{Execute and display all five sample programs.}
begin
ExecuteProgram(Memo,ProgList[0]);
ExecuteProgram(Memo,ProgList[1]);
ExecuteProgram(Memo,ProgList[2]);
ExecuteProgram(Memo,ProgList[3]);
ExecuteProgram(Memo,ProgList[4]);
end;
 
</syntaxhighlight>
{{out}}
<pre>
Two plus two
0 $23 LDA Mem[3]= 2
1 $64 ADD Mem[4]= 2
2 $E0 STP
Result=4
 
Seven times eight
0 $2C LDA Mem[12]= 0
1 $6A ADD Mem[10]= 8
2 $4C STA Mem[12]= 0
3 $2B LDA Mem[11]= 7
4 $8D SUB Mem[13]= 1
5 $4B STA Mem[11]= 7
6 $A8 BRZ 8
7 $C0 JMP 0
0 $2C LDA Mem[12]= 8
1 $6A ADD Mem[10]= 8
2 $4C STA Mem[12]= 8
3 $2B LDA Mem[11]= 6
4 $8D SUB Mem[13]= 1
5 $4B STA Mem[11]= 6
6 $A8 BRZ 8
7 $C0 JMP 0
0 $2C LDA Mem[12]= 16
1 $6A ADD Mem[10]= 8
2 $4C STA Mem[12]= 16
3 $2B LDA Mem[11]= 5
4 $8D SUB Mem[13]= 1
5 $4B STA Mem[11]= 5
6 $A8 BRZ 8
7 $C0 JMP 0
0 $2C LDA Mem[12]= 24
1 $6A ADD Mem[10]= 8
2 $4C STA Mem[12]= 24
3 $2B LDA Mem[11]= 4
4 $8D SUB Mem[13]= 1
5 $4B STA Mem[11]= 4
6 $A8 BRZ 8
7 $C0 JMP 0
0 $2C LDA Mem[12]= 32
1 $6A ADD Mem[10]= 8
2 $4C STA Mem[12]= 32
3 $2B LDA Mem[11]= 3
4 $8D SUB Mem[13]= 1
5 $4B STA Mem[11]= 3
6 $A8 BRZ 8
7 $C0 JMP 0
0 $2C LDA Mem[12]= 40
1 $6A ADD Mem[10]= 8
2 $4C STA Mem[12]= 40
3 $2B LDA Mem[11]= 2
4 $8D SUB Mem[13]= 1
5 $4B STA Mem[11]= 2
6 $A8 BRZ 8
7 $C0 JMP 0
0 $2C LDA Mem[12]= 48
1 $6A ADD Mem[10]= 8
2 $4C STA Mem[12]= 48
3 $2B LDA Mem[11]= 1
4 $8D SUB Mem[13]= 1
5 $4B STA Mem[11]= 1
6 $A8 BRZ 8
8 $2C LDA Mem[12]= 56
9 $E0 STP
Result=56
 
The Fibonacci sequence
0 $2E LDA Mem[14]= 1
1 $4F STA Mem[15]= 0
2 $6D ADD Mem[13]= 1
3 $4E STA Mem[14]= 1
4 $2F LDA Mem[15]= 1
5 $4D STA Mem[13]= 1
6 $30 LDA Mem[16]= 8
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
9 $50 STA Mem[16]= 8
10 $C0 JMP 0
0 $2E LDA Mem[14]= 2
1 $4F STA Mem[15]= 1
2 $6D ADD Mem[13]= 1
3 $4E STA Mem[14]= 2
4 $2F LDA Mem[15]= 2
5 $4D STA Mem[13]= 1
6 $30 LDA Mem[16]= 7
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
9 $50 STA Mem[16]= 7
10 $C0 JMP 0
0 $2E LDA Mem[14]= 3
1 $4F STA Mem[15]= 2
2 $6D ADD Mem[13]= 2
3 $4E STA Mem[14]= 3
4 $2F LDA Mem[15]= 3
5 $4D STA Mem[13]= 2
6 $30 LDA Mem[16]= 6
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
9 $50 STA Mem[16]= 6
10 $C0 JMP 0
0 $2E LDA Mem[14]= 5
1 $4F STA Mem[15]= 3
2 $6D ADD Mem[13]= 3
3 $4E STA Mem[14]= 5
4 $2F LDA Mem[15]= 5
5 $4D STA Mem[13]= 3
6 $30 LDA Mem[16]= 5
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
9 $50 STA Mem[16]= 5
10 $C0 JMP 0
0 $2E LDA Mem[14]= 8
1 $4F STA Mem[15]= 5
2 $6D ADD Mem[13]= 5
3 $4E STA Mem[14]= 8
4 $2F LDA Mem[15]= 8
5 $4D STA Mem[13]= 5
6 $30 LDA Mem[16]= 4
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
9 $50 STA Mem[16]= 4
10 $C0 JMP 0
0 $2E LDA Mem[14]= 13
1 $4F STA Mem[15]= 8
2 $6D ADD Mem[13]= 8
3 $4E STA Mem[14]= 13
4 $2F LDA Mem[15]= 13
5 $4D STA Mem[13]= 8
6 $30 LDA Mem[16]= 3
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
9 $50 STA Mem[16]= 3
10 $C0 JMP 0
0 $2E LDA Mem[14]= 21
1 $4F STA Mem[15]= 13
2 $6D ADD Mem[13]= 13
3 $4E STA Mem[14]= 21
4 $2F LDA Mem[15]= 21
5 $4D STA Mem[13]= 13
6 $30 LDA Mem[16]= 2
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
9 $50 STA Mem[16]= 2
10 $C0 JMP 0
0 $2E LDA Mem[14]= 34
1 $4F STA Mem[15]= 21
2 $6D ADD Mem[13]= 21
3 $4E STA Mem[14]= 34
4 $2F LDA Mem[15]= 34
5 $4D STA Mem[13]= 21
6 $30 LDA Mem[16]= 1
7 $91 SUB Mem[17]= 1
8 $AB BRZ 11
11 $2E LDA Mem[14]= 55
12 $E0 STP
Result=55
 
Linked list
0 $2D LDA Mem[13]= 32
1 $6F ADD Mem[15]= 28
2 $45 STA Mem[5]= 0
3 $70 ADD Mem[16]= 1
4 $47 STA Mem[7]= 0
5 $3C LDA Mem[28]= 1
6 $4E STA Mem[14]= 0
7 $3D LDA Mem[29]= 22
8 $AB BRZ 11
9 $4F STA Mem[15]= 28
10 $C0 JMP 0
0 $2D LDA Mem[13]= 32
1 $6F ADD Mem[15]= 22
2 $45 STA Mem[5]= 60
3 $70 ADD Mem[16]= 1
4 $47 STA Mem[7]= 61
5 $36 LDA Mem[22]= 2
6 $4E STA Mem[14]= 1
7 $37 LDA Mem[23]= 26
8 $AB BRZ 11
9 $4F STA Mem[15]= 22
10 $C0 JMP 0
0 $2D LDA Mem[13]= 32
1 $6F ADD Mem[15]= 26
2 $45 STA Mem[5]= 54
3 $70 ADD Mem[16]= 1
4 $47 STA Mem[7]= 55
5 $3A LDA Mem[26]= 3
6 $4E STA Mem[14]= 2
7 $3B LDA Mem[27]= 30
8 $AB BRZ 11
9 $4F STA Mem[15]= 26
10 $C0 JMP 0
0 $2D LDA Mem[13]= 32
1 $6F ADD Mem[15]= 30
2 $45 STA Mem[5]= 58
3 $70 ADD Mem[16]= 1
4 $47 STA Mem[7]= 59
5 $3E LDA Mem[30]= 4
6 $4E STA Mem[14]= 3
7 $3F LDA Mem[31]= 24
8 $AB BRZ 11
9 $4F STA Mem[15]= 30
10 $C0 JMP 0
0 $2D LDA Mem[13]= 32
1 $6F ADD Mem[15]= 24
2 $45 STA Mem[5]= 62
3 $70 ADD Mem[16]= 1
4 $47 STA Mem[7]= 63
5 $38 LDA Mem[24]= 5
6 $4E STA Mem[14]= 4
7 $39 LDA Mem[25]= 20
8 $AB BRZ 11
9 $4F STA Mem[15]= 24
10 $C0 JMP 0
0 $2D LDA Mem[13]= 32
1 $6F ADD Mem[15]= 20
2 $45 STA Mem[5]= 56
3 $70 ADD Mem[16]= 1
4 $47 STA Mem[7]= 57
5 $34 LDA Mem[20]= 6
6 $4E STA Mem[14]= 5
7 $35 LDA Mem[21]= 0
8 $AB BRZ 11
11 $2E LDA Mem[14]= 6
12 $E0 STP
Result=6
 
Prisoner’s Dilemma
0 $00 NOP
1 $00 NOP
2 $E0 STP
Result=0
Elapsed Time: 611.666 ms.
</pre>
 
 
=={{header|EasyLang}}==
<syntaxhighlight>
proc run name$ mem[] . .
write name$ & ": "
pc = 1
len mem[] 32
repeat
ppc = mem[pc]
op = ppc div 32
addr = ppc mod 32 + 1
pc += 1
if op = 1
acc = mem[addr]
elif op = 2
mem[addr] = acc
elif op = 3
acc = (acc + mem[addr]) mod 255
elif op = 4
acc = (acc - mem[addr]) mod 255
elif op = 5
if acc = 0
pc = addr
.
elif op = 6
pc = addr
.
until op = 7 or pc > 32
.
print acc
.
run "2+2" [ 35 100 224 2 2 ]
run "7*8" [ 44 106 76 43 141 75 168 192 44 224 8 7 0 1 ]
run "Fibonacci" [ 46 79 109 78 47 77 48 145 171 80 192 46 224 1 1 0 8 1 ]
run "List" [ 45 111 69 112 71 0 78 0 171 79 192 46 224 32 0 28 1 0 0 0 6 0 2 26 5 20 3 30 1 22 4 24 ]
run "Prisoner" [ 0 0 224 0 0 35 157 178 35 93 174 33 127 65 194 32 127 64 192 35 93 33 126 99 ]
</syntaxhighlight>
 
{{out}}
<pre>
2+2: 4
7*8: 56
Fibonacci: 55
List: 6
Prisoner: 0
</pre>
 
=={{header|Forth}}==
{{works with|gforth|0.7.3}}
<br>
<syntaxhighlight lang="forth">#! /usr/bin/gforth
 
\ Execute Computer/Zero
 
\ reserve 32 cells for memory
 
CREATE MEMORY 32 cells allot
MEMORY 32 cells erase
 
 
\ gets the address of the memory cell with the given index
: mem ( ix - addr )
cells MEMORY +
;
 
\ splits a byte into instruction and argument
: instruction ( ix -> arg inst )
mem @ dup
32 mod swap
32 /
;
 
\ defines a program by giving its name and the 32 memory contents (in binary)
: PROGRAM ( "name" "b01" ... "b31" -- )
CREATE
base @ >r 2 base !
32 0 DO
BEGIN
parse-name
dup 0= WHILE
2drop refill drop
REPEAT
s>number? 2drop ,
LOOP
r> base !
DOES> ( -- n00 ... n31 )
32 0 DO
dup @ swap cell+
LOOP
drop
;
 
\ loads 32 bytes from the stack into memory
: >memory ( n00 ... n31 -- )
-1 31 -DO
i mem !
1 -LOOP
;
 
\ prints accumulator and program counter
: .acc-pc ( acc pc -- acc pc )
over 3 .r dup 3 .r
;
 
\ prints the argument
: .x ( x -- x )
dup 2 .r
;
 
\ performs one step of the simulation
: step ( acc pc -- acc' pc' )
.acc-pc ." : "
tuck instruction CASE
0 OF ." NOP " .x drop swap 1+ ENDOF
1 OF ." LDA " .x nip mem @ swap 1+ ENDOF
2 OF ." STA " .x over swap mem ! swap 1+ ENDOF
3 OF ." ADD " .x mem @ + 256 mod swap 1+ ENDOF
4 OF ." SUB " .x mem @ - 256 mod swap 1+ ENDOF
5 OF ." BRZ " .x over 0= if rot drop else drop swap 1+ then ENDOF
6 OF ." JMP " .x rot drop ENDOF
7 OF ." STP " .x drop nip -1 ENDOF
ENDCASE
." -> " .acc-pc
;
 
\ runs the simulation, starting with accumulator zero and program counter zero
: run ( -- acc )
0 0 cr
BEGIN
dup 0>= WHILE
step cr
REPEAT
drop
;
 
 
\ the five example programs
 
PROGRAM 2+2
00100011 01100100
11100000 00000010
00000010 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
 
PROGRAM 7*8
00101100 01101010
01001100 00101011
10001101 01001011
10101000 11000000
00101100 11100000
00001000 00000111
00000000 00000001
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
 
PROGRAM Fibonacci
00101110 01001111
01101101 01001110
00101111 01001101
00110000 10010001
10101011 01010000
11000000 00101110
11100000 00000001
00000001 00000000
00001000 00000001
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
 
PROGRAM List'
00101101 01101111
01000101 01110000
01000111 00000000
01001110 00000000
10101011 01001111
11000000 00101110
11100000 00100000
00000000 00011100
00000001 00000000
00000000 00000000
00000110 00000000
00000010 00011010
00000101 00010100
00000011 00011110
00000001 00010110
00000100 00011000
 
PROGRAM Prisoner
00000000 00000000
11100000 00000000
00100011 10011101
10110010 00100011
01011101 10101110
00100001 01111111
01000001 11000010
00100000 01111111
01000000 11000010
00100011 01011101
00100001 01111110
01100011 01000001
00100000 01111110
01100011 01000000
11000010 00000000
00000001 00000011
 
 
\ runs a program and drops the result
: run-sample-program ( -- )
>memory run drop
;
 
 
\ run the five example programs
 
2+2 run-sample-program
7*8 run-sample-program
Fibonacci run-sample-program
List' run-sample-program
Prisoner run-sample-program
 
bye
</syntaxhighlight>
 
{{out}}
0 0 : LDA 3 -> 2 1
2 1 : ADD 4 -> 4 2
4 2 : STP 0 -> 4 -1
 
0 0 : LDA 12 -> 0 1
0 1 : ADD 10 -> 8 2
8 2 : STA 12 -> 8 3
8 3 : LDA 11 -> 7 4
7 4 : SUB 13 -> 6 5
6 5 : STA 11 -> 6 6
6 6 : BRZ 8 -> 6 7
6 7 : JMP 0 -> 6 0
6 0 : LDA 12 -> 8 1
8 1 : ADD 10 -> 16 2
16 2 : STA 12 -> 16 3
16 3 : LDA 11 -> 6 4
6 4 : SUB 13 -> 5 5
5 5 : STA 11 -> 5 6
5 6 : BRZ 8 -> 5 7
5 7 : JMP 0 -> 5 0
5 0 : LDA 12 -> 16 1
16 1 : ADD 10 -> 24 2
24 2 : STA 12 -> 24 3
24 3 : LDA 11 -> 5 4
5 4 : SUB 13 -> 4 5
4 5 : STA 11 -> 4 6
4 6 : BRZ 8 -> 4 7
4 7 : JMP 0 -> 4 0
4 0 : LDA 12 -> 24 1
24 1 : ADD 10 -> 32 2
32 2 : STA 12 -> 32 3
32 3 : LDA 11 -> 4 4
4 4 : SUB 13 -> 3 5
3 5 : STA 11 -> 3 6
3 6 : BRZ 8 -> 3 7
3 7 : JMP 0 -> 3 0
3 0 : LDA 12 -> 32 1
32 1 : ADD 10 -> 40 2
40 2 : STA 12 -> 40 3
40 3 : LDA 11 -> 3 4
3 4 : SUB 13 -> 2 5
2 5 : STA 11 -> 2 6
2 6 : BRZ 8 -> 2 7
2 7 : JMP 0 -> 2 0
2 0 : LDA 12 -> 40 1
40 1 : ADD 10 -> 48 2
48 2 : STA 12 -> 48 3
48 3 : LDA 11 -> 2 4
2 4 : SUB 13 -> 1 5
1 5 : STA 11 -> 1 6
1 6 : BRZ 8 -> 1 7
1 7 : JMP 0 -> 1 0
1 0 : LDA 12 -> 48 1
48 1 : ADD 10 -> 56 2
56 2 : STA 12 -> 56 3
56 3 : LDA 11 -> 1 4
1 4 : SUB 13 -> 0 5
0 5 : STA 11 -> 0 6
0 6 : BRZ 8 -> 0 8
0 8 : LDA 12 -> 56 9
56 9 : STP 0 -> 56 -1
 
0 0 : LDA 14 -> 1 1
1 1 : STA 15 -> 1 2
1 2 : ADD 13 -> 2 3
2 3 : STA 14 -> 2 4
2 4 : LDA 15 -> 1 5
1 5 : STA 13 -> 1 6
1 6 : LDA 16 -> 8 7
8 7 : SUB 17 -> 7 8
7 8 : BRZ 11 -> 7 9
7 9 : STA 16 -> 7 10
7 10 : JMP 0 -> 7 0
7 0 : LDA 14 -> 2 1
2 1 : STA 15 -> 2 2
2 2 : ADD 13 -> 3 3
3 3 : STA 14 -> 3 4
3 4 : LDA 15 -> 2 5
2 5 : STA 13 -> 2 6
2 6 : LDA 16 -> 7 7
7 7 : SUB 17 -> 6 8
6 8 : BRZ 11 -> 6 9
6 9 : STA 16 -> 6 10
6 10 : JMP 0 -> 6 0
6 0 : LDA 14 -> 3 1
3 1 : STA 15 -> 3 2
3 2 : ADD 13 -> 5 3
5 3 : STA 14 -> 5 4
5 4 : LDA 15 -> 3 5
3 5 : STA 13 -> 3 6
3 6 : LDA 16 -> 6 7
6 7 : SUB 17 -> 5 8
5 8 : BRZ 11 -> 5 9
5 9 : STA 16 -> 5 10
5 10 : JMP 0 -> 5 0
5 0 : LDA 14 -> 5 1
5 1 : STA 15 -> 5 2
5 2 : ADD 13 -> 8 3
8 3 : STA 14 -> 8 4
8 4 : LDA 15 -> 5 5
5 5 : STA 13 -> 5 6
5 6 : LDA 16 -> 5 7
5 7 : SUB 17 -> 4 8
4 8 : BRZ 11 -> 4 9
4 9 : STA 16 -> 4 10
4 10 : JMP 0 -> 4 0
4 0 : LDA 14 -> 8 1
8 1 : STA 15 -> 8 2
8 2 : ADD 13 -> 13 3
13 3 : STA 14 -> 13 4
13 4 : LDA 15 -> 8 5
8 5 : STA 13 -> 8 6
8 6 : LDA 16 -> 4 7
4 7 : SUB 17 -> 3 8
3 8 : BRZ 11 -> 3 9
3 9 : STA 16 -> 3 10
3 10 : JMP 0 -> 3 0
3 0 : LDA 14 -> 13 1
13 1 : STA 15 -> 13 2
13 2 : ADD 13 -> 21 3
21 3 : STA 14 -> 21 4
21 4 : LDA 15 -> 13 5
13 5 : STA 13 -> 13 6
13 6 : LDA 16 -> 3 7
3 7 : SUB 17 -> 2 8
2 8 : BRZ 11 -> 2 9
2 9 : STA 16 -> 2 10
2 10 : JMP 0 -> 2 0
2 0 : LDA 14 -> 21 1
21 1 : STA 15 -> 21 2
21 2 : ADD 13 -> 34 3
34 3 : STA 14 -> 34 4
34 4 : LDA 15 -> 21 5
21 5 : STA 13 -> 21 6
21 6 : LDA 16 -> 2 7
2 7 : SUB 17 -> 1 8
1 8 : BRZ 11 -> 1 9
1 9 : STA 16 -> 1 10
1 10 : JMP 0 -> 1 0
1 0 : LDA 14 -> 34 1
34 1 : STA 15 -> 34 2
34 2 : ADD 13 -> 55 3
55 3 : STA 14 -> 55 4
55 4 : LDA 15 -> 34 5
34 5 : STA 13 -> 34 6
34 6 : LDA 16 -> 1 7
1 7 : SUB 17 -> 0 8
0 8 : BRZ 11 -> 0 11
0 11 : LDA 14 -> 55 12
55 12 : STP 0 -> 55 -1
 
0 0 : LDA 13 -> 32 1
32 1 : ADD 15 -> 60 2
60 2 : STA 5 -> 60 3
60 3 : ADD 16 -> 61 4
61 4 : STA 7 -> 61 5
61 5 : LDA 28 -> 1 6
1 6 : STA 14 -> 1 7
1 7 : LDA 29 -> 22 8
22 8 : BRZ 11 -> 22 9
22 9 : STA 15 -> 22 10
22 10 : JMP 0 -> 22 0
22 0 : LDA 13 -> 32 1
32 1 : ADD 15 -> 54 2
54 2 : STA 5 -> 54 3
54 3 : ADD 16 -> 55 4
55 4 : STA 7 -> 55 5
55 5 : LDA 22 -> 2 6
2 6 : STA 14 -> 2 7
2 7 : LDA 23 -> 26 8
26 8 : BRZ 11 -> 26 9
26 9 : STA 15 -> 26 10
26 10 : JMP 0 -> 26 0
26 0 : LDA 13 -> 32 1
32 1 : ADD 15 -> 58 2
58 2 : STA 5 -> 58 3
58 3 : ADD 16 -> 59 4
59 4 : STA 7 -> 59 5
59 5 : LDA 26 -> 3 6
3 6 : STA 14 -> 3 7
3 7 : LDA 27 -> 30 8
30 8 : BRZ 11 -> 30 9
30 9 : STA 15 -> 30 10
30 10 : JMP 0 -> 30 0
30 0 : LDA 13 -> 32 1
32 1 : ADD 15 -> 62 2
62 2 : STA 5 -> 62 3
62 3 : ADD 16 -> 63 4
63 4 : STA 7 -> 63 5
63 5 : LDA 30 -> 4 6
4 6 : STA 14 -> 4 7
4 7 : LDA 31 -> 24 8
24 8 : BRZ 11 -> 24 9
24 9 : STA 15 -> 24 10
24 10 : JMP 0 -> 24 0
24 0 : LDA 13 -> 32 1
32 1 : ADD 15 -> 56 2
56 2 : STA 5 -> 56 3
56 3 : ADD 16 -> 57 4
57 4 : STA 7 -> 57 5
57 5 : LDA 24 -> 5 6
5 6 : STA 14 -> 5 7
5 7 : LDA 25 -> 20 8
20 8 : BRZ 11 -> 20 9
20 9 : STA 15 -> 20 10
20 10 : JMP 0 -> 20 0
20 0 : LDA 13 -> 32 1
32 1 : ADD 15 -> 52 2
52 2 : STA 5 -> 52 3
52 3 : ADD 16 -> 53 4
53 4 : STA 7 -> 53 5
53 5 : LDA 20 -> 6 6
6 6 : STA 14 -> 6 7
6 7 : LDA 21 -> 0 8
0 8 : BRZ 11 -> 0 11
0 11 : LDA 14 -> 6 12
6 12 : STP 0 -> 6 -1
 
0 0 : NOP 0 -> 0 1
0 1 : NOP 0 -> 0 2
0 2 : STP 0 -> 0 -1
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
"bufio"
"fmt"
"io"
"regexp"
"strconv"
"strings"
)
 
const (
NOP = iota
LDA
STA
ADD
SUB
BRZ
JMP
STP
)
 
var opcodes = map[string]int{
"NOP": NOP,
"LDA": LDA,
"STA": STA,
"ADD": ADD,
"SUB": SUB,
"BRZ": BRZ,
"JMP": JMP,
"STP": STP,
}
 
var reIns = regexp.MustCompile(
`\s*(?:(\w+):)?\s*` + // label
`(NOP|LDA|STA|ADD|SUB|BRZ|JMP|STP)?\s*` + // opcode
`(\w+)?\s*` + // argument
`(?:;([\w\s]+))?`) // comment
 
type ByteCode [32]int
 
type instruction struct {
Label string
Opcode string
Arg string
}
 
type Program struct {
Instructions []instruction
Labels map[string]int
}
 
func newInstruction(line string) (*instruction, error) {
match := reIns.FindStringSubmatch(line)
if match == nil {
return nil, fmt.Errorf("syntax error: '%s'", line)
}
return &instruction{Label: match[1], Opcode: match[2], Arg: match[3]}, nil
}
 
func Parse(asm io.Reader) (*Program, error) {
var p Program
p.Labels = make(map[string]int, 32)
scanner := bufio.NewScanner(asm)
lineNumber := 0
 
for scanner.Scan() {
if instruction, err := newInstruction(scanner.Text()); err != nil {
return &p, err
} else {
if instruction.Label != "" {
p.Labels[instruction.Label] = lineNumber
}
p.Instructions = append(p.Instructions, *instruction)
lineNumber++
}
}
 
if err := scanner.Err(); err != nil {
return nil, err
}
 
return &p, nil
}
 
func (p *Program) Compile() (ByteCode, error) {
var bytecode ByteCode
var arg int
for i, ins := range p.Instructions {
if ins.Arg == "" {
arg = 0
} else if addr, err := strconv.Atoi(ins.Arg); err == nil {
arg = addr
} else if addr, ok := p.Labels[ins.Arg]; ok {
arg = addr
} else {
return bytecode, fmt.Errorf("unknown label %v", ins.Arg)
}
 
if opcode, ok := opcodes[ins.Opcode]; ok {
bytecode[i] = opcode<<5 | arg
} else {
bytecode[i] = arg
}
}
return bytecode, nil
}
 
func floorMod(a, b int) int {
return ((a % b) + b) % b
}
 
func Run(bytecode ByteCode) (int, error) {
acc := 0
pc := 0
mem := bytecode
 
var op int
var arg int
 
loop:
for pc < 32 {
op = mem[pc] >> 5
arg = mem[pc] & 31
pc++
 
switch op {
case NOP:
continue
case LDA:
acc = mem[arg]
case STA:
mem[arg] = acc
case ADD:
acc = floorMod(acc+mem[arg], 256)
case SUB:
acc = floorMod(acc-mem[arg], 256)
case BRZ:
if acc == 0 {
pc = arg
}
case JMP:
pc = arg
case STP:
break loop
default:
return acc, fmt.Errorf("runtime error: %v %v", op, arg)
}
}
 
return acc, nil
}
 
func Execute(asm string) (int, error) {
program, err := Parse(strings.NewReader(asm))
if err != nil {
return 0, fmt.Errorf("assembly error: %v", err)
}
 
bytecode, err := program.Compile()
if err != nil {
return 0, fmt.Errorf("compilation error: %v", err)
}
 
result, err := Run(bytecode)
if err != nil {
return 0, err
}
 
return result, nil
}
 
func main() {
examples := []string{
`LDA x
ADD y ; accumulator = x + y
STP
x: 2
y: 2`,
`loop: LDA prodt
ADD x
STA prodt
LDA y
SUB one
STA y
BRZ done
JMP loop
done: LDA prodt ; to display it
STP
x: 8
y: 7
prodt: 0
one: 1`,
`loop: LDA n
STA temp
ADD m
STA n
LDA temp
STA m
LDA count
SUB one
BRZ done
STA count
JMP loop
done: LDA n ; to display it
STP
m: 1
n: 1
temp: 0
count: 8 ; valid range: 1-11
one: 1`,
`start: LDA load
ADD car ; head of list
STA ldcar
ADD one
STA ldcdr ; next CONS cell
ldcar: NOP
STA value
ldcdr: NOP
BRZ done ; 0 stands for NIL
STA car
JMP start
done: LDA value ; CAR of last CONS
STP
load: LDA 0
value: 0
car: 28
one: 1
; order of CONS cells
; in memory
; does not matter
6
0 ; 0 stands for NIL
2 ; (CADR ls)
26 ; (CDDR ls) -- etc.
5
20
3
30
1 ; value of (CAR ls)
22 ; points to (CDR ls)
4
24`,
`LDA 3
SUB 4
STP 0
0
255`,
`LDA 3
SUB 4
STP 0
0
1`,
`LDA 3
ADD 4
STP 0
1
255`,
}
 
for _, asm := range examples {
if result, err := Execute(asm); err == nil {
fmt.Println(result)
} else {
fmt.Println(err)
}
}
}
</syntaxhighlight>
 
{{out}}
<pre>
4
56
55
6
1
255
0
</pre>
 
=={{header|J}}==
Line 20 ⟶ 1,405:
Here's one approach which might be sufficiently close to the task requirements:
 
<syntaxhighlight lang J="j">OPS=: ;:'nop lda sta add sub brz jmp stp lit'
 
assemble1=: {{
insy=. ;:tolower y
codins=. OPS {.;:y-.":i. {.ins10
valcod=. {.0".8|(;}:OPS) i. ins
val=. {.0".y-.OPS
if. 8=cod do.
if. *cod assertdo. 256>val
val
else.
assert. 8>cod
assert. 32>val
val+32*cod
else.
assert. 256>val
val
end.
}}
 
assemble=: {{
acc=:if. pc0=:L. 0y do.
delim=. {.((tolower y)-.(":i.10),;OPS),LF
code=. assemble1@> cutLF^:(0=L.) y
y=. delim cut y
end.
code=. assemble1@> y
mem=: code (i.#code)} 32#0
}}
Line 61 ⟶ 1,449:
while. 0<:pc do. exec1'' end.
acc
}}</langsyntaxhighlight>
 
With this implementation, we can assemble and run representations of the five suggested programs:
 
<langsyntaxhighlight Jlang="j"> exec assemble 'LDA 3';' ADD 4';' STP';'NOP 2';'NOP 2'
4
exec assemble 'LDA 12';' ADD 10';' STA 12';' LDA 11';' SUB 13';' STA 11';' BRZ 8';'JMP 0'JMP;' LDA 12';' STP 0';'NOP 8';'NOP 7';'NOP 0';'NOP 1'
56
exec assemble 'LDA 14';' STA 15';' ADD 13';' STA 14';' LDA 15';' STA 13';' LDA 16';' SUB 17';' BRZ 11';' STA 16';'JMP 0'JMP;' LDA 14';' STP 0';'NOP 1';'NOP 1';'NOP 0';'NOP 8';'NOP 1'
55
exec assemble 'LDA 13';' ADD 15';' STA 5';' ADD 16';' STA 7';'NOP 0'NOP;' STA 14';'NOP 0'NOP;' BRZ 11';' STA 15';'JMP 0'JMP;' LDA 14';' STP; 0';'LDA 0';'NOP 0';'NOP 28';'NOP 1';'NOP 0';'NOP 0';'NOP 0';'NOP 6';'NOP 0';'NOP 2';'NOP 26';'NOP 5';'NOP 20';'NOP 3';'NOP 30';'NOP 1';'NOP 22';'NOP 4';'NOP 24'
6
exec assemble 'NOP; 0'NOP;'NOP 0'STP;'STP 0'NOP;'NOP 0';'LDA 3';' SUB 29';' BRZ 18';' LDA 3';' STA 29';' BRZ 14';' LDA 1';' ADD 31';' STA 1';' JMP 2';'LDA 0'LDA;' ADD 31';'STA 0'STA;' JMP 2';' LDA 3';' STA 29';' LDA 1';' ADD 30';' ADD 3';' STA 1';'LDA 0'LDA;' ADD 30';' ADD 3';'STA 0'STA;' JMP 2';'NOP 0';'NOP 1';'NOP 3'
0</langsyntaxhighlight>
 
=== Alternate approach ===
 
Another approach would be to eliminate the 'assemble' command and implement the opcodes as native J commands (which build a representation of the memory space). To conform with J syntax, the right arguments of these opcodes is required (so you need a 0 even for NOP and STP). The implementation of <code>exec</code> remains much the same as before, but it's convenient to have exec save the code to memory. In other words:
 
<syntaxhighlight lang="j">opcode=: {{
(m+{.y),}.y
:
x,m opcode y
}}
 
({{((x)=: y opcode)0}}&>32*i.@#);:'NOP LDA STA ADD SUB BRZ JMP STP'
 
exec1=: {{
'cod val'=. 0 32#:pc{mem
pc=: 32|pc+1
select. cod
case. 0 do. NB. NOP
case. 1 do. acc=: val{mem NB. LDA
case. 2 do. mem=: acc val} mem NB. STA
case. 3 do. acc=: 256|acc+val{mem NB. ADD
case. 4 do. acc=: 256|acc-val{mem NB. SUB
case. 5 do. pc=: 32|pc[^:(*acc) val NB. BRZ
case. 6 do. pc=: 32|val NB. JMP
case. 7 do. pc=: __ NB. STP
end.
}}
 
exec=: {{
mem=: 32{.y
pc=: acc=: 0
while. 0<:pc do. exec1'' end.
acc
}}</syntaxhighlight>
 
and:
 
<syntaxhighlight lang="j"> exec LDA 3 ADD 4 STP 0 2 2
4
exec LDA 12 ADD 10 STA 12 LDA 11 SUB 13 STA 11 BRZ 8 JMP 0 LDA 12 STP 0 8 7 0 1
56
exec 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 0 1 1 0 8 1
55
exec LDA 13 ADD 15 STA 5 ADD 16 STA 7 NOP 0 STA 14 NOP 0 BRZ 11 STA 15 JMP 0 LDA 14 STP 0 LDA 0 0 28 1 0 0 0 6 0 2 26 5 20 3 30 1 22 4 24
6
exec NOP 0 NOP 0 STP 0 NOP 0 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 1 ADD 30 ADD 3 STA 1 LDA 0 ADD 30 ADD 3 STA 0 JMP 2 0 1 3
0</syntaxhighlight>
 
=={{header|Java}}==
{{trans|Python}}
{{works with|Java|8}}
 
<syntaxhighlight lang="python">import static java.lang.Math.floorMod;
import static java.lang.Math.min;
import static java.util.stream.Collectors.toMap;
 
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
 
public class ComputerZero {
 
private static final int MEM = 32;
 
private static final int NOP = 0;
private static final int LDA = 1;
private static final int STA = 2;
private static final int ADD = 3;
private static final int SUB = 4;
private static final int BRZ = 5;
private static final int JMP = 6;
private static final int STP = 7;
 
private static final Map<String, Integer> OPCODES = Stream.of(
new SimpleEntry<>("NOP", NOP),
new SimpleEntry<>("LDA", LDA),
new SimpleEntry<>("STA", STA),
new SimpleEntry<>("ADD", ADD),
new SimpleEntry<>("SUB", SUB),
new SimpleEntry<>("BRZ", BRZ),
new SimpleEntry<>("JMP", JMP),
new SimpleEntry<>("STP", STP))
.collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));
 
private static final Pattern RE_INSTRUCTION = Pattern.compile(
"\\s*" +
"(?:(?<label>\\w+):)?" +
"\\s*" +
String.format("(?<opcode>%s)?", String.join("|", OPCODES.keySet())) +
"\\s*" +
"(?<argument>\\w+)?" +
"\\s*" +
"(?:;(?<comment>.+))?");
 
public static class ComputerZeroException extends RuntimeException {
public ComputerZeroException(String msg) {
super(msg);
}
}
 
private static class Instruction {
String opcode;
String argument;
 
public Instruction(String opcode, String argument) {
this.opcode = opcode;
this.argument = argument;
}
}
 
private static class Assembly {
public Iterable<Instruction> instructions;
public Map<String, Integer> labels;
 
public Assembly(Iterable<Instruction> instructions, Map<String, Integer> labels) {
this.instructions = instructions;
this.labels = labels;
}
}
 
public static Assembly parse(String assembly) {
ArrayList<Instruction> instructions = new ArrayList<Instruction>();
HashMap<String, Integer> labels = new HashMap<String, Integer>();
int lineNumber = 0;
 
for (String line : assembly.split("\\R")) {
Matcher matcher = RE_INSTRUCTION.matcher(line);
 
if (!matcher.matches()) {
throw new ComputerZeroException(String.format("%s %d", line, lineNumber));
}
 
if (matcher.group("label") != null) {
labels.put(matcher.group("label"), lineNumber);
}
 
instructions.add(new Instruction(matcher.group("opcode"), matcher.group("argument")));
lineNumber++;
}
 
return new Assembly(instructions, labels);
}
 
public static Integer[] compile(Assembly assembly) {
ArrayList<Integer> bytecode = new ArrayList<Integer>();
 
for (Instruction instruction : assembly.instructions) {
int argument;
if (instruction.argument == null) {
argument = 0;
} else if (instruction.argument.matches("\\d+")) {
argument = Integer.parseInt(instruction.argument);
} else {
argument = assembly.labels.getOrDefault(instruction.argument, 0);
}
 
if (instruction.opcode != null) {
bytecode.add(OPCODES.get(instruction.opcode) << 5 | argument);
} else {
bytecode.add(argument);
}
}
 
return bytecode.toArray(new Integer[0]);
}
 
public static int run(Integer[] bytecode) {
int accumulator = 0;
int instruction_pointer = 0;
Integer[] memory = new Integer[MEM];
Arrays.fill(memory, 0);
System.arraycopy(bytecode, 0, memory, 0, min(MEM, bytecode.length));
 
vm: while (instruction_pointer < MEM) {
int operation = memory[instruction_pointer] >> 5;
int argument = memory[instruction_pointer] & 0b11111;
instruction_pointer++;
 
switch (operation) {
case NOP:
continue;
case LDA:
accumulator = memory[argument];
break;
case STA:
memory[argument] = accumulator;
break;
case ADD:
accumulator = floorMod(accumulator + memory[argument], 256);
break;
case SUB:
accumulator = floorMod(accumulator - memory[argument], 256);
break;
case BRZ:
if (accumulator == 0) {
instruction_pointer = argument;
}
break;
case JMP:
instruction_pointer = argument;
break;
case STP:
break vm;
default:
throw new ComputerZeroException(
String.format("error: %d %d", operation, argument));
}
 
}
 
return accumulator;
}
 
public static int run(String source) {
return run(compile(parse(source)));
}
 
public static final List<String> TEST_CASES = Arrays.asList(
String.join("\n",
" LDA x",
" ADD y ; accumulator = x + y",
" STP",
"x: 2",
"y: 2"),
String.join("\n",
"loop: LDA prodt",
" ADD x",
" STA prodt",
" LDA y",
" SUB one",
" STA y",
" BRZ done",
" JMP loop",
"done: LDA prodt ; to display it",
" STP",
"x: 8",
"y: 7",
"prodt: 0",
"one: 1"),
String.join("\n",
"loop: LDA n",
" STA temp",
" ADD m",
" STA n",
" LDA temp",
" STA m",
" LDA count",
" SUB one",
" BRZ done",
" STA count",
" JMP loop",
"done: LDA n ; to display it",
" STP",
"m: 1",
"n: 1",
"temp: 0",
"count: 8 ; valid range: 1-11",
"one: 1"),
String.join("\n",
"start: LDA load",
" ADD car ; head of list",
" STA ldcar",
" ADD one",
" STA ldcdr ; next CONS cell",
"ldcar: NOP",
" STA value",
"ldcdr: NOP",
" BRZ done ; 0 stands for NIL",
" STA car",
" JMP start",
"done: LDA value ; CAR of last CONS",
" STP",
"load: LDA 0",
"value: 0",
"car: 28",
"one: 1",
" ; order of CONS cells",
" ; in memory",
" ; does not matter",
" 6",
" 0 ; 0 stands for NIL",
" 2 ; (CADR ls)",
" 26 ; (CDDR ls) -- etc.",
" 5",
" 20",
" 3",
" 30",
" 1 ; value of (CAR ls)",
" 22 ; points to (CDR ls)",
" 4",
" 24"),
String.join("\n",
"p: 0 ; NOP in first round",
"c: 0",
"start: STP ; wait for p's move",
"pmove: NOP",
" LDA pmove",
" SUB cmove",
" BRZ same",
" LDA pmove",
" STA cmove ; tit for tat",
" BRZ cdeft",
" LDA c ; p defected, c did not",
" ADD three",
" STA c",
" JMP start",
"cdeft: LDA p",
" ADD three",
" STA p",
" JMP start",
"same: LDA pmove",
" STA cmove ; tit for tat",
" LDA p",
" ADD one",
" ADD pmove",
" STA p",
" LDA c",
" ADD one",
" ADD pmove",
" STA c",
" JMP start",
"cmove: 0 ; co-operate initially",
"one: 1",
"three: 3 "),
String.join("\n",
"LDA 3",
"SUB 4",
"STP 0",
" 0",
" 255"),
String.join("\n",
"LDA 3",
"SUB 4",
"STP 0",
" 0",
" 1"),
String.join("\n",
"LDA 3",
"ADD 4",
"STP 0",
" 1",
" 255")
 
);
 
public static void main(String[] args) {
for (String source : TEST_CASES) {
System.out.println(run(source));
}
}
}
</syntaxhighlight>
 
{{out}}
<pre>
4
56
55
6
0
1
255
0
</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
 
This entry assumes all the programs have been placed in a text file
in which each program takes the form of a header followed
by the instructions, one per line, followed by at least one blank line.
 
The header is assumed to have the form:
<pre>
; title
</pre>
<syntaxhighlight lang="jq">
### Utility
def trim: sub("^ +";"") | sub(" +$";"");
 
### Computer/Zero
def NOP: 0;
def LDA: 1;
def STA: 2;
def ADD: 3;
def SUB: 4;
def BRZ: 5;
def JMP: 6;
def STP: 7;
 
def ops: {"NOP": NOP, "LDA": LDA, "STA": STA, "ADD": ADD,
"SUB": SUB, "BRZ": BRZ, "JMP": JMP, "STP": STP};
 
# Input: the program in the form of an array of strings,
# each string corresponding to an input line of the form
# "INSTR N" or "N"
# Output: an array of integers
def load:
map([splits(" *")] as $split
| $split[0] as $instr
| (if ($split|length == 2) then $split[1]|tonumber
else 0
end) as $addr
| if ops[$instr]
then ops[$instr] * 32 + $addr
else try ($instr|tonumber) catch 0
end );
 
# input: an array as produced by `load`
def interp:
{ acc: 0, pc: 0, mem: .}
| until(.break;
(.mem[.pc] % 32) as $addr
| ((.mem[.pc] - $addr) / 32) as $instr
| .pc += 1
| if $instr == LDA then .acc = .mem[$addr]
elif $instr == STA then .mem[$addr] = .acc
elif $instr == ADD then .acc += .mem[$addr]
| if .acc > 255 then .acc += -256 else . end
elif $instr == SUB then .acc += (- .mem[$addr])
| if .acc < 0 then .acc += 256 else . end
elif $instr == BRZ
then if .acc == 0 then .pc = $addr else . end
elif $instr == JMP then .pc = $addr
else .
end
| .break = $instr == STP or .pc > 31 )
| .acc;
 
# Assume the input file consists of several programs, each structured as:
# ; program name
# one instruction per line
#
def task:
def init: map_values(null);
foreach (inputs, null) as $line ({};
if $line == null then .program = .buffer
elif $line[0:1] == ";" then init | .title = $line
else ($line|trim) as $line
| if $line == "" then .program = .buffer | .buffer = []
else .buffer += [$line]
end
end)
| .title as $title
| .program
| if length == 0 then empty
else
$title, (load|interp)
end ;
 
task
</syntaxhighlight>
'''Program file - scrollable window''' (programs.txt)
<div style="overflow:scroll; height:400px;">
<pre>
; 2+2
LDA 3
ADD 4
STP
2
2
 
; 7 * 8
LDA 12
ADD 10
STA 12
LDA 11
SUB 13
STA 11
BRZ 8
JMP 0
LDA 12
STP
8
7
0
1
 
; fibonacci
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
 
; linkedList
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
 
; prisoner
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
</pre>
</div>
 
{{output}}
'''Invocation:''' jq -nR -f execute-computer-zero.jq programs.txt
<pre>
"; 2+2"
4
"; 7 * 8"
56
"; fibonacci"
55
"; linkedList"
6
"; prisoner"
0
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">mutable struct ComputerZero
ip::Int
ram::Vector{UInt8}
accum::UInt8
isready::Bool
end
function ComputerZero(program)
memory = zeros(UInt8, 32)
for i in 1:min(32, length(program))
memory[i] = program[i]
end
return ComputerZero(1, memory, 0, true)
end
 
NOP(c) = (c.ip = mod1(c.ip + 1, 32))
LDA(c) = (c.accum = c.ram[c.ram[c.ip] & 0b00011111 + 1]; c.ip = mod1(c.ip + 1, 32))
STA(c) = (c.ram[c.ram[c.ip] & 0b00011111 + 1] = c.accum; c.ip = mod1(c.ip + 1, 32))
ADD(c) = (c.accum += c.ram[c.ram[c.ip] & 0b00011111 + 1]; c.ip = mod1(c.ip + 1, 32))
SUB(c) = (c.accum -= c.ram[c.ram[c.ip] & 0b00011111 + 1]; c.ip = mod1(c.ip + 1, 32))
BRZ(c) = (c.ip = (c.accum == 0) ? c.ram[c.ip] & 0b00011111 + 1 : mod1(c.ip + 1, 32))
JMP(c) = (c.ip = c.ram[c.ip] & 0b00011111 + 1)
STP(c) = (println("Program completed with accumulator value $(c.accum).\n"); c.isready = false)
 
const step = [NOP, LDA, STA, ADD, SUB, BRZ, JMP, STP]
const instructions = ["NOP", "LDA", "STA", "ADD", "SUB", "BRZ", "JMP", "STP"]
const assemblywords = Dict(s => i - 1 for (i, s) in pairs(instructions))
 
function run(compzero::ComputerZero, debug = false)
while compzero.isready
instruction = compzero.ram[compzero.ip]
opcode, operand = instruction >> 5 + 1, instruction & 0b00011111
debug && println("op $(instructions[opcode]), operand $operand")
step[opcode](compzero)
end
return compzero.accum
end
run(program::Vector, debug = false) = run(ComputerZero(program), debug)
 
function compile(text::String)
bin, lines = UInt8[], 0
for line in strip.(split(text, "\n"))
lines += 1
if isempty(line)
push!(bin, 0)
elseif (m = match(r"(\w\w\w)\s+(\d\d?)", line)) != nothing
push!(bin, UInt8((assemblywords[m.captures[1]] << 5) | parse(UInt8, m.captures[2])))
elseif (m = match(r"(\w\w\w)", line)) != nothing
push!(bin, UInt8(assemblywords[m.match] << 5))
elseif (m = match(r"\d\d?", line)) != nothing
push!(bin, parse(UInt8, m.match))
else
error("Compilation error at line $lines: error parsing <$line>")
end
end
println("Compiled $lines lines.")
return bin
end
 
const testprograms = [
"""
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
 
 
 
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 t in testprograms
run(compile(t))
end
</syntaxhighlight>{{out}}
<pre>
Compiled 6 lines.
Program completed with accumulator value 4.
 
Compiled 15 lines.
Program completed with accumulator value 56.
 
Compiled 19 lines.
Program completed with accumulator value 55.
 
Compiled 33 lines.
Program completed with accumulator value 6.
 
Compiled 33 lines.
Program completed with accumulator value 0.
</pre>
=== Interpreter version with labels ===
Uses the Python examples.
<syntaxhighlight lang="julia">function interpret(text::String)
ip, accum, isready, ram = 0x1, 0x0, true, zeros(UInt8, 32)
NOP() = (ip = mod1(ip + 1, 32))
LDA() = (accum = ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32))
STA() = (ram[ram[ip] & 0b00011111 + 1] = accum; ip = mod1(ip + 1, 32))
ADD() = (accum += ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32))
SUB() = (accum -= ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32))
BRZ() = (ip = (accum == 0) ? ram[ip] & 0b00011111 + 1 : mod1(ip + 1, 32))
JMP() = (ip = ram[ip] & 0b00011111 + 1)
STP() = (println("Program completed with accumulator value $(accum).\n"); isready = false)
step = [NOP, LDA, STA, ADD, SUB, BRZ, JMP, STP]
assemblywords = Dict(s => i - 1 for (i, s) in pairs(string.(step)))
labels = Dict{String, Int}()
arglabels = Dict{Int, Tuple{Int, String}}()
for (i, line) in pairs(strip.(split(text, "\n")))
i > 32 && break
line = replace(line, r";.*$" => "") # remove comment
if occursin(":", line)
label, line = split(line, ":", limit = 2)
haskey(labels, label) && error("Duplicate label at line $i")
labels[strip(label)] = i - 1
end
if isempty(line)
ram[i] = 0
elseif (m = match(r"(\w\w\w)\s+([a-zA-Z]\w*)", line)) != nothing
arglabels[i] = (UInt8((assemblywords[m.captures[1]] << 5)), m.captures[2])
elseif (m = match(r"(\w\w\w)\s+(\d\d*)", line)) != nothing
ram[i] = UInt8((assemblywords[m.captures[1]] << 5) | parse(UInt8, m.captures[2]))
elseif (m = match(r"([a-zA-Z]\w*)", line)) != nothing
ram[i] = UInt8(assemblywords[m.match] << 5)
elseif (m = match(r"\d\d*", line)) != nothing
ram[i] = parse(UInt8, m.match)
else
error("Compilation error at line $i: error parsing <$line>")
end
end
for (i, t) in arglabels
ram[i] = t[1] | labels[t[2]]
end
while isready
step[ram[ip] >> 5 + 1]()
end
return accum
end
 
const testprograms = [
"""
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
 
 
 
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
""",
"""\
LDA x
ADD y ; accumulator = x + y
STP
x: 2
y: 2
""",
"""\
loop: LDA prodt
ADD x
STA prodt
LDA y
SUB one
STA y
BRZ done
JMP loop
done: LDA prodt ; to display it
STP
x: 8
y: 7
prodt: 0
one: 1
""",
"""\
loop: LDA n
STA temp
ADD m
STA n
LDA temp
STA m
LDA count
SUB one
BRZ done
STA count
JMP loop
done: LDA n ; to display it
STP
m: 1
n: 1
temp: 0
count: 8 ; valid range: 1-11
one: 1
""",
"""\
start: LDA load
ADD car ; head of list
STA ldcar
ADD one
STA ldcdr ; next CONS cell
ldcar: NOP
STA value
ldcdr: NOP
BRZ done ; 0 stands for NIL
STA car
JMP start
done: LDA value ; CAR of last CONS
STP
load: LDA 0
value: 0
car: 28
one: 1
; order of CONS cells
; in memory
; does not matter
6
0 ; 0 stands for NIL
2 ; (CADR ls)
26 ; (CDDR ls) -- etc.
5
20
3
30
1 ; value of (CAR ls)
22 ; points to (CDR ls)
4
24
""",
"""\
p: 0 ; NOP in first round
c: 0
start: STP ; wait for p's move
pmove: NOP
LDA pmove
SUB cmove
BRZ same
LDA pmove
STA cmove ; tit for tat
BRZ cdeft
LDA c ; p defected, c did not
ADD three
STA c
JMP start
cdeft: LDA p
ADD three
STA p
JMP start
same: LDA pmove
STA cmove ; tit for tat
LDA p
ADD one
ADD pmove
STA p
LDA c
ADD one
ADD pmove
STA c
JMP start
cmove: 0 ; co-operate initially
one: 1
three: 3
""",
"""\
LDA 3
SUB 4
STP 0
0
255
""",
"""\
LDA 3
SUB 4
STP 0
0
1
""",
"""\
LDA 3
ADD 4
STP 0
1
255
""",
]
 
for t in testprograms
interpret(t)
end
</syntaxhighlight>{{out}}
<pre>
Program completed with accumulator value 4.
 
Program completed with accumulator value 56.
 
Program completed with accumulator value 55.
 
Program completed with accumulator value 6.
 
Program completed with accumulator value 0.
 
Program completed with accumulator value 4.
 
Program completed with accumulator value 56.
 
Program completed with accumulator value 55.
 
Program completed with accumulator value 6.
 
Program completed with accumulator value 0.
 
Program completed with accumulator value 1.
 
Program completed with accumulator value 255.
 
Program completed with accumulator value 0.
</pre>
 
=={{header|Lua}}==
===Execute (2+2, 7*8)===
Per primary task, just execute first two examples:
<syntaxhighlight lang="lua">vmz = {
pc = 0,
acc = 0,
mem = { [0]=0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 },
b2oa = function(byte) return math.floor(byte / 32), byte % 32 end,
boot = function(self) self.pc, self.acc = 0, 0 for pc=0,31 do self.mem[pc]=0 end return self end,
load = function(self, bytes) for pc = 0, 31 do self.mem[pc]=bytes[pc] or 0 end return self end,
clam = function(n) if n<0 then n=n+256 elseif n>255 then n=n-256 end return n end,
opfn = {[0]=
function(self,addr) self.pc=self.pc+1 return true end, -- NOP
function(self,addr) self.acc=self.mem[addr] self.pc=self.pc+1 return true end, -- LDA
function(self,addr) self.mem[addr]=self.acc self.pc=self.pc+1 return true end, -- STA
function(self,addr) self.acc=self.clam(self.acc+self.mem[addr]) self.pc=self.pc+1 return true end, -- ADD
function(self,addr) self.acc=self.clam(self.acc-self.mem[addr]) self.pc=self.pc+1 return true end, -- SUB
function(self,addr) if (self.acc==0) then self.pc=addr else self.pc=self.pc+1 end return true end, -- BRZ
function(self,addr) self.pc=addr return true end, -- JMP
function(self,addr) self.pc=self.pc+1 return false end, -- STP
},
step = function(self)
local oper, addr = self.b2oa(self.mem[self.pc])
return self.opfn[oper](self,addr)
end,
exec = function(self)
while self.pc < 32 and self:step() do end
return self
end,
}
-- object code derived from js sim code
print("2 + 2 = " .. vmz:boot():load({[0]=35,100,224,2,2}):exec().acc)
print("7 x 8 = " .. vmz:boot():load({[0]=44,106,76,43,141,75,168,192,44,224,8,7,0,1}):exec().acc)</syntaxhighlight>
{{out}}
<pre>2 + 2 = 4
7 x 8 = 56</pre>
===Disassembler (7*8)===
Assembly syntax doesn't seem well-specified (except as shown in descriptive text, which is presumably just pseudocode), but next step might be to add a minimal disassembler:
<syntaxhighlight lang="lua">vmz.dism = function(self)
local mnem, imax = { [0]="NOP", "LDA", "STA", "ADD", "SUB", "BRZ", "JMP", "STP" }
for pc = 31,0,-1 do imax=pc if self.mem[pc]~=0 then break end end
local result, pretty = "", " %3s %2d\n"
for i = 0, imax do
local oper, addr = self.b2oa(self.mem[i])
result = result .. pretty:format(mnem[oper], addr)
end
return result
end
vmz:boot():load({[0]=44,106,76,43,141,75,168,192,44,224,8,7,0,1})
print("Disassembly of 7 x 8 (PRE-RUN):")
print(vmz:dism())
print("Disassembly of 7 x 8 (POST-RUN):")
print(vmz:exec():dism())</syntaxhighlight>
{{out}}
<pre>Disassembly of 7 x 8 (PRE-RUN):
LDA 12
ADD 10
STA 12
LDA 11
SUB 13
STA 11
BRZ 8
JMP 0
LDA 12
STP 0
NOP 8
NOP 7
NOP 0
NOP 1
 
Disassembly of 7 x 8 (POST-RUN):
LDA 12
ADD 10
STA 12
LDA 11
SUB 13
STA 11
BRZ 8
JMP 0
LDA 12
STP 0
NOP 8
NOP 0
LDA 24
NOP 1</pre>
===Assembler (fibo, list)===
Add an assembler (same minimal syntax as disassembler) for the next two examples:
<syntaxhighlight lang="lua">-- <statement> ::= <opcode> <address>
vmz.assm = function(self, source)
local function oa2b(oper, addr) return oper * 32 + addr end
local pc, objc = 0, { NOP=0, LDA=1, STA=2, ADD=3, SUB=4, BRZ=5, JMP=6, STP=7 }
for oper, addr in source:gmatch("%s*(%a%a%a)%s*(%d*)") do
self.mem[pc] = oa2b(objc[oper], tonumber(addr) or 0)
pc = pc + 1
end
return self
end
 
srcfibo = "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 0 NOP 1 NOP 1 NOP 0 NOP 8 NOP 1"
print("Fibonacci = " .. vmz:boot():assm(srcfibo):exec().acc)
 
srclist = [[
LDA 13 ADD 15 STA 5 ADD 16 STA 7 NOP 0 STA 14 NOP 0
BRZ 11 STA 15 JMP 0 LDA 14 STP 0 LDA 0 NOP 0 NOP 28
NOP 1 NOP 0 NOP 0 NOP 0 NOP 6 NOP 0 NOP 2 NOP 26
NOP 5 NOP 20 NOP 3 NOP 30 NOP 1 NOP 22 NOP 4 NOP 24
]]
print("Linked list = " .. vmz:boot():assm(srclist):exec().acc)</syntaxhighlight>
{{out}}
<pre>Fibonacci = 55
Linked list = 6</pre>
===Prisoner===
Some additional helper routines, then multiple rounds:
<syntaxhighlight lang="lua">vmz.peek = function(self,addr) return self.mem[addr] end
vmz.poke = function(self,addr,byte) self.mem[addr]=byte end
vmz.entr = function(self,byte) self.mem[self.pc]=byte self.pc=self.pc+1 end
-- derived from the javascript "object code", rather than the descriptive "source code", as they appear to differ
srcpris = [[
NOP 0 NOP 0 STP 0 NOP 0 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 1 ADD 30 ADD 3 STA 1 LDA 0 ADD 30 ADD 3 STA 0 JMP 2 NOP 0 NOP 1 NOP 3
]]
print("\nPrisoner (priming) = " .. vmz:boot():assm(srcpris):exec().acc)
-- play five rounds,ie: poke 0 or 1 into mem[3], pc+=1, exec again
mvnm = {[0]="coop", "defe"}
for r = 1, 5 do
local move = r%2 -- artificial stupidity?
vmz:entr(move)
vmz:exec()
print("Round: " .. r .. " Move: " .. mvnm[move] .. " Player: " .. vmz:peek(0) .. " Computer: " .. vmz:peek(1))
end</syntaxhighlight>
{{out}}
<pre>Prisoner (priming) = 0
Round: 1 Move: defe Player: 0 Computer: 3
Round: 2 Move: coop Player: 3 Computer: 3
Round: 3 Move: defe Player: 3 Computer: 6
Round: 4 Move: coop Player: 6 Computer: 6
Round: 5 Move: defe Player: 6 Computer: 9</pre>
 
=={{header|Nim}}==
We don’t use an assembly language but define the memory values using functions named NOP, LDA, STA, etc. To be able to use Uniform Function Call Syntax (i.e. call without parentheses),
all these functions have an argument, even NOP and STP.
 
In the last example, “Prisoners”, an input is expected from the user. We defined a function “enterValue” which stores the input value into the byte at address referenced by the PC then increments the PC by one. We have chosen the same player strategy as the one used by the Lua program and, of course, we get the same result.
 
<syntaxhighlight lang="Nim">import std/strformat
 
type
OpCode = enum opNOP, opLDA, opSTA, opADD, opSUB, opBRZ, opJMP, opSTP
Instruction = byte
Address = 0..31
# Definition of a computer zero.
Computer = object
mem: array[Address, byte] # Memory.
pc: Address # Program counter.
acc: byte # Accumulator.
Program = tuple
name: string # Name of the program.
code: seq[Instruction] # List of instructions.
 
proc split(inst: Instruction): tuple[code: OpCode, address: Address] =
## Split an instruction into an opCode and a value.
(OpCode((inst and 0b11100000u8) shr 5), Address(inst and 0b00011111u8))
 
proc toInst(opCode: OpCode; address: int): Instruction =
## Build an instruction with given opcode and value.
if address notin Address.low..Address.high:
raise newException(ValueError, "address out of range.")
byte(opCode) shl 5 or byte(address)
 
# Functions to build instructions.
func NOP(n: int): Instruction = toInst(opNOP, n)
func LDA(n: int): Instruction = toInst(opLDA, n)
func STA(n: int): Instruction = toInst(opSTA, n)
func ADD(n: int): Instruction = toInst(opADD, n)
func SUB(n: int): Instruction = toInst(opSUB, n)
func BRZ(n: int): Instruction = toInst(opBRZ, n)
func JMP(n: int): Instruction = toInst(opJMP, n)
func STP(n: int): Instruction = toInst(opSTP, n)
 
proc reset(comp: var Computer) =
## Reset the computer state.
comp.mem.reset()
comp.pc = 0
comp.acc = 0
 
proc load(comp: var Computer; program: Program) =
## Load a program into a computer.
comp.reset()
var idx = 0
for inst in program.code:
comp.mem[idx] = inst
inc idx
 
proc run(comp: var Computer) =
## Run a computer.
## The execution starts or resumes at the instruction
## at current PC, with current value in the accumulator.
while true:
let (opCode, address) = comp.mem[comp.pc].split()
inc comp.pc
case opCode
of opNOP:
discard
of opLDA:
comp.acc = comp.mem[address]
of opSTA:
comp.mem[address] = comp.acc
of opADD:
comp.acc += comp.mem[address]
of opSUB:
comp.acc -= comp.mem[address]
of opBRZ:
if comp.acc == 0:
comp.pc = address
of opJMP:
comp.pc = address
of opSTP:
break
 
proc enterValue(comp: var Computer; value: byte) =
## Enter a value into memory at address given by the PC,
## then increment the PC.
comp.mem[comp.pc] = value
inc comp.pc
 
 
# Programs are built using the functions NOP, LDA, STA, etc.
# To be able to use Uniform Function Call Syntax (i.e. call without parentheses),
# all these functions have an argument, even NOP and STP.
const
Prog1 = (name: "2+2",
code: @[LDA 3, ADD 4, STP 0, 2, 2])
Prog2 = (name: "7*8",
code: @[LDA 12, ADD 10, STA 12, LDA 11, SUB 13, STA 11, BRZ 8, JMP 0,
LDA 12, STP 0, 8, 7, 0, 1])
Prog3 = (name: "Fibonacci",
code: @[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 0, 1, 1, 0,
8, 1])
Prog4 = (name: "List",
code: @[LDA 13, ADD 15, STA 5, ADD 16, STA 7, NOP 0, STA 14, NOP 0,
BRZ 11, STA 15, JMP 0, LDA 14, STP 0, LDA 0, 0, 28,
1, 0, 0, 0, 6, 0, 2, 26,
5, 20, 3, 30, 1, 22, 4, 24])
Prog5 = (name: "Prisoner",
code: @[NOP 0, NOP 0, STP 0, NOP 0, 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 1, ADD 30, ADD 3, STA 1,
LDA 0, ADD 30, ADD 3, STA 0, JMP 2, 0, 1, 3])
 
var computer: Computer
 
for prog in [Prog1, Prog2, Prog3, Prog4]:
computer.load prog
computer.run()
echo &"Result for {prog.name}: {computer.acc}"
 
# "Prog5" is different as it stops and waits for an input from the user.
# Input is stored at address 3 (current PC value) and scores are stored at addresses 0 and 1.
 
type Action = enum cooperate, defect
 
echo &"\nResult for {Prog5.name}:"
computer.load Prog5
computer.run()
 
for round in 1..5:
let action = Action(round and 1)
computer.enterValue(byte(action))
computer.run()
echo &"Round {round} Action: {action:9} Player: {computer.mem[0]} Computer: {computer.mem[1]}"
</syntaxhighlight>
 
{{out}}
<pre>Result for 2+2: 4
Result for 7*8: 56
Result for Fibonacci: 55
Result for List: 6
 
Result for Prisoner:
Round 1 Action: defect Player: 0 Computer: 3
Round 2 Action: cooperate Player: 3 Computer: 3
Round 3 Action: defect Player: 3 Computer: 6
Round 4 Action: cooperate Player: 6 Computer: 6
Round 5 Action: defect Player: 6 Computer: 9
</pre>
 
=={{header|Phix}}==
Assumes there is no need for an "assembler", just a runtime interpreter. Output matches Algol 68.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">NOP</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b000_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- no operation</span>
<span style="color: #000000;">LDA</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b001_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- load accumulator, a := memory [xxxxx]</span>
<span style="color: #000000;">STA</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b010_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- store accumulator, memory [xxxxx] := a</span>
<span style="color: #000000;">ADD</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b011_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- add, a := a + memory [xxxxx]</span>
<span style="color: #000000;">SUB</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b100_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- subtract, a := a – memory [xxxxx]</span>
<span style="color: #000000;">BRZ</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b101_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- branch on zero, if a = 0 then goto xxxxx</span>
<span style="color: #000000;">JMP</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b110_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- jump, goto xxxxx</span>
<span style="color: #000000;">STP</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b111_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- stop</span>
<span style="color: #000000;">OP</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b111_00000</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- operator mask</span>
<span style="color: #000000;">ARG</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0b000_11111</span> <span style="color: #000080;font-style:italic;">-- memory location (0 based)</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">program</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">memory</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">program</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">pc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ppc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">memory</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pc</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bitsu</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ppc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">OP</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">arg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ppc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ARG</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">pc</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">op</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">NOP</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">break</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">memory</span><span style="color: #0000FF;">[</span><span style="color: #000000;">arg</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">memory</span><span style="color: #0000FF;">[</span><span style="color: #000000;">arg</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bitsu</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">memory</span><span style="color: #0000FF;">[</span><span style="color: #000000;">arg</span><span style="color: #0000FF;">],</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">SUB</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bitsu</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">-</span><span style="color: #000000;">memory</span><span style="color: #0000FF;">[</span><span style="color: #000000;">arg</span><span style="color: #0000FF;">],</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">BRZ</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">arg</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">JMP</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">pc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">arg</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">:</span> <span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%12s: %3d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"2+2"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"7*8"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">SUB</span><span style="color: #0000FF;">+</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BRZ</span><span style="color: #0000FF;">+</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">JMP</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"fibonacci"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">SUB</span><span style="color: #0000FF;">+</span><span style="color: #000000;">17</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BRZ</span><span style="color: #0000FF;">+</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">JMP</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"linkedList"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NOP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NOP</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">BRZ</span><span style="color: #0000FF;">+</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">JMP</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">28</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">26</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">24</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"prisoner"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">NOP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NOP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">SUB</span><span style="color: #0000FF;">+</span><span style="color: #000000;">29</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BRZ</span><span style="color: #0000FF;">+</span><span style="color: #000000;">18</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">29</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">BRZ</span><span style="color: #0000FF;">+</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">JMP</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">JMP</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">29</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">JMP</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">})</span>
<span style="color: #000080;font-style:italic;">-- subtractions yielding negative results</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"0-255"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">SUB</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">255</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"0-1"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">SUB</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #000080;font-style:italic;">-- overflow on addition</span>
<span style="color: #000000;">execute</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1+255"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">LDA</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">STP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">255</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
You could of course define the programs using (say) 0b001_00011 instead of LDA+3.
{{out}}
<pre>
2+2: 4
7*8: 56
fibonacci: 55
linkedList: 6
prisoner: 0
0-255: 1
0-1: 255
1+255: 0
</pre>
 
=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
Uses PL/M's macro facility to provide "inline assembler" for the computerZero instructions.
The assembler code is enclosed by CODE-EDOC brackets (CODE-EDOC bracketing for inline assembler was used in some Algol 68 compilers - EDOC being CODE backwards).
<br>An additional pseudo-instruction: VAL is used to indicate literal values.
<br>As all PL/M arithmetic is unsigned and the BYTE type is 8-bits, computations are naturally MOD 255 and so there is no need to force the results to be in the range 0-255.
<syntaxhighlight lang="plm">
100H: /* EXECUTE SOME COMPUTERZERO PROGRAMS */
 
/* CP/M SYSTEM CALL AND I/O ROUTINES */
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
PR$NUMBER: PROCEDURE( N ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH */
DECLARE N ADDRESS;
DECLARE V ADDRESS, N$STR ( 6 )BYTE, W BYTE;
V = N;
W = LAST( N$STR );
N$STR( W ) = '$';
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
END;
CALL PR$STRING( .N$STR( W ) );
END PR$NUMBER;
 
/* TASK */
 
DECLARE FALSE LITERALLY '0'
, TRUE LITERALLY '0FFH'
;
DECLARE NOP$C LITERALLY '0' /* INSTRUCTION CODES */
, LDA$C LITERALLY '32'
, STA$C LITERALLY '(2*32)'
, ADD$C LITERALLY '(3*32)'
, SUB$C LITERALLY '(4*32)'
, BRZ$C LITERALLY '(5*32)'
, JMP$C LITERALLY '(6*32)'
, STP$C LITERALLY '(7*32)'
;
DECLARE CODE LITERALLY 'PC=255' /* ASSEMBLER MNEMONICS */
, LOAD LITERALLY 'PC=PC+1;PGM(PC)='
, NOP LITERALLY 'LOAD NOP$C'
, LDA LITERALLY 'LOAD LDA$C+'
, STA LITERALLY 'LOAD STA$C+'
, ADD LITERALLY 'LOAD ADD$C+'
, SUB LITERALLY 'LOAD SUB$C+'
, BRZ LITERALLY 'LOAD BRZ$C+'
, JMP LITERALLY 'LOAD JMP$C+'
, STP LITERALLY 'LOAD STP$C '
, VAL LITERALLY 'LOAD '
, EDOC LITERALLY 'CALL EXECUTE'
;
DECLARE PGM (32)BYTE; /* THE PROGRAM */
DECLARE PC BYTE; /* PROGRAM COUNTER */
EXECUTE: PROCEDURE; /* EXECUTES THE PROGRAM */
DECLARE ( RUNNING, A, OP, OPERAND ) BYTE;
PC, A = 0;
RUNNING = TRUE;
DO WHILE RUNNING;
OP = PGM( PC ) AND 0E0H;
OPERAND = PGM( PC ) AND 1FH;
PC = ( PC + 1 ) MOD 32;
IF OP = NOP$C THEN DO; /* NOTHING */ END;
ELSE IF OP = LDA$C THEN A = PGM( OPERAND );
ELSE IF OP = STA$C THEN PGM( OPERAND ) = A;
ELSE IF OP = ADD$C THEN A = A + PGM( OPERAND );
ELSE IF OP = SUB$C THEN A = A - PGM( OPERAND );
ELSE IF OP = BRZ$C THEN DO; IF A = 0 THEN PC = OPERAND MOD 32; END;
ELSE IF OP = JMP$C THEN PC = OPERAND MOD 32;
ELSE DO; /* MUST BE STP$C */
RUNNING = FALSE;
CALL PR$NUMBER( A );
CALL PR$NL;
END;
END;
END EXECUTE ;
/* TEST PROGRAMS (FROM THE COMPUTER ZERO WEBSITE) */
CALL PR$STRING( .' 2+2: $' );
CODE; LDA 3; ADD 4; STP; VAL 2; VAL 2; EDOC;
 
CALL PR$STRING( .' 7*8: $' );
CODE; LDA 12; ADD 10; STA 12; LDA 11; SUB 13; STA 11; BRZ 8; JMP 0;
LDA 12; STP; VAL 8; VAL 7; VAL 0; VAL 1;
EDOC;
 
CALL PR$STRING( .' FIBONACCI: $' );
CODE; 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;
VAL 1; VAL 1; VAL 0; VAL 8; VAL 1;
EDOC;
 
CALL PR$STRING( .'LINKEDLIST: $' );
CODE; 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; VAL 0; VAL 28;
VAL 1; VAL 0; VAL 0; VAL 0; VAL 6; VAL 0; VAL 2; VAL 26;
VAL 5; VAL 20; VAL 3; VAL 30; VAL 1; VAL 22; VAL 4; VAL 24;
EDOC;
 
CALL PR$STRING( .' PRISONER: $' );
CODE; NOP; NOP; STP; VAL 0; 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 1; ADD 30; ADD 3; STA 1;
LDA 0; ADD 30; ADD 3; STA 0; JMP 2; VAL 0; VAL 1; VAL 3;
EDOC;
 
/* SUBTRACTIONS YIELDING NEGATIVE RESULTS */
CALL PR$STRING( .' 0-255: $' );
CODE; LDA 3; SUB 4; STP; VAL 0; VAL 255; EDOC;
CALL PR$STRING( .' 0-1: $' );
CODE; LDA 3; SUB 4; STP; VAL 0; VAL 1; EDOC;
/* OVERFLOW ON ADDITION */
CALL PR$STRING( .' 1+255: $' );
CODE; LDA 3; ADD 4; STP; VAL 1; VAL 255; EDOC;
 
EOF
</syntaxhighlight>
{{out}}
<pre>
2+2: 4
7*8: 56
FIBONACCI: 55
LINKEDLIST: 6
PRISONER: 0
0-255: 1
0-1: 255
1+255: 0
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">"""Computer/zero Assembly emulator. Requires Python >= 3.7"""
 
import re
 
from typing import Dict
from typing import Iterable
from typing import List
from typing import NamedTuple
from typing import Optional
from typing import Tuple
 
 
NOP = 0b000
LDA = 0b001
STA = 0b010
ADD = 0b011
SUB = 0b100
BRZ = 0b101
JMP = 0b110
STP = 0b111
 
OPCODES = {
"NOP": NOP,
"LDA": LDA,
"STA": STA,
"ADD": ADD,
"SUB": SUB,
"BRZ": BRZ,
"JMP": JMP,
"STP": STP,
}
 
RE_INSTRUCTION = re.compile(
r"\s*"
r"(?:(?P<label>\w+):)?"
r"\s*"
rf"(?P<opcode>{'|'.join(OPCODES)})?"
r"\s*"
r"(?P<argument>\w+)?"
r"\s*"
r"(?:;(?P<comment>[\w\s]+))?"
)
 
 
class AssemblySyntaxError(Exception):
pass
 
 
class Instruction(NamedTuple):
label: Optional[str]
opcode: Optional[str]
argument: Optional[str]
comment: Optional[str]
 
 
def parse(assembly: str) -> Tuple[List[Instruction], Dict[str, int]]:
instructions: List[Instruction] = []
labels: Dict[str, int] = {}
linenum: int = 0
 
for line in assembly.split("\n"):
match = RE_INSTRUCTION.match(line)
 
if not match:
raise AssemblySyntaxError(f"{line}: {linenum}")
 
instructions.append(Instruction(**match.groupdict()))
label = match.group(1)
if label:
labels[label] = linenum
 
linenum += 1
 
return instructions, labels
 
 
def compile(instructions: List[Instruction], labels: Dict[str, int]) -> Iterable[int]:
for instruction in instructions:
if instruction.argument is None:
argument = 0
elif instruction.argument.isnumeric():
argument = int(instruction.argument)
else:
argument = labels[instruction.argument]
 
if instruction.opcode:
yield OPCODES[instruction.opcode] << 5 | argument
else:
yield argument
 
 
def run(bytecode: bytes) -> int:
accumulator = 0
program_counter = 0
memory = list(bytecode)[:32] + [0 for _ in range(32 - len(bytecode))]
 
while program_counter < 32:
operation = memory[program_counter] >> 5
argument = memory[program_counter] & 0b11111
program_counter += 1
 
if operation == NOP:
continue
elif operation == LDA:
accumulator = memory[argument]
elif operation == STA:
memory[argument] = accumulator
elif operation == ADD:
accumulator = (accumulator + memory[argument]) % 256
elif operation == SUB:
accumulator = (accumulator - memory[argument]) % 256
elif operation == BRZ:
if accumulator == 0:
program_counter = argument
elif operation == JMP:
program_counter = argument
elif operation == STP:
break
else:
raise Exception(f"error: {operation} {argument}")
 
return accumulator
 
 
SAMPLES = [
"""\
LDA x
ADD y ; accumulator = x + y
STP
x: 2
y: 2
""",
"""\
loop: LDA prodt
ADD x
STA prodt
LDA y
SUB one
STA y
BRZ done
JMP loop
done: LDA prodt ; to display it
STP
x: 8
y: 7
prodt: 0
one: 1
""",
"""\
loop: LDA n
STA temp
ADD m
STA n
LDA temp
STA m
LDA count
SUB one
BRZ done
STA count
JMP loop
done: LDA n ; to display it
STP
m: 1
n: 1
temp: 0
count: 8 ; valid range: 1-11
one: 1
""",
"""\
start: LDA load
ADD car ; head of list
STA ldcar
ADD one
STA ldcdr ; next CONS cell
ldcar: NOP
STA value
ldcdr: NOP
BRZ done ; 0 stands for NIL
STA car
JMP start
done: LDA value ; CAR of last CONS
STP
load: LDA 0
value: 0
car: 28
one: 1
; order of CONS cells
; in memory
; does not matter
6
0 ; 0 stands for NIL
2 ; (CADR ls)
26 ; (CDDR ls) -- etc.
5
20
3
30
1 ; value of (CAR ls)
22 ; points to (CDR ls)
4
24
""",
"""\
p: 0 ; NOP in first round
c: 0
start: STP ; wait for p's move
pmove: NOP
LDA pmove
SUB cmove
BRZ same
LDA pmove
STA cmove ; tit for tat
BRZ cdeft
LDA c ; p defected, c did not
ADD three
STA c
JMP start
cdeft: LDA p
ADD three
STA p
JMP start
same: LDA pmove
STA cmove ; tit for tat
LDA p
ADD one
ADD pmove
STA p
LDA c
ADD one
ADD pmove
STA c
JMP start
cmove: 0 ; co-operate initially
one: 1
three: 3
""",
"""\
LDA 3
SUB 4
STP 0
0
255
""",
"""\
LDA 3
SUB 4
STP 0
0
1
""",
"""\
LDA 3
ADD 4
STP 0
1
255
""",
]
 
 
def main() -> None:
for sample in SAMPLES:
instructions, labels = parse(sample)
bytecode = bytes(compile(instructions, labels))
result = run(bytecode)
print(result)
 
 
if __name__ == "__main__":
main()
</syntaxhighlight>
 
{{out}}
<pre>
4
56
55
6
0
1
255
0
</pre>
 
=={{header|Raku}}==
Didn't bother implementing an assembler or disassembler.
<syntaxhighlight lang="raku" line>my (@mem, $ip, $acc); # memory, instruction pointer, accumulator
 
sub load (@program) {
die "memory exceeded" if +@program > 32;
$ip = 0;
$acc = 0;
@mem = @program »%» 256;
}
 
sub execute (*@program) {
load @program;
loop {
my $reg = @mem[$ip];
quietly my ($inst, $data) = $reg +> 5 +& 7, $reg +& 31;
given $inst {
when 0 { #`{ NOP } }
when 1 { #`{ LDA } $acc = @mem[$data] }
when 2 { #`{ STA } @mem[$data] = $acc }
when 3 { #`{ ADD } $acc += @mem[$data] }
when 4 { #`{ SUB } $acc -= @mem[$data] }
when 5 { #`{ BRZ } $ip = $data - 1 unless $acc }
when 6 { #`{ JMP } $ip = $data - 1 }
when 7 { #`{ STP } last }
default { die 'Invalid instruction' }
}
++$ip;
last if $ip == 32;
}
$acc
}
 
say "2 + 2 = " ~ execute 35,100,224,2,2;
say "7 x 8 = " ~ execute 44,106,76,43,141,75,168,192,44,224,8,7,0,1;
say "Fibonacci: " ~
execute 46,79,109,78,47,77,48,145,171,80,192,46,224,1,1,0,8,1;
say "Linked list: " ~
execute 45,111,69,112,71,0,78,0,171,79,192,46,
224,32,0,28,1,0,0,0,6,0,2,26,5,20,3,30,1,22,4,24;
say "Prisoners dilemma: " ~
execute 0,0,224,0,35,157,178,35,93,174,33,127,65,194,
32,127,64,194,35,93,33,126,99,65,32,126,99,64,194,0,1,3;</syntaxhighlight>
{{out}}
<pre>2 + 2 = 4
7 x 8 = 56
Fibonacci: 55
Linked list: 6
Prisoners dilemma: 0</pre>
 
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.8}}
{| class="wikitable"
! RPL code
! Comment
|-
|
{
≪ SWAP DROP ''''RAM'''' SWAP 1 + GET ≫
≪ ''''RAM'''' SWAP 1 + 3 PICK PUT ≫
≪ ''''RAM'''' SWAP 1 + GET + 256 MOD ≫
≪ ''''RAM'''' SWAP 1 + GET - 256 MOD ≫
≪ '''IF''' OVER NOT '''THEN''' ROT DROP SWAP '''ELSE''' DROP '''END''' ≫
≪ ROT DROP SWAP ≫
≪ DROP 1 SF ≫
} ''''µCODE'''' STO
{ 32 } RDM ''''RAM'''' STO
0 0 1 CF
'''WHILE''' 1 FC? '''REPEAT'''
SWAP 1 + DUP 32 MOD ROT ROT ''''RAM'''' SWAP GET
32 DUP2 MOD ROT ROT / FLOOR
'''IF THEN 'µCODE'''' LAST GET EVAL '''ELSE''' DROP
'''END END'''
≫ ‘'''RUN'''’ STO
|
'''µCODE''' ''( counter accumulator address -- counter accumulator )''
LDA x
STA x
ADD x
SUB x
BRZ x
JMP x
STP x
'''RUN''' ''( [ program ] -- counter accumulator )''
load program to memory
reset accumulator, counter and flag
loop until STP
increment pointer and read byte
instruction, addresss = divmod(byte,32)
if instruction <> NOP then execute it
|}
{{in}}
<pre>
[ 35 100 224 2 2 ] RUN
[ 44 106 76 43 141 75 168 192 44 224 8 7 0 1 ] RUN
[ 46 79 109 78 47 77 48 145 171 80 192 46 224 1 1 0 8 1 ] RUN
[ 45 111 69 112 71 0 78 0 171 79 192 46 224 32 0 28 1 0 0 0 6 0 2 26 5 20 3 30 1 22 4 24 ] RUN
[ 0 0 224 0 0 35 157 178 35 93 174 33 127 65 194 32 127 64 192 35 93 33 126 99 ] RUN
</pre>
{{out}}
<pre>
5: 4
4: 56
3: 55
2: 6
1: 0
</pre>
On a basic HP-28S, it takes 9.5 seconds takes to multiply 7 by 8 and 15 seconds to get the 11th Fibonacci number.
 
=={{header|Wren}}==
Line 80 ⟶ 3,462:
 
Although I've entered the fifth program, it just returns 0 when reaching the STP instruction. I'm unclear how we can make it interactive without having another instruction though possibly, if STP had address bits other than 0, this could signal that user input was required.
<langsyntaxhighlight ecmascriptlang="wren">var NOP = 0
var LDA = 1
var STA = 2
Line 256 ⟶ 3,638:
"""
]
for (prog in progs) interp.call(prog)</langsyntaxhighlight>
 
{{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}}
<pre>
Line 269 ⟶ 3,743:
=={{header|Z80 Assembly}}==
Output is in hexadecimal but is otherwise correct.
<langsyntaxhighlight lang="z80">org &1000
PrintChar equ &BB5A
 
Line 463 ⟶ 3,937:
db %00000000,%00000000
db %00000000,%00000000
db %00000000,%00000000</langsyntaxhighlight>
{{out}}
<pre>04
1,981

edits