#!/usr/bin/env python3 import json import sys class env: def __init__(self, mem=[]): self.ds = [] self.rs = [] self.ip = 0 self.mem = mem self.dict = dict def dup(self): self.ds.append(self.ds[-1]) def drop(self): self.ds.pop() def swap(self): x = self.ds.pop() y = self.ds.pop() self.ds.append(x) self.ds.append(y) def lit(self): self.ds.append(self.mem[self.ip]) self.ip += 1 def dip(self): block = self.ds.pop() value = self.ds.pop() oldmem = self.mem oldip = self.ip def kont(self): self.mem = oldmem self.ip = oldip self.ds.append(value) self.mem = block self.ip = 0 self.rs.append(kont) def print(self): print(self.ds.pop()) def call(self, val): if callable(val): val(self) elif isinstance(val, str): word = self.dict[val] if callable(word): word(self) elif isinstance(word, list): oldmem = self.mem oldip = self.ip def kont(self): self.mem = oldmem self.ip = oldip self.rs.append(kont) self.mem = word self.ip = 0 else: raise TypeError("unexpected definition:", val, "->", word) else: self.ds.append(val) def run(self): while True: if self.ip < len(self.mem): word = self.mem[self.ip] self.ip += 1 self.call(word) elif len(self.rs) > 0: k = self.rs.pop() k(self) else: break return self dict = { "dup": env.dup, "drop": env.drop, "swap": env.swap, "lit": env.lit, "dip": env.dip, "print": env.print, } with open(sys.argv[1], "r") as fp: code = json.load(fp) dict.update(code) e = env(["main"]).run() if e.ds: print(e.ds)