コード例 #1
0
ファイル: main.py プロジェクト: frankwillard/Nand2Tetris
def main():
  #Takes in filename
  newfile = input("Which asm file do you want me to read (don't include .asm)? ")
  #Opens and reads file
  Parser.Parser(newfile + ".asm")
  #Removes whitespace/fixes labels
  firstPass()
  #Fixes variables
  secondPass()
  global finalOut
  finalOut = []
  #While more commands, determine if A or C and add to finalOut array
  while Parser.hasMoreCommands():
    Parser.categorize()
    if Parser.A:
      global binnum
      binnum = str(code.AInstruction())
      addA()
    else:
      global comp
      comp = str(code.comp())
      global dest
      dest = str(code.dest())
      global jump
      jump = str(code.jump())
      addC()
    Parser.advance()
  #Writes to hack file
  hack = open(newfile + ".hack", "w")
  hack.writelines(finalOut)
コード例 #2
0
ファイル: hack_assembler.py プロジェクト: max-zia/nand2tetris
def second_pass(commands, symbol_table, output_file):
    """
	Pass through the assembly program's commands, parse each line, and translate
	commands into binary form, and write to .hack file that CPU can load in ROM.
	"""
    RAM_counter = 16  # 16 is next free RAM address after predefined symbols
    with open(output_file, 'a') as f:
        for command in commands:
            c_type = parser.command_type(command)
            if c_type == "A_COMMAND":
                chars = parser.symbol(command)
                # Test whether chars in the A-instruction are symbol or number
                results = char_test(chars, symbol_table, RAM_counter)
                chars = results['c']
                symbol_table = results['st']
                RAM_counter = results['ram']
                # Translate chars into a instruction and write to f
                f.write(code.get_a_instruction(chars) + '\n')
            elif c_type == "C_COMMAND":
                jump_mnemonic = parser.jump(command)
                dest_mnemonic = parser.dest(command)
                comp_mnemonic = parser.comp(command)
                f.write("111" + code.comp(comp_mnemonic) +
                        code.dest(dest_mnemonic) + code.jump(jump_mnemonic) +
                        '\n')
コード例 #3
0
ファイル: parser2.py プロジェクト: adamitai/ex6
def write_commands(commands, hack_file, symbolTable, var_sym_start):
	for command in commands: # For all commands
		if command.type == 'A_Command': # In the case of A_Commands
			label = command.cmd_string # ...grab the A_Command itself
			if (not label.isdigit()) and (label not in symbolTable.keys()): # Check if the A_Command is a variable label, and not already entered into symbolTable
				symbolTable[label] = var_sym_start # Enter new Variable Label into Symobl Table
				var_sym_start = var_sym_start + 1 # Set memory location of next Variable Symbol
			if command.cmd_string in symbolTable.keys(): # If the A_Command is a Variable Symbol for a RAM address
				address = int(symbolTable[command.cmd_string]) # Grab the corresponding decimal address
			else:
				address = int(command.cmd_string) # Otherwise, get the decimal address explicitly from the A_Command
			address = bin(address)[2:] # Turn the address from decimal to binary
			address = (16-len(address))*'0' + address # Pad the binary address with zeros so it is 16 bits
			hack_file.write(address + '\n') # Write the address specified by the A_Command to the .hack file

		elif command.type == 'C_Command': # In the case of a C_Command
			if '=' in command.cmd_string: # If there is an equal sign in the command:
				dest = command.cmd_string.partition('=')[0] # Get the dest bits
				cmp = command.cmd_string.partition('=')[2] # Get the cmp bits
				jmp = None # Get the jmp bits (note that when there is an = in the C_Command, the jump bits are '000'
			elif ';' in command.cmd_string: # Same thing if there is an ';' in the command, except the dest bits are '000'
				dest = None
				cmp = command.cmd_string.partition(';')[0]
				jmp = command.cmd_string.partition(';')[2]
			hack_file.write('111' + code.cmp(cmp) + code.dest(dest) + code.jmp(jmp) + '\n') # Write the C_Command to the .hack file.
コード例 #4
0
 def test_dest(self):
     self.assertEqual(code.dest(None), '000')
     self.assertEqual(code.dest('M'), '001')
     self.assertEqual(code.dest('D'), '010')
     self.assertEqual(code.dest('MD'), '011')
     self.assertEqual(code.dest('A'), '100')
     self.assertEqual(code.dest('AM'), '101')
     self.assertEqual(code.dest('AD'), '110')
     self.assertEqual(code.dest('AMD'), '111')
