#!/usr/bin/python
# Run a simple addition program on the WDR paper computer
# and output steps as PNGs
# Create GIF animation with ImageMagick:
# convert -delay 150 wdr_step*.png -loop 0 wdr.gif
from PIL import Image, ImageDraw, ImageFont
w, h = 800, 800
fnt = ImageFont.truetype('Courier Prime.ttf', 40)
# the paper computer program to run
prog = """# Add register 2 to register 1
1 jmp 4
2 inc 1
3 dec 2
4 isz 2
5 jmp 2
6 stp"""
# set up registers
reg = 10 * [0]
reg[1] = 5
reg[2] = 4
# set up program counter
pc = 1
pp = prog.splitlines()
step = 0
while True:
ins = pp[pc].split()
step += 1
print(pp[pc])
print(step, reg)
# create output image for current step
im = Image.new('RGBA', (w, h), (0,0,0))
d = ImageDraw.Draw(im)
for n, x in enumerate(pp):
if pc == n:
col = (255, 255, 255)
s = "> "
else:
col = (0, 255, 0)
s = " "
d.text((0, 50 * n), s + pp[n], font = fnt, fill = col, align = "left")
for n in range(1, 3):
d.text((0, 50 * (n + len(pp) + 2)), "REGISTER %u: %u" % (n, reg[n]), font = fnt, fill = (255, 255, 0), align = "left")
d.text((0, 50 * (n + len(pp) + 4)), "PROGRAM STEP: %u" % step, font = fnt, fill = (255, 0, 0), align = "left")
im.save("wdr_step%04u.png" % step)
# carry out the current instruction
if ins[1] == "stp":
break
if ins[1] == "isz":
if reg[int(ins[2])] == 0:
pc += 2
else:
pc += 1
continue
if ins[1] == "jmp":
pc = int(ins[2])
continue
if ins[1] == "inc":
reg[int(ins[2])] += 1
if ins[1] == "dec":
reg[int(ins[2])] -= 1
pc += 1