アセンブラを作る / 最終版を作る

Chapter 6

これでPart I Hardware全6章が終わり。最初はここ

from Parser import *
from Code import *
from Symbol_Table import *

class Hack_Assember:
    def __init__(self, input_file_path):
        
        # 出力ファイル名は入力ファイル名の拡張子を.hackに変えたものにする。
        self.output_file_path = input_file_path.split(".")[0] + ".hack"
        self.output_file = open(self.output_file_path, "w")
        
        self.parser = Parser(input_file_path)
        self.code = Code()
        self.symbols = Symbol_Table()
        
        self.__first_pass()
        self.__second_pass()

    def __first_pass(self):
        self.parser.file.seek(0)
        line_number = -1
        
        while (self.parser.has_more_lines()):
            self.parser.advance()

            if (self.parser.inst_type() == "C") or (self.parser.inst_type() == "A"):
                line_number += 1

            elif self.parser.inst_type() == "L":
                self.symbols.add_entry(self.parser.symbol(), line_number + 1)
                
        print(self.symbols.symbols)

    def __second_pass(self):
        self.parser.file.seek(0)
        
        while (self.parser.has_more_lines()):
            self.parser.advance()

            if self.parser.inst_type() == "C":
                self.__second_pass_for_C_inst()

            elif self.parser.inst_type() == "A":
                self.__second_pass_for_A_inst()

        self.parser.file.close()
        self.output_file.close()

    def __second_pass_for_C_inst(self):
        comp_part = self.code.comp(self.parser.comp())
        dest_part = self.code.dest(self.parser.dest())
        jump_part = self.code.jump(self.parser.jump())
                
        processed_string = "111" + comp_part + dest_part + jump_part
        self.output_file.write(processed_string + "\n")

    def __second_pass_for_A_inst(self):
        address_part = self.parser.symbol()
        try:
            int(address_part)
        except:
            if self.symbols.contains(address_part):
                address_part = self.symbols.get_address(address_part)
            else:
                self.symbols.ram_last_address += 1
                self.symbols.add_entry(address_part, self.symbols.ram_last_address)
                address_part = self.symbols.ram_last_address
                        
        processed_string = "0" + bin(int(address_part))[2:].zfill(15)
        self.output_file.write(processed_string + "\n")
            

####################################################################
if __name__ == "__main__":
    Hack_Assember("Max.asm")

実行結果:
左が正解、右が自作アセンブラの出力。