def test_assemble_pong(self):
        with open("data/Expected_Pong.hack", "r") as f:
            expected = f.read()

        with open("data/Pong.asm", "r") as f:
            asm_string = f.read()

        actual = assemble(asm_string)
        self.assertEqual(expected, actual,
                         "Compare assembler output to a verified file")
Esempio n. 2
0
    def test_assemble_label_lookup(self):
        program = [
            ':loop SET A, B',
            '; commented line',
            'JSR loop'
        ]

        code = assemble(program)
        self.assertEqual(code[1], hex((0x1f << 10) + (0x1 << 4)))
        self.assertEqual(code[2], hex(0))

        # Push the label down by 3 words
        program = ['SET 0x1000, 0x1000'] + program
        code = assemble(program)
        self.assertEqual(code[4], hex((0x1f << 10) + (0x1 << 4)))
        self.assertEqual(code[5], hex(0x3))

        # Invalid lookup
        self.assertRaisesRegexp(InvalidValueReference, 'foo', assemble, ['JSR foo'])
    def test_assembler_a_commands_constants(self):
        asm = """
        @0
        @12345
        @32767
        """

        expected_output = str("0000000000000000\n"
                              "0011000000111001\n"
                              "0111111111111111\n")

        actual_output = assemble(asm)
        self.assertEqual(expected_output, actual_output,
                         "A-Commands with constant symbols only")
    def test_assembler_l_commands(self):
        asm = """D=M+1;JGE
        (LOOP)
        MD=1
        @LOOP
        0;JMP
        """
        expected_output = str(
            "1111110111010011\n"  # D=M+1;JGE
            "1110111111011000\n"  # MD=1
            "0000000000000001\n"  # @LOOP points to line 1 (MD=1)
            "1110101010000111\n"  # 0;JMP
        )
        actual_output = assemble(asm)

        self.assertEqual(expected_output, actual_output)
Esempio n. 5
0
    def test_assemble_examples(self):
        path = os.path.join(__file__, "../../../examples/")

        for assembly_file in glob.glob(os.path.join(path, '*.' + specs.ASSEMBLER_FILE_EXT)):
            f = open(assembly_file)
            program = f.readlines()
            f.close()

            machine_file = assembly_file[:assembly_file.find(specs.ASSEMBLER_FILE_EXT)] + specs.MACHINE_FILE_EXT

            expected_output = []
            f = open(machine_file)
            for line in f:
                expected_output.append("%#x" % int(line.strip(), base=16))
            f.close()

            code = assemble(program)

            self.assertEqual(code, expected_output, "Assembled output of example file %s did not match %s" % (assembly_file, machine_file))
Esempio n. 6
0
def main():
    args = cmd.parse_args(['filename'], msg="Please supply filename")
    filename = args['filename']
    try:
        infile = open(filename, 'r')
    except:
        print "Cannot open file {}".format(filename)
        sys.exit(0)

    inlines = kill_white_spaces(infile.readlines(), True)
    try:
        outlines = assemble(inlines)
    except Exception as e:
        print e
        sys.exit(0)
    outname = cmd.change_extension(filename, "hack")
    outfile = open(outname, 'w')
    outfile.writelines([line + '\n' for line in outlines])
    infile.close()
    outfile.close()
    def test_assembler_a_commands(self):
        asm = """
        @x
        M=1
        @y
        M=0
        @x
        M=0
        """

        expected_output = str("0000000000010000\n"  # create new variable at 16
                              "1110111111001000\n"  # M=1
                              "0000000000010001\n"  # create new variable at 17
                              "1110101010001000\n"  # M=0
                              "0000000000010000\n"  # re-use x variable at 16
                              "1110101010001000\n"  # M=0
                              )

        actual_output = assemble(asm)
        self.assertEqual(expected_output, actual_output)
Esempio n. 8
0
# Send test command to set X gradient to grad_offset
#socket.write(struct.pack('<I', 5 << 28 | x_grad << 24 | sign << 20 | abs(grad_offset)))
#while(True): # Wait until bytes written
#    if not socket.waitForBytesWritten(): break
# Send frequency to server
socket.write(struct.pack('<I', 2 << 28 | int(1.0e6 * freq)))
while (True):  # Wait until bytes written
    if not socket.waitForBytesWritten(): break
# Semd attemiaton to server
socket.write(struct.pack('<I', 3 << 28 | int(abs(at) / 0.25)))
while (True):  # Wait until bytes written
    if not socket.waitForBytesWritten(): break

# Send Sequence
socket.write(struct.pack('<I', 4 << 28))
byte_array = assembler.assemble(seq)
socket.write(byte_array)
while (True):  # Wait until bytes written
    if not socket.waitForBytesWritten(): break

# Test 2D SE acquisition
#socket.write(struct.pack('<I', 6 << 28 | npe))

# Test FID
socket.write(struct.pack('<I', 1 << 28))

while (True):  # Wait until bytes written
    if not socket.waitForBytesWritten(): break

# Perform npe-times readout
for n in range(npe):
 def test_assembler_c_commands(self):
     self.assertEqual("1111110111010011\n", assemble("D=M+1;JGE"))
     self.assertEqual("1110101010000111\n", assemble("0;JMP"))
     self.assertEqual("1110111111011000\n", assemble("MD=1"))
