コード例 #1
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)
コード例 #2
0
def main():
    #put the files in the same folder as the code and put the names in the filenames array, pass codewriter the name you want to output or filename[x] if you want it to be the same name with .asm
    #filenames = ["BasicTest","PointerTest","SimpleAdd","StackTest","StaticTest"]

    filesnames = []
    inputList = []
    ##put the file directory here
    filesPath = "C:\\Users\\drumm\\OneDrive\\Documents\\Code\\nand2tetris\\projects\\08\\FunctionCalls\\StaticsTest\\"
    runInit = False

    inputList = glob.glob(filesPath + "*.vm")
    for x in range(0, len(inputList)):
        filesnames.append(inputList[x].split('\\')[-1].replace('.vm', ''))

    if len(inputList) > 1:
        runInit = True

    if runInit == True:
        codewriter = CodeWriter(
            filesPath + inputList[0].split('\\')[-2].replace('.vm', '') +
            ".asm")
        codewriter.writeInit()
    else:
        codewriter = CodeWriter(filesPath + filesnames[0] + ".asm")

    for x in range(0, len(inputList)):

        filename = inputList[x]
        parser = Parser(filename)

        while parser.hasMoreCommands():
            parser.advance()
            if parser.arg1() == 'push' or parser.arg1() == 'pop':
                codewriter.WritePushPop(
                    parser.arg1(), parser.arg2(), parser.arg3(),
                    filename.split('\\')[-1].replace('.vm', ''))
            elif parser.commandType() == 'C_ARITHMETIC':
                codewriter.writeArithmetic(parser.currentCommand)
            elif parser.commandType() == 'C_LABEL':
                codewriter.writeLabel(parser.arg2())
            elif parser.commandType() == 'C_GOTO':
                codewriter.writeGoto(parser.arg2())
            elif parser.commandType() == 'C_IF':
                codewriter.writeIf(parser.arg2())
            elif parser.commandType() == 'C_CALL':
                codewriter.writeCall(parser.arg2(), parser.arg3())
            elif parser.commandType() == 'C_RETURN':
                codewriter.writeReturn()
            elif parser.commandType() == 'C_FUNCTION':
                codewriter.writeFunction(parser.arg2(), parser.arg3())
            else:
                print("hitelse")

        parser.close()

    codewriter.Close()
コード例 #3
0
def main():
    inputFileName = getInputName()
    isDirectory = os.path.isdir(inputFileName)

    if isDirectory:
        files = os.listdir(inputFileName)
        vmFiles = filter(isVMFile, files)
        listOfFiles = list(
            map(lambda fileName: inputFileName + "/" + fileName, vmFiles))

        outputFileName = trimFile(inputFileName)
        writer = CodeWriter(inputFileName + "/" + outputFileName)
        if len(listOfFiles) > 1:
            writer.bootstrap()
    else:
        listOfFiles = [inputFileName]
        outputFileName = trimFile(inputFileName)
        writer = CodeWriter(outputFileName)

    for currentFile in listOfFiles:
        print("File to be parsed: {}".format(currentFile))

        writer.setNewInputFile(trimFile(currentFile))
        parser = Parser(currentFile)

        while parser.hasMoreCommands():
            parser.advance()
            command = parser.getCommand()
            if parser.isArithmetic():
                writer.writeArithmetic(command)
            elif parser.isPush() or parser.isPop():
                writer.writePushPop(command)
            elif parser.isLabel():
                writer.writeLabel(command)
            elif parser.isGoto():
                writer.writeGoto(command)
            elif parser.isIf():
                writer.writeIf(command)
            elif parser.isFunction():
                writer.writeFunction(command)
            elif parser.isCall():
                writer.writeCall(command)
            elif parser.isReturn():
                writer.writeReturn(command)
            elif parser.isComment() or parser.isBlankLine():
                continue
            else:
                raise Exception("Command not supported")

    parser.close()
    writer.close()
    print("VMTranslator finished.")
コード例 #4
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)
コード例 #5
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)
コード例 #6
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)
コード例 #7
0
def main():
    filename = sys.argv[1]
    parser = Parser(filename)
    writer = CodeWriter(filename)
    writer.writeInit()

    while parser.hasMoreCommands():
        parser.advance()
        lineType = parser.commandType()
        if lineType == 'C_ARITHMETIC':
            writer.writeArithmetic(parser.getCommand())
        elif lineType == 'C_PUSH' or lineType == 'C_POP':
            writer.writePushPop(lineType, parser.arg1(), parser.arg2())
        elif lineType == 'C_LABEL':
            writer.writeLabel(parser.arg1())
        elif lineType == 'C_GOTO':
            writer.writeGoto(parser.arg1())
        elif lineType == 'C_IF':
            writer.writeIf(parser.arg1())
        elif lineType == 'C_CALL':
            writer.writeCall(parser.arg1(), parser.arg2())
        elif lineType == 'C_RETURN':
            writer.writeReturn()
        elif lineType == 'C_FUNCTION':
            writer.writeFunction(parser.arg1(), parser.arg2())
