コード例 #1
0
ファイル: VMtranslator.py プロジェクト: DavidAriel/Nand
class VMtranslator(object):
    def __init__(self, input_file_path):
        self.input_file_path = input_file_path
        self.code_writer = CodeWriter(input_file_path.replace(".vm", ".asm"))

    def translate(self):
        self.parser = Parser.Parser(self.input_file_path)
        while self.parser.has_more_commands():
            self.parser.advance()
            self._gen_command()
        self.code_writer.close()

    def _gen_command(self):
        command_type = self.parser.command_type()
        command_handler, args_amount = {
            Parser.C_PUSH       : [self.code_writer.write_push, 2],
            Parser.C_POP        : [self.code_writer.write_pop, 2],
            Parser.C_ARITHMETIC : [self.code_writer.write_arithmetic, 1],
            Parser.C_IF         : [self.code_writer.write_if, 1],
            Parser.C_LABEL      : [self.code_writer.write_label, 1],
            Parser.C_RETURN     : [self.code_writer.write_return, 0],
            Parser.C_GOTO       : [self.code_writer.write_goto, 1],
            Parser.C_FUNCTION   : [self.code_writer.write_function, 2],
            Parser.C_CALL       : [self.code_writer.write_call, 2]
        }[command_type]
        self._handle_command(command_handler, args_amount)

    def _handle_command(self, command_handler, args_amount):
        if args_amount == 2:
            command_handler(self.parser.arg1(), self.parser.arg2())
            return
        if args_amount == 1:
            command_handler(self.parser.arg1())
            return
        command_handler()
コード例 #2
0
 def __init__(self, tokenizer, file_path):
     self.tokenizer = tokenizer
     self.file_path = file_path
     self.symbol_table = SymbolTable()
     self.class_name = ""
     self.code_writer = CodeWriter(self)
     self.label_ind = 0
コード例 #3
0
class VM_Translator:
    def __init__(self, path):
        self.cw = CodeWriter()
        self.files = []
        if ".vm" in path:
            self.files.append(path)
        else:
            os.chdir(path)
            for filepath in os.listdir():
                self.files.append(filepath)
        self.asmcode = ""

    def parseFiles(self):
        self.parsed = []
        for filename in self.files:
            with open(filename) as vmcode:
                for line in vmcode.readlines():
                    self.parsed.append(parser(line, filename))
        self.parsed = [
            parsed for parsed in self.parsed if not parsed["Type"] == "UNKNOWN"
        ]

    def translate(self):
        for line in self.parsed:
            if line["Type"] == "C_ARITHMETIC":
                self.asmcode += self.cw.writeArithmetic(line)
            elif line["Type"] == "C_PUSH":
                self.asmcode += self.cw.writePush(line)
            elif line["Type"] == "C_POP":
                self.asmcode += self.cw.writePop(line)

    def write(self, path):
        with open(path, "w") as f:
            f.write(self.asmcode)
コード例 #4
0
 def test_not(self):
     code_writer = CodeWriter()
     cmd = '@SP\nAM=M-1\n'
     cmd += 'D=!M\n'
     cmd += '@SP\nA=M\nM=D\n'
     cmd += '@SP\nM=M+1\n'
     self.assertEqual(code_writer.get_not(), cmd)
コード例 #5
0
ファイル: VMtranslator.py プロジェクト: adirz/Nand
class VMtranslator(object):
    def __init__(self, input_file_path):
        self.input_file_path = input_file_path
        if not os.path.isdir(input_file_path):
            self.code_writer = CodeWriter(input_file_path.replace(".vm", ".asm"))
        else:
            file_name = input_file_path.split("/")
            file_name = file_name[len(file_name)-1]
            file_name = file_name.split("\\")
            file_name = file_name[len(file_name)-1]
            path = os.path.join(input_file_path, file_name+".asm")
            self.code_writer = CodeWriter(path)
        
    def translate(self, file_name):
        name = file_name.split(".vm")[0]
        self.parser = Parser.Parser(os.path.join(self.input_file_path, file_name))
        self.code_writer._set_file_name(name)
        while self.parser.has_more_commands():
            self.parser.advance()
            self._gen_command()
        self.code_writer.close()

    def _get_number_of_arguments(self, command_type):
        if command_type == Parser.C_PUSH or command_type == Parser.C_POP:
            return 2
        if command_type == Parser.C_ARITHMETIC:
            return 0
        return 0

    def _gen_command(self):
        command_type = self.parser.command_type()
        if command_type == Parser.C_PUSH or command_type == Parser.C_POP:
            self.code_writer.WritePushPop(self.parser.current_commands[0], self.parser.arg1(), self.parser.arg2())
        elif command_type == Parser.C_ARITHMETIC:
            self.code_writer.WriteArithmetic(self.parser.arg1())
コード例 #6
0
    def __init__(self, prodir, WriteInit=True):
        vmfiles = []
        for vf in os.listdir(prodir):
            if vf[-3:] == ".vm":
                vmfiles.append(os.path.join(prodir, vf))
        assert vmfiles

        self.parser = [Parser() for vmf in vmfiles]
        for vmf, parser in zip(vmfiles, self.parser):
            parser.coms = self.read_vm(vmf)
            parser.len_coms = len(parser.coms)
            parser.vmf = os.path.basename(vmf)

        directory = os.path.dirname(vmfiles[0])
        asm_name = os.path.basename(directory) + '.asm'
        self.asmf = os.path.join(directory, asm_name)

        print ''
        print "direct: ", directory
        print "vmfiles:"
        for vmf in vmfiles:
            print "\t", vmf
        print "asmname: ", asm_name
        print "asmf:    ", self.asmf
        print ''

        self.codewriter = CodeWriter(self.asmf)
        self.WI = WriteInit
