Execute Computer/Zero: Difference between revisions
Content added Content deleted
(Python improve assembly parser) |
|||
Line 414: | Line 414: | ||
Program completed with accumulator value 0. |
Program completed with accumulator value 0. |
||
</pre> |
</pre> |
||
=== Interpreter version === |
=== Interpreter version with labels === |
||
Uses the Python examples. |
|||
<lang ruby>function interpret(text::String) |
<lang ruby>function interpret(text::String) |
||
ip, accum, isready, ram = |
ip, accum, isready, ram = 0x1, 0x0, true, zeros(UInt8, 32) |
||
NOP() = (ip = mod1(ip + 1, 32)) |
NOP() = (ip = mod1(ip + 1, 32)) |
||
LDA() = (accum = ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32)) |
LDA() = (accum = ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32)) |
||
Line 427: | Line 428: | ||
step = [NOP, LDA, STA, ADD, SUB, BRZ, JMP, STP] |
step = [NOP, LDA, STA, ADD, SUB, BRZ, JMP, STP] |
||
assemblywords = Dict(s => i - 1 for (i, s) in pairs(string.(step))) |
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"))) |
for (i, line) in pairs(strip.(split(text, "\n"))) |
||
i > 32 && break |
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) |
if isempty(line) |
||
ram[i] = 0 |
ram[i] = 0 |
||
elseif (m = match(r"(\w\w\w)\s+(\ |
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])) |
ram[i] = UInt8((assemblywords[m.captures[1]] << 5) | parse(UInt8, m.captures[2])) |
||
elseif (m = match(r"(\w |
elseif (m = match(r"([a-zA-Z]\w*)", line)) != nothing |
||
ram[i] = UInt8(assemblywords[m.match] << 5) |
ram[i] = UInt8(assemblywords[m.match] << 5) |
||
elseif (m = match(r"\d\d |
elseif (m = match(r"\d\d*", line)) != nothing |
||
ram[i] = parse(UInt8, m.match) |
ram[i] = parse(UInt8, m.match) |
||
else |
else |
||
error("Compilation error at line $i: error parsing <$line>") |
error("Compilation error at line $i: error parsing <$line>") |
||
end |
end |
||
end |
|||
for (i, t) in arglabels |
|||
ram[i] = t[1] | labels[t[2]] |
|||
end |
end |
||
while isready |
while isready |
||
Line 558: | Line 572: | ||
1 |
1 |
||
3 |
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 |
|||
""", |
|||
] |
] |
||
Line 573: | Line 719: | ||
Program completed with accumulator value 6. |
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. |
Program completed with accumulator value 0. |