コード例 #8
0
 def translate(self):
     print("Starting translation...")
     if (self._file_list is None) or (len(self._file_list) == 0):
         raise Exception("No valid files to translate.")
     with CodeWriter(self._out_filename) as writer:
         writer.write_init()
         for infile in self._file_list:
             print("Processing file '{}' ...".format(infile))
             writer.set_filename(os.path.splitext(os.path.basename(infile))[0])
             p = Parser(infile)
             while p.has_more_commands():
                 p.advance()
                 if p.command_type == VmToken.ARITHMETIC:
                     writer.write_arithmetic(p.arg1)
                 elif p.command_type == VmToken.POP or p.command_type == VmToken.PUSH:
                     writer.write_push_pop(p.command_type, p.arg1, p.arg2)
                 elif p.command_type == VmToken.LABEL:
                     writer.write_label(p.arg1)
                 elif p.command_type == VmToken.IF:
                     writer.write_if(p.arg1)
                 elif p.command_type == VmToken.GOTO:
                     writer.write_goto(p.arg1)
                 elif p.command_type == VmToken.FUNCTION:
                     writer.write_function(p.arg1, p.arg2)
                 elif p.command_type == VmToken.CALL:
                     writer.write_call(p.arg1, p.arg2)
                 elif p.command_type == VmToken.RETURN:
                     writer.write_return()
                 else:
                     raise Exception('Unknown command type "{}".'.format(p.command_type))
     print("Translation complete.\nOutput is '{}'".format(self._out_filename))
コード例 #9
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 = [os.path.abspath(args[1])]
    print(input_files)
    output_file_name = os.path.abspath(args[1])
    is_input_dir = False

    if os.path.isdir(input_files[0]):
        is_input_dir = True
        input_files = [f for f in os.listdir(input_files[0])]
        input_files = [f for f in input_files if f.split(".")[-1] == "asm"]
        input_files = [os.path.join(output_file_name, f) for f in input_files]
        output_file_name = os.path.join(output_file_name,
                                        os.path.basename(output_file_name))
        print(input_files)
        print(output_file_name)

    for file_name in input_files:
        parser = Parser(file_name)
        codeWriter = CodeWriter(file_name, parser.tokens, parser.symbol_table)
コード例 #10
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
コード例 #11
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)
コード例 #12
0
def run_vm_translator():
    file_path = str(argv[1])

    vm_files = []
    write_init = 0

    code_writer = CodeWriter(file_path)

    if file_path.endswith(".vm"):
        vm_files.append(file_path)
        if file_path == "Sys.vm":
            write_init = 1
    else:
        file_list = listdir(file_path)
        for file in file_list:
            if file.endswith(".vm"):
                vm_files.append(file_path + "/" + file)
                if file == "Sys.vm":
                    write_init = 1
    if write_init == 1:
        code_writer.write_init()

    for file in vm_files:
        current_parser = Parser(file)
        single_parser(current_parser, code_writer)
    code_writer.finish_code_writer()
コード例 #13
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
コード例 #14
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()
コード例 #15
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)
コード例 #16
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()
コード例 #17
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()
コード例 #18
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)
コード例 #19
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()
コード例 #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
 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)
コード例 #22
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)
コード例 #23
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)
コード例 #24
0
    def translate(self):
        '''Function responsible for orchestrating the translation'''

        #Following code for determining arguments and file/dir existence may need to be refactored out
        #However, not sure yet so will wait till further in development to make decision

        statusCode = None

        if (len(sys.argv) == 1):
            print("No file provided...")
            statusCode = 2

        else:
            path = sys.argv[1]

            if not os.path.exists(path):
                print("Provided File/Folder does not exist")
                statusCode = 2
            else:
                print(path)
                print(path.split("/")[-1])
                print(self.__getFileName(path))
                print(self.__getFileName(path).split('.'))
                print(self.__getFileName(path).split('.')[0])
                asmFileLocation = "{0}.asm".format(
                    self.__getFileName(path).split('.')[0])
                print(asmFileLocation)

                with CodeWriter(asmFileLocation) as writer:

                    paths = []

                    if os.path.isdir(path):
                        paths = glob.glob("{0}/*.vm".format(path))
                    else:
                        paths.append(path)

                    for currentPath in paths:
                        currentFileName = self.__getFileName(
                            currentPath).split('.')[0]
                        writer.setFileName(currentFileName)
                        with Parser(currentPath) as parser:
                            while (parser.hasMoreCommands()):
                                parser.advance()
                                commandType = parser.commandType()
                                if commandType == CommandType.C_PUSH:
                                    writer.writePushPop(
                                        commandType, parser.arg1(),
                                        parser.arg2())
                                elif commandType == CommandType.C_POP:
                                    writer.writePushPop(
                                        commandType, parser.arg1(),
                                        parser.arg2())
                                elif commandType == CommandType.C_ARITHMETIC:
                                    writer.writeArithmetic(parser.arg1())

        return statusCode
コード例 #25
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)
コード例 #26
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 = ""
コード例 #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 main():
    foldername = str(sys.argv[-1])
    code = CodeWriter()
    if foldername[-2:] == 'vm':
        translate(code,foldername)
    else:
        if '{0}Sys.vm'.format(foldername) in glob.glob(foldername+'*.vm'):
            code.write_init()
        for filename in glob.glob(foldername+'*.vm'):
            translate(code,filename)
    code.create_file(foldername)
    print("Done!")
コード例 #29
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)
コード例 #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)