コード例 #7
0
 def test_pop_that_pointer_symbol(self):
     code_writer = CodeWriter()
     i = '1'
     segment = MemorySegmentType.POINTER
     cmd = '@SP\nAM=M-1\n'
     cmd += 'D=M\n@THAT\nM=D\n'
     self.assertEqual(code_writer.get_pop(segment, i), cmd)
コード例 #8
0
ファイル: main.py プロジェクト: dserver/Nand2Tetris
def translateFile(vm_file):
    parser = Parser()
    codeWriter = CodeWriter(parser)
    codeWriter.setCurrentVMFile(os.path.basename(vm_file))

    hack_file_name = vm_file[:-3] + ".asm"
    hack_file = open(hack_file_name, "w+")

    with open(vm_file) as f:
        for nextLine in f:
            if hasNewLine(nextLine):
                nextLine = nextLine[:-1]

            nextLine = removeCommentsOnLine(nextLine)
            if (nextLine == ''):
                continue

            print nextLine


            asm_instructions = codeWriter.assembleVMCommand(nextLine)

            for i in xrange(0, len(asm_instructions)):
                asm_instructions[i] = asm_instructions[i] + '\n'

            hack_file.writelines(asm_instructions)

        hack_file.close()
コード例 #9
0
 def test_push_this_pointer_symbol(self):
     code_writer = CodeWriter()
     i = '0'
     segment = MemorySegmentType.POINTER
     cmd = '@THIS\nD=M\n@SP\nA=M\nM=D\n'
     cmd += '@SP\nM=M+1\n'
     self.assertEqual(code_writer.get_push(segment, i), cmd)
コード例 #10
0
def main():
    args = [x for x in sys.argv]

    if len(args) < 2:
        raise Exception(
            "Error[7]: No file/dir name provided \"Usage: python VMTranslator.py file.vm\""
        )

    if not os.path.isfile(args[1]) and not os.path.isdir(args[1]):
        raise FileNotFoundError("Error[8]: \"" + args[1] + "\" does not exist")

    input_files = [args[1]]
    output_file_name = os.path.basename(os.path.abspath(args[1])).split(".")

    if len(output_file_name) > 1:
        output_file_name.pop()

    output_file_name = ".".join(output_file_name)

    if os.path.isdir(input_files[0]):
        input_files = [
            f for f in os.listdir(input_files[0])
            if os.path.isfile(os.path.join(input_files[0], f))
        ]
        input_files = [f for f in input_files if f.split(".")[-1] == "vm"]
        input_files = [os.path.abspath(f) for f in input_files]
        print(input_files)
        print(output_file_name)

    code_writer = CodeWriter(output_file_name)

    for file_name in input_files:
        parser = Parser(file_name)
        code_writer.setFileName(file_name)

        while parser.hasMoreCommands():
            parser.advance()
            arg1 = None
            arg2 = None

            if parser.commandType() != COMMAND_TYPES["C_RETURN"]:
                arg1 = parser.arg1()

            if parser.commandType() == COMMAND_TYPES["C_PUSH"] or \
                    parser.commandType() == COMMAND_TYPES["C_POP"] or \
                    parser.commandType() == COMMAND_TYPES["C_FUNCTION"] or \
                    parser.commandType() == COMMAND_TYPES["C_CALL"]:
                arg2 = parser.arg2()

            if parser.commandType(
            ) == COMMAND_TYPES["C_ARITHMETIC"] and arg1 is not None:
                code_writer.writeArithmetic(arg1)

            if (parser.commandType() == COMMAND_TYPES["C_PUSH"] or \
                    parser.commandType() == COMMAND_TYPES["C_POP"]) and \
                    arg1 is not None and arg2 is not None:
                code_writer.writePushPop(parser.commandType(), arg1, arg2)

    code_writer.close()
コード例 #11
0
ファイル: VMtranslator.py プロジェクト: adirz/sample-projects
 def __init__(self, input_path):
     self.input_path = input_path
     if not os.path.isdir(input_path):
         self.input_path = os.path.dirname(input_path)
         self.code_writer = CodeWriter(input_path.replace(".vm", ".asm"))
     else:
         ouptut_path = os.path.join(input_path, os.path.basename(input_path) + ".asm")
         self.code_writer = CodeWriter(ouptut_path)
コード例 #12
0
ファイル: CodeParser.py プロジェクト: Infinidrix/nand2tetris
 def __init__(self, input: TextIOBase, output: TextIOBase):
     self.input = input
     self.output = output
     self.tokens = []
     self.location = 0
     self.writer = CodeWriter(output)
     self.generate_tokens()
     self.parse_file()
コード例 #13
0
 def __init__(self, vmfilename):
     """Constructs the Parser and CodeWriter objects to be used in
     translating the file and supplies them with the appropriate filenames.
     """
     asmfilename = vmfilename.split('.')[0] + '.asm'
     
     self.parser = Parser(vmfilename)
     self.code_writer = CodeWriter(asmfilename)