コード例 #5
0
def assemble(fileName):
    import assemblerParser
    from assemblerParser import Parser
    import code
    import symbolTable
    from symbolTable import SymbolTable

    WORD_SIZE = 16  #words are 16 bits long
    currentDataAddr = 16
    file = open(fileName, 'r')
    parser = Parser(file)

    table = SymbolTable()
    #Symbol generating pass
    counter = 0
    while (parser.hasMoreCommands()):
        parser.advance()
        if (parser.commandType() == Parser.L_COMMAND):
            table.addEntry(parser.symbol(), counter)
        else:
            counter += 1

    newFileName = fileName[:fileName.find(".", 1)] + ".hack"
    outputFile = open(newFileName, 'w')
    #Code generating pass
    file = open(fileName, 'r')
    parser = Parser(file)
    while parser.hasMoreCommands():
        parser.advance()
        output = "BLANK"
        if (parser.commandType() == Parser.C_COMMAND):
            output = "111" + code.comp(parser.comp()) + code.dest(
                parser.dest()) + code.jump(parser.jump())
            outputFile.write(output + "\n")
        elif parser.commandType() == Parser.A_COMMAND:
            symbol = parser.symbol()
            try:
                symbol = int(symbol)
            except:
                pass

            if type(symbol) is int:
                binVal = bin(
                    int(symbol)
                )[2:]  #the slice is because the value will be in the form 0b# so we need to remove the 0b
            elif table.contains(symbol):
                binVal = bin(table.getAddress(symbol))[2:]
            else:
                table.addEntry(symbol, currentDataAddr)
                binVal = bin(currentDataAddr)[2:]
                currentDataAddr += 1
            output = "0" * (WORD_SIZE - len(binVal)) + binVal
            outputFile.write(output + "\n")
        elif parser.commandType() == Parser.L_COMMAND:
            pass
        else:
            print("Bad Munkey!")
        print("Original is " + parser.current() + " BIN: " + output +
              "COMP: " + parser.comp())
def assemble(fileName):
    import assemblerParser
    from assemblerParser import Parser
    import code
    import symbolTable
    from symbolTable import SymbolTable

    WORD_SIZE = 16 #words are 16 bits long
    currentDataAddr = 16
    file = open(fileName, 'r')
    parser = Parser(file)
    
    table = SymbolTable()
    #Symbol generating pass
    counter = 0
    while(parser.hasMoreCommands()):
        parser.advance()
        if(parser.commandType() == Parser.L_COMMAND):
            table.addEntry(parser.symbol(), counter)
        else:
            counter += 1


    newFileName = fileName[:fileName.find(".", 1)] + ".hack"
    outputFile = open(newFileName, 'w')
    #Code generating pass
    file = open(fileName, 'r')
    parser = Parser(file)
    while parser.hasMoreCommands():
        parser.advance()
        output = "BLANK"
        if(parser.commandType() == Parser.C_COMMAND):
            output = "111" + code.comp(parser.comp()) + code.dest(parser.dest()) + code.jump(parser.jump())
            outputFile.write(output + "\n")
        elif parser.commandType() == Parser.A_COMMAND:
            symbol = parser.symbol()
            try:
                symbol = int(symbol)
            except:
                pass

            if type(symbol) is int:
                binVal=bin(int(symbol))[2:] #the slice is because the value will be in the form 0b# so we need to remove the 0b
            elif table.contains(symbol):
                binVal = bin(table.getAddress(symbol))[2:]
            else:
                table.addEntry(symbol, currentDataAddr)
                binVal = bin(currentDataAddr)[2:]
                currentDataAddr += 1
            output = "0" * (WORD_SIZE - len(binVal)) + binVal
            outputFile.write(output + "\n")
        elif parser.commandType() == Parser.L_COMMAND:
            pass
        else:
            print("Bad Munkey!")
        print("Original is " + parser.current() + " BIN: " + output + "COMP: " + parser.comp())
コード例 #7
0
def parseCommand(cmd):
    if commandType(cmd) == 'A_COMMAND':
        smb = int(symbol(cmd))
        return code.decimalToBinary(smb)
    if commandType(cmd) == 'C_COMMAND':
        cmdDest = dest(cmd)
        cmdComp = comp(cmd)
        cmdJump = jump(cmd)
        return '111' + code.comp(cmdComp) + code.dest(cmdDest) + code.jump(
            cmdJump)
    return cmd
