Execute Computer/Zero: Difference between revisions

Content added Content deleted
(implementation in Forth)
m (syntax highlighting fixup automation)
Line 15: Line 15:


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
<lang algol68>BEGIN # execute some ComputerZero programs #
<syntaxhighlight lang="algol68">BEGIN # execute some ComputerZero programs #
# instructions #
# instructions #
INT nop = 0, lda = 1, sta = 2, add = 3, sub = 4, brz = 5, jmp = 6, stp = 7;
INT nop = 0, lda = 1, sta = 2, add = 3, sub = 4, brz = 5, jmp = 6, stp = 7;
Line 96: Line 96:
execute( "1+255", ( LDA 3, ADD 4, STP 0, 1, 255 ) )
execute( "1+255", ( LDA 3, ADD 4, STP 0, 1, 255 ) )
END
END
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 110: Line 110:


=={{header|Applesoft BASIC}}==
=={{header|Applesoft BASIC}}==
<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
<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
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
2 LET P$ = MID$ (P$,1,MEM) + CHR$ (A) + MID$ (P$,MEM + 2,31 - MEM): PRINT MID$ ("",1 ^ FRE (0));: RETURN
Line 133: Line 133:
300 DATA "FIBONACCI",46,79,109,78,47,77,48,145,171,80,192,46,224,1,1,0,8,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
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,</lang>
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|Forth}}==
=={{header|Forth}}==
{{works with|gforth|0.7.3}}
{{works with|gforth|0.7.3}}
<br>
<br>
<lang forth>#! /usr/bin/gforth
<syntaxhighlight lang="forth">#! /usr/bin/gforth


\ Execute Computer/Zero
\ Execute Computer/Zero
Line 332: Line 332:


bye
bye
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 563: Line 563:
Here's one approach which might be sufficiently close to the task requirements:
Here's one approach which might be sufficiently close to the task requirements:


<lang J>OPS=: 'nop lda sta add sub brz jmp stp'
<syntaxhighlight lang="j">OPS=: 'nop lda sta add sub brz jmp stp'


assemble1=: {{
assemble1=: {{
Line 607: Line 607:
while. 0<:pc do. exec1'' end.
while. 0<:pc do. exec1'' end.
acc
acc
}}</lang>
}}</syntaxhighlight>


With this implementation, we can assemble and run representations of the five suggested programs:
With this implementation, we can assemble and run representations of the five suggested programs:


<lang J> exec assemble 'LDA 3; ADD 4; STP; 2; 2'
<syntaxhighlight lang="j"> exec assemble 'LDA 3; ADD 4; STP; 2; 2'
4
4
exec assemble 'LDA 12; ADD 10; STA 12; LDA 11; SUB 13; STA 11; BRZ 8; JMP; LDA 12; STP; 8; 7; 0; 1'
exec assemble 'LDA 12; ADD 10; STA 12; LDA 11; SUB 13; STA 11; BRZ 8; JMP; LDA 12; STP; 8; 7; 0; 1'
Line 620: Line 620:
6
6
exec assemble 'NOP; NOP; STP; NOP; LDA 3; SUB 29; BRZ 18; LDA 3; STA 29; BRZ 14; LDA 1; ADD 31; STA 1; JMP 2; LDA; ADD 31; STA; JMP 2; LDA 3; STA 29; LDA 1; ADD 30; ADD 3; STA 1; LDA; ADD 30; ADD 3; STA; JMP 2; 0; 1; 3'
exec assemble 'NOP; NOP; STP; NOP; LDA 3; SUB 29; BRZ 18; LDA 3; STA 29; BRZ 14; LDA 1; ADD 31; STA 1; JMP 2; LDA; ADD 31; STA; JMP 2; LDA 3; STA 29; LDA 1; ADD 30; ADD 3; STA 1; LDA; ADD 30; ADD 3; STA; JMP 2; 0; 1; 3'
0</lang>
0</syntaxhighlight>


