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?


View edit of January 26, 2010 or FindPage with title or text search