class InstructionSet:
def __init__(self, stack):
self.locals = {}
self.stack = stack
self.popped = 0
self.flag = 'flag'
self.codelines = []
def do(self, code):
self.codelines.append(code)
def push(self, expr):
self.stack.append(expr)
def compute(self, expr):
if expr in self.locals:
return expr
name = 'l%d' % len(self.locals)
self.locals[name] = expr
self.do('%s = %s;' % (name, expr))
return name
def pop(self):
if self.stack:
name = self.compute(self.stack.pop())
else:
name = self.compute('stack_nth(%d);' % self.popped)
self.popped += 1
return name
def setflag(self, expr):
self.flag = expr
def forgetflag(self):
self.flag = None
def consumeflag(self):
result = self.flag
self.forgetflag()
return result
def normalize(self, stack):
rstack = list(stack)
rstack.reverse()
code = ['%s = %s;' % (target, self.pop()) for target in rstack]
shift = self.popped-len(self.stack)
code += ['stack_nth(%d) = %s;' % (i, self.pop())
for i in range(len(self.stack))]
if self.flag is not None and self.flag != 'flag':
self.do('flag = %s;' % self.flag)
if shift != 0:
if shift > 0:
self.do('stack_shift_pos(%d);' % shift)
else:
self.do('stack_shift(%d);' % shift)
for line in code:
self.do(line)
self.stack = list(stack)
self.popped = 0
def write(self):
print '{'
if self.locals:
locals = self.locals.keys()
locals.sort()
print '\tword_t %s;' % (', '.join(locals),)
for line in self.codelines:
print '\t' + line
print '}'
class InstructionSetWriter:
def __init__(self, InsnSet, nbaccum=1):
self.InsnSet = InsnSet
self.nbaccum = nbaccum
|