Neue Spielerei: Ein Compiler der einen Code in einer PoC Sprache mit if, while, +, and, or und not in einen funktionierenden Brainfuck Code compiliert.
This commit is contained in:
parent
998cf32353
commit
2efff1d9ee
1 changed files with 319 additions and 0 deletions
319
bfcompiler.py
Normal file
319
bfcompiler.py
Normal file
|
@ -0,0 +1,319 @@
|
|||
class CompileState(object):
|
||||
def __init__(self):
|
||||
self.vars = {}
|
||||
self.cells = set()
|
||||
self.currentCell = 0
|
||||
|
||||
def requestVar(self,name):
|
||||
try:
|
||||
return self.vars[name]
|
||||
except:
|
||||
cell = 0
|
||||
while cell in self.cells:
|
||||
cell+=1
|
||||
self.vars[name] = cell
|
||||
self.cells.add(cell)
|
||||
return cell
|
||||
|
||||
def releaseVar(self,name):
|
||||
try:
|
||||
cell = self.vars[name]
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
del self.vars[name]
|
||||
self.cells.remove(cell)
|
||||
|
||||
def requestTempVar(self):
|
||||
vid = object()
|
||||
cell = self.requestVar(vid)
|
||||
return vid, cell
|
||||
|
||||
def incrementCell(self):
|
||||
self.currentCell += 1
|
||||
|
||||
def decrementCell(self):
|
||||
self.currentCell -= 1
|
||||
|
||||
class Command(object):
|
||||
def __str__(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
def compile(self,state):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class SimpleRepeatedCommand(Command):
|
||||
def __init__(self,repeats,command):
|
||||
self.repeats = repeats
|
||||
self.command = command
|
||||
|
||||
def compile(self,state):
|
||||
s = ""
|
||||
for i in range(self.repeats):
|
||||
s += self.command.compile(state)
|
||||
return s
|
||||
|
||||
def __str__(self):
|
||||
return "Repeat(%d)(%s)" % (self.repeats, str(self.command))
|
||||
|
||||
class CompositeCommand(Command):
|
||||
def __init__(self,commands):
|
||||
self.commands = commands
|
||||
|
||||
def compile(self,state):
|
||||
s=""
|
||||
for command in self.commands:
|
||||
s+=command.compile(state)
|
||||
return s
|
||||
|
||||
def __str__(self):
|
||||
return "[" + ",".join([ str(command) for command in self.commands]) + "]"
|
||||
|
||||
class SimpleIncrement(Command):
|
||||
def compile(self,state):
|
||||
return '+'
|
||||
|
||||
class SimpleDecrement(Command):
|
||||
def compile(self,state):
|
||||
return '-'
|
||||
|
||||
class SimpleNextCell(Command):
|
||||
def compile(self,state):
|
||||
state.incrementCell()
|
||||
return '>'
|
||||
|
||||
class SimplePrevCell(Command):
|
||||
def compile(self,state):
|
||||
state.decrementCell()
|
||||
return '<'
|
||||
|
||||
class SimpleOutput(Command):
|
||||
def compile(self,state):
|
||||
return '.'
|
||||
|
||||
class SimpleInput(Command):
|
||||
def compile(self,state):
|
||||
return ','
|
||||
|
||||
class SimpleLoopBegin(Command):
|
||||
def compile(self,state):
|
||||
return '['
|
||||
|
||||
class SimpleLoopEnd(Command):
|
||||
def compile(self,state):
|
||||
return ']'
|
||||
|
||||
class SimpleLoop(Command):
|
||||
def __init__(self,command):
|
||||
self.command = command
|
||||
|
||||
def compile(self,state):
|
||||
return CompositeCommand([SimpleLoopBegin(), self.command, SimpleLoopEnd()]).compile(state)
|
||||
|
||||
class SelectVariable(Command):
|
||||
def __init__(self,variable):
|
||||
self.variable = variable
|
||||
|
||||
def compile(self,state):
|
||||
d = state.requestVar(self.variable) - state.currentCell
|
||||
if d < 0:
|
||||
return SimpleRepeatedCommand(-d,SimplePrevCell()).compile(state)
|
||||
elif d > 0:
|
||||
return SimpleRepeatedCommand(d,SimpleNextCell()).compile(state)
|
||||
else:
|
||||
return ""
|
||||
|
||||
class ClearCell(Command):
|
||||
def compile(self,state):
|
||||
return SimpleLoop(SimpleDecrement()).compile(state)
|
||||
|
||||
class WriteConstant(Command):
|
||||
def __init__(self,const):
|
||||
self.const = const
|
||||
|
||||
def compile(self,state):
|
||||
return CompositeCommand([ClearCell(),SimpleRepeatedCommand(self.const, SimpleIncrement())]).compile(state)
|
||||
|
||||
class SetConstant(Command):
|
||||
def __init__(self,variable,const):
|
||||
self.variable = variable
|
||||
self.const = const
|
||||
|
||||
def compile(self,state):
|
||||
return CompositeCommand([SelectVariable(self.variable),WriteConstant(self.const)]).compile(state)
|
||||
|
||||
SetVariable = SetConstant
|
||||
|
||||
class Move(Command):
|
||||
def __init__(self, source, dest):
|
||||
self.source = source
|
||||
self.dest = dest
|
||||
|
||||
def compile(self,state):
|
||||
return CompositeCommand([
|
||||
SelectVariable(self.dest),
|
||||
ClearCell(),
|
||||
SimpleAddition(self.source,self.dest)
|
||||
]).compile(state)
|
||||
|
||||
class Copy(Command):
|
||||
def __init__(self,source,dest):
|
||||
self.source = source
|
||||
self.dest = dest
|
||||
|
||||
def compile(self,state):
|
||||
tmp, _ = state.requestTempVar()
|
||||
s = CompositeCommand([
|
||||
SelectVariable(self.dest),
|
||||
ClearCell(),
|
||||
SelectVariable(tmp),
|
||||
ClearCell(),
|
||||
SelectVariable(self.source),
|
||||
SimpleLoop(CompositeCommand([
|
||||
SelectVariable(self.dest),
|
||||
SimpleIncrement(),
|
||||
SelectVariable(tmp),
|
||||
SimpleIncrement(),
|
||||
SelectVariable(self.source),
|
||||
SimpleDecrement()
|
||||
])),
|
||||
Move(tmp,self.source)
|
||||
]).compile(state)
|
||||
state.releaseVar(tmp)
|
||||
return s
|
||||
|
||||
class SimpleAddition(Command):
|
||||
def __init__(self, source, dest):
|
||||
self.source = source
|
||||
self.dest = dest
|
||||
|
||||
def compile(self,state):
|
||||
return CompositeCommand([
|
||||
SelectVariable(self.source),
|
||||
SimpleLoop(CompositeCommand([
|
||||
SelectVariable(self.dest),
|
||||
SimpleIncrement(),
|
||||
SelectVariable(self.source),
|
||||
SimpleDecrement(),
|
||||
]))
|
||||
]).compile(state)
|
||||
|
||||
class Addition2(Command):
|
||||
def __init__(self,source,dest):
|
||||
self.source = source
|
||||
self.dest = dest
|
||||
|
||||
def compile(self,state):
|
||||
tmp, _ = state.requestTempVar()
|
||||
s = CompositeCommand([
|
||||
Copy(self.source,tmp),
|
||||
SimpleAddition(tmp,self.dest)
|
||||
]).compile(state)
|
||||
state.releaseVar(tmp)
|
||||
return s
|
||||
|
||||
class Condition(Command):
|
||||
def __init__(self,condition,command):
|
||||
self.condition = condition
|
||||
self.command = command
|
||||
|
||||
def compile(self,state):
|
||||
return CompositeCommand([
|
||||
SelectVariable(self.condition),
|
||||
SimpleLoop(CompositeCommand([
|
||||
self.command,
|
||||
SelectVariable(self.condition),
|
||||
ClearCell(),
|
||||
])),
|
||||
]).compile(state)
|
||||
|
||||
class ConditionKeep(Command):
|
||||
def __init__(self,condition,command):
|
||||
self.condition = condition
|
||||
self.command = command
|
||||
|
||||
def compile(self,state):
|
||||
tmp, _ = state.requestTempVar()
|
||||
s = CompositeCommand([
|
||||
Copy(self.condition,tmp),
|
||||
Condition(tmp,self.command)
|
||||
]).compile(state)
|
||||
state.releaseVar(tmp)
|
||||
return s
|
||||
|
||||
class Booleanize(Command):
|
||||
def __init__(self,variable):
|
||||
self.variable = variable
|
||||
|
||||
def compile(self,state):
|
||||
tmp, _ = state.requestTempVar()
|
||||
s = CompositeCommand([
|
||||
SelectVariable(tmp),
|
||||
ClearCell(),
|
||||
Condition(self.variable,CompositeCommand([
|
||||
SelectVariable(tmp),
|
||||
SimpleIncrement()
|
||||
])),
|
||||
Move(tmp,self.variable)
|
||||
]).compile(state)
|
||||
state.releaseVar(tmp)
|
||||
return s
|
||||
|
||||
class Not(Command):
|
||||
def __init__(self,variable):
|
||||
self.variable = variable
|
||||
|
||||
def compile(self,state):
|
||||
tmp, _ = state.requestTempVar()
|
||||
s = CompositeCommand([
|
||||
SelectVariable(tmp),
|
||||
WriteConstant(1),
|
||||
Condition(self.variable,CompositeCommand([
|
||||
SelectVariable(tmp),
|
||||
SimpleDecrement()
|
||||
])),
|
||||
Move(tmp,self.variable)
|
||||
]).compile(state)
|
||||
state.releaseVar(tmp)
|
||||
return s
|
||||
|
||||
class And(Command):
|
||||
def __init__(self,source,dest):
|
||||
self.source = source
|
||||
self.dest = dest
|
||||
|
||||
def compile(self,state):
|
||||
return ConditionKeep(self.dest, Move(self.source,self.dest)).compile(state)
|
||||
|
||||
class Or(Command):
|
||||
def __init__(self,source,dest):
|
||||
self.source = source
|
||||
self.dest = dest
|
||||
|
||||
def compile(self,state):
|
||||
return CompositeCommand([
|
||||
SimpleAddition(self.source, self.dest),
|
||||
SelectVariable(self.dest),
|
||||
Booleanize(self.dest)
|
||||
]).compile(state)
|
||||
|
||||
if __name__ == "__main__":
|
||||
c = CompositeCommand([
|
||||
SetVariable("a",2),
|
||||
SetVariable("b",5),
|
||||
Addition2("b","a"),
|
||||
Copy("a","tmp"),
|
||||
Or("tmp","b"),
|
||||
ConditionKeep("tmp",CompositeCommand([
|
||||
SelectVariable("b"),
|
||||
SimpleIncrement()
|
||||
])),
|
||||
Not("tmp"),
|
||||
Condition("tmp",CompositeCommand([
|
||||
SelectVariable("b"),
|
||||
SimpleDecrement()
|
||||
]))
|
||||
])
|
||||
|
||||
print(c.compile(CompileState()))
|
Loading…
Reference in a new issue