Skip to content

Instantly share code, notes, and snippets.

@jadudm
Last active December 14, 2015 06:18
Show Gist options
  • Save jadudm/5041094 to your computer and use it in GitHub Desktop.
Save jadudm/5041094 to your computer and use it in GitHub Desktop.
comporg-assembler
# 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
@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