VMトランスレーター / Code_Writerを作る / 単項演算子

Chapter 7

まずは簡単な単項演算子だけを実装する。

class Code_Writer:
    def __init__(self, file_path):
        self.file = open(file_path, "w")
 
    def write_arithmetic(self, command):
        # まず最後尾値をDレジスタに取り出して、
        self.__decrement_pointer("SP")
        self.file.write("@SP\n")
        self.file.write("A=M\n")
        self.file.write("D=M\n")

        
        # 何かをしてから、取り出したのと同じアドレスに上書きして、
        if command == "neg":
            self.file.write("M=-D\n")
        elif command == "not":
            self.file.write("M=!D\n")


        # 最後にスタックポインタをインクリメントする。
        self.__increment_pointer("SP")

    def write_push_pop(self, command, segment, index):
        if command == "C_PUSH":
            if segment == "constant":
                self.__load_d_with_immediate_value(index) # 即値をDレジスタに読み込んで、
                self.__load_ram_ram_pointer_with_d("SP") # それを、スタックポインタの指し示すアドレスに書き込んで、
                self.__increment_pointer("SP") # 最後にスタックポインタをインクリメントする。

    def halt(self):
        self.file.write("(HALT)\n")
        self.file.write("@HALT\n")
        self.file.write("0;JMP\n")

    def close(self):
        self.file.close()

        


    def set_pointer(self, name, val):
        self.file.write("@" + str(val) + "\n")
        self.file.write("D=A\n")
        self.file.write("@" + name + "\n")
        self.file.write("M=D\n")


    def __decrement_pointer(self, name):
        self.file.write("@" + name + "\n")
        self.file.write("M=M-1\n")
    def __increment_pointer(self, name):
        self.file.write("@" + name + "\n")
        self.file.write("M=M+1\n")
    def __load_d_with_immediate_value(self, immediate_value):
        self.file.write("@" + str(immediate_value) + "\n")
        self.file.write("D=A\n")
    def __load_ram_ram_pointer_with_d(self, name):
        self.file.write("@" + name + "\n")
        self.file.write("A=M\n")
        self.file.write("M=D\n")

        
########################################################################
if __name__ == "__main__":
    c = Code_Writer("Unary_Test.asm")
    c.set_pointer("SP", 256)

    c.write_push_pop("C_PUSH", "constant", 7)
    c.write_arithmetic("neg")
    c.write_arithmetic("not")

    c.halt()
    c.close()

実行結果:
negは負数にする。notはビット反転。
7 → neg(7) = -7 → not(-7) = 6
(0b0_0111 → 0b1_1001 → 0b0_0110)