コード例 #14
0
 def compile_jack(jack_file_name):
     token_file_name = jack_file_name.replace('.jack', 'T.xml')
     token_file = open(token_file_name, 'w')
     jack_file = open(jack_file_name, 'r')
     tokenizer = Tokenizer(jack_file, token_file)
     vm_file = open(jack_file_name.replace('.jack', '') + '.vm', 'w')
     code_writer = CodeWriter(tokenizer, vm_file)
     code_writer.compile_class()
コード例 #15
0
 def test_pop_argument(self):
     code_writer = CodeWriter()
     i = '5'
     segment = MemorySegmentType.ARGUMENT
     segment_pointer = 'ARG'
     cmd = '@' + i + '\nD=A\n@' + segment_pointer + '\nD=D+M\n@addr\nM=D\n'
     cmd += '@SP\nAM=M-1\n'
     cmd += 'D=M\n@addr\nA=M\nM=D\n'
     self.assertEqual(code_writer.get_pop(segment, i), cmd)
コード例 #16
0
 def test_pop_temp(self):
     code_writer = CodeWriter()
     i = '2'
     segment = MemorySegmentType.TEMP
     start_address = '5'
     cmd = '@' + start_address + '\nD=A\n@' + i + '\nD=D+A\n@addr\nM=D\n'
     cmd += '@SP\nAM=M-1\n'
     cmd += 'D=M\n@addr\nA=M\nM=D\n'
     self.assertEqual(code_writer.get_pop(segment, i), cmd)
コード例 #17
0
 def test_pop_static(self):
     code_writer = CodeWriter()
     filename = 'filename1'
     code_writer.set_current_filename(filename)
     i = '5'
     segment = MemorySegmentType.STATIC
     cmd = '@SP\nAM=M-1\n'
     cmd += 'D=M\n@' + filename + '.' + i + '\nM=D\n'
     self.assertEqual(code_writer.get_pop(segment, i), cmd)
コード例 #18
0
ファイル: VMtranslator.py プロジェクト: dansalerno712/CS810
def main():
    #make sure they used the program right
    if len(sys.argv) != 2:
        print(
            "usage: python VMtranslator.py <some .vm file or a directory with .vm files in it>"
        )
        return

    #holds the open file descriptors to pass to the Parser constructor
    fileHandles = []
    inputPath = sys.argv[1]
    outputPath = ""
    #see if file or directory
    if inputPath.endswith(".vm"):
        #file
        vmFile = open(inputPath, 'r')
        fileHandles.append(vmFile)
        #set output path to be the vm file but with .asm extension
        outputPath = inputPath.replace(".vm", ".asm")

    elif os.path.isdir(inputPath):
        #make sure that the path doesn't end in a slash for a directory
        if inputPath.endswith("/"):
            inputPath = inputPath[:-1]
        #get .vm files and open them from directory
        for file in os.listdir(inputPath):
            if file.endswith(".vm"):
                vm = open(os.path.join(inputPath, file), 'r')
                fileHandles.append(vm)
        #outputpath is the path/directoryName.asm
        outputPath = inputPath + "/" + os.path.basename(inputPath) + ".asm"
    else:
        #error
        print(
            "You must enter a single .vm file or a directory with .vm files in it"
        )

    #instantiate the codewriter with the correct output path
    writer = CodeWriter(outputPath)
    #run through all the .vm files we have
    for file in fileHandles:
        #make a new parser for each .vm file
        parser = Parser(file)
        #make sure to give the writer the current file name for static memory access stuff
        writer.setFileName(os.path.basename(file.name))
        #write either arithmetic or memory access commands
        while (parser.hasMoreCommands()):
            if parser.commandType() == "C_ARITHMETIC":
                writer.writeArithmetic(parser.arg1())
            elif parser.commandType() == "C_PUSH" or parser.commandType(
            ) == "C_POP":
                writer.writePushPop(parser.commandType(), parser.arg1(),
                                    parser.arg2())

            parser.advance()
    #close the output file
    writer.close()
コード例 #19
0
 def __init__(self, path):
     self.path = path.replace('\\', '/')
     try:
         self.filename = self.path[len(self.path) -
                                   self.path[::-1].index('/'):-3]
     except ValueError:
         self.filename = self.path[:-3]
     self.cw = CodeWriter(self.filename)
     self.parser = Parser(path)
コード例 #20
0
 def test_push_local(self):
     code_writer = CodeWriter()
     i = '5'
     segment = MemorySegmentType.LOCAL
     segment_pointer = 'LCL'
     cmd = '@' + i + '\nD=A\n@' + segment_pointer + '\nA=M+D\nD=M\n'
     cmd += '@SP\nA=M\nM=D\n'
     cmd += '@SP\nM=M+1\n'
     self.assertEqual(code_writer.get_push(segment, i), cmd)
コード例 #21
0
ファイル: main.py プロジェクト: zenovy/nand2tetris-vm
def run():
    with ExitStack() as exit_stack:
        filename = filepath.split("/")[-1:][0].rstrip(".vm")
        input_file: IO = exit_stack.enter_context(open(filepath))
        output_file: IO = exit_stack.enter_context(
            open(filepath.rstrip("vm") + "asm", "w"))
        code_writer = CodeWriter(filename, output_file)

        for command_type, arg1, arg2 in parse_commands(input_file):
            code_writer.write_command(command_type, arg1, arg2)
コード例 #22
0
 def __init__(self, path):
     self.cw = CodeWriter()
     self.files = []
     if ".vm" in path:
         self.files.append(path)
     else:
         os.chdir(path)
         for filepath in os.listdir():
             self.files.append(filepath)
     self.asmcode = ""
