Beispiel #1
0
class Main(object):
    def __init__(self, f):
        self.asm_file = f
        self.table = SymbolTable()
        self.data = self.read_file()
        self.parser = Parser(self.data)
        self.commands = self.parser.commands
        self.translator = Translator()
        self.filename = self.asm_file.split(".")[0]

    def read_file(self):
        with open(self.asm_file) as f:
            data = f.readlines()
        return data

    def write_file(self, output_lines):
        with open('%sassembled.hack' % self.filename, 'w') as output_file:
            for line in output_lines:
                output_file.write(line + '\n')

    def assemble(self):
        self.first_pass()
        output_lines = self.second_pass()
        self.write_file(output_lines)

    def first_pass(self):
        program_line = 0
        for line in self.commands:
            # if we have encountered a label pseudocommand
            # check if it is in the table, if not assign it to value of next program line
            # don't increment program counter because this shouldn't count as a program line
            if line[0] == '(':
                if not self.table.contains(line[1:-1]):
                    self.table.add_entry(line[1:-1], program_line)
                continue
            # if none of these conditions are hit, keep incrementing program line
            program_line += 1

    def second_pass(self):
        translated_commands = []
        next_available_RAM = 16
        for line in self.commands:
            if line[0] == '@':
                symbol = line[1:]
                try:
                    # translate directly if @ is referencing a specific value
                    translated_commands.append('{0:016b}'.format(int(symbol)))
                    continue
                except ValueError:
                    pass
                # check if symbol is already in the symbol table and convert value to binary
                if self.table.contains(symbol):
                    translated_commands.append('{0:016b}'.format(
                        self.table.get_address(symbol)))
                # add symbol to symbol table, increment available RAM count, and translate to binary
                else:
                    self.table.add_entry(symbol, next_available_RAM)
                    next_available_RAM += 1
                    translated_commands.append('{0:016b}'.format(
                        self.table.get_address(symbol)))
            elif line[0] == '(':
                continue
            else:
                translated_commands.append(
                    self.translator.handle_C_instruction(line))
        return translated_commands