Execute Computer/Zero: Difference between revisions

m
add second version
m (add second version)
Line 412:
 
Compiled 33 lines.
Program completed with accumulator value 0.
</pre>
=== Interpreter version ===
<lang ruby>function interpret(text::String)
ip, accum, isready, ram = 1, 0, 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)))
for (i, line) in pairs(strip.(split(text, "\n")))
i > 32 && break
if isempty(line)
ram[i] = 0
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"(\w\w\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
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
"""
]
 
for t in testprograms
interpret(t)
end
</lang>{{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.
</pre>
4,102

edits