RosettaCodeData/Task/Execute-Computer-Zero/Wren/execute-computer-zero.wren

178 lines
2.9 KiB
Plaintext

var NOP = 0
var LDA = 1
var STA = 2
var ADD = 3
var SUB = 4
var BRZ = 5
var JMP = 6
var STP = 7
var ops = {"NOP": NOP, "LDA": LDA, "STA": STA, "ADD": ADD,
"SUB": SUB, "BRZ": BRZ, "JMP": JMP, "STP": STP}
var load = Fn.new { |prog|
var mem = List.filled(32, 0)
var lines = prog.trimEnd().split("\n")
for (i in 0...lines.count) {
var line = lines[i].trim()
var split = line.split(" ")
var instr = split[0]
var addr = 0
if (split.count == 2) addr = Num.fromString(split[1])
if (ops[instr]) {
mem[i] = ops[instr] * 32 + addr
} else {
var v = Num.fromString(instr)
if (v) mem[i] = v
}
}
return mem
}
var output = Fn.new { |acc|
System.print(acc)
}
var interp = Fn.new { |prog|
var acc = 0
var pc = 0
var mem = load.call(prog)
while (true) {
var instr = mem[pc] >> 5
var addr = mem[pc] % 32
pc = pc + 1
if (instr == LDA) {
acc = mem[addr]
} else if (instr == STA) {
mem[addr] = acc
} else if (instr == ADD) {
acc = acc + mem[addr]
if (acc > 255) acc = acc - 256
} else if (instr == SUB) {
acc = acc - mem[addr]
if (acc < 0) acc = acc + 256
} else if (instr == BRZ) {
if (acc == 0) pc = addr
} else if (instr == JMP) {
pc = addr
}
if (instr == STP || pc > 31) break
}
output.call(acc)
}
var progs = [
"""
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 (prog in progs) interp.call(prog)