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