Execute Computer/Zero: Difference between revisions

no edit summary
(Created Nim solution.)
No edit summary
Line 135:
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|Forth}}==
465

edits