=== Alternate approach ===
=== Alternate approach ===
Line 626: Line 626:
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:
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:


<lang J>opcode=: {{
<syntaxhighlight lang="j">opcode=: {{
(m+{.y),}.y
(m+{.y),}.y
:
:
Line 654: Line 654:
while. 0<:pc do. exec1'' end.
while. 0<:pc do. exec1'' end.
acc
acc
}}</lang>
}}</syntaxhighlight>


and:
and:


<lang J> exec LDA 3 ADD 4 STP 0 2 2
<syntaxhighlight lang="j"> exec LDA 3 ADD 4 STP 0 2 2
4
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
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
Line 667: Line 667:
6
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
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</lang>
0</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
Line 673: Line 673:
{{works with|Java|8}}
{{works with|Java|8}}


<lang python>import static java.lang.Math.floorMod;
<syntaxhighlight lang="python">import static java.lang.Math.floorMod;
import static java.lang.Math.min;
import static java.lang.Math.min;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toMap;
Line 978: Line 978:
}
}
}
}
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 993: Line 993:


=={{header|Julia}}==
=={{header|Julia}}==
<lang ruby>mutable struct ComputerZero
<syntaxhighlight lang="ruby">mutable struct ComputerZero
ip::Int
ip::Int
ram::Vector{UInt8}
ram::Vector{UInt8}
Line 1,168: Line 1,168:
run(compile(t))
run(compile(t))
end
end
</lang>{{out}}
</syntaxhighlight>{{out}}
<pre>
<pre>
Compiled 6 lines.
Compiled 6 lines.
Line 1,187: Line 1,187:
=== Interpreter version with labels ===
=== Interpreter version with labels ===
Uses the Python examples.
Uses the Python examples.
<lang ruby>function interpret(text::String)
<syntaxhighlight lang="ruby">function interpret(text::String)
ip, accum, isready, ram = 0x1, 0x0, true, zeros(UInt8, 32)
ip, accum, isready, ram = 0x1, 0x0, true, zeros(UInt8, 32)
NOP() = (ip = mod1(ip + 1, 32))
NOP() = (ip = mod1(ip + 1, 32))
Line 1,481: Line 1,481:
interpret(t)
interpret(t)
end
end
</lang>{{out}}
</syntaxhighlight>{{out}}
<pre>
<pre>
Program completed with accumulator value 4.
Program completed with accumulator value 4.
Line 1,513: Line 1,513:
===Execute (2+2, 7*8)===
===Execute (2+2, 7*8)===
Per primary task, just execute first two examples:
Per primary task, just execute first two examples:
<lang lua>vmz = {
<syntaxhighlight lang="lua">vmz = {
pc = 0,
pc = 0,
acc = 0,
acc = 0,
Line 1,542: Line 1,542:
-- object code derived from js sim code
-- object code derived from js sim code
print("2 + 2 = " .. vmz:boot():load({[0]=35,100,224,2,2}):exec().acc)
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)</lang>
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}}
{{out}}
<pre>2 + 2 = 4
<pre>2 + 2 = 4
Line 1,548: Line 1,548:
===Disassembler (7*8)===
===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:
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:
<lang lua>vmz.dism = function(self)
<syntaxhighlight lang="lua">vmz.dism = function(self)
local mnem, imax = { [0]="NOP", "LDA", "STA", "ADD", "SUB", "BRZ", "JMP", "STP" }
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
for pc = 31,0,-1 do imax=pc if self.mem[pc]~=0 then break end end
Line 1,562: Line 1,562:
print(vmz:dism())
print(vmz:dism())
print("Disassembly of 7 x 8 (POST-RUN):")
print("Disassembly of 7 x 8 (POST-RUN):")
print(vmz:exec():dism())</lang>
print(vmz:exec():dism())</syntaxhighlight>
{{out}}
{{out}}
<pre>Disassembly of 7 x 8 (PRE-RUN):
<pre>Disassembly of 7 x 8 (PRE-RUN):
Line 1,597: Line 1,597:
===Assembler (fibo, list)===
===Assembler (fibo, list)===
Add an assembler (same minimal syntax as disassembler) for the next two examples:
Add an assembler (same minimal syntax as disassembler) for the next two examples:
<lang lua>-- <statement> ::= <opcode> <address>
<syntaxhighlight lang="lua">-- <statement> ::= <opcode> <address>
vmz.assm = function(self, source)
vmz.assm = function(self, source)
local function oa2b(oper, addr) return oper * 32 + addr end
local function oa2b(oper, addr) return oper * 32 + addr end
Line 1,617: Line 1,617:
NOP 5 NOP 20 NOP 3 NOP 30 NOP 1 NOP 22 NOP 4 NOP 24
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)</lang>
print("Linked list = " .. vmz:boot():assm(srclist):exec().acc)</syntaxhighlight>
{{out}}
{{out}}
<pre>Fibonacci = 55
<pre>Fibonacci = 55
Line 1,623: Line 1,623:
===Prisoner===
===Prisoner===
Some additional helper routines, then multiple rounds:
Some additional helper routines, then multiple rounds:
<lang lua>vmz.peek = function(self,addr) return self.mem[addr] end
<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.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
vmz.entr = function(self,byte) self.mem[self.pc]=byte self.pc=self.pc+1 end
Line 1,639: Line 1,639:
vmz:exec()
vmz:exec()
print("Round: " .. r .. " Move: " .. mvnm[move] .. " Player: " .. vmz:peek(0) .. " Computer: " .. vmz:peek(1))
print("Round: " .. r .. " Move: " .. mvnm[move] .. " Player: " .. vmz:peek(0) .. " Computer: " .. vmz:peek(1))
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre>Prisoner (priming) = 0
<pre>Prisoner (priming) = 0
Line 1,650: Line 1,650:
=={{header|Phix}}==
=={{header|Phix}}==
Assumes there is no need for an "assembler", just a runtime interpreter. Output matches Algol 68.
Assumes there is no need for an "assembler", just a runtime interpreter. Output matches Algol 68.
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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: #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>
Line 1,702: Line 1,702:
<span style="color: #000080;font-style:italic;">-- overflow on addition</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>
<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>
<!--</lang>-->
<!--</syntaxhighlight>-->
You could of course define the programs using (say) 0b001_00011 instead of LDA+3.
You could of course define the programs using (say) 0b001_00011 instead of LDA+3.
{{out}}
{{out}}
Line 1,717: Line 1,717:


