Last active
December 14, 2015 06:18
-
-
Save jadudm/5041094 to your computer and use it in GitHub Desktop.
comporg-assembler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A Hack assembler in 5 Minutes | |
import re | |
# Set up hash tables (dictionaries, in Python) to capture all of | |
# the instruction transformations. This is a "lookup table," of sorts. | |
# When we encounter an "A", it will always be transformed to | |
# "110000", which we will get by looking up the key "A" in the dictionary | |
# called "comp". | |
# | |
# I like my hash tables to line up all pretty-like when I can pull it off. | |
comp = {'A' : '110000', | |
'D' : '001100', | |
'D+A' : '000010'} | |
# Do the same for the destinations | |
dest = {'D' : '010', | |
'M' : '001'} | |
# We will need a table for the jumps. | |
# Open the file. It might be good to read it into an | |
# array; at least, for small (lines < 100K) programs. | |
f = open('program.hack', 'r') | |
# Convert a number into a 15 bit binary number. | |
# From this Stack Overflow post: | |
# http://goo.gl/ihXfp | |
def as_binary (n): | |
return '{0:015b}'.format(int(n)) | |
# Convert a textual line of Hack assembly into a binary string. | |
# There are probably be better ways. | |
def convertInstruction (line): | |
# We'll return this at the end. | |
binary_string = "ERROR: %s" % line | |
search_result = re.search("@(\d+)", line) | |
if search_result != None: | |
binary_string = "0" + as_binary(search_result.group(1)) | |
search_result = re.search('^(.*?)=(.*?)$', line) | |
if search_result != None: | |
lhs = search_result.group(1) | |
rhs = search_result.group(2) | |
# print "L %s R %s" % (lhs, rhs) | |
if re.search(rhs, 'M'): | |
a = 1 | |
else: | |
a = 0 | |
j ="000" | |
binary_string = "111%s%s%s%s" % (a, comp[rhs], dest[lhs], j) | |
# Our 'if' clauses should have set the value of "binary_string" | |
# before this point. If not, we will return the line that caused | |
# the error for our conversion. That will help us debug our assembler. | |
return binary_string | |
# Instead of doing everything in the loop, I | |
# put the original contents into a function. | |
# It does the same thing, but this allows us to extend our | |
# processing within the loop with new functions. | |
# For example, you need to build a "lookup table" | |
# for variables when you see things like: | |
# | |
# @varRef | |
# | |
# and turn those into actual RAM locations. That must happen before | |
# we can write out binary. | |
for line in f: | |
zeros_and_ones = convertInstruction(line) | |
print zeros_and_ones | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@3 | |
D=A | |
@5 | |
D=D+A | |
@0 | |
M=D |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment