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 = 1, 0, 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))
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+(\d\d?)", line)) != nothing
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\w\w)", line)) != nothing
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?", line)) != nothing
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.