コード例 #23
0
class VM_Translator:
    def __init__(self, path):
        self.cw = CodeWriter()
        self.files = []
        self.dir = False

        if ".vm" in path:
            self.files.append(path)
        else:
            self.dir = True
            os.chdir(path)
            for filepath in os.listdir():
                self.files.append(filepath)
        self.asmcode = ""

    def parseFiles(self):
        self.parsed = []
        for filename in self.files:
            with open(filename) as vmcode:
                for line in vmcode.readlines():
                    self.parsed.append(parser(line, filename[:-3]))
        self.parsed = [
            parsed for parsed in self.parsed if not parsed["Type"] == "UNKNOWN"
        ]

    def translate(self):
        # initialize with Sys.init
        if self.dir:
            self.asmcode += self.cw.boostrap()

        for line in self.parsed:
            if line["Type"] == "C_ARITHMETIC":
                self.asmcode += self.cw.writeArithmetic(line)
            elif line["Type"] == "C_PUSH":
                self.asmcode += self.cw.writePush(line)
            elif line["Type"] == "C_POP":
                self.asmcode += self.cw.writePop(line)
            elif line["Type"] == "C_LABEL":
                self.asmcode += self.cw.writeLabel(line)
            elif line["Type"] == "C_GOTO":
                self.asmcode += self.cw.writeGoto(line)
            elif line["Type"] == "C_IF":
                self.asmcode += self.cw.writeIfGoto(line)
            elif line["Type"] == "C_FUNCTION":
                self.asmcode += self.cw.writeFuncDef(line)
            elif line["Type"] == "C_CALL":
                self.asmcode += self.cw.writeFuncCall(line)
            elif line["Type"] == "C_RETURN":
                self.asmcode += self.cw.writeReturn(line)
            else:
                self.asmcode += ""

    def write(self, path):
        with open(path, "w") as f:
            f.write(self.asmcode)
コード例 #24
0
def main():
    input_path = sys.argv[FILE_POS]
    if isdir(input_path):
        input_list = [ input_path + "/" +f for f in listdir(input_path)
            if (isfile(join(input_path, f))) and (f.endswith(".vm")) ]
        # check if we're getting a path or something else
        index = input_path.rfind("/")
        name = input_path[index + 1:]
        output_file_name = input_path + "/" + name + ".asm"
    else:
        input_list = [input_path]
        index = input_path.index(".vm")
        output_file_name = input_path[:index] + ".asm"

    code_writer = CodeWriter(output_file_name)

    for input_file in input_list:
        parser = Parser(input_file)
        code_writer.set_file_name(input_file)
        while parser.has_more_commands():
            command = parser.advance()
            if parser.command_type() == C_ARITHMETIC:
                code_writer.write_arithmetic(command)
            if (parser.command_type() == C_PUSH) or (parser.command_type() == C_POP):
                code_writer.write_push_pop(parser.command_type(), parser.arg1(), parser.arg2())

    code_writer.close()
コード例 #25
0
 def get_correct_lines(self, command_type, line):
     lines = list()
     # project 7 part -
     if command_type == CommandType.C_ARITHMETIC:
         lines = CodeWriter.arithmetic_line(str(self.label_counter), line)
     elif command_type == CommandType.C_PUSH:
         lines = CodeWriter.push_line(str(self.file_name), line)
     elif command_type == CommandType.C_POP:
         lines = CodeWriter.pop_line(str(self.file_name), line)
     # project 8 part -
     elif command_type == CommandType.C_LABEL:
         # ( functionName $ labelName )
         lines = CodeWriter.label_line(str(self.last_function), line)
     elif command_type == CommandType.C_GOTO:
         # ( functionName $ labelName )
         lines = CodeWriter.goto_line(str(self.last_function), line)
     elif command_type == CommandType.C_IF:
         # ( functionName $ labelName )
         lines = CodeWriter.if_line(str(self.last_function), line)
     elif command_type == CommandType.C_FUNCTION:
         lines = CodeWriter.function_line(line)
     elif command_type == CommandType.C_RETURN:
         lines = CodeWriter.return_line()
     elif command_type == CommandType.C_CALL:
         # building return address
         # which is FILE_NAME$ret.(SOME COUNTER FOR RETURNS)
         return_address = self.file_name + "$" + "ret." + str(
             self.label_counter)
         self.label_counter = self.label_counter + 1
         lines = CodeWriter.call_line(return_address, line)
     return lines
コード例 #26
0
ファイル: VMtranslator.py プロジェクト: adirz/Nand
 def __init__(self, input_file_path):
     self.input_file_path = input_file_path
     if not os.path.isdir(input_file_path):
         self.code_writer = CodeWriter(input_file_path.replace(".vm", ".asm"))
     else:
         file_name = input_file_path.split("/")
         file_name = file_name[len(file_name)-1]
         file_name = file_name.split("\\")
         file_name = file_name[len(file_name)-1]
         path = os.path.join(input_file_path, file_name+".asm")
         self.code_writer = CodeWriter(path)
