RosettaCodeData/Task/Execute-Computer-Zero/Pluto/execute-computer-zero.pluto
2026-04-30 12:34:36 -04:00

179 lines
3 KiB
Text

enum begin NOP = 0, LDA, STA, ADD, SUB, BRZ, JMP, STP end
local ops = {NOP = NOP, LDA = LDA, STA = STA, ADD = ADD,
SUB = SUB, BRZ = BRZ, JMP = JMP, STP = STP}
local function load(prog)
local mem = table.create(31, 1)
for i = 0, 31 do mem[i] = 0 end
local lines = prog:rstrip():split("\n")
for i = 1, #lines do
local line = lines[i]:strip()
local split = line:split(" ")
local instr = split[1]
local addr = 0
if #split == 2 then addr = tonumber(split[2]) end
if ops[instr] then
mem[i - 1] = ops[instr] * 32 + addr
else
local v = tonumber(instr)
if v then mem[i - 1] = v end
end
end
return mem
end
local function output(acc)
print(acc)
end
local function interp(prog)
local acc = 0
local pc = 0
local mem = load(prog)
while true do
local instr = mem[pc] >> 5
local addr = mem[pc] % 32
pc += 1
switch instr do
case LDA:
acc = mem[addr]
break
case STA:
mem[addr] = acc
break
case ADD:
acc += mem[addr]
if acc > 255 then acc -= 256 end
break
case SUB:
acc -= mem[addr]
if acc < 0 then ac += 256 end
break
case BRZ:
if acc == 0 then pc = addr end
break
case JMP:
pc = addr
break
end
if instr == STP or pc > 31 then break end
end
output(acc)
end
local 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 progs as prog do interp(prog) end