def main(): "output file is the file where output will be written to" filename = sys.argv[1].split('.')[0] outputfile = open( filename + ".hack", "a" ) "input file is the file where input will come from" inputfile = Parser( sys.argv[1] ) lines = inputfile.commandLines() for line in lines: if( ParserComd( line ).commandType() == 'A_command' ): symbol_line = ParserComd( line ).symbol( ) symbol_a = SymbolTable( ) symbol_a.addEntry( symbol_line ) f = symbol_a.GetAddress( symbol_line ) outputfile.write( f ) outputfile.write( '\n' ) elif( ParserComd( line ).commandType() == 'C_command_a' or ParserComd( line ).commandType() == 'C_command_b'): dest_line = ParserComd( line ).dest() comp_line = ParserComd( line ).comp() jump_line = ParserComd( line ).jump() cbinary = Code( dest_line, comp_line, jump_line ).cinstruction() outputfile.write( cbinary ) outputfile.write( '\n' ) elif( ParserComd( line ).commandType() == 'L_command' ): outputfile.write( 'This line is going to delete\n' ) outputfile.close()
class symboltabletests(unittest.TestCase): def setUp(self): self.st = SymbolTable() def testContains(self): self.st.addEntry("loop", 100) self.assertTrue(self.st.contains("loop")) self.assertFalse(self.st.contains("bobby"))
class HackAssembler: def __init__(self,fileName): self.parser = Parser(fileName) self.symbolTable = SymbolTable() self.code = Code() self.fileName=fileName def execute(self): self.firstPass() self.finalPass() def firstPass(self): """ uses parser to read the file and add the labels used for flow control to the symbol table class """ instructionCount= 0 #count number of instructions,not including comments or L_COMMANDS while self.parser.hasMoreLines: self.parser.advance() instructionType = self.parser.instructionType() if self.parser.currentInstruction == '': continue if instructionType == "L_COMMAND": self.symbolTable.addEntry(self.parser.symbol(), address = instructionCount) elif instructionType == "NOT_COMMAND": continue else: instructionCount += 1 def finalPass(self): self.parser.reset() writeFileName = self.fileName.split('.')[0] + ".hack" f = open(writeFileName, "w") writeLine = "" while self.parser.hasMoreLines: self.parser.advance() instructionType = self.parser.instructionType() if instructionType == "A_COMMAND": symbol = self.parser.symbol() writeLine = "" if not isNumber(symbol): if not self.symbolTable.contains(symbol): self.symbolTable.addEntry(symbol) address = self.symbolTable.getAddress(symbol) else: address = symbol temp = '{0:016b}'.format(int(address)) writeLine += temp elif instructionType == "C_COMMAND": writeLine ="111" writeLine += self.code.comp(self.parser.comp()) writeLine += self.code.dest(self.parser.dest()) writeLine += self.code.jump(self.parser.jump()) else: continue f.write(writeLine + '\n') self.parser.close() f.close()
def main(): if len(sys.argv) < 2: print(u"使い方: %s FILENAME" % sys.argv[0]) sys.exit(1) asm_file = sys.argv[1] hack_file = os.path.splitext(asm_file)[0] + ".hack" st = SymbolTable() # SymbolTable作成 with Parser(asm_file) as hp: # ROM アドレス op_address = 0 # 1行ごとに読みながら, ROMアドレス番号を保持 while hp.advance() != None: cmd_type = hp.commandType() if cmd_type == A_COMMAND or cmd_type == C_COMMAND: op_address += 1 elif cmd_type == L_COMMAND: st.addEntry(hp.symbol(), op_address) # シンボルをアドレスに置き換え, 機械語コードの生成 with Parser(asm_file) as hp: with open(hack_file, 'w') as wf: # 1行ごとに構文解析 while hp.advance() != None: cmd_type = hp.commandType() # print(cmd_type) # A_COMMAND の変数を処理 if cmd_type == A_COMMAND: symbol = hp.symbol() m = SYMBOL_PATTERN.match(symbol) if m.group(1): # @100など bincode = '0' + int_to_bin(int(m.group(1))) # SymbolTableに書き込み elif m.group(2): # @SYMBOL など # symbol = m.group(2) if st.contains(symbol): address = st.getAddress(symbol) bincode = '0' + int_to_bin(address, 15) else: st.addVariable(symbol) address = st.getAddress(symbol) bincode = '0' + int_to_bin(address, 15) elif cmd_type == C_COMMAND: bincode = "111" + Code.comp(hp.comp()) + Code.dest( hp.dest()) + Code.jump(hp.jump()) if cmd_type != L_COMMAND: wf.write(bincode + '\n')
def run(self, isWrite=True): parser = Parser(self.content) symbolTable = SymbolTable() hackCmds = self.hackCmds asmCmds = parser.asmCmds print(asmCmds) lineNum = 0 for asmCmd in asmCmds: commandType = parser.commandType(asmCmd) if commandType == 'L': symbol = parser.symbol(asmCmd) symbolTable.addEntry(symbol, lineNum) else: lineNum += 1 ramNo = 16 for asmCmd in asmCmds: commandType = parser.commandType(asmCmd) if commandType in ['A','L']: symbol = parser.symbol(asmCmd) if not symbol.isdigit(): if symbolTable.contains(symbol): address = symbolTable.getAddress(symbol) else: symbolTable.addEntry(symbol,ramNo) address = ramNo ramNo+=1 else: address = symbol if commandType == 'A': hackCmds += ['0'+decimalToBinary15(address)+ '\n'] elif commandType == 'C': dest = parser.dest(asmCmd) print('dest:', dest) print('code dest',Code.dest(dest)) comp = parser.comp(asmCmd) print('comp:', comp) print('code comp',Code.comp(comp)) jump = parser.jump(asmCmd) print('jump:', jump) print('code jump',Code.dest(jump)) hackCmds += ['111'+Code.comp(comp)+Code.dest(dest)+Code.jump(jump)+'\n'] print(hackCmds) print(self.outputPath) if isWrite: with open(self.outputPath, 'w') as f: f.write(''.join(hackCmds))
def __firstPass(path): symbolTable = SymbolTable() with Parser(path) as parser: currentRomAddress = 0 while parser.hasMoreCommands(): parser.advance() if parser.commandType() == CommandType.L_COMMAND: print("Adding symbol:" + parser.symbol() + " @ line:" + str(currentRomAddress)) symbolTable.addEntry(parser.symbol(), currentRomAddress) else: currentRomAddress += 1 return symbolTable
class Assembler: def __init__(self): self.symboltable = SymbolTable() self.address = 16 def assembler(self, file): self.file = file self.outputFile = file.replace(".asm", ".hack") self.firstStep() self.secondStep() def firstStep(self): p = Parser(self.file) cur_addr = 0 while p.hasMoreCommands(): p.advance() if p.commandType() == p.A_COMMAND or p.commandType( ) == p.C_COMMAND: cur_addr += 1 elif p.commandType() == p.L_COMMAND: self.symboltable.addEntry(p.symbol(), cur_addr) def secondStep(self): p = Parser(self.file) outFile = open(self.outputFile, 'w') code = Code() while p.hasMoreCommands(): p.advance() if p.commandType() == p.A_COMMAND: outFile.write(code.A(self.getAddr(p.symbol())) + '\n') elif p.commandType() == p.C_COMMAND: outFile.write(code.C(p.comp(), p.dest(), p.jump()) + '\n') elif p.commandType() == p.L_COMMAND: pass outFile.close() def getAddr(self, symbol): if symbol.isdigit(): return symbol else: if not self.symboltable.contains(symbol): self.symboltable.addEntry(symbol, self.address) self.address += 1 return self.symboltable.getAddress(symbol)
class Assembler: def __init__(self): self.rowcodes = [] self.table = SymbolTable() const = [ "SP","LCL","ARG","THIS","THAT", "R0", "R1", "R2", "R3", "R4", "R5", "R6","R7", "R8","R9","R10","R11","R12","R13","R14","R15", "SCREEN","KBD"] address = [ 0,1,2,3,4,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16384,24576] for s,n in zip(const,address): self.table.addEntry(s,n) def parse(self,codes): self.parsed = [parser(c) for c in codes] def readLabel(self,codes): pc = 0 for line in self.parsed: if line["Type"] == "L_COMMAND": self.table.addEntry(line["symbol"],pc) elif line["Type"] == "A_COMMAND" or line["Type"] == "C_COMMAND": pc += 1 else: pass def readVar(self,codes): address = 16 for line in self.parsed: if line["Type"] == "COMMENT" or line["Type"] == "L_COMMAND": continue elif line["Type"] == "A_COMMAND" and not line["symbol"].isdigit(): if not self.table.contains(line["symbol"]): self.table.addEntry(line["symbol"],address) address += 1 line["symbol"] = str(self.table.getAddress(line["symbol"])) self.rowcodes.append(line) def assemble(self,codes): self.parse(codes) self.readLabel(codes) self.readVar(codes) self.binary = [rowCoder(line) for line in self.rowcodes] return self.binary def read(self,path): with open(path) as f: codes = [line for line in f.readlines()] return codes def write(self,path): with open(path,"w") as f: for code in self.binary: f.write(code+"\n")
offset = 0 symbols = SymbolTable() while p.hasMoreCommands(): t = p.commandType() if t == "A_COMMAND": offset += 1 s = p.symbol() elif t == "C_COMMAND": offset += 1 elif t == "L_COMMAND": s = p.symbol() if symbols.contains(s): raise SyntaxError("multiple declarations of %s" % s) else: symbols.addEntry(s, offset) else: raise Error p.advance() p.reset() output = [] variable_offset = itertools.count(16) def new_variable(name): symbols.addEntry(name, variable_offset.__next__()) while p.hasMoreCommands(): t = p.commandType()
# counter which tells us which instruction line we're on (ignores label declarations) instruct_counter = 0 while f.hasMoreCommands(): current = f.current_command # Chek if current command is L command if f.commandType(current) == 'L_COMMAND': # Get the symbol for the L command symbol = f.get_symbol(current) # Get the address of next command and store it in the symbolTable address = instruct_counter s.addEntry(symbol, address) f.advance() continue instruct_counter += 1 f.advance() # Second Pass # Reset Parser object f = Parser(input) with open(sys.argv[2], 'w') as test: # Initialize variable address space var_address = 16 while f.hasMoreCommands():
class Assembler(): NewSymbolAdd = 16 def __init__(self, readfile): self.readfile = readfile self.writefile = readfile.replace( '.asm', '.hack' ) #creates new output file named the same as input file but with .hack extension self.symboltable = SymbolTable() #populates symbol table def FirstPass( self ): #grabs (xxx) symbols and notes them in symbol tables with the correct address firstPassParser = Parser(self.readfile) firstPassAddress = 0 while firstPassParser.hasMoreCommands(): firstPassParser.advance() if (firstPassParser.commandType() == 'A_COMMAND' or firstPassParser.commandType() == 'C_COMMAND'): firstPassAddress += 1 elif firstPassParser.commandType() == 'L_COMMAND': print(firstPassParser.command) self.symboltable.addEntry(firstPassParser.symbol(), firstPassAddress) def SecondPass(self): secondPassParser = Parser(self.readfile) outfile = open(self.writefile, 'w+') code = Code() while secondPassParser.hasMoreCommands(): secondPassParser.advance() if secondPassParser.commandType() == 'A_COMMAND': if secondPassParser.symbol().isdigit(): writeline = '0' + ('{0:b}'.format( int(secondPassParser.symbol())).zfill(15)) outfile.write(writeline + '\n') elif self.symboltable.contains(secondPassParser.symbol( )): # if symbol is in table write binary to file writeline = '0' + '{0:b}'.format( self.symboltable.GetAddress(secondPassParser.symbol()) ).zfill( 15 ) #makes writeline with 0 (a instruction)+15 bit address of symbol outfile.write(writeline + '\n') else: #if symbol is not in table add to table then write to file in binary self.symboltable.addEntry(secondPassParser.symbol(), self.NewSymbolAdd) self.NewSymbolAdd += 1 writeline2 = '0' + '{0:b}'.format( self.symboltable.GetAddress( secondPassParser.symbol())).zfill(15) outfile.write(writeline2 + '\n') if secondPassParser.commandType() == 'C_COMMAND': writelineC = '111' + code.comp_conv( secondPassParser.comp()) + code.dest_conv( secondPassParser.dest()) + code.jump_conv( secondPassParser.jump()) outfile.write(writelineC + '\n') ''' if secondPassParser.commandType()=='L_COMMAND': if self.symboltable.contains(secondPassParser.symbol()): writeline=writeline='0'+('{0:b}'.format(self.symboltable.GetAddress(secondPassParser.symbol())).zfill(15)) else: continue ''' outfile.close()
from SymbolTable import SymbolTable tab = SymbolTable() tab.addEntry("testSymbol", 32767) print "=====Testing SymbolTable" if not tab.contains("testSymbol"): print "SymbolTable.contains should return true" if tab.getAddress("testSymbol") != "111111111111111": print "SymbolTable.getAddress did not return correct value" tab.addVariable("testVar") if tab.getAddress("testVar") != "000000000010000": print "SymbolTable.getAddress did not return correct value for var" print "Done testing SymbolTable====="
import sys,re from Parser import Parser from Code import Code from SymbolTable import SymbolTable # Set Filenames asmfilename = sys.argv[1] hackfilename = asmfilename.replace(".asm", ".hack") # Initialize symbol table syms = SymbolTable() syms.addEntry('SP', 0) syms.addEntry('LCL', 1) syms.addEntry('ARG', 2) syms.addEntry('THIS', 3) syms.addEntry('THAT', 4) for i in range(16): syms.addEntry('R'+str(i), i) syms.addEntry('SCREEN', 16384) syms.addEntry('KBD', 24576) # Pass 1 (define jump symbols only) parser = Parser(asmfilename) pc = 0 for junk in parser.advance(): ctype = parser.commandType() if ctype == Parser.L_COMMAND: syms.addEntry(parser.symbol(), pc) else: pc = pc + 1
sys.exit("One argument and one argument only is allowed following assembler.py: the *.asm file to be assembled") else: input_file = sys.argv[1] output_file = input_file.replace("asm", "hack") f = open(output_file, 'w') parser_obj = Parser(input_file) table_obj = SymbolTable() assembled_line_num = 0 # line number of lines that will be assembled (not labels) # First pass - find all labels and add to symbol table while parser_obj.hasMoreCommands(): if parser_obj.commandType() == "L_COMMAND": symbol = parser_obj.symbol() table_obj.addEntry(symbol, assembled_line_num) # all labels are new assembled_line_num -= 1 # this line won't be assembeled assembled_line_num += 1 parser_obj.advance() # Second pass - exchange variable names for values and assemble parser_obj.line_num = 0 avail_address = 16 while parser_obj.hasMoreCommands(): if parser_obj.commandType() == "C_COMMAND": comp = Code.comp(parser_obj.comp()) jump = Code.jump(parser_obj.jump()) dest = Code.dest(parser_obj.dest()) f.write('111'+comp+dest+jump) elif parser_obj.commandType() == "A_COMMAND": symbol = parser_obj.symbol()
from Parser import Parser from Code import Code from SymbolTable import SymbolTable C = Code() S = SymbolTable() if __name__ == "__main__": P = Parser(argv[1]) out = open(argv[1].split(".")[0] + ".hack", "w") # 1パス目lは読んでる行 l = 0 while (P.hasMoreCommands): P.advance() if P.commandType == "L": S.addEntry(P.symbol, l) continue elif P.commandType: l += 1 # ここクソ P.hasMoreCommands = True varptr = 16 while (P.hasMoreCommands): P.advance() if P.commandType == "A": # constant if P.symbol.isnumeric(): out.write(bin(int(P.symbol))[2:].zfill(16) + "\n") # label elif P.symbol in S.table: out.write(bin(S.table[P.symbol])[2:].zfill(16) + "\n")
def main(): #make sure they used the program right if len(sys.argv) != 2: print("usage: python assempler.py <some .asm file>") return #get the path to the asm file path = sys.argv[1] #make sure it is an asm file if path.split('.')[1] != 'asm': print("Error: you did not supply an asm file") #parse the asm file to get the instructions in a good format to parse instructions = [] file = open(path, 'r') #create modules and keep track of current ram address for symbols parser = Parser(file) code = Code() symbolTable = SymbolTable() symbolEntry = 16 #holds the binary output lines output = [] #first pass to add L command labels to symbol table rom = 0 while parser.hasMoreCommands(): if parser.commandType() == "L_COMMAND": print(parser.symbol()) symbolTable.addEntry(parser.symbol(), rom) else: rom += 1 parser.advance() #reset the parser for 2nd pass parser.reset() #2nd pass while parser.hasMoreCommands(): #get command type and create a command to output iType = parser.commandType() command = None print(parser.currentInstruction) if iType == 'C_COMMAND': #get all parts of c command in binary dest = code.dest(parser.dest()) comp = code.comp(parser.comp()) jump = code.jump(parser.jump()) #error check if dest is None or comp is None or jump is None: print("Error: invalid dest, comp, or jump") return else: command = '111' + comp + dest + jump elif iType == 'A_COMMAND': #get symbol and error check symbol = parser.symbol() if symbol is None: print("Error: invalid symbol declaration") return #just convert to binary if integer if isInt(symbol): command = decimalToBinary(symbol) else: #if the symbol isnt in the symbol table add it if not symbolTable.contains(symbol): symbolTable.addEntry(symbol, symbolEntry) symbolEntry += 1 #convert address from symbol table to binary command = decimalToBinary(symbolTable.getAddress(symbol)) #since l commands are already handles, dont do anything elif iType == 'L_COMMAND': parser.advance() continue #error check command and add to output if command is None: print("Error: binary string longer than 16bits") return else: output.append(command) #next line parser.advance() #write to file but change to .hack outputPath = os.path.splitext(path)[0] + '.hack' outfile = open(outputPath, 'w') for binary in output: outfile.write(binary + '\n')
lc = 0 new_address_counter = 16 compiled_lines = [] filename = sys.argv[1] # First Pass p = Parser(filename) st = SymbolTable() while p.hasMoreCommands(): if p.commandType() == "L_COMMAND": symbol = p.symbol() if not st.contains(symbol): st.addEntry(symbol, lc) else: lc += 1 p.advance() # Second Pass p = Parser(filename) while (p.hasMoreCommands()): print("\nInput: '{0}'".format(p.current_line)) print("CommandType: {0}".format(p.commandType())) if p.commandType() == "C_COMMAND": dest = p.dest() comp = p.comp() jump = p.jump() instruction = "111{0}{1}{2}".format(Code.comp(comp), Code.dest(dest), Code.jump(jump))
""" import sys from Parser import Parser import Code from SymbolTable import SymbolTable asmFilename = sys.argv[1] # This goes through the file and adds the address for each label to the symbol table. parser = Parser(asmFilename) symbolTable = SymbolTable() romAddress = 0 while parser.hasMoreCommands(): parser.advance() if parser.commandType() == "L_COMMAND": symbolTable.addEntry(parser.symbol(), romAddress) else: romAddress += 1 # This opens the file that will be written to. hackFilename = asmFilename[:-3] + "hack" hackFile = open(hackFilename, "w") # This writes the translated code to the hack file. parser.restart() ramAddress = 16 while parser.hasMoreCommands(): parser.advance() commandType = parser.commandType() if commandType == "C_COMMAND": hackFile.write("111" + Code.comp(parser.comp()) + Code.dest(parser.dest()) + Code.jump(parser.jump()) + "\n")
print outPath + ": file could not be opened" exit(1) #init parser and symbolTable parser = Parser(inPath) symbolTable = SymbolTable() #pass 0 i = 0 while parser.hasMoreCommands(): parser.advance() if parser.commandType() == "L": symbolTable.addEntry(parser.symbol(), i) else: i += 1 #pass 1 parser.reset() while parser.hasMoreCommands(): parser.advance() type = parser.commandType() if type == "A": sym = parser.symbol() #sym is a constant if ord(sym[0]) >= ord("0") and ord(sym[0]) <= ord("9"):