コード例 #27
0
 def test_return(self):
     code_writer = CodeWriter()
     cmd = '@LCL\nD=M\n@endFrame\nM=D\n@5\nA=D-A\nD=M\n@retAddr\nM=D\n'
     cmd += '@SP\nAM=M-1\nD=M\n@ARG\nA=M\nM=D\n'
     cmd += '@ARG\nD=M+1\n@SP\nM=D\n'
     cmd += '@endFrame\nD=M\n@1\nA=D-A\nD=M\n@THAT\nM=D\n'
     cmd += '@endFrame\nD=M\n@2\nA=D-A\nD=M\n@THIS\nM=D\n'
     cmd += '@endFrame\nD=M\n@3\nA=D-A\nD=M\n@ARG\nM=D\n'
     cmd += '@endFrame\nD=M\n@4\nA=D-A\nD=M\n@LCL\nM=D\n'
     cmd += '@retAddr\nA=M\n0;JMP\n'
     self.assertEqual(code_writer.get_return(), cmd)
コード例 #28
0
 def test_push_const(self):
     code_writer = CodeWriter()
     i = '5'
     segment = MemorySegmentType.CONSTANT
     cmd = '@' + i + '\n'
     cmd += 'D=A\n'
     cmd += '@SP\n'
     cmd += 'A=M\n'
     cmd += 'M=D\n'
     cmd += '@SP\n'
     cmd += 'M=M+1\n'
     self.assertEqual(code_writer.get_push(segment, i), cmd)
コード例 #29
0
class VMTranslator:
    def __init__(self):
        self.parser = VMParser()
        self.coder = CodeWriter()
        self.myPath = Path(sys.argv[1])
        self.initParameters()

    def initParameters(self):
        self.filelists = list()
        if self.myPath.is_file():
            self.filelists = [self.myPath]
            self.outputFile = str(self.myPath.with_suffix('.asm'))
        elif self.myPath.is_dir():
            self.filelists = [
                file for file in self.myPath.iterdir()
                if str(file).endswith('.vm')
            ]
            self.outputFile = str(
                self.myPath) + ('/' + str(self.myPath.stem) + '.asm')
        self.outputFileHandle = open(self.outputFile, 'w')

    def run(self):
        self.outputFileHandle.write(
            self.coder.translateCode(['bootstrap'], 'Call Sys.init 0'))

        for file in self.filelists:
            fileHandle = open(str(file))
            filename = file.stem  #extract filename without the extendion e.g foo.vm => foo

            self.coder.setFilename(filename)

            for line in fileHandle:
                sanitizedLine = self.sanitizeInput(line)
                if len(sanitizedLine) == 0: continue
                parsedInstruction = self.parser.parse(sanitizedLine)
                codeString = self.coder.translateCode(parsedInstruction,
                                                      sanitizedLine)
                self.outputFileHandle.write(codeString)
            fileHandle.close()

        print('Translated VM code to assembly successfully.')
        # noinspection PyUnboundLocalVariable
        self.outputFileHandle.close()

    # remove whitespace and comments from input[line]
    def sanitizeInput(self, line):
        if len(line) == 0 or line.startswith('//'):
            return ''
        line = line.strip()
        commentIndex = line.find('//')
        if commentIndex > -1:
            line = line[:commentIndex]
        return line
コード例 #30
0
    def __init__(self, path):
        is_directory = False
        if os.path.isfile(path):
            self.files = [path]
        elif os.path.isdir(path):
            self.files = [
                os.path.join(path, file) for file in os.listdir(path)
                if file.endswith('.vm')
            ]
            is_directory = True

        self.parser = None
        self.writer = CodeWriter(path, is_directory)
コード例 #31
0
def main(filepath):

    out_filename, filenames = parseFilePath(filepath)

    if os.path.exists(out_filename):
        os.remove(out_filename)

    if os.path.isfile(filepath):
        with open(filepath, "r") as infile:
            data = infile.readlines()

        parser = Parser(data)
        code_writer = CodeWriter(out_filename, filenames[0])

        writeFile(parser, code_writer)

    elif os.path.isdir(filepath):
        for filename in filenames:
            full_path = os.path.join(filepath, filename + ".vm")
            with open(full_path, "r") as infile:
                data = infile.readlines()

            parser = Parser(data)
            code_writer = CodeWriter(out_filename, filename)

            if filenames[0] == filename:
                code_writer.writeComment("call Sys.init 0")
                code_writer.writeInit()
            writeFile(parser, code_writer)
コード例 #32
0
    def __init__(self, filepath):
        self.parse_files(filepath)
        # Initialize CW with a filename, so that
        # Write init
        self.cw = CodeWriter(outFile='outFile')
        self.cw.writeInit()

        print(f"Files that is to be translated: {self.vm_filenames}")

        # Note: filename does not include '.vm'
        for filename in self.vm_filenames:
            self.translate(filename=filename)

        self.cw.close()
コード例 #33
0
    def __init__(self, vmfile):
        # project7 不考虑分支命令 和 函数调用命令
        # 只考虑单个vm文件
        if os.path.isdir(vmfile):
            return
        else:
            f = open(vmfile, 'r')
            lines = f.readlines()
            f.close()

            vm_commands = []
            for i in range(len(lines)):
                line = lines[i].strip()

                slash_idx = len(line)
                if '//' in line:
                    slash_idx = line.index('//')
                line = line[:slash_idx]

                line= line.rstrip()

                line = line.split(' ')
                line = filter(lambda x:x, line)
                line = ' '.join(line)

                if line == '':
                    continue

                if not self.valid(line):
                    raise Exception("invalid vm statement in line {0}".format(i+1))

                print "line: ", line
                vm_commands.append(line)

            self.parser = Parser()
            self.parser.coms = vm_commands
            self.parser.len_coms = len(vm_commands)

            dirt = os.path.dirname(vmfile)
            filename = os.path.basename(vmfile)
            asm_name = filename.split('.')[0] + '.asm'
            self.asm_name = os.path.join(dirt, asm_name)

            print ''
            print "direct: ", dirt
            print "vmname: ", filename
            print "asmname: ", asm_name
            print "fullpath_asm: ", self.asm_name
            print ''
            self.codewriter = CodeWriter(self.asm_name)