Esempio n. 10
0
def compile(text, path=None):



    def errortext(error, msg, node=None):
        out = error + ":\n"
        if node is not None:
            try:
                out += "Line %i: " % node.line + "\n"
                out += clean.split("\n")[node.line-1] + "\n"
                out += " "*node.column+"^\n"
            except AttributeError as e:
                print("AttributeError", e)
        out += msg
        return out

    def warn(msg, node=None):
        print(errortext("Warning",msg, node))

    def abort(msg, node=None):
        raise Exception(errortext("Error",msg, node))

    def pairs(tree):
        return [[n.children[0].value,n.children[1].value] for n in tree.children]

    class TypeGetter(Visitor):
        def start(self, node):
            #print(node)
            if DEBUG:
                print("Collected type definitions and function signatures.")

        def importdef(self, node):
            imports[node.children[0].value] = {}

        def typedef(self, node):
            node = node.children
            types[node[0].value] = pairs(node[1])

        def funcdef(self, node):
            indef = getChildByName(node, "funparams")
            if indef is None:
                indef = []
            else:
                indef = [[t,n] for t,n in pairs(indef)]

            outdef = getChildByName(node, "funrets")
            if outdef is None:
                outdef = []
            else:
                outdef = [n.value for n in outdef.children]


            funcs[getChildByName(node, "funname").children[0].value] = {
                "in":indef,
                "out":outdef,
                "body": getChildByName(node, "funcbody")}

    tg = TypeGetter()

    types = {}
    funcs = {}
    imports = {}

    def prepare(text=None, path=None):
        if text is None and path:
            with open(path, "r") as f:
                text = f.read()
        elif path is None and text:
            text = text
        else:
            print("wat")
            exit(1)
        clean = text.strip()

        prepped = prep(clean)
        if DEBUG:
            print(prepped)
        parsed = l.parse(prepped)

        tg.visit(parsed)

    prepare(text)
    if path is None:
        path = ""

    if len(imports) > 0 and path == None:
        abort("Have imports but don't know where to look for them. Set the path.")

    for name in imports:
        fullpath = path+name+".et"
        if not os.path.exists(fullpath):
            stdlibpath = "stdlib/"+fullpath
            if os.path.exists(stdlibpath):
                fullpath = stdlibpath
            else:
                abort("Tried to import %s but could not find it in the path" % (importname))
        prepare(path=fullpath)
        if DEBUG:
            print("Imported %s" % (name))

    # Kahn's algorithm (DAG)

    for k,v in types.items():
        types[k] = {"def":v,"len":0}

    basetypes = {"u":{"def":[],"len":1}}
    types = {**basetypes, **types}

    # Add pointer types
    for typename in list(types):
        types["*"+typename] = {"def":[], "len":1}

    indexorder = kahn(list(types.keys()), [[tnpair[0] for tnpair in value["def"]] for value in types.values()])
    for index in indexorder:
        key = list(types.keys())[index]
        for tnpairindex, tnpair in enumerate(types[key]["def"]):
            # Add subtype length and cumulated offset
            types[key]["def"][tnpairindex] = {
                "type":types[key]["def"][tnpairindex][0],
                "name":types[key]["def"][tnpairindex][1],
                "len":types[tnpair[0]]["len"],
                "offset":types[key]["len"]
            }
            types[key]["len"] += types[tnpair[0]]["len"]

    for typename in types:
        types[typename]["name"] = typename

    generator = Generator()

    hasmain = False
    for funcname in funcs:
        if funcname == "main":
            hasmain = True
        funcs[funcname]["name"] = funcname
        funcs[funcname]["code"] = compile_function(abort, warn, generator, types, funcs, funcname)

    if not hasmain:
        abort("No main function specified")

    # Create stack, heap and io areas
    intro = ["AREA", "AREA", "AREA"]
    # Push return address
    intro += asm("push(0)")
    # Allocate 0 stack frame
    #XXX code += asm("area")
    intro += asm("alloc(%i,1)" % MEM_STACK)

    intro += ["PUSH main", "JUMP"]
    intro = "\n".join(intro) + "\n"

    code = assemble(intro)

    offset = len(code)
    for funcname, func in funcs.items():
        func["offset"] = offset + 1
        # Can't do cross-func optimization this way
        func["code"] = funcname+":"+"\n" + func["code"]
        func["compiled"] = assemble(func["code"])
        code += [len(func["compiled"])] + func["compiled"]
        if DEBUG:
            print(funcname, func["offset"], len(func["compiled"]))
        #code += str(len(func["code"])) + "\n"#XXX not len of CODE STRING, BUT COMPILED!
        #
        #code += func["code"] + "\n"
        offset = len(code)

    code = [funcs["main"]["offset"] if c=="main" else c for c in code]
    #print(code)
    map = []
    for funcname in funcs:
        #intro += ["PUSH %i" % nametoint(funcname), "PUSH %s" % funcname, "KEYSET"]
        map += [nametoint(funcname), funcs[funcname]["offset"]]
    #print(code)
    binary = pack(code,[],map)#See ^XXX^
    #print(binary.data)

    code += ["HALT"]

    return binary
Esempio n. 11
0
import argparse
from simulator import specifications as specs
from assembler import assembler

def read_program(program):
    f = open(program)
    lines = f.readlines()
    f.close()

    return lines

def get_args():
    parser = argparse.ArgumentParser(description='Assemble the given code')

    parser.add_argument('program', help='the file containing the code to be assembled')
    parser.add_argument('--version', action='version', version='DCPU v%s' % specs.DCPU_VERSION)

    return parser.parse_args()

if __name__ == '__main__':

    args = get_args()
    print "\n".join(assembler.assemble(read_program(args.program)))