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()
Example #2
0
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"))
Example #3
0
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()
Example #4
0
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')
Example #5
0
    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
Example #7
0
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)
Example #8
0
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()
Example #10
0
    # 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():
Example #11
0
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()
Example #12
0
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
Example #14
0
    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()        
Example #15
0
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")
Example #16
0
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')
Example #17
0

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))
Example #18
0
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====="
Example #19
0
"""
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")
Example #20
0
	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"):