コード例 #34
0
def main():
    input_file = parse_arguments()
    if validate(input_file):
        if Path(input_file).is_dir():
            files = get_files_from_directory(input_file)
            code_writer = CodeWriter(input_file)
            for file in files:
                lines = read_file(f'{input_file}/{file}')
                for line in lines:
                    handle_file_output(line, code_writer)
        else:
            lines = read_file(input_file)
            code_writer = CodeWriter(input_file)
            for line in lines:
                handle_file_output(line, code_writer)
コード例 #35
0
 def test_function(self):
     code_writer = CodeWriter()
     f_name = 'file.foo'
     num_vars = 3
     cmd = '(' + f_name + ')\n'
     i = '0'
     push_cmd = '@' + i + '\n'
     push_cmd += 'D=A\n'
     push_cmd += '@SP\n'
     push_cmd += 'A=M\n'
     push_cmd += 'M=D\n'
     push_cmd += '@SP\n'
     push_cmd += 'M=M+1\n'
     cmd += push_cmd * num_vars
     self.assertEqual(code_writer.get_function(f_name, num_vars), cmd)
コード例 #36
0
 def test_call(self):
     code_writer = CodeWriter()
     f_name = 'fun'
     n_args = '3'
     ret_addr = f_name + '$ret.1'
     cmd = '@' + ret_addr + '\nD=A\n@SP\nA=M\nM=D\n@SP\nM=M+1\n'
     cmd += '@LCL\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n'
     cmd += '@ARG\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n'
     cmd += '@THIS\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n'
     cmd += '@THAT\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n'
     cmd += '@SP\nD=M\n@5\nD=D-A\n@' + n_args + '\nD=D-A\n@ARG\nM=D\n'
     cmd += '@SP\nD=M\n@LCL\nM=D\n'
     cmd += '@' + f_name + '\n0;JMP\n'
     cmd += '(' + ret_addr + ')\n'
     self.assertEqual(code_writer.get_call(f_name, n_args), cmd)
コード例 #37
0
def main():
	"output file setup"
	filename = sys.argv[1]
	output = CodeWriter( filename )

	"input file setup"
	input = Parser( )
	commandlines = input.commandLines( filename )
	for line in commandlines:
		if input.typeCommand( line ) == 'C_ARITHMETIC':
			output.writeArithmetic( line )
			output.Write()
		elif input.typeCommand( line ) in [ 'C_PUSH', 'C_POP' ]:
			output.writePushPop( line )
			output.Write()
	output.Close()
コード例 #38
0
ファイル: VMtranslator.py プロジェクト: adirz/Nand-1
class VMtranslator(object):
    def __init__(self, input_file_path):
        self.input_file_path = input_file_path
        self.code_writer = CodeWriter(input_file_path.replace(".vm", ".asm"))

    def translate(self):
        self.parser = Parser.Parser(self.input_file_path)
        while self.parser.has_more_commands():
            self.parser.advance()
            self._gen_command()
        self.code_writer.close()

    def _gen_command(self):
        command_type = self.parser.command_type()
        if command_type == Parser.C_PUSH:
            self.code_writer.write_push(self.parser.arg1(), self.parser.arg2())
        elif command_type == Parser.C_POP:
            self.code_writer.write_pop(self.parser.arg1(), self.parser.arg2())
        elif command_type == Parser.C_ARITHMETIC:
            self.code_writer.write_arithmetic(self.parser.arg1())
コード例 #39
0
ファイル: VMtranslator.py プロジェクト: adirz/Nand-1
 def __init__(self, input_file_path):
     self.input_file_path = input_file_path
     self.code_writer = CodeWriter(input_file_path.replace(".vm", ".asm"))
