Execute Computer/Zero: Difference between revisions

Content added Content deleted
m (add second version)
Line 412: Line 412:


Compiled 33 lines.
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.
Program completed with accumulator value 0.
</pre>
</pre>