75 lines
3.5 KiB
Plaintext
75 lines
3.5 KiB
Plaintext
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
|
|
|