コード例 #40
0
ファイル: Main.py プロジェクト: bendanon/n2t-proj7
def main(args):
    '''
    You can set vm_file_path to be either a folder (and then an asm file
    with the folder source_file will be created in the folder) or set it to be
    a vm file (and then an asm file with the file source_file will be created
    in the same location)
    '''
    if len(args) != 1:
        print "Usage: (python) Main.py [<.vm file path>|<source dir path>]"
        return

    vm_file_path = args[0]

    # vm_file_path = "Input/StackArithmetic/SimpleAdd/SimpleAdd.vm"
    # vm_file_path = "Input/StackArithmetic/StackTest/StackTest.vm"
    # vm_file_path = "Input/MemoryAccess/BasicTest/BasicTest.vm"
    # vm_file_path = "Input/MemoryAccess/PointerTest/PointerTest.vm"
    # vm_file_path = "Input/MemoryAccess/StaticTest/StaticTest.vm"
    # vm_file_path = "Input/ProgramFlow/BasicLoop/BasicLoop.vm"
    # vm_file_path = "Input/ProgramFlow/FibonacciSeries/FibonacciSeries.vm"
    # vm_file_path = "Input/FunctionCalls/SimpleFunction/SimpleFunction.vm"

    init_code_required = False
    source_file_paths = []
    sep = '/' if '/' in vm_file_path else os.sep

    if not vm_file_path.endswith(".vm"):
        source_file_names = [file_name for file_name in
                             os.listdir(vm_file_path) if
                             file_name.endswith('.vm')]
        source_file_paths += [os.path.join(vm_file_path, file_name) for
                              file_name in source_file_names]
        init_code_required = 'Sys.vm' in source_file_names
        asm_file_name = "{0}.asm".format(vm_file_path.split(sep)[-2])
        asm_file_path = os.path.join(vm_file_path, asm_file_name)
    else:
        source_file_paths = [vm_file_path]
        asm_file_path = vm_file_path.replace(".vm", ".asm")

    cw = CodeWriter(asm_file_path)
    if init_code_required:
        cw.writeInit()
        cw.writeFinishLoop()

    for source_file in source_file_paths:
        cw.setFileName(source_file)
        p = Parser(source_file)

        while(p.hasMoreCommands()):
            cmdType = p.commandType()

            if(cmdType == CommandType.C_ARITHMETIC):
                cw.writeArithmetic(p.arg1())

            elif(cmdType == CommandType.C_PUSH or
                 cmdType == CommandType.C_POP):
                cw.writePushPop(cmdType, p.arg1(), p.arg2())

            elif(cmdType == CommandType.C_LABEL):
                cw.writeLabel(p.arg1())

            elif(cmdType == CommandType.C_GOTO):
                cw.writeGoto(p.arg1())

            elif(cmdType == CommandType.C_IF):
                cw.writeIf(p.arg1())

            elif(cmdType == CommandType.C_CALL):
                cw.writeCall(p.arg1(), p.arg2())

            elif(cmdType == CommandType.C_FUNCTION):
                cw.writeFunction(p.arg1(), p.arg2())

            elif(cmdType == CommandType.C_RETURN):
                cw.writeReturn()

            p.advance()

    cw.Close()
コード例 #41
0
	
	inFile.close()

#open output file, fail nicely if it fails
try:
	outFile = open(outPath, "w")
	
except:
	print outPath + ": file could not be opened"
	exit(1)
finally:
	outFile.close()



writer = CodeWriter(outPath)

for f in vmNames:
	fn = path.basename(f)
	print "Working on:",fn
	writer.setFileName(fn)
	parser = Parser(f)
	while parser.hasMoreCommands():
		parser.advance()
		if parser.commandType() == "C_ARITHMETIC":
			writer.writeArithmetic(parser.arg1())
		elif parser.commandType() == "C_PUSH":
			writer.writePushPop("PUSH", parser.arg1(), parser.arg2())
		elif parser.commandType() == "C_POP":
			writer.writePushPop("POP", parser.arg1(), parser.arg2())
		elif parser.commandType() == "C_LABEL":
コード例 #42
0
	
	inFile.close()

#open output file, fail nicely if it fails
try:
	outFile = open(outPath, "w")
	
except:
	print outPath + ": file could not be opened"
	exit(1)
finally:
	outFile.close()



writer = CodeWriter(outPath)

for f in vmNames:
	fn = path.basename(f)
	print "Working on:",fn
	writer.setFileName(fn)
	parser = Parser(f)
	while parser.hasMoreCommands():
		parser.advance()
		if parser.commandType() == "C_ARITHMETIC":
			writer.writeArithmetic(parser.arg1())
		if parser.commandType() == "C_PUSH":
			writer.writePushPop("PUSH", parser.arg1(), parser.arg2())
		if parser.commandType() == "C_POP":
			writer.writePushPop("POP", parser.arg1(), parser.arg2())
			
コード例 #43
0
ファイル: Parser.py プロジェクト: TaoZang/FromNandToTetris
	def hasMoreCommands(self):
		return self.index < len(self.instructions);

	def advance(self):
		self.index = self.index + 1;

	def commandType(self):
		match = re.match(r'(\w+).*', self.instructions[self.index]);
		return match.groups()[0];

	def arg1(self):
		match = re.match(r'\w+\s+(\w+).*', self.instructions[self.index]);
		return match.groups()[0];

	def arg2(self):
		match = re.match(r'\w+\s+\w+\s+(\w+)', self.instructions[self.index]);
		return match.groups()[0];

if __name__ == '__main__':
	path = os.path.dirname(sys.argv[1]);
	filename = os.path.basename(sys.argv[1]);
	parser = Parser(path + '/' + filename);
	writer = CodeWriter(path, filename.split('.')[0]);
	while parser.hasMoreCommands():
		command = parser.commandType();
		if(command == 'push' or command == 'pop'):
			writer.writePushPop(command, parser.arg1(), parser.arg2());
		else:
			writer.writeArithmetic(command);
		parser.advance();
	writer.close();
コード例 #44
0
#Author: Josh Wretlind
#Class: CSCI 410 - Elements of Computing Systems
#Project: ECS 07 - VM Part #1
#Date: 03/03/13

import sys,string,os
from Parse import Parser
from CodeWriter import CodeWriter

infile = sys.argv[1] # Sys.argv is the system argument list object

outfile = infile.replace(".vm",".asm")
parse = Parser(infile)
cw = CodeWriter()