コード例 #8
0
def main(filename):

  outputFilename = os.path.splitext(filename)[0]+".hack"
  st = symbol_table.SymbolTable()  

  # First pass store all LABELS
  p = parser.Parser(filename)
  p.advance()
  instructionCount = 0
  while p.hasMoreCommands():
    commandType = p.commandType()
    if p.commandType() == command_types.L_COMMAND: 
      symbol = p.symbol()
      st.addEntry(symbol, instructionCount)
    else:
      instructionCount += 1
    p.advance()

  # Second pass
  n = 16  
  p = parser.Parser(filename)
  p.advance()
  while p.hasMoreCommands():

    command = ""

    if p.commandType() == command_types.A_COMMAND:
      symbol = p.symbol()
      address = ""
      if st.contains(symbol):
        address = st.getAddress(symbol)
      elif symbol.isdigit():
        address = symbol
      else:
        st.addEntry(symbol, n)
        address = n
        n += 1
      command = format(int(address), '#018b')[2:]
    elif p.commandType() == command_types.C_COMMAND:
      command = "111" + code.comp(p.comp()) + code.dest(p.dest()) + code.jump(p.jump())

    if bool(command):
      with open(outputFilename, 'a') as outFile:
        outFile.write(command+"\n")

    p.advance()
コード例 #9
0
ファイル: assembler.py プロジェクト: awilsoncs/hackassembler
def get_code(command):

    command = clear_trash(command)

    output = ""
    if parser.command_type(command) == "A_COMMAND":
        output = "0" + address_of(parser.symbol(command)) + "\n"
    elif parser.command_type(command) == "L_COMMAND":
        pass
    elif parser.command_type(command) == "C_COMMAND":
        dest = code.dest(parser.dest(command))
        jump = code.jump(parser.jump(command))
        comp = code.comp(parser.comp(command))

        output = "111" + comp + dest + jump + "\n"
    else:
        raise ValueError("Code not a valid command: {0}".format(command))

    return output
コード例 #10
0
def assemble_command(parser: parse.Parser, table: symbol.SymbolTable) -> str:
    """convert the current command into a binary string"""
    if parser.command_type() == parse.CmdType.A:
        symbol = parser.symbol()
        num = resolve_symbol(symbol, table)
        return "{:016b}".format(num)
    elif parser.command_type() == parse.CmdType.C: #C command
        op = "1"
        dest_sym = parser.dest()
        dest = code.dest(dest_sym)

        comp_sym = parser.comp()
        comp = code.comp(comp_sym)

        jump_sym = parser.jump()
        jump = code.jump(jump_sym)

        return "111{comp}{dest}{jump}".format(dest=dest, comp=comp, jump=jump)
    else:
        raise RuntimeError("Cannot assemble pseudo-command")
コード例 #11
0
ファイル: assembler.py プロジェクト: disdi/nand2tetris
        elif parse.commandType() == "L_COMMAND":
             symbolTable.addEntry(parse.symbol(), ROMaddress)

    parse.currentCommandCounter = 0     #The current command needs to be set to the start so the instrunction can be parsed and translated

    RAMaddress = 16
    while parse.hasMoreCommands():
        parse.advance()
        if parse.commandType() == "A_COMMAND": #If A_COMMAND then translated instruction is a 0 followed by symbol address (15 bits)
            if parse.symbol().isdigit():
                f.write("0%s\n" %(format(int(parse.symbol()), '015b'))) #If the A_COMMAND does not use a symbol then convert to binary
            else:
                if symbolTable.contains(parse.symbol()):
                    f.write("0%s\n" %(format(int(symbolTable.getAddress(parse.symbol())), '015b'))) #If symbol exists in the symbol table then use it associated value
                else:
                    symbolTable.addEntry((parse.symbol()), str(RAMaddress))
                    f.write("0%s\n" %(format(int(symbolTable.getAddress(parse.symbol())), '015b'))) #If the symbol does not exist then add it to the symbol table
                    RAMaddress += 1

        elif parse.commandType() == "C_COMMAND":
            a = "0"
            if "M" in parse.comp():
                a = "1"
            f.write("111%s%s%s%s\n" %(      #C_COMMAND is as follows:   111
                a,                          #                           a       is 0 if comp using A, 1 if using M
                code.comp(parse.comp()),    #                           c1..c6  Comp bits
                code.dest(parse.dest()),    #                           d1..d3  Dest bits
                code.jump(parse.jump())     #                           j1..j3  Jump bits
                ))                          # Put together is: 1 1 1 a c1 c2 c3 c4 c5 c6 d1 d2 d3 j1 j2 j3
    f.close
