Beispiel #1
0
class Translator:
    def __init__(self):
        self.__parser = None
        self.__generator = None


    @contextlib.contextmanager
    def __init_resorces(self):
        self.__parser = Parser()
        self.__generator = CodeGenerator()
        yield
        self.__parser = None
        self.__generator = None


    def translate(self, path, dry_run=False):
        with self.__init_resorces():
            blocks = self.__translate(path)

            if dry_run:
                for _ in blocks:
                    pass
            else:
                output = self.__make_output_name(path)
                with open(output, 'w') as f:
                    for block in blocks:
                        f.write(block)
                        f.write('\n')


    def __translate(self, path):
        if os.path.isdir(path):
            yield from self.__translate_project(path)
        else:
            yield from self.__translate_file(path)


    def __translate_project(self, path):
        yield self.__generator.gen_initializer()
        for fname in glob.iglob(os.path.join(path, '*.vm')):
            yield from self.__translate_file(fname)


    def __translate_file(self, path):
        filename = os.path.splitext(os.path.basename(path))[0]
        commands = self.__parser.parse_file(path)
        yield from self.__generator.itranslate(filename, commands)


    def __make_output_name(self, input_name):
        if os.path.isdir(input_name):
            dirname = os.path.basename(os.path.abspath(input_name))
            fname = os.path.join(input_name, dirname)
        else:
            fname, _ = os.path.splitext(input_name)
        return fname + '.asm'
def test_program(vm):
    g = CodeGenerator()
    code = g.gen_initializer()
    code += '\n' + g.translate(commands=[
            (0, 'goto', 'end'),

            (1, 'function', 'Sys.init', 0),
            (2, 'push', 'constant', 0),
            (3, 'return'),

            (4, 'label', 'end')
        ],
        filename='<input>',
    )
    vm.execute(code, 500)

    assert vm.ram[vm.symbols['SP']] == vm.stack_offset + 1