while parse.hasMoreCommands():
    parse.advance()
    parse.output()
    arg1 = ""
    arg2 = ""
    print parse.parsedline
    if(parse.commandType() == parse.C_ERROR):
        print "Oops, there was an error"
        break
    elif(parse.commandType() != parse.C_RETURN):
        arg1 = parse.arg1()
    if(parse.commandType() == parse.C_PUSH or parse.commandType() == parse.C_POP or parse.commandType() == parse.C_FUNCTION or parse.commandType() == parse.C_CALL):
        arg2 = parse.arg2()
    cw.write(parse.parsedline, parse)

output = open(outfile, 'w')
コード例 #45
0
def main():
	"output file setup"
	arg_length = len( sys.argv ) - 2
	if arg_length == 0:
		objectFileName = sys.argv[1].split('.')[0]
		filename = sys.argv[1]
		output = CodeWriter(objectFileName, filename)
		input = Parser( )
		commandlines = input.commandLines( filename )
		for line in commandlines:
			if input.typeCommand( line ) == 'C_ARITHMETIC':
				output.writeArithmetic( line )
				output.Write()
			elif input.typeCommand( line ) in [ 'C_PUSH', 'C_POP' ]:
				output.writePushPop( line )
				output.Write()
			elif input.typeCommand( line ) == 'C_LABEL':
				output.writeLabel( line )
				output.Write()
			elif input.typeCommand( line ) == 'C_GOTO':
				output.writeGoto( line )
				output.Write()
			elif input.typeCommand( line ) == 'C_IFGOTO':
				output.writeIfGoTo( line )
				output.Write()
			elif input.typeCommand( line ) == 'C_FUNCTION':
				#output.writeInit( line )
				output.writeFunction( line )
				output.Write()
			elif input.typeCommand( line ) == 'C_RETURN':
				output.writeReturn( line )
				output.Write()
			elif input.typeCommand( line ) == 'C_CALL':
				output.writeCall( line )
				output.Write()
	else:
		count = 0
		objectFileName = sys.argv[-1]
		while count < arg_length:
			"input file setup"
			filename = sys.argv[ count + 1 ]
			output = CodeWriter(objectFileName, filename)
			input = Parser( )
			commandlines = input.commandLines( filename )
			for line in commandlines:
				if input.typeCommand( line ) == 'C_ARITHMETIC':
					output.writeArithmetic( line )
					output.Write()
				elif input.typeCommand( line ) in [ 'C_PUSH', 'C_POP' ]:
					output.writePushPop( line )
					output.Write()
				elif input.typeCommand( line ) == 'C_LABEL':
					output.writeLabel( line )
					output.Write()
				elif input.typeCommand( line ) == 'C_GOTO':
					output.writeGoto( line )
					output.Write()
				elif input.typeCommand( line ) == 'C_IFGOTO':
					output.writeIfGoTo( line )
					output.Write()
				elif input.typeCommand( line ) == 'C_FUNCTION':
					#output.writeInit( line )
					output.writeFunction( line )
					output.Write()
				elif input.typeCommand( line ) == 'C_RETURN':
					output.writeReturn( line )
					output.Write()
				elif input.typeCommand( line ) == 'C_CALL':
					output.writeCall( line )
					output.Write()
			count += 1

	output.Close()
コード例 #46
0
args = argument_parser.parse_args()

if isdir(args.source):
    source = args.source.rstrip("/")
    filenames = glob(join(source, "*.vm"))
    output_filename = join(source, splitext(basename(source))[0] + ".asm")
else:
    filenames = [args.source]
    output_filename = split(args.source)[0] + ".asm"

if args.stdout:
    output_file = sys.stdout
else:
    output_file = open(output_filename, "w")

cw = CodeWriter(output_file, args.stamp)

if args.bootstrap:
    cw.writeInit()

for filename in filenames:
    cw.setFileName(filename)
    p = VMParser(filename)
    while p.hasMoreCommands():
        t = p.commandType()
        if t in ["C_PUSH", "C_POP"]:
            cw.WritePushPop(t, p.arg1(), p.arg2())
        elif t == "C_ARITHMETIC":
            cw.writeArithmetic(p.arg1())
        elif t == "C_LABEL":
            cw.writeLabel(p.arg1())
コード例 #47
0
ファイル: VMtranslator.py プロジェクト: SeanHAu/Nand2Tetris
        elif ctype == 'C_RETURN':
            codeWriter.writeReturn()
        elif ctype == 'C_CALL':
            arg1 = parser.arg1().strip()
            arg2 = parser.arg2().strip()
            codeWriter.writeCall(arg1,arg2)
        parser.advance()
    parser.rfile.close()



filename = sys.argv[1]

if os.path.isfile(filename):
	parser = Parser(filename)
	codeWriter = CodeWriter()
	codeWriter.setFileName(filename)
	codeWriter.wfile.write('@256\nD=A\n@SP\nM=D\n')
	Main(parser,codeWriter,filename)
elif os.path.isfile('Sys.vm'):
	codeWriter = CodeWriter()
	codeWriter.setFileName(filename)
	codeWriter.wfile.write('@256\nD=A\n@SP\nM=D\n')
	codeWriter.wfile.write('@return_address0\nD=A\n@SP\nA=M\nM=D\n@SP\nM=M+1\
		\n@LCL\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n@ARG\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\
		\n@THIS\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n@THAT\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\
		\n@0\nD=A\n@5\nD=D+A\n@SP\nD=M-D\n@ARG\nM=D\n@SP\nD=M\n@LCL\nM=D\
		\[email protected]\n0;JMP\n(return_address0)\n')
	filelist = os.listdir(os.getcwd())
	for item in filelist:
		if item.endswith('.vm'):