コード例 #12
0
ファイル: parser.py プロジェクト: macdaliot/nand2tetris
def cmd(dest, comp, jump):
    return '111' + code.comp(comp) + code.dest(dest) + code.jump(jump)
コード例 #13
0
while 1:
    if prsInstance.commandType() == "A_COMMAND":
        A_binLine = bin(int(prsInstance.symbol()))[2:].zfill(16)
        bin_codes.append(A_binLine)
        print(A_binLine)
        prsInstance.advance()
        #write to a .hack file

    elif prsInstance.commandType() == "L_COMMAND":
        pass

        #try to write the program when I reach the next step (symbolic table)

    elif prsInstance.commandType() == "C_COMMAND":
        dest_mnic = prsInstance.dest()
        dest_bin = code.dest(dest_mnic)

        comp_mnic = prsInstance.comp()
        comp_bin = code.comp(comp_mnic)

        jump_mnic = prsInstance.jump()
        jump_bin = code.jump(jump_mnic)

        C_binLine = "111" + comp_bin + dest_bin + jump_bin
        bin_codes.append(C_binLine)
        print(C_binLine)
        prsInstance.advance()

    elif prsInstance.commandType() == "COMMENT":
        #print("This is a comment")
        prsInstance.advance()
コード例 #14
0
ファイル: assembler.py プロジェクト: ChavezCheong/Nand2Tetris
            command_line)  # Clean comments and whitespace
        if len(command_line) > 0:
            if commandtype(command_line) == "A_Command":
                if not command_line[1:].isnumeric():
                    if not command_line[1:] in symbol_table:
                        symbol_table[command_line[1:]] = convert_binary(
                            str(variable_memory_count))
                        variable_memory_count += 1
                    address = symbol_table[command_line[1:]]
                else:
                    address = convert_binary(command_line[1:])
                outputline = outputline + "0" + address
                outputlist.append(outputline)
            elif commandtype(command_line) == "C_Command":
                dest = ""
                jump = ""
                comp = ""
                if command_line.find(";") > 0:
                    comp, sep, jump = command_line.partition(";")
                else:
                    dest, sep, comp = command_line.partition("=")
                outputline = outputline + "111" + code.comp(comp) + code.dest(
                    dest) + code.jump(jump)
                outputlist.append(outputline)
    #Write to a file
    filename, sep, extension = assembly_file.name.partition(".")
    filename = filename + ".hack"
    with open(filename, "w+") as outputfile:
        for outputline in outputlist:
            outputfile.write(outputline + "\n")
コード例 #15
0
#!/usr/bin/env python
import sys

from parser import Parser
import code

in_file = sys.argv[1]

with open(in_file, 'r') as f:
    contents = f.read()

commands = []
for line in contents.split('\n'):
    if not line or line.startswith('//'):
        continue
    commands.append(line)

p = Parser(commands)
while p.has_more_commands():
    p.advance()
    command_type = p.command_type
    if command_type == 'A_COMMAND':
        print code.integer(p.symbol)
    elif command_type == 'C_COMMAND':
        print '111' + code.comp(p.comp) + code.dest(p.dest) + code.jump(p.jump)
    elif command_type == 'L_COMMAND':
        pass
コード例 #16
0
ファイル: parser.py プロジェクト: Jonnymcc/nand2tetris
def cmd(dest, comp, jump):
    return '111' + code.comp(comp) + code.dest(dest) + code.jump(jump)
コード例 #17
0
ファイル: assembler.py プロジェクト: HarveyHunt/hackAssembler

newFilename = filename.split('.')[0] + '.hack'
outputFile = open(newFilename, 'w')

#Second pass to create code

WORD_SIZE = 16
currentMemoryLocation = 16
Parser = assemblerParser.parser(filename)

while Parser.hasMoreCommands():
    Parser.advanceCommand()
    output = ''
    if Parser.commandType() == Parser.C_COMMAND:
        output = '111' + code.comp(Parser.comp()) + code.dest(Parser.dest()) + code.jump(Parser.jump()) + '\n'
        outputFile.write(output)
    elif Parser.commandType() == Parser.A_COMMAND:
        symbol = Parser.symbol()
        try:
            symbol = int(symbol)
        except:
            pass
        
        if type(symbol) is int:
            binVal = bin(int(symbol))[2:]
        elif Table.contains(symbol):
            binVal = bin(Table.getAddress(symbol))[2:]
        else:
            Table.addEntry(symbol, currentMemoryLocation)
            binVal = bin(currentMemoryLocation)[2:]