Add solutions for part 1
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/06/add/Add.asm
|
||||
|
||||
// Computes R0 = 2 + 3 (R0 refers to RAM[0])
|
||||
|
||||
@2
|
||||
D=A
|
||||
@3
|
||||
D=D+A
|
||||
@0
|
||||
M=D
|
||||
@@ -0,0 +1,6 @@
|
||||
0000000000000010
|
||||
1110110000010000
|
||||
0000000000000011
|
||||
1110000010010000
|
||||
0000000000000000
|
||||
1110001100001000
|
||||
Executable
+201
@@ -0,0 +1,201 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
|
||||
def preprocess(lines):
|
||||
lines = remove_whitespaces(lines)
|
||||
lines = replace_symbols(lines)
|
||||
return lines
|
||||
|
||||
|
||||
def replace_symbols(lines):
|
||||
symbols = {
|
||||
"SP": "0",
|
||||
"LCL": "1",
|
||||
"ARG": "2",
|
||||
"THIS": "3",
|
||||
"THAT": "4",
|
||||
"R0": "0",
|
||||
"R1": "1",
|
||||
"R2": "2",
|
||||
"R3": "3",
|
||||
"R4": "4",
|
||||
"R5": "5",
|
||||
"R6": "6",
|
||||
"R7": "7",
|
||||
"R8": "8",
|
||||
"R9": "9",
|
||||
"R10": "10",
|
||||
"R11": "11",
|
||||
"R12": "12",
|
||||
"R13": "13",
|
||||
"R14": "14",
|
||||
"R15": "15",
|
||||
"SCREEN": "16384",
|
||||
"KBD": "24576",
|
||||
}
|
||||
|
||||
# Find all labels, remove them, and add them to symbol table.
|
||||
address = 0
|
||||
re_label = re.compile("\((\S*)\)")
|
||||
lines_without_labels = []
|
||||
for line in lines:
|
||||
m = re_label.match(line)
|
||||
if m:
|
||||
label = m.groups()[0]
|
||||
if label in symbols:
|
||||
raise Exception("Multiple defines for {}.".format(line))
|
||||
symbols[label] = str(address)
|
||||
else:
|
||||
lines_without_labels.append(line)
|
||||
address += 1
|
||||
lines = lines_without_labels
|
||||
|
||||
# Find all address instruction and replace symbols.
|
||||
lines_without_symbols = []
|
||||
re_symbol = re.compile("@([A-Za-z]\S*)")
|
||||
address = 16
|
||||
for line in lines:
|
||||
m = re_symbol.match(line)
|
||||
if m:
|
||||
symbol = m.groups()[0]
|
||||
if symbol in symbols:
|
||||
symbol_value = symbols[symbol]
|
||||
else:
|
||||
symbol_value = str(address)
|
||||
symbols[symbol] = symbol_value
|
||||
address += 1
|
||||
lines_without_symbols.append("@" + symbol_value)
|
||||
else:
|
||||
lines_without_symbols.append(line)
|
||||
return lines_without_symbols
|
||||
|
||||
|
||||
def assemble(lines):
|
||||
lines = assemble_instructions(lines)
|
||||
return lines
|
||||
|
||||
|
||||
def remove_whitespaces(lines):
|
||||
r_whitespace = re.compile("\s")
|
||||
r_comment = re.compile("//.*")
|
||||
lines = [r_whitespace.sub("", line) for line in lines]
|
||||
lines = [r_comment.sub("", line) for line in lines]
|
||||
return [line for line in lines if line]
|
||||
|
||||
|
||||
def assemble_instructions(lines):
|
||||
return [assemble_instruction(line) for line in lines]
|
||||
|
||||
|
||||
def assemble_instruction(line):
|
||||
if line.startswith("@"):
|
||||
return assemble_a_instruction(line)
|
||||
else:
|
||||
return assemble_c_instruction(line)
|
||||
|
||||
|
||||
def assemble_a_instruction(line):
|
||||
adr_str = line.replace("@", "")
|
||||
adr_int = int(adr_str)
|
||||
adr_bin_str = bin(adr_int)[2:]
|
||||
adr_bin_str = "0" * (16 - len(adr_bin_str)) + adr_bin_str
|
||||
return adr_bin_str
|
||||
|
||||
|
||||
def assemble_c_instruction(line):
|
||||
r = re.compile("(\S+)=(\S+);(\S+)")
|
||||
if not ";" in line:
|
||||
line = line + ";null"
|
||||
if not "=" in line:
|
||||
line = "null=" + line
|
||||
dest, comp, jump = r.match(line).groups()
|
||||
ins_str = "111" + comp_lookup(comp) + dest_lookup(dest) + jump_lookup(jump)
|
||||
return ins_str
|
||||
|
||||
def comp_lookup(comp_str):
|
||||
return {
|
||||
"0": "0101010",
|
||||
"1": "0111111",
|
||||
"-1": "0111010",
|
||||
"D": "0001100",
|
||||
"A": "0110000",
|
||||
"M": "1110000",
|
||||
"!D": "0001101",
|
||||
"!A": "0110001",
|
||||
"!M": "1110001",
|
||||
"-D": "0001111",
|
||||
"-A": "0110011",
|
||||
"-M": "1110011",
|
||||
"D+1": "0011111",
|
||||
"A+1": "0110111",
|
||||
"M+1": "1110111",
|
||||
"D-1": "0001110",
|
||||
"A-1": "0110010",
|
||||
"M-1": "1110010",
|
||||
"D+A": "0000010",
|
||||
"D+M": "1000010",
|
||||
"D-A": "0010011",
|
||||
"D-M": "1010011",
|
||||
"A-D": "0000111",
|
||||
"M-D": "1000111",
|
||||
"D&A": "0000000",
|
||||
"D&M": "1000000",
|
||||
"D|A": "0010101",
|
||||
"D|M": "1010101"
|
||||
}[comp_str]
|
||||
|
||||
|
||||
def dest_lookup(dest_str):
|
||||
return {
|
||||
"null": "000",
|
||||
"M": "001",
|
||||
"D": "010",
|
||||
"MD": "011",
|
||||
"A": "100",
|
||||
"AM": "101",
|
||||
"AD": "110",
|
||||
"AMD": "111"
|
||||
}[dest_str]
|
||||
|
||||
|
||||
def jump_lookup(jump_str):
|
||||
return {
|
||||
"null": "000",
|
||||
"JGT": "001",
|
||||
"JEQ": "010",
|
||||
"JGE": "011",
|
||||
"JLT": "100",
|
||||
"JNE": "101",
|
||||
"JLE": "110",
|
||||
"JMP": "111"
|
||||
}[jump_str]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
hack_asm_file = sys.argv[1]
|
||||
if not hack_asm_file.endswith(".asm"):
|
||||
sys.exit("Hack asm file must have a .asm file ending.")
|
||||
hack_asm_ns_file = hack_asm_file.replace(".asm", ".nosymbol.asm")
|
||||
hack_bin_file = hack_asm_file.replace(".asm", ".hack")
|
||||
except IndexError:
|
||||
sys.exit("Call: ./assembler.py <hack_asm_file>")
|
||||
|
||||
with open(hack_asm_file, 'r') as f:
|
||||
assembly_lines = f.readlines()
|
||||
|
||||
preprocessed_lines = preprocess(assembly_lines)
|
||||
binary_lines = assemble(preprocessed_lines)
|
||||
|
||||
with open(hack_asm_ns_file, 'w') as f:
|
||||
for line in preprocessed_lines:
|
||||
f.write(line + "\n")
|
||||
|
||||
with open(hack_bin_file, 'w') as f:
|
||||
for line in binary_lines:
|
||||
f.write(line + "\n")
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/06/max/Max.asm
|
||||
|
||||
// Computes R2 = max(R0, R1) (R0,R1,R2 refer to RAM[0],RAM[1],RAM[2])
|
||||
|
||||
@R0
|
||||
D=M // D = first number
|
||||
@R1
|
||||
D=D-M // D = first number - second number
|
||||
@OUTPUT_FIRST
|
||||
D;JGT // if D>0 (first is greater) goto output_first
|
||||
@R1
|
||||
D=M // D = second number
|
||||
@OUTPUT_D
|
||||
0;JMP // goto output_d
|
||||
(OUTPUT_FIRST)
|
||||
@R0
|
||||
D=M // D = first number
|
||||
(OUTPUT_D)
|
||||
@R2
|
||||
M=D // M[2] = D (greatest number)
|
||||
(INFINITE_LOOP)
|
||||
@INFINITE_LOOP
|
||||
0;JMP // infinite loop
|
||||
@@ -0,0 +1,23 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/06/max/MaxL.asm
|
||||
|
||||
// Symbol-less version of the Max.asm program.
|
||||
|
||||
@0
|
||||
D=M
|
||||
@1
|
||||
D=D-M
|
||||
@10
|
||||
D;JGT
|
||||
@1
|
||||
D=M
|
||||
@12
|
||||
0;JMP
|
||||
@0
|
||||
D=M
|
||||
@2
|
||||
M=D
|
||||
@14
|
||||
0;JMP
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/06/rect/Rect.asm
|
||||
|
||||
// Draws a rectangle at the top-left corner of the screen.
|
||||
// The rectangle is 16 pixels wide and R0 pixels high.
|
||||
|
||||
@0
|
||||
D=M
|
||||
@INFINITE_LOOP
|
||||
D;JLE
|
||||
@counter
|
||||
M=D
|
||||
@SCREEN
|
||||
D=A
|
||||
@address
|
||||
M=D
|
||||
(LOOP)
|
||||
@address
|
||||
A=M
|
||||
M=-1
|
||||
@address
|
||||
D=M
|
||||
@32
|
||||
D=D+A
|
||||
@address
|
||||
M=D
|
||||
@counter
|
||||
MD=M-1
|
||||
@LOOP
|
||||
D;JGT
|
||||
(INFINITE_LOOP)
|
||||
@INFINITE_LOOP
|
||||
0;JMP
|
||||
@@ -0,0 +1,32 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/06/rect/RectL.asm
|
||||
|
||||
// Symbol-less version of the Rect.asm program.
|
||||
|
||||
@0
|
||||
D=M
|
||||
@23
|
||||
D;JLE
|
||||
@16
|
||||
M=D
|
||||
@16384
|
||||
D=A
|
||||
@17
|
||||
M=D
|
||||
@17
|
||||
A=M
|
||||
M=-1
|
||||
@17
|
||||
D=M
|
||||
@32
|
||||
D=D+A
|
||||
@17
|
||||
M=D
|
||||
@16
|
||||
MD=M-1
|
||||
@10
|
||||
D;JGT
|
||||
@23
|
||||
0;JMP
|
||||
@@ -0,0 +1,25 @@
|
||||
0000000000000000
|
||||
1111110000010000
|
||||
0000000000010111
|
||||
1110001100000110
|
||||
0000000000010000
|
||||
1110001100001000
|
||||
0100000000000000
|
||||
1110110000010000
|
||||
0000000000010001
|
||||
1110001100001000
|
||||
0000000000010001
|
||||
1111110000100000
|
||||
1110111010001000
|
||||
0000000000010001
|
||||
1111110000010000
|
||||
0000000000100000
|
||||
1110000010010000
|
||||
0000000000010001
|
||||
1110001100001000
|
||||
0000000000010000
|
||||
1111110010011000
|
||||
0000000000001010
|
||||
1110001100000001
|
||||
0000000000010111
|
||||
1110101010000111
|
||||
Reference in New Issue
Block a user