Back Ward Language

# BackWardLanguage -
# stack-based language w/bare minimum
# functionality to do WardNumber algorithm
# Inspired by PostScript Language
# Author: SteveHowell
#
# See WardNumberInManyProgrammingLanguages for an
# example usage.
class Parser:
def __init__(self, fn):
self.fn = fn
def parse(self):
f = open(self.fn)
stack = interpreterStack()
for line in f.readlines():
tokens = line.split()
stack.pushmany(tokens)
class interpreterStack:
def __init__(self):
self.command = {}
self.builtins(['Output', 'Debug',
'Copy', 'Swap', 'Pop',
'Def', 'If', 'While',
'Clear', 'Add', 'Forall',
'Assign', 'Incr', 'Val',
'Set', 'Obj', 'Dict'])
self.command['}'] = builtIn(self.Anon)
self.stack = []
self.scope = Scope(self)
self.namespace = nameSpace()
def builtins(self, names):
for name in names:
self.command[name] = builtIn(getattr(self, name))
def pushmany(self, tokens):
for token in tokens:
self.push(token)
def push(self, token):
self.scope.push(token)
def run(self, token):
if token in self.command:
self.command[token].run()
else:
self.stack.append(token)
def append(self, token):
self.stack.append(token)
def pop(self):
return self.stack.pop()
def Def(self):
name = self.pop()
self.command[name] = self.pop()
def Anon(self):
cmd = Command(self)
self.stack.append(cmd)
def If(self):
else_cmd = self.pop()
if_cmd = self.pop()
self.pop().run()
cond = self.pop()
if int(cond) > 0:
if_cmd.run()
else:
else_cmd.run()
def While(self):
repeat_cmd = self.pop()
cond_cmd = self.pop()
while 1:
cond_cmd.run()
cond = self.pop()
if int(cond) == 0:
break
repeat_cmd.run()
def Copy(self):
count = int(self.pop())
list = self.stack[-1 * (count):]
for item in list:
self.stack.append(item)
def Pop(self):
self.stack.pop()
def Swap(self):
(self.stack[-1], self.stack[-2]) = (self.stack[-2], self.stack[-1])
def Obj(self):
self.namespace.lookup(self, 'obj')
def Set(self):
self.namespace.lookup(self, 'set')
def Dict(self):
self.namespace.lookup(self, 'dict')
def Add(self):
obj = self.pop()
obj.Add(self.pop())
def Clear(self):
obj = self.pop()
obj.Clear()
def Forall(self):
obj = self.pop()
obj.Forall(self)
def Val(self):
obj = self.pop()
self.append(obj.Val())
def Assign(self):
value = self.pop()
obj = self.pop()
obj.Assign(value)
def Incr(self):
obj = self.pop()
obj.Incr()
def Output(self):
obj = self.pop()
try:
obj.Output()
except:
print obj
def Debug(self):
obj = self.pop()
obj.Debug()
class builtIn:
def __init__(self, cmd):
self.cmd = cmd
def run(self):
apply(self.cmd)
class Scope:
def __init__(self, stack):
self.stack = stack
self.level = 0
def push(self, token):
if token == '{':
self.level = self.level + 1
if token == '}':
self.level = self.level - 1
if self.level == 0:
self.stack.run(token)
else:
self.stack.append(token)
class Command:
def __init__(self, stack):
# last curly should already be popped
self.stack = stack
self.tokens = []
level = 1
while 1:
token = stack.pop()
if token == '}':
level += 1
if token == '{':
level -= 1
if level == 0:
break
self.tokens.append(token)
self.tokens.reverse()
def run(self):
self.stack.pushmany(self.tokens)
class Keeper:
def __init__(self):
self.vars = {}
def find(self, key):
if key not in self.vars:
self.vars[key] = self.new_item()
return self.vars[key]
class setKeeper(Keeper):
def new_item(set): return Set()
class objKeeper(Keeper):
def new_item(set): return Obj()
class dictKeeper(Keeper):
def new_item(set): return nameSpace()
class nameSpace:
def __init__(self):
self.set = setKeeper()
self.keeper = {
'obj' : objKeeper(),
'set' : setKeeper(),
'dict' : dictKeeper(),
}
def lookup(self, stack, datatype):
key = stack.pop()
try:
key.lookup(stack, datatype)
except:
stack.append(self.keeper[datatype].find(key))
class Obj:
def __init__(self, obj=None):
self.obj = obj
def Assign(self, value):
self.obj = value
def Val(self):
return self.obj
def Incr(self):
self.obj = int(self.obj) + 1
class Set:
def __init__(self):
self.Clear()
def Add(self, value):
if value not in self.dict:
self.set.append(value)
self.dict[value] = 1
def Debug(self):
print 'debug:', self.set
def Forall(self, stack):
cmd = stack.pop()
for item in self.set:
stack.append(item)
cmd.run()
def Clear(self):
self.set = []
self.dict = {}
def Val(self):
return len(self.set)
Parser('stack.ps').parse()

Strange; that looks like PythonLanguage to me... ;)

OK, so it's a BackWardLanguage interpreter written in Python. Now that you've bootstrapped yourself, you need to supply a BackWard interpreter implemented in BackWard.

:)

Thank you for providing grammar, documentation, and examples for all us lazy people out there. :P

Yes, but where are its tests?