=={{header|Python}}==
=={{header|Python}}==
<lang python>"""Computer/zero Assembly emulator. Requires Python >= 3.7"""
<syntaxhighlight lang="python">"""Computer/zero Assembly emulator. Requires Python >= 3.7"""


import re
import re
Line 1,987: Line 1,987:
if __name__ == "__main__":
if __name__ == "__main__":
main()
main()
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 2,005: Line 2,005:


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.
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.
<lang ecmascript>var NOP = 0
<syntaxhighlight lang="ecmascript">var NOP = 0
var LDA = 1
var LDA = 1
var STA = 2
var STA = 2
Line 2,181: Line 2,181:
"""
"""
]
]
for (prog in progs) interp.call(prog)</lang>
for (prog in progs) interp.call(prog)</syntaxhighlight>


{{out}}
{{out}}
Line 2,194: Line 2,194:
=={{header|Z80 Assembly}}==
=={{header|Z80 Assembly}}==
Output is in hexadecimal but is otherwise correct.
Output is in hexadecimal but is otherwise correct.
<lang z80>org &1000
<syntaxhighlight lang="z80">org &1000
PrintChar equ &BB5A
PrintChar equ &BB5A


Line 2,388: Line 2,388:
db %00000000,%00000000
db %00000000,%00000000
db %00000000,%00000000
db %00000000,%00000000
db %00000000,%00000000</lang>
db %00000000,%00000000</syntaxhighlight>
{{out}}
{{out}}
<pre>04
<pre>04