Add solutions for part 1

This commit is contained in:
2020-11-15 13:57:48 -05:00
parent e4f9fd2682
commit 742db6d102
479 changed files with 202980 additions and 13 deletions
+13
View 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
View File
@@ -0,0 +1,6 @@
0000000000000010
1110110000010000
0000000000000011
1110000010010000
0000000000000000
1110001100001000
+201
View 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
View 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
View 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
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
+35
View 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
View 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
View 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