Пример #1
0
    def chr(self):
        c = self.get()
        program = Program()
        container = program
        prev = program.lastToken
        while None != c:
            if '>' == c:
                token = Move(1)
            elif '<' == c:
                token = Move(-1)
            elif '+' == c:
                token = Data(1)
            elif '-' == c:
                token = Data(-1)
            elif '.' == c:
                token = Out()
            elif '[' == c:
                token = Loop(container)
                token.setpos(self.pos)
                token.link(prev)
                prev = token.firstToken
                container.addToken(token)
                container = token
                token = None
            elif ']' == c:
                prev = container
                container = container.close()
                token = None
            elif ',' == c:
                token = In()
            elif 'x' == c:
                token = Data(self.getGroup())
            elif '_' == c:
                token = Data(-self.getGroup())
            elif '{' == c:
                token = Move(-self.getGroup())
            elif '}' == c:
                token = Move(self.getGroup())
            elif '0' == c:
                token = Reset()
            elif 'R' == c:
                token = Reset()
            elif 'm' == c:
                token = self.createComplexOp()

            if None != token:
                token.setpos(self.pos)
                container.addToken(token)
                token.link(prev)
                prev = token
            c = self.get()
            token = None

        if program != container:
            raise RuntimeError('Program ended in an unclosed loop')

        self.template = Pyth(self)
        #self.template = Php(self)
        #self.template = C(self)
        program.process(self)
        program.write(self)

        tempToken = self.currentToken
        self.currentToken = self.headerToken
        self.template.header()
        self.currentToken = tempToken

        self.currentToken = self.footerToken
        self.template.footer()
        self.currentToken = tempToken
Пример #2
0
class Brainfuck2Python():
    '''
    Constructor

    @param source: brainfuck source code
    '''
    def __init__(self, source, bits = 8):
        # bf source code
        self.source = source
        # position of pointer to source code
        self.pos = 0
        # generated py source code parts "tokens"
        self.token = {'lines':[], 'loops':{}}
        self.headerToken = {'lines':[], 'loops':{}}
        self.footerToken = {'lines':[], 'loops':{}}
        # cycle stack
        self.stack = []
        # current token
        self.currentToken = self.token
        # current indentation for pretty-print
        self.indent = 0
        # previous op
        self.last = ''
        # static value
        self.staticValue = 0
        # max value
        self.bits = bits
        self.maxValue = 2**bits

        # program features
        self.features = {
            'move': False,
            'data': False,
            'dataop': False,
            'out': False,
            'cin': False,
            'ptr': False,
            'find': False,
            'tmp': False
        }

        self.chr()

        # destination file
        self.dst = open(self.template.filename, mode='w', encoding='utf-8')

        self.file(self.headerToken)
        self.file(self.currentToken)
        self.file(self.footerToken)

        self.dst.close()

    '''
    Processes next character
    '''
    def chr(self):
        c = self.get()
        program = Program()
        container = program
        prev = program.lastToken
        while None != c:
            if '>' == c:
                token = Move(1)
            elif '<' == c:
                token = Move(-1)
            elif '+' == c:
                token = Data(1)
            elif '-' == c:
                token = Data(-1)
            elif '.' == c:
                token = Out()
            elif '[' == c:
                token = Loop(container)
                token.setpos(self.pos)
                token.link(prev)
                prev = token.firstToken
                container.addToken(token)
                container = token
                token = None
            elif ']' == c:
                prev = container
                container = container.close()
                token = None
            elif ',' == c:
                token = In()
            elif 'x' == c:
                token = Data(self.getGroup())
            elif '_' == c:
                token = Data(-self.getGroup())
            elif '{' == c:
                token = Move(-self.getGroup())
            elif '}' == c:
                token = Move(self.getGroup())
            elif '0' == c:
                token = Reset()
            elif 'R' == c:
                token = Reset()
            elif 'm' == c:
                token = self.createComplexOp()

            if None != token:
                token.setpos(self.pos)
                container.addToken(token)
                token.link(prev)
                prev = token
            c = self.get()
            token = None

        if program != container:
            raise RuntimeError('Program ended in an unclosed loop')

        self.template = Pyth(self)
        #self.template = Php(self)
        #self.template = C(self)
        program.process(self)
        program.write(self)

        tempToken = self.currentToken
        self.currentToken = self.headerToken
        self.template.header()
        self.currentToken = tempToken

        self.currentToken = self.footerToken
        self.template.footer()
        self.currentToken = tempToken

    '''
    Returns next character of code. None at the end.
    '''
    def get(self):
        if self.pos < len(self.source):
            self.pos += 1
            return self.source[self.pos - 1]
        return None

    '''
    Appends nicely indented line to target source code
    '''
    def write(self, line):
        self.currentToken['lines'].append(('\t' * self.indent) + line.lstrip())

    '''
    Puts generated tokens into file
    '''
    def file(self, token):
        line = ''
        for line in token['lines']:
            if None != line:
                self.dst.write(line + '\n')

        if 'class Pybf():' != line:
            # hack, we skipped header
            self.dst.write('\n')

        for loop in token['loops'].values():
            self.file(loop)

    '''
    Returns the size of current group (group inc, move, etc.)
    '''
    def getGroup(self):
        end = self.source.index(';', self.pos)
        tmp = self.pos
        self.pos = end + 1
        return int(self.source[tmp:end])

    def createComplexOp(self):
        token = ComplexOp()

        i = self.getGroup()
        while 0 != i:
            token.addReset(i)
            i = self.getGroup()

        i = self.getGroup()
        while 0 != i:
            x = self.getGroup()
            token.addMove(i, x)
            i = self.getGroup()

        return token