Add solutions for part 1
This commit is contained in:
13
projects/06/add/Add.asm
Normal file
13
projects/06/add/Add.asm
Normal file
@@ -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
|
||||
6
projects/06/add/Add.hack
Normal file
6
projects/06/add/Add.hack
Normal file
@@ -0,0 +1,6 @@
|
||||
0000000000000010
|
||||
1110110000010000
|
||||
0000000000000011
|
||||
1110000010010000
|
||||
0000000000000000
|
||||
1110001100001000
|
||||
201
projects/06/assembler.py
Executable file
201
projects/06/assembler.py
Executable file
@@ -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")
|
||||
|
||||
26
projects/06/max/Max.asm
Normal file
26
projects/06/max/Max.asm
Normal file
@@ -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
|
||||
23
projects/06/max/MaxL.asm
Normal file
23
projects/06/max/MaxL.asm
Normal file
@@ -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
|
||||
28375
projects/06/pong/Pong.asm
Normal file
28375
projects/06/pong/Pong.asm
Normal file
File diff suppressed because it is too large
Load Diff
27483
projects/06/pong/Pong.hack
Normal file
27483
projects/06/pong/Pong.hack
Normal file
File diff suppressed because it is too large
Load Diff
27483
projects/06/pong/Pong.nosymbol.asm
Normal file
27483
projects/06/pong/Pong.nosymbol.asm
Normal file
File diff suppressed because it is too large
Load Diff
27490
projects/06/pong/PongL.asm
Normal file
27490
projects/06/pong/PongL.asm
Normal file
File diff suppressed because it is too large
Load Diff
27483
projects/06/pong/PongL.hack
Normal file
27483
projects/06/pong/PongL.hack
Normal file
File diff suppressed because it is too large
Load Diff
27483
projects/06/pong/PongL.nosymbol.asm
Normal file
27483
projects/06/pong/PongL.nosymbol.asm
Normal file
File diff suppressed because it is too large
Load Diff
35
projects/06/rect/Rect.asm
Normal file
35
projects/06/rect/Rect.asm
Normal file
@@ -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
|
||||
32
projects/06/rect/RectL.asm
Normal file
32
projects/06/rect/RectL.asm
Normal file
@@ -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
|
||||
25
projects/06/rect/RectL.hack
Normal file
25
projects/06/rect/RectL.hack
Normal file
@@ -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