from os import listdir class VirtualMachineCompiler: def __init__(self,file_path): self.file_path=file_path self.files=[] self.files_content=[] self.is_folder=True if ".vm" in file_path: self.is_folder=False self.files.append(file_path) self.assembly_commands={ None:"", "add":"@SP\nA=M-1\nD=M\n@SP\nM=M-1\nA=M-1\nM=D+M\n", "sub":"@SP\nA=M-1\nD=M\n@SP\nM=M-1\nA=M-1\nM=M-D\n", "neg":"@SP\nA=M-1\nM=-M\n", "eq":"@SP\nA=M-1\nD=M\n@SP\nM=M-1\nA=M-1\nD=M-D\nM=-1\n@LABEL{number}\nD;JEQ\n@SP\nA=M\nM=0\n(LABLE{number})\n", "gt":"@SP\nA=M-1\nD=M\n@SP\nM=M-1\nA=M-1\nD=M-D\nM=-1\n@LABEL{number}\nD;JGT\n@SP\nA=M\nM=0\n(LABLE{number})\n", "lt":"@SP\nA=M-1\nD=M\n@SP\nM=M-1\nA=M-1\nD=M-D\nM=-1\n@LABEL{number}\nD;JLT\n@SP\nA=M\nM=0\n(LABLE{number})\n", "and":"@SP\nA=M-1\nD=M\n@SP\nM=M-1\nA=M-1\nM=D&M\n", "or":"@SP\nA=M-1\nD=M\n@SP\nM=M-1\nA=M-1\nM=D|M\n", "not":"@SP\nA=M-1\nM=!M\n", "push":"{m_arg}D=M\n@SP\nM=M+1\nA=M-1\nM=D\n", "pop":"{m_arg}D=A\n@R13\nM=D\n@SP\nAM=M-1\nD=M\n@R13\nA=M\nM=D\n", "label":"({l_arg})\n", "goto":"@{l_arg}\n0;JMP\n", "if-goto":"@SP\nAM=M-1\nD=M\n@{l_arg}\nD;JNE\n", "function":"({f_arg})\n", "call":"@{r_address}\nD=A\n@SP\nAM=M-1\nM=D\n@LCL\nD=M\n@SP\nAM=M-1\nM=D\n@ARG\nD=M\n@SP\nAM=M-1\nM=D\n@THIS\nD=M\n@SP\nAM=M-1\nM=D\n@THAT\nD=M\n@SP\nAM=M-1\nM=D\n@SP\nD=M\n@5\nD=D-A\n@{arg2}\nD=D-A\n@ARG\nM=D\n@SP\nD=M\n@LCL\nM=D\n@{f_arg}\n({r_address})\n", "return":"@LCL\nD=M\n@R5\nM=D\nD=D-A\n@R6\nM=D\n@ARG\nAD=M\n@R13\nM=D\n@SP\nAM=M-1\nD=M\n@R13\nA=M\nM=D\n@ARG\nD=M+1\n@SP\nM=D\n@R5\nAM=M-1\nD=M\n@THAT\nM=D\n@R5\nAM=M-1\nD=M\n@THIS\nM=D\n@R5\nAM=M-1\nD=M\n@ARG\nM=D\n@R5\nAM=M-1\nD=M\n@LCL\nM=D\n@R6\nA=M\n0;JMP\n" } self.arguments={ None:"", "argument":"@ARG\nD=M\n@{arg2}\nA=D+M\n", "local":"@LCL\nD=M\n@{arg2}\nA=D+M\n", "static":"@{s_arg}\n", "constant":"@{arg2}\n", "this":"@THIS\nD=M\n@{arg2}\nA=D+M\n", "that":"@THAT\nD=M\n@{arg2}\nA=D+M\n", "pointer":"@R3\nD=M\n@{arg2}\nA=D+M\n", "temp":"@R5\nD=M\n@{arg2}\nA=D+M\n" } self.label_number=0 def folder_search(self): for item in listdir(self.file_path): if ".vm" in item: self.files.append(self.file_path+"\\"+item) def parser_module(self): if self.is_folder: self.folder_search() for file in self.files: file_content=open(file) file_array=[] for line in file_content: command=[None,None,None] line=line[:line.find("//")] line = line.strip() if line =="": continue line_array=line.split() for index in range(len(line_array)): command[index]=line_array[index] file_array.append(command) self.files_content.append(file_array) file_content.close() def code_writer_module(self): file_path=self.file_path if not self.is_folder: file_path=file_path[:file_path.find(".")] assembly_file=open(file_path,"w") for file in range(len(self.files_content)): current_function="" for line in self.files_content[file]: continue