def main(argv):
    """
    Main flow of program dealing with extracting files for reading and initializing files to translate into
    """
    if not check_args(argv):
        return

    #  extracting asm file to be processed
    vm_files_path = argv[1]

    #  creating a .asm file to contain vm files translation to hack machine language
    if os.path.isdir(vm_files_path):
        dir_name = os.path.basename(vm_files_path)
        asm_file_name = "{0}/{1}.asm".format(vm_files_path, dir_name)
        code_writer = CodeWriter(asm_file_name)
        code_writer.write_init()
        for file in os.listdir(vm_files_path):
            if file.endswith(".vm"):
                code_writer.set_file_name(file)
                vm_parser = VMParser('{0}/{1}'.format(vm_files_path, file))
                translate_vm_file(code_writer, vm_parser)
    else:
        asm_file_name = "{0}.asm".format(os.path.splitext(vm_files_path)[0])
        code_writer = CodeWriter(asm_file_name)
        code_writer.write_init()
        code_writer.set_file_name(vm_files_path)
        vm_parser = VMParser(vm_files_path)
        translate_vm_file(code_writer, vm_parser)
Exemple #2
0
def main(infile_path: str, outfile_path: str):
    print(infile_path)
    vm_files = [path for path in glob.glob(infile_path + "/*.vm")]
    code_writer = CodeWriter(filepath=outfile_path)
    code_writer.write_init()
    for filepath in vm_files:
        print(filepath)
        parser = Parser(filepath=filepath)
        code_writer.set_file_path(filepath)
        while parser.hasMoreCommands():
            cmd = parser.commandType()
            if cmd == C_ARITHMETIC:
                code_writer.writeArithmetic(parser.arithmetic())
            elif cmd == C_PUSH or cmd == C_POP:
                code_writer.writePushPop(cmd,
                                         parser.arg1(),
                                         index=int(parser.arg2()))
            elif cmd == C_LABEL:
                code_writer.writeLabel(parser.arg1())
            elif cmd == C_GOTO:
                code_writer.writeGoto(parser.arg1())
            elif cmd == C_IF:
                code_writer.writeIf(parser.arg1())
            elif cmd == C_FUNCTION:
                code_writer.writeFunction(parser.arg1(), parser.arg2())
            elif cmd == C_RETURN:
                code_writer.writeReturn()
            elif cmd == C_CALL:
                code_writer.writeCall(parser.arg1(), parser.arg2())
            parser.advance()
    code_writer.close()
def main(input_file):
    if len(input_file.split('.')) == 1:
        if input_file[-1] == '/':
            input_file = input_file[:-1]
        output_file = join(input_file, input_file.split('/')[-1])
        input_files = [
            join(input_file, f) for f in listdir(input_file)
            if f.split('.')[1] == 'vm' and f != 'Sys.vm'
            and isfile(join(input_file, f))
        ]
        input_files.insert(0, join(input_file, 'Sys.vm'))
        print('Input files: {}'.format(input_files))
    else:
        input_files = [input_file]
        directory = '/'.join(input_file.split('/')[:-1])
        output_file = join(directory, input_file.split('/')[-1].split('.')[0])

    code_writer = CodeWriter(output_file)
    code_writer.write_init()

    for input_file in input_files:
        parser = Parser(input_file)
        code_writer.set_filename(input_file)
        n = 0
        while parser.advance():
            com_type = parser.command_type()
            print('LINE {}'.format(n))
            print('\tcom type: {}'.format(com_type))
            print('\tcommand: {}'.format(parser.command))
            if com_type != parser.c_return:
                arg1 = parser.arg1()
                if com_type in [
                        parser.c_push, parser.c_pop, parser.c_function,
                        parser.c_call
                ]:
                    arg2 = parser.arg2()

            if com_type == parser.c_arithmetic:
                code_writer.write_arithmetic(arg1)
            elif com_type in [parser.c_pop, parser.c_push]:
                code_writer.write_push_pop(com_type, arg1, int(arg2))
            elif com_type == parser.c_label:
                code_writer.write_label(arg1)
            elif com_type == parser.c_goto:
                code_writer.write_goto(arg1)
            elif com_type == parser.c_if:
                code_writer.write_if(arg1)
            elif com_type == parser.c_function:
                code_writer.write_function(arg1, arg2)
            elif com_type == parser.c_return:
                code_writer.write_return()
            elif com_type == parser.c_call:
                code_writer.write_call(arg1, arg2)
            n += 1
    code_writer.close()
Exemple #4
0
def main():
    argument = sys.argv[1]
    if argument.endswith('.vm'):
        asm_filename = argument.replace('.vm', '.asm')
        asm_file = open(asm_filename, 'a')
        code_writer = CodeWriter(asm_file)
        open_vm_file(argument, code_writer)
        code_writer.close()
    else:
        if argument.endswith('/'):
            argument = argument[0:-1]
        foldername = os.path.basename(argument)
        asm_file = open('%s/%s.asm' % (argument, foldername), 'a')
        code_writer = CodeWriter(asm_file)
        code_writer.write_comment('write init')
        code_writer.write_init()
        files = glob.glob('%s/*.vm' % argument)
        for file in files:
            open_vm_file(file, code_writer)
        code_writer.close()
Exemple #5
0
from parser import Parser
from code_writer import CodeWriter

# TODO: make this command line arguments
FILENAME='StaticsTest'
BASE = '/Users/plum/Desktop/codes/nand2tetris/projects/08/FunctionCalls/StaticsTest/'
READ_ADDRESS = '{0}'.format(BASE)
WRITE_ADDRESS = '{0}{1}.asm'.format(BASE, FILENAME)

if __name__ == '__main__':
    c = CodeWriter(WRITE_ADDRESS)

    files = [f for f in listdir(READ_ADDRESS) if f.find('.vm') != -1]
    sys_init = files.index('Sys.vm')
    rest = [f for f in files if files.index(f) != sys_init]
    c.write_init()
    for filename in [files[sys_init]] + rest: #  order matters
        # only parse .vm files
        if filename.find('.vm') != -1:
            c.set_filename(filename)
            p = Parser(BASE + filename)
            while p.has_more_lines():
                p.advance()
                command = p.command_type()
                arg_1 = p.arg_1()
                arg_2 = p.arg_2()
                if command in ['C_PUSH', 'C_POP']:
                    c.write_push_pop(command, arg_1, arg_2)

                if command == 'C_ARITHMETIC':
                    c.write_arithmetic(arg_1)
Exemple #6
0
        elif parser.command_type() == 'C_RETURN':
            code_writer.write_return()

        elif parser.command_type() == 'C_CALL':
            function_name = parser.arg1()
            num_args = int(parser.arg2())
            code_writer.write_call(function_name, num_args)


if __name__ == '__main__':
    input_file = sys.argv[1]

    if path.isfile(input_file):
        src_vm_files = [input_file]
        asm_file = path.splitext(input_file)[0] + ".asm"
    else:
        src_vm_files = glob.glob(path.join(sys.argv[1], '*.vm'))
        asm_file = path.split(input_file.rstrip('/') + ".asm")[1]
        asm_file = path.join(input_file, asm_file)

    code_writer = CodeWriter(asm_file)

    if len(src_vm_files) != 1:
        code_writer.write_init()

    for src_vm_file in src_vm_files:
        parse_and_write(code_writer, src_vm_file)

    code_writer.close()