Execute Computer/Zero: Difference between revisions

m
(Python improve assembly parser)
Line 414:
Program completed with accumulator value 0.
</pre>
=== Interpreter version with labels ===
Uses the Python examples.
<lang ruby>function interpret(text::String)
ip, accum, isready, ram = 10x1, 00x0, true, zeros(UInt8, 32)
NOP() = (ip = mod1(ip + 1, 32))
LDA() = (accum = ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32))
Line 427 ⟶ 428:
step = [NOP, LDA, STA, ADD, SUB, BRZ, JMP, STP]
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")))
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)
ram[i] = 0
elseif (m = match(r"(\w\w\w)\s+([a-zA-Z]\d\d?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]))
elseif (m = match(r"([a-zA-Z]\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
for (i, t) in arglabels
ram[i] = t[1] | labels[t[2]]
end
while isready
Line 558 ⟶ 572:
1
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 ⟶ 719:
 
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.
4,105

edits