├── 10 ├── nodes │ ├── this_term_node.rb │ ├── true_term_node.rb │ ├── false_term_node.rb │ ├── expression_node.rb │ ├── string_term_node.rb │ ├── integer_term_node.rb │ ├── else_statement_node.rb │ ├── unary_operation_node.rb │ ├── if_statement_node.rb │ ├── variable_term_node.rb │ ├── binary_operation_node.rb │ ├── while_statement_node.rb │ ├── return_statement_node.rb │ ├── do_statement_node.rb │ ├── parameter_node.rb │ ├── subroutine_call_node.rb │ ├── variable_declaration_node.rb │ ├── class_variable_declaration_node.rb │ ├── subroutine_body_node.rb │ ├── let_statement_node.rb │ ├── class_node.rb │ └── subroutine_node.rb ├── Gemfile ├── ArrayTest │ ├── Blah.jack │ └── Main.jack ├── Gemfile.lock ├── Square │ ├── Main.jack │ └── MainT.xml └── ExpressionlessSquare │ ├── Main.jack │ ├── MainT.xml │ └── MainT-gen.xml ├── 11 ├── Gemfile ├── nodes │ ├── this_term_node.rb │ ├── false_term_node.rb │ ├── null_term_node.rb │ ├── integer_term_node.rb │ ├── expression_node.rb │ ├── true_term_node.rb │ ├── class_variable_declaration_node.rb │ ├── string_term_node.rb │ ├── unary_operation_node.rb │ ├── parameter_node.rb │ ├── do_statement_node.rb │ ├── return_statement_node.rb │ ├── variable_declaration_node.rb │ ├── while_statement_node.rb │ ├── variable_term_node.rb │ ├── subroutine_body_node.rb │ ├── if_statement_node.rb │ ├── class_node.rb │ ├── binary_operation_node.rb │ ├── let_statement_node.rb │ ├── subroutine_call_node.rb │ └── subroutine_node.rb ├── Seven │ ├── Main.vm │ └── Main.jack ├── Square │ ├── Main.vm │ └── Main.jack ├── Pong │ ├── Main.vm │ ├── Array.vm │ ├── Main.jack │ ├── Main.jack.bak │ └── Sys.vm ├── Gemfile.lock ├── compiler.rb ├── Average │ └── Main.jack ├── vm_writer.rb └── symbol_table.rb ├── 12 ├── Output.jack ├── ArrayTest │ ├── ArrayTest.out │ ├── ArrayTest.cmp │ ├── Array.vm │ ├── ArrayTest.tst │ ├── Array.jack │ └── Main.jack ├── OutputTest │ ├── OutputTestOutput.gif │ └── Main.jack ├── ScreenTest │ ├── ScreenTestOutput.gif │ ├── Screen.jack │ └── Main.jack ├── StringTest │ └── StringTestOutput.gif ├── KeyboardTest │ └── KeyboardTestOutput.gif ├── MemoryTest │ ├── MemoryTest.cmp │ ├── MemoryTest.out │ ├── MemoryTest.tst │ └── Main.jack ├── Main.jack ├── MathTest │ ├── MathTest.cmp │ ├── MathTest.out │ ├── MathTest.tst │ └── Main.jack ├── Main.vm ├── Array.jack ├── SysTest │ ├── Main.jack │ ├── Sys.jack │ └── Sys.vm ├── Screen.jack └── Sys.jack ├── 13 └── more fun to go.txt ├── 05 ├── CPU.out ├── Computer.hdl ├── Add.hack ├── Max.hack ├── Rect.hack ├── ComputerAdd-external.cmp ├── ComputerAdd-external.tst ├── ComputerRect-external.cmp ├── ComputerAdd.tst ├── ComputerRect-external.tst ├── ComputerRect.tst ├── ComputerAdd.out ├── ComputerAdd.cmp ├── ComputerMax-external.tst ├── ComputerMax.tst ├── Memory.out ├── Memory.cmp └── ComputerMax-external.cmp ├── 07 ├── StackArithmetic │ ├── SimpleAdd │ │ ├── SimpleAdd.out │ │ ├── SimpleAdd.cmp │ │ ├── SimpleAdd.asm │ │ ├── SimpleAdd.vm │ │ ├── SimpleAdd.tst │ │ └── SimpleAddVME.tst │ └── StackTest │ │ ├── StackTest.out │ │ ├── StackTest.cmp │ │ ├── SimpleTest.vm │ │ ├── SimpleTest.asm │ │ ├── StackTest.tst │ │ ├── StackTestVME.tst │ │ └── StackTest.vm ├── MemoryAccess │ ├── StaticTest │ │ ├── StaticTest.cmp │ │ ├── StaticTest.out │ │ ├── StaticTest.tst │ │ ├── StaticTestVME.tst │ │ ├── StaticTest.vm │ │ └── StaticTest.asm │ ├── PointerTest │ │ ├── PointerTest.cmp │ │ ├── PointerTest.out │ │ ├── PointerTest.tst │ │ ├── PointerTestVME.tst │ │ └── PointerTest.vm │ └── BasicTest │ │ ├── BasicTest.cmp │ │ ├── BasicTest.out │ │ ├── BasicTestVME.tst │ │ ├── BasicTest.tst │ │ ├── BasicTest.vm │ │ └── SimpleTest.vm ├── commands │ ├── neg_command.rb │ ├── not_command.rb │ ├── label_command.rb │ ├── add_command.rb │ ├── and_command.rb │ ├── or_command.rb │ ├── sub_command.rb │ ├── goto_command.rb │ ├── bootstrap_command.rb │ ├── if_goto_command.rb │ ├── eq_command.rb │ ├── gt_command.rb │ ├── lt_command.rb │ ├── function_command.rb │ ├── return_command.rb │ ├── call_command.rb │ ├── pop_command.rb │ └── push_command.rb └── translator.rb ├── 01 ├── Not.out ├── Not.cmp ├── And.out ├── Or.out ├── Or8Way.out ├── Xor.out ├── And.cmp ├── Or.cmp ├── Xor.cmp ├── Or8Way.cmp ├── DMux.out ├── DMux.cmp ├── Not16.out ├── Not16.cmp ├── Mux.out ├── Mux.cmp ├── Not.hdl ├── DMux4Way.out ├── DMux4Way.cmp ├── Not.tst ├── And.hdl ├── And16.out ├── Or16.out ├── And16.cmp ├── Or16.cmp ├── Or.hdl ├── DMux.hdl ├── Mux.hdl ├── Xor.hdl ├── DMux.tst ├── Or.tst ├── And.tst ├── Xor.tst ├── Or8Way.tst ├── Or8Way.hdl ├── Mux16.out ├── Mux16.cmp ├── Mux4Way16.hdl ├── Not16.tst ├── DMux4Way.hdl ├── DMux4Way.tst ├── Mux.tst ├── Mux8Way16.hdl ├── Or16.tst ├── And16.tst ├── DMux8Way.hdl ├── Not16.hdl ├── Mux16.tst ├── Mux4Way16.tst ├── Mux4Way16.out ├── Mux4Way16.cmp ├── Or16.hdl ├── And16.hdl ├── DMux8Way.out ├── DMux8Way.cmp ├── Mux16.hdl ├── DMux8Way.tst └── Mux8Way16.tst ├── 02 ├── ALU.hdl ├── HalfAdder.out ├── HalfAdder.cmp ├── Or16Way.hdl ├── Inc16.out ├── Inc16.cmp ├── FullAdder.out ├── Add16.out ├── FullAdder.cmp ├── Add16.cmp ├── Inc16.hdl ├── HalfAdder.hdl ├── HalfAdder.tst ├── Inc16.tst ├── FullAdder.hdl ├── FullAdder.tst ├── Add16.tst └── Add16.hdl ├── 08 ├── ProgramFlow │ ├── BasicLoop │ │ ├── BasicLoop.cmp │ │ ├── BasicLoop.out │ │ ├── BasicLoop.tst │ │ ├── BasicLoopVME.tst │ │ └── BasicLoop.vm │ └── FibonacciSeries │ │ ├── FibonacciSeries.out │ │ ├── FibonacciSeries.cmp │ │ ├── FibonacciSeries.tst │ │ ├── FibonacciSeriesVME.tst │ │ └── FibonacciSeries.vm └── FunctionCalls │ ├── FibonacciElement │ ├── FibonacciElement.out │ ├── FibonacciElement.cmp │ ├── FibonacciElementVME.tst │ ├── FibonacciElement.tst │ ├── Sys.vm │ └── Main.vm │ ├── StaticsTest │ ├── StaticsTest.cmp │ ├── StaticsTest.out │ ├── StaticsTest.tst │ ├── StaticsTestVME.tst │ ├── Class1.vm │ ├── Class2.vm │ └── Sys.vm │ └── SimpleFunction │ ├── SimpleFunction.cmp │ ├── SimpleFunction.out │ ├── SimpleFunction.vm │ ├── SimpleFunction.vm.bak │ ├── SimpleFunction.tst │ └── SimpleFunctionVME.tst ├── README.md ├── 06 ├── add │ ├── Add.hack │ └── Add.asm ├── address_command.rb ├── max │ ├── MaxL.hack │ ├── MaxL.asm │ └── Max.asm └── rect │ ├── RectL.asm │ ├── Rect.hack │ ├── RectL.hack │ └── Rect.asm ├── 09 ├── HelloWorld │ ├── Main.jack │ └── Main.vm └── Square │ ├── Main.vm │ └── Main.jack ├── 00 ├── And.cmp ├── Xor.cmp ├── And.tst ├── Xor.hdl ├── Xor.tst ├── Register.cmp ├── RAM8.cmp ├── Mux8Way16.cmp ├── Register.tst ├── Mux8Way16.tst └── RAM8.tst ├── 04 ├── mult │ ├── Mult.out │ ├── Mult.cmp │ ├── Mult.hack │ ├── Mult.asm │ └── Mult.tst └── fill │ ├── Fill.tst │ ├── Fill.hack │ └── Fill.asm └── 03 ├── a ├── Bit.hdl ├── PC.hdl ├── Register.hdl ├── RAM8.hdl ├── PC.out ├── PC.cmp ├── RAM64.hdl └── DMux8Way16.hdl └── b ├── RAM16K.hdl ├── RAM512.hdl └── RAM4K.hdl /05/CPU.out: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /07/StackArithmetic/SimpleAdd/SimpleAdd.out: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /07/StackArithmetic/StackTest/StackTest.out: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10/nodes/this_term_node.rb: -------------------------------------------------------------------------------- 1 | class ThisTermNode 2 | end 3 | -------------------------------------------------------------------------------- /10/nodes/true_term_node.rb: -------------------------------------------------------------------------------- 1 | class TrueTermNode 2 | end 3 | -------------------------------------------------------------------------------- /10/nodes/false_term_node.rb: -------------------------------------------------------------------------------- 1 | class FalseTermNode 2 | end 3 | -------------------------------------------------------------------------------- /07/MemoryAccess/StaticTest/StaticTest.cmp: -------------------------------------------------------------------------------- 1 | |RAM[256]| 2 | | 1110 | 3 | -------------------------------------------------------------------------------- /07/MemoryAccess/StaticTest/StaticTest.out: -------------------------------------------------------------------------------- 1 | |RAM[256]| 2 | | 1110 | 3 | -------------------------------------------------------------------------------- /01/Not.out: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0 | 1 | 3 | | 1 | 0 | 4 | -------------------------------------------------------------------------------- /02/ALU.hdl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtdowney/nand2tetris/HEAD/02/ALU.hdl -------------------------------------------------------------------------------- /01/Not.cmp: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0 | 1 | 3 | | 1 | 0 | 4 | -------------------------------------------------------------------------------- /10/nodes/expression_node.rb: -------------------------------------------------------------------------------- 1 | class ExpressionNode < Struct.new(:term) 2 | end 3 | -------------------------------------------------------------------------------- /10/nodes/string_term_node.rb: -------------------------------------------------------------------------------- 1 | class StringTermNode < Struct.new(:value) 2 | end 3 | -------------------------------------------------------------------------------- /05/Computer.hdl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtdowney/nand2tetris/HEAD/05/Computer.hdl -------------------------------------------------------------------------------- /08/ProgramFlow/BasicLoop/BasicLoop.cmp: -------------------------------------------------------------------------------- 1 | | RAM[0] |RAM[256]| 2 | | 257 | 6 | 3 | -------------------------------------------------------------------------------- /08/ProgramFlow/BasicLoop/BasicLoop.out: -------------------------------------------------------------------------------- 1 | | RAM[0] |RAM[256]| 2 | | 257 | 6 | 3 | -------------------------------------------------------------------------------- /10/nodes/integer_term_node.rb: -------------------------------------------------------------------------------- 1 | class IntegerTermNode < Struct.new(:value) 2 | end 3 | -------------------------------------------------------------------------------- /12/Output.jack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtdowney/nand2tetris/HEAD/12/Output.jack -------------------------------------------------------------------------------- /10/nodes/else_statement_node.rb: -------------------------------------------------------------------------------- 1 | class ElseStatementNode < Struct.new(:statements) 2 | end 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tecs 2 | ==== 3 | 4 | My solutions to the projects in The Elements of Computing Systems -------------------------------------------------------------------------------- /07/StackArithmetic/SimpleAdd/SimpleAdd.cmp: -------------------------------------------------------------------------------- 1 | | RAM[0] | RAM[256] | 2 | | 257 | 15 | 3 | -------------------------------------------------------------------------------- /08/FunctionCalls/FibonacciElement/FibonacciElement.out: -------------------------------------------------------------------------------- 1 | | RAM[0] |RAM[261]| 2 | | 262 | 3 | 3 | -------------------------------------------------------------------------------- /10/Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gem 'activesupport', '~> 3.2.9' 4 | gem 'builder', '~> 3.1.4' 5 | -------------------------------------------------------------------------------- /10/nodes/unary_operation_node.rb: -------------------------------------------------------------------------------- 1 | class UnaryOperationNode < Struct.new(:operator, :term) 2 | end 3 | -------------------------------------------------------------------------------- /11/Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gem 'activesupport', '~> 3.2.9' 4 | gem 'builder', '~> 3.1.4' 5 | -------------------------------------------------------------------------------- /08/FunctionCalls/FibonacciElement/FibonacciElement.cmp: -------------------------------------------------------------------------------- 1 | | RAM[0] |RAM[261]| 2 | | 262 | 3 | 3 | -------------------------------------------------------------------------------- /10/nodes/if_statement_node.rb: -------------------------------------------------------------------------------- 1 | class IfStatementNode < Struct.new(:value_expression, :statements) 2 | end 3 | -------------------------------------------------------------------------------- /10/nodes/variable_term_node.rb: -------------------------------------------------------------------------------- 1 | class VariableTermNode < Struct.new(:name, :index_expression) 2 | end 3 | -------------------------------------------------------------------------------- /08/FunctionCalls/StaticsTest/StaticsTest.cmp: -------------------------------------------------------------------------------- 1 | | RAM[0] |RAM[261]|RAM[262]| 2 | | 263 | -2 | 8 | 3 | -------------------------------------------------------------------------------- /08/FunctionCalls/StaticsTest/StaticsTest.out: -------------------------------------------------------------------------------- 1 | | RAM[0] |RAM[261]|RAM[262]| 2 | | 263 | -2 | 8 | 3 | -------------------------------------------------------------------------------- /10/nodes/binary_operation_node.rb: -------------------------------------------------------------------------------- 1 | class BinaryOperationTermNode < Struct.new(:operator, :left, :right) 2 | end 3 | -------------------------------------------------------------------------------- /12/ArrayTest/ArrayTest.out: -------------------------------------------------------------------------------- 1 | |RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]| 2 | | 222 | 122 | 100 | 10 | 3 | -------------------------------------------------------------------------------- /12/ArrayTest/ArrayTest.cmp: -------------------------------------------------------------------------------- 1 | |RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]| 2 | | 222 | 122 | 100 | 10 | 3 | -------------------------------------------------------------------------------- /12/OutputTest/OutputTestOutput.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtdowney/nand2tetris/HEAD/12/OutputTest/OutputTestOutput.gif -------------------------------------------------------------------------------- /12/ScreenTest/ScreenTestOutput.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtdowney/nand2tetris/HEAD/12/ScreenTest/ScreenTestOutput.gif -------------------------------------------------------------------------------- /12/StringTest/StringTestOutput.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtdowney/nand2tetris/HEAD/12/StringTest/StringTestOutput.gif -------------------------------------------------------------------------------- /12/KeyboardTest/KeyboardTestOutput.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtdowney/nand2tetris/HEAD/12/KeyboardTest/KeyboardTestOutput.gif -------------------------------------------------------------------------------- /11/nodes/this_term_node.rb: -------------------------------------------------------------------------------- 1 | class ThisTermNode 2 | def emit(writer, symbols) 3 | writer.write_push(:pointer, 0) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /05/Add.hack: -------------------------------------------------------------------------------- 1 | 0000000000000010 2 | 1110110000010000 3 | 0000000000000011 4 | 1110000010010000 5 | 0000000000000000 6 | 1110001100001000 7 | -------------------------------------------------------------------------------- /06/add/Add.hack: -------------------------------------------------------------------------------- 1 | 0000000000000010 2 | 1110110000010000 3 | 0000000000000011 4 | 1110000010010000 5 | 0000000000000000 6 | 1110001100001000 -------------------------------------------------------------------------------- /11/nodes/false_term_node.rb: -------------------------------------------------------------------------------- 1 | class FalseTermNode 2 | def emit(writer, symbols) 3 | writer.write_push(:constant, 0) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /11/nodes/null_term_node.rb: -------------------------------------------------------------------------------- 1 | class NullTermNode 2 | def emit(writer, symbols) 3 | writer.write_push(:constant, 0) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /07/MemoryAccess/PointerTest/PointerTest.cmp: -------------------------------------------------------------------------------- 1 | |RAM[256]| RAM[3] | RAM[4] |RAM[3032|RAM[3046| 2 | | 6084 | 3030 | 3040 | 32 | 46 | 3 | -------------------------------------------------------------------------------- /07/MemoryAccess/PointerTest/PointerTest.out: -------------------------------------------------------------------------------- 1 | |RAM[256]| RAM[3] | RAM[4] |RAM[3032|RAM[3046| 2 | | 6084 | 3030 | 3040 | 32 | 46 | 3 | -------------------------------------------------------------------------------- /09/HelloWorld/Main.jack: -------------------------------------------------------------------------------- 1 | class Main { 2 | function void main() { 3 | do Output.printString("Hello World"); 4 | return; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /10/nodes/while_statement_node.rb: -------------------------------------------------------------------------------- 1 | class WhileStatementNode < Struct.new(:value_expression, :statements) 2 | def to_xml 3 | '' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /01/And.out: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 0 | 4 | | 1 | 0 | 0 | 5 | | 1 | 1 | 1 | 6 | -------------------------------------------------------------------------------- /01/Or.out: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 1 | 6 | -------------------------------------------------------------------------------- /01/Or8Way.out: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 00000000 | 0 | 3 | | 11111111 | 1 | 4 | | 00010000 | 1 | 5 | | 00000001 | 1 | 6 | | 00100110 | 1 | 7 | -------------------------------------------------------------------------------- /01/Xor.out: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 0 | 6 | -------------------------------------------------------------------------------- /12/MemoryTest/MemoryTest.cmp: -------------------------------------------------------------------------------- 1 | |RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]|RAM[8004]|RAM[8005]| 2 | | 333 | 334 | 222 | 122 | 100 | 10 | 3 | -------------------------------------------------------------------------------- /12/MemoryTest/MemoryTest.out: -------------------------------------------------------------------------------- 1 | |RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]|RAM[8004]|RAM[8005]| 2 | | 333 | 334 | 222 | 122 | 100 | 10 | 3 | -------------------------------------------------------------------------------- /00/And.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 0 | 4 | | 1 | 0 | 0 | 5 | | 1 | 1 | 1 | 6 | -------------------------------------------------------------------------------- /00/Xor.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 0 | 6 | -------------------------------------------------------------------------------- /01/And.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 0 | 4 | | 1 | 0 | 0 | 5 | | 1 | 1 | 1 | 6 | -------------------------------------------------------------------------------- /01/Or.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 1 | 6 | -------------------------------------------------------------------------------- /01/Xor.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 0 | 6 | -------------------------------------------------------------------------------- /07/StackArithmetic/StackTest/StackTest.cmp: -------------------------------------------------------------------------------- 1 | | RAM[0] | RAM[256] | RAM[257] | RAM[258] | RAM[259] | 2 | | 260 | -1 | 0 | -1 | 90 | 3 | -------------------------------------------------------------------------------- /01/Or8Way.cmp: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 00000000 | 0 | 3 | | 11111111 | 1 | 4 | | 00010000 | 1 | 5 | | 00000001 | 1 | 6 | | 00100110 | 1 | 7 | -------------------------------------------------------------------------------- /08/FunctionCalls/SimpleFunction/SimpleFunction.cmp: -------------------------------------------------------------------------------- 1 | | RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] |RAM[310]| 2 | | 311 | 305 | 300 | 3010 | 4010 | 1196 | 3 | -------------------------------------------------------------------------------- /08/FunctionCalls/SimpleFunction/SimpleFunction.out: -------------------------------------------------------------------------------- 1 | | RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] |RAM[310]| 2 | | 311 | 305 | 300 | 3010 | 4010 | 1196 | 3 | -------------------------------------------------------------------------------- /11/nodes/integer_term_node.rb: -------------------------------------------------------------------------------- 1 | class IntegerTermNode < Struct.new(:value) 2 | def emit(writer, symbols) 3 | writer.write_push(:constant, value) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /11/nodes/expression_node.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | class ExpressionNode < Struct.new(:term) 4 | extend Forwardable 5 | 6 | def_delegator :term, :emit 7 | end 8 | -------------------------------------------------------------------------------- /11/nodes/true_term_node.rb: -------------------------------------------------------------------------------- 1 | class TrueTermNode 2 | def emit(writer, symbols) 3 | writer.write_push(:constant, 0) 4 | writer.write_arithmetic(:not) 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /08/ProgramFlow/FibonacciSeries/FibonacciSeries.out: -------------------------------------------------------------------------------- 1 | |RAM[3000]|RAM[3001]|RAM[3002]|RAM[3003]|RAM[3004]|RAM[3005]| 2 | | 0 | 1 | 1 | 2 | 3 | 5 | 3 | -------------------------------------------------------------------------------- /08/ProgramFlow/FibonacciSeries/FibonacciSeries.cmp: -------------------------------------------------------------------------------- 1 | |RAM[3000]|RAM[3001]|RAM[3002]|RAM[3003]|RAM[3004]|RAM[3005]| 2 | | 0 | 1 | 1 | 2 | 3 | 5 | 3 | -------------------------------------------------------------------------------- /11/Seven/Main.vm: -------------------------------------------------------------------------------- 1 | function Main.main 0 2 | push constant 1 3 | push constant 2 4 | push constant 3 5 | call Math.multiply 2 6 | add 7 | call Output.printInt 1 8 | push constant 0 9 | return -------------------------------------------------------------------------------- /12/Main.jack: -------------------------------------------------------------------------------- 1 | class Main { 2 | function void main() { 3 | var int c; 4 | /*let c = Keyboard.readChar();*/ 5 | let c = Keyboard.readInt("Blah: "); 6 | return; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /07/MemoryAccess/BasicTest/BasicTest.cmp: -------------------------------------------------------------------------------- 1 | |RAM[256]|RAM[300]|RAM[401]|RAM[402]|RAM[3006|RAM[3012|RAM[3015|RAM[11] | 2 | | 472 | 10 | 21 | 22 | 36 | 42 | 45 | 510 | 3 | -------------------------------------------------------------------------------- /07/MemoryAccess/BasicTest/BasicTest.out: -------------------------------------------------------------------------------- 1 | |RAM[256]|RAM[300]|RAM[401]|RAM[402]|RAM[3006|RAM[3012|RAM[3015|RAM[11] | 2 | | 472 | 10 | 21 | 22 | 36 | 42 | 45 | 510 | 3 | -------------------------------------------------------------------------------- /01/DMux.out: -------------------------------------------------------------------------------- 1 | | in | sel | a | b | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 1 | 0 | 0 | 4 | | 1 | 0 | 1 | 0 | 5 | | 1 | 1 | 0 | 1 | 6 | -------------------------------------------------------------------------------- /01/DMux.cmp: -------------------------------------------------------------------------------- 1 | | in | sel | a | b | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 1 | 0 | 0 | 4 | | 1 | 0 | 1 | 0 | 5 | | 1 | 1 | 0 | 1 | 6 | -------------------------------------------------------------------------------- /02/HalfAdder.out: -------------------------------------------------------------------------------- 1 | | a | b | sum | carry | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 0 | 4 | | 1 | 0 | 1 | 0 | 5 | | 1 | 1 | 0 | 1 | 6 | -------------------------------------------------------------------------------- /02/HalfAdder.cmp: -------------------------------------------------------------------------------- 1 | | a | b | sum | carry | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 0 | 4 | | 1 | 0 | 1 | 0 | 5 | | 1 | 1 | 0 | 1 | 6 | -------------------------------------------------------------------------------- /06/address_command.rb: -------------------------------------------------------------------------------- 1 | class AddressCommand 2 | def initialize(command) 3 | @constant = command.slice(1..-1) 4 | end 5 | 6 | def emit 7 | @constant.to_i.to_s(2).rjust(16, '0') 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /08/FunctionCalls/SimpleFunction/SimpleFunction.vm: -------------------------------------------------------------------------------- 1 | function SimpleFunction.test 2 2 | push local 0 3 | push local 1 4 | add 5 | not 6 | push argument 0 7 | add 8 | push argument 1 9 | sub 10 | return 11 | -------------------------------------------------------------------------------- /02/Or16Way.hdl: -------------------------------------------------------------------------------- 1 | CHIP Or16Way { 2 | IN 3 | in[16]; 4 | OUT 5 | out; 6 | 7 | PARTS: 8 | Or8Way(in=in[0..7], out=t1); 9 | Or8Way(in=in[8..15], out=t2); 10 | Or(a=t1, b=t2, out=out); 11 | } 12 | -------------------------------------------------------------------------------- /10/ArrayTest/Blah.jack: -------------------------------------------------------------------------------- 1 | class Blah { 2 | function int foo() { 3 | var int x, y, z; 4 | return x + g(2, y, -z) * 5; 5 | } 6 | 7 | function int g(int a, int b, int c) { 8 | return 0; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /02/Inc16.out: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0000000000000000 | 0000000000000001 | 3 | | 1111111111111111 | 0000000000000000 | 4 | | 0000000000000101 | 0000000000000110 | 5 | | 1111111111111011 | 1111111111111100 | 6 | -------------------------------------------------------------------------------- /02/Inc16.cmp: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0000000000000000 | 0000000000000001 | 3 | | 1111111111111111 | 0000000000000000 | 4 | | 0000000000000101 | 0000000000000110 | 5 | | 1111111111111011 | 1111111111111100 | 6 | -------------------------------------------------------------------------------- /11/Square/Main.vm: -------------------------------------------------------------------------------- 1 | function Main.main 1 2 | call SquareGame.new 0 3 | pop local 0 4 | push local 0 5 | call SquareGame.run 1 6 | pop temp 0 7 | push local 0 8 | call SquareGame.dispose 1 9 | pop temp 0 10 | push constant 0 11 | return -------------------------------------------------------------------------------- /09/Square/Main.vm: -------------------------------------------------------------------------------- 1 | function Main.main 1 2 | call SquareGame.new 0 3 | pop local 0 4 | push local 0 5 | call SquareGame.run 1 6 | pop temp 0 7 | push local 0 8 | call SquareGame.dispose 1 9 | pop temp 0 10 | push constant 0 11 | return 12 | -------------------------------------------------------------------------------- /07/commands/neg_command.rb: -------------------------------------------------------------------------------- 1 | class NegCommand 2 | def initialize(id, filename, current_function) 3 | end 4 | 5 | def emit 6 | <<-ASM 7 | // neg 8 | @SP 9 | M=M-1 10 | A=M 11 | M=-M 12 | @SP 13 | M=M+1 14 | ASM 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /07/commands/not_command.rb: -------------------------------------------------------------------------------- 1 | class NotCommand 2 | def initialize(id, filename, current_function) 3 | end 4 | 5 | def emit 6 | <<-ASM 7 | // not 8 | @SP 9 | M=M-1 10 | A=M 11 | M=!M 12 | @SP 13 | M=M+1 14 | ASM 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /13/more fun to go.txt: -------------------------------------------------------------------------------- 1 | See Chapter 13. It's your call! 2 | 3 | And, if you develop something cool, please let us know about it. 4 | 5 | We hope that you enjoyed the ride! 6 | 7 | -- Noam and Shimon 8 | 9 | nand2tetris.gmail.com 10 | www.nand2tetris.org -------------------------------------------------------------------------------- /01/Not16.out: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0000000000000000 | 1111111111111111 | 3 | | 1111111111111111 | 0000000000000000 | 4 | | 1010101010101010 | 0101010101010101 | 5 | | 0011110011000011 | 1100001100111100 | 6 | | 0001001000110100 | 1110110111001011 | 7 | -------------------------------------------------------------------------------- /01/Not16.cmp: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0000000000000000 | 1111111111111111 | 3 | | 1111111111111111 | 0000000000000000 | 4 | | 1010101010101010 | 0101010101010101 | 5 | | 0011110011000011 | 1100001100111100 | 6 | | 0001001000110100 | 1110110111001011 | 7 | -------------------------------------------------------------------------------- /04/mult/Mult.out: -------------------------------------------------------------------------------- 1 | | RAM[0] | RAM[1] | RAM[2] | 2 | | 0 | 0 | 0 | 3 | | 1 | 0 | 0 | 4 | | 0 | 2 | 0 | 5 | | 3 | 1 | 3 | 6 | | 2 | 4 | 8 | 7 | | 6 | 7 | 42 | 8 | -------------------------------------------------------------------------------- /11/Pong/Main.vm: -------------------------------------------------------------------------------- 1 | function Main.main 1 2 | call PongGame.newInstance 0 3 | pop temp 0 4 | call PongGame.getInstance 0 5 | pop local 0 6 | push local 0 7 | call PongGame.run 1 8 | pop temp 0 9 | push local 0 10 | call PongGame.dispose 1 11 | pop temp 0 12 | push constant 0 13 | return -------------------------------------------------------------------------------- /04/mult/Mult.cmp: -------------------------------------------------------------------------------- 1 | | RAM[0] | RAM[1] | RAM[2] | 2 | | 0 | 0 | 0 | 3 | | 1 | 0 | 0 | 4 | | 0 | 2 | 0 | 5 | | 3 | 1 | 3 | 6 | | 2 | 4 | 8 | 7 | | 6 | 7 | 42 | 8 | -------------------------------------------------------------------------------- /12/ArrayTest/Array.vm: -------------------------------------------------------------------------------- 1 | function Array.new 1 2 | push argument 0 3 | call Memory.alloc 1 4 | pop local 0 5 | push local 0 6 | return 7 | function Array.dispose 0 8 | push argument 0 9 | pop pointer 0 10 | push pointer 0 11 | call Memory.deAlloc 1 12 | pop temp 0 13 | push constant 0 14 | return 15 | -------------------------------------------------------------------------------- /06/add/Add.asm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/06/add/Add.asm 5 | 6 | // Computes R0 = 2 + 3 7 | 8 | @2 9 | D=A 10 | @3 11 | D=D+A 12 | @0 13 | M=D 14 | -------------------------------------------------------------------------------- /07/StackArithmetic/SimpleAdd/SimpleAdd.asm: -------------------------------------------------------------------------------- 1 | @7 2 | D=A 3 | @SP 4 | A=M 5 | M=D 6 | @SP 7 | M=M+1 8 | @8 9 | D=A 10 | @SP 11 | A=M 12 | M=D 13 | @SP 14 | M=M+1 15 | @SP 16 | A=M 17 | A=A-1 18 | A=A-1 19 | D=M 20 | A=A+1 21 | D=D+M 22 | @SP 23 | M=M-1 24 | A=M 25 | A=A-1 26 | M=D -------------------------------------------------------------------------------- /10/nodes/return_statement_node.rb: -------------------------------------------------------------------------------- 1 | class ReturnStatementNode < Struct.new(:value_expression) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | builder.returnStatement do |xml| 5 | xml.keyword('return') 6 | xml.symbol(';') 7 | end 8 | builder.target! 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /12/MathTest/MathTest.cmp: -------------------------------------------------------------------------------- 1 | |RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]|RAM[8004]|RAM[8005]|RAM[8006]|RAM[8007]|RAM[8008]|RAM[8009]|RAM[8010]|RAM[8011]|RAM[8012]|RAM[8013]| 2 | | 6 | -180 | -18000 | -18000 | 0 | 3 | -3000 | 0 | 3 | 181 | 123 | 123 | 27 | 32767 | 3 | -------------------------------------------------------------------------------- /12/MathTest/MathTest.out: -------------------------------------------------------------------------------- 1 | |RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]|RAM[8004]|RAM[8005]|RAM[8006]|RAM[8007]|RAM[8008]|RAM[8009]|RAM[8010]|RAM[8011]|RAM[8012]|RAM[8013]| 2 | | 6 | -180 | -18000 | -18000 | 0 | 3 | -3000 | 0 | 3 | 181 | 123 | 123 | 27 | 32767 | 3 | -------------------------------------------------------------------------------- /10/nodes/do_statement_node.rb: -------------------------------------------------------------------------------- 1 | class DoStatementNode < Struct.new(:call) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | builder.doStatement do |xml| 5 | xml.keyword('do') 6 | xml << call.to_xml 7 | xml.symbol(';') 8 | end 9 | builder.target! 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /07/commands/label_command.rb: -------------------------------------------------------------------------------- 1 | class LabelCommand 2 | def initialize(id, filename, current_function, label) 3 | @current_function = current_function 4 | @label = label 5 | end 6 | 7 | def emit 8 | <<-ASM 9 | // label #{@label} 10 | (#{@current_function}$#{@label}) 11 | ASM 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /07/commands/add_command.rb: -------------------------------------------------------------------------------- 1 | class AddCommand 2 | def initialize(id, filename, current_function) 3 | end 4 | 5 | def emit 6 | <<-ASM 7 | // add 8 | @SP 9 | A=M 10 | A=A-1 11 | A=A-1 12 | D=M 13 | A=A+1 14 | D=D+M 15 | @SP 16 | M=M-1 17 | M=M-1 18 | A=M 19 | M=D 20 | @SP 21 | M=M+1 22 | ASM 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /07/commands/and_command.rb: -------------------------------------------------------------------------------- 1 | class AndCommand 2 | def initialize(id, filename, current_function) 3 | end 4 | 5 | def emit 6 | <<-ASM 7 | // and 8 | @SP 9 | A=M 10 | A=A-1 11 | A=A-1 12 | D=M 13 | A=A+1 14 | D=D&M 15 | @SP 16 | M=M-1 17 | M=M-1 18 | A=M 19 | M=D 20 | @SP 21 | M=M+1 22 | ASM 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /07/commands/or_command.rb: -------------------------------------------------------------------------------- 1 | class OrCommand 2 | def initialize(id, filename, current_function) 3 | end 4 | 5 | def emit 6 | <<-ASM 7 | // or 8 | @SP 9 | A=M 10 | A=A-1 11 | A=A-1 12 | D=M 13 | A=A+1 14 | D=D|M 15 | @SP 16 | M=M-1 17 | M=M-1 18 | A=M 19 | M=D 20 | @SP 21 | M=M+1 22 | ASM 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /07/commands/sub_command.rb: -------------------------------------------------------------------------------- 1 | class SubCommand 2 | def initialize(id, filename, current_function) 3 | end 4 | 5 | def emit 6 | <<-ASM 7 | // sub 8 | @SP 9 | A=M 10 | A=A-1 11 | A=A-1 12 | D=M 13 | A=A+1 14 | D=D-M 15 | @SP 16 | M=M-1 17 | M=M-1 18 | A=M 19 | M=D 20 | @SP 21 | M=M+1 22 | ASM 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /07/commands/goto_command.rb: -------------------------------------------------------------------------------- 1 | class GotoCommand 2 | def initialize(id, filename, current_function, label) 3 | @current_function = current_function 4 | @label = label 5 | end 6 | 7 | def emit 8 | <<-ASM 9 | // goto #{@label} 10 | @#{@current_function}$#{@label} 11 | 0;JMP 12 | ASM 13 | end 14 | end 15 | 16 | -------------------------------------------------------------------------------- /11/nodes/class_variable_declaration_node.rb: -------------------------------------------------------------------------------- 1 | class ClassVariableDeclarationNode < Struct.new(:name, :type, :kind) 2 | def emit(writer, symbols) 3 | case kind.to_sym 4 | when :field 5 | symbols.define_field(name, type) 6 | when :static 7 | symbols.define_static(name, type) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /10/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (3.2.9) 5 | i18n (~> 0.6) 6 | multi_json (~> 1.0) 7 | builder (3.1.4) 8 | i18n (0.6.1) 9 | multi_json (1.5.0) 10 | 11 | PLATFORMS 12 | ruby 13 | 14 | DEPENDENCIES 15 | activesupport (~> 3.2.9) 16 | builder (~> 3.1.4) 17 | -------------------------------------------------------------------------------- /11/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (3.2.10) 5 | i18n (~> 0.6) 6 | multi_json (~> 1.0) 7 | builder (3.1.4) 8 | i18n (0.6.1) 9 | multi_json (1.5.0) 10 | 11 | PLATFORMS 12 | ruby 13 | 14 | DEPENDENCIES 15 | activesupport (~> 3.2.9) 16 | builder (~> 3.1.4) 17 | -------------------------------------------------------------------------------- /01/Mux.out: -------------------------------------------------------------------------------- 1 | | a | b | sel | out | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 1 | 0 | 4 | | 0 | 1 | 0 | 0 | 5 | | 0 | 1 | 1 | 1 | 6 | | 1 | 0 | 0 | 1 | 7 | | 1 | 0 | 1 | 0 | 8 | | 1 | 1 | 0 | 1 | 9 | | 1 | 1 | 1 | 1 | 10 | -------------------------------------------------------------------------------- /07/commands/bootstrap_command.rb: -------------------------------------------------------------------------------- 1 | class BootstrapCommand 2 | def initialize 3 | end 4 | 5 | def emit 6 | output = <<-ASM 7 | // bootstrap 8 | @256 9 | D=A 10 | @SP 11 | M=D 12 | 13 | ASM 14 | call = CallCommand.new("bootstrap", "bootstrap", "bootstrap", "Sys.init", 0) 15 | output += call.emit 16 | output 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /07/StackArithmetic/SimpleAdd/SimpleAdd.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/StackArithmetic/SimpleAdd/SimpleAdd.vm 5 | 6 | // Pushes and adds two constants. 7 | push constant 7 8 | push constant 8 9 | add 10 | -------------------------------------------------------------------------------- /10/nodes/parameter_node.rb: -------------------------------------------------------------------------------- 1 | class ParameterNode < Struct.new(:name, :type) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | if Tokenizer::Keywords.include?(type) 5 | builder.keyword(type) 6 | else 7 | builder.identifier(type) 8 | end 9 | 10 | builder.identifier(name) 11 | builder.target! 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /01/Mux.cmp: -------------------------------------------------------------------------------- 1 | | a | b | sel | out | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 1 | 0 | 4 | | 0 | 1 | 0 | 0 | 5 | | 0 | 1 | 1 | 1 | 6 | | 1 | 0 | 0 | 1 | 7 | | 1 | 0 | 1 | 0 | 8 | | 1 | 1 | 0 | 1 | 9 | | 1 | 1 | 1 | 1 | 10 | -------------------------------------------------------------------------------- /01/Not.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Not.hdl 5 | 6 | /** 7 | * Not gate: out = not in 8 | */ 9 | 10 | CHIP Not { 11 | IN in; 12 | OUT out; 13 | 14 | PARTS: 15 | Nand(a=in, b=in, out=out); 16 | } 17 | -------------------------------------------------------------------------------- /06/max/MaxL.hack: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | 1111110000010000 3 | 0000000000000001 4 | 1111010011010000 5 | 0000000000001010 6 | 1110001100000001 7 | 0000000000000001 8 | 1111110000010000 9 | 0000000000001100 10 | 1110101010000111 11 | 0000000000000000 12 | 1111110000010000 13 | 0000000000000010 14 | 1110001100001000 15 | 0000000000001110 16 | 1110101010000111 -------------------------------------------------------------------------------- /07/commands/if_goto_command.rb: -------------------------------------------------------------------------------- 1 | class IfGotoCommand 2 | def initialize(id, filename, current_function, label) 3 | @current_function = current_function 4 | @label = label 5 | end 6 | 7 | def emit 8 | <<-ASM 9 | // if-goto #{@label} 10 | @SP 11 | M=M-1 12 | A=M 13 | D=M 14 | @#{@current_function}$#{@label} 15 | D;JNE 16 | ASM 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /11/nodes/string_term_node.rb: -------------------------------------------------------------------------------- 1 | class StringTermNode < Struct.new(:value) 2 | def emit(writer, symbols) 3 | writer.write_push(:constant, value.length) 4 | writer.write_call('String.new', 1) 5 | value.each_codepoint do |char| 6 | writer.write_push(:constant, char) 7 | writer.write_call('String.appendChar', 2) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /05/Max.hack: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | 1111110000010000 3 | 0000000000000001 4 | 1111010011010000 5 | 0000000000001010 6 | 1110001100000001 7 | 0000000000000001 8 | 1111110000010000 9 | 0000000000001100 10 | 1110101010000111 11 | 0000000000000000 12 | 1111110000010000 13 | 0000000000000010 14 | 1110001100001000 15 | 0000000000001110 16 | 1110101010000111 17 | -------------------------------------------------------------------------------- /11/nodes/unary_operation_node.rb: -------------------------------------------------------------------------------- 1 | class UnaryOperationNode < Struct.new(:operator, :term) 2 | def emit(writer, symbols) 3 | term.emit(writer, symbols) 4 | 5 | case operator 6 | when '-' 7 | writer.write_arithmetic(:neg) 8 | when '~' 9 | writer.write_arithmetic(:not) 10 | else 11 | raise "Unknown operation #{operator}" 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /01/DMux4Way.out: -------------------------------------------------------------------------------- 1 | | in | sel | a | b | c | d | 2 | | 0 | 00 | 0 | 0 | 0 | 0 | 3 | | 0 | 01 | 0 | 0 | 0 | 0 | 4 | | 0 | 10 | 0 | 0 | 0 | 0 | 5 | | 0 | 11 | 0 | 0 | 0 | 0 | 6 | | 1 | 00 | 1 | 0 | 0 | 0 | 7 | | 1 | 01 | 0 | 1 | 0 | 0 | 8 | | 1 | 10 | 0 | 0 | 1 | 0 | 9 | | 1 | 11 | 0 | 0 | 0 | 1 | 10 | -------------------------------------------------------------------------------- /07/StackArithmetic/StackTest/SimpleTest.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/StackArithmetic/StackTest/StackTest.vm 5 | 6 | // Executes a sequence of arithmetic and logical operations 7 | // on the stack. 8 | push constant 17 9 | push constant 17 10 | eq 11 | -------------------------------------------------------------------------------- /01/DMux4Way.cmp: -------------------------------------------------------------------------------- 1 | | in | sel | a | b | c | d | 2 | | 0 | 00 | 0 | 0 | 0 | 0 | 3 | | 0 | 01 | 0 | 0 | 0 | 0 | 4 | | 0 | 10 | 0 | 0 | 0 | 0 | 5 | | 0 | 11 | 0 | 0 | 0 | 0 | 6 | | 1 | 00 | 1 | 0 | 0 | 0 | 7 | | 1 | 01 | 0 | 1 | 0 | 0 | 8 | | 1 | 10 | 0 | 0 | 1 | 0 | 9 | | 1 | 11 | 0 | 0 | 0 | 1 | 10 | -------------------------------------------------------------------------------- /01/Not.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Not.tst 5 | 6 | load Not.hdl, 7 | output-file Not.out, 8 | compare-to Not.cmp, 9 | output-list in%B3.1.3 out%B3.1.3; 10 | 11 | set in 0, 12 | eval, 13 | output; 14 | 15 | set in 1, 16 | eval, 17 | output; 18 | -------------------------------------------------------------------------------- /04/fill/Fill.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/04/fill/Fill.tst 5 | 6 | load Fill.hack; 7 | echo "First, make sure that 'No Animation' is selected. Then, select the Keyboard icon, click on any key and inspect the screen."; 8 | 9 | repeat { 10 | ticktock; 11 | } 12 | -------------------------------------------------------------------------------- /01/And.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/And.hdl 5 | 6 | /** 7 | * And gate: out = 1 if {a == 1 and b == 1}, 0 otherwise 8 | */ 9 | 10 | CHIP And { 11 | IN a, b; 12 | OUT out; 13 | 14 | PARTS: 15 | Nand(a=a, b=b, out=temp); 16 | Not(in=temp, out=out); 17 | } 18 | -------------------------------------------------------------------------------- /02/FullAdder.out: -------------------------------------------------------------------------------- 1 | | a | b | c | sum | carry | 2 | | 0 | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 1 | 1 | 0 | 4 | | 0 | 1 | 0 | 1 | 0 | 5 | | 0 | 1 | 1 | 0 | 1 | 6 | | 1 | 0 | 0 | 1 | 0 | 7 | | 1 | 0 | 1 | 0 | 1 | 8 | | 1 | 1 | 0 | 0 | 1 | 9 | | 1 | 1 | 1 | 1 | 1 | 10 | -------------------------------------------------------------------------------- /06/max/MaxL.asm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/06/max/MaxL.asm 5 | 6 | // Symbol-less version of the Max.asm program. 7 | 8 | @0 9 | D=M 10 | @1 11 | D=D-M 12 | @10 13 | D;JGT 14 | @1 15 | D=M 16 | @12 17 | 0;JMP 18 | @0 19 | D=M 20 | @2 21 | M=D 22 | @14 23 | 0;JMP 24 | -------------------------------------------------------------------------------- /01/And16.out: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 0000000000000000 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111111 | 5 | | 1010101010101010 | 0101010101010101 | 0000000000000000 | 6 | | 0011110011000011 | 0000111111110000 | 0000110011000000 | 7 | | 0001001000110100 | 1001100001110110 | 0001000000110100 | 8 | -------------------------------------------------------------------------------- /01/Or16.out: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 1111111111111111 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111111 | 5 | | 1010101010101010 | 0101010101010101 | 1111111111111111 | 6 | | 0011110011000011 | 0000111111110000 | 0011111111110011 | 7 | | 0001001000110100 | 1001100001110110 | 1001101001110110 | 8 | -------------------------------------------------------------------------------- /02/Add16.out: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 1111111111111111 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111110 | 5 | | 1010101010101010 | 0101010101010101 | 1111111111111111 | 6 | | 0011110011000011 | 0000111111110000 | 0100110010110011 | 7 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 8 | -------------------------------------------------------------------------------- /02/FullAdder.cmp: -------------------------------------------------------------------------------- 1 | | a | b | c | sum | carry | 2 | | 0 | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 1 | 1 | 0 | 4 | | 0 | 1 | 0 | 1 | 0 | 5 | | 0 | 1 | 1 | 0 | 1 | 6 | | 1 | 0 | 0 | 1 | 0 | 7 | | 1 | 0 | 1 | 0 | 1 | 8 | | 1 | 1 | 0 | 0 | 1 | 9 | | 1 | 1 | 1 | 1 | 1 | 10 | -------------------------------------------------------------------------------- /04/mult/Mult.hack: -------------------------------------------------------------------------------- 1 | 0000000000010000 2 | 1110101010001000 3 | 0000000000000010 4 | 1110101010001000 5 | 0000000000010000 6 | 1111110000010000 7 | 0000000000000001 8 | 1111010011010000 9 | 0000000000010010 10 | 1110001100000011 11 | 0000000000000000 12 | 1111110000010000 13 | 0000000000000010 14 | 1111000010001000 15 | 0000000000010000 16 | 1111110111001000 17 | 0000000000000100 18 | 1110101010000111 19 | 0000000000010010 20 | 1110101010000111 21 | -------------------------------------------------------------------------------- /10/nodes/subroutine_call_node.rb: -------------------------------------------------------------------------------- 1 | class SubroutineCallNode < Struct.new(:target, :name, :arguments) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | unless target.nil? 5 | builder.identifier(target) 6 | builder.symbol('.') 7 | end 8 | 9 | builder.identifier(name) 10 | builder.symbol('(') 11 | builder.expressionList 12 | builder.symbol(')') 13 | 14 | builder.target! 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /01/And16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 0000000000000000 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111111 | 5 | | 1010101010101010 | 0101010101010101 | 0000000000000000 | 6 | | 0011110011000011 | 0000111111110000 | 0000110011000000 | 7 | | 0001001000110100 | 1001100001110110 | 0001000000110100 | 8 | -------------------------------------------------------------------------------- /01/Or16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 1111111111111111 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111111 | 5 | | 1010101010101010 | 0101010101010101 | 1111111111111111 | 6 | | 0011110011000011 | 0000111111110000 | 0011111111110011 | 7 | | 0001001000110100 | 1001100001110110 | 1001101001110110 | 8 | -------------------------------------------------------------------------------- /02/Add16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 1111111111111111 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111110 | 5 | | 1010101010101010 | 0101010101010101 | 1111111111111111 | 6 | | 0011110011000011 | 0000111111110000 | 0100110010110011 | 7 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 8 | -------------------------------------------------------------------------------- /11/nodes/parameter_node.rb: -------------------------------------------------------------------------------- 1 | class ParameterNode < Struct.new(:name, :type) 2 | def emit(writer, symbols) 3 | symbols.define_argument(name, type) 4 | end 5 | 6 | def to_xml 7 | builder = Builder::XmlMarkup.new 8 | if Tokenizer::Keywords.include?(type) 9 | builder.keyword(type) 10 | else 11 | builder.identifier(type) 12 | end 13 | 14 | builder.identifier(name) 15 | builder.target! 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /01/Or.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Or.hdl 5 | 6 | /** 7 | * Or gate: out = 1 if {a == 1 or b == 1}, 0 otherwise 8 | */ 9 | 10 | CHIP Or { 11 | IN a, b; 12 | OUT out; 13 | 14 | PARTS: 15 | Not(in=a, out=nota); 16 | Not(in=b, out=notb); 17 | Nand(a=nota, b=notb, out=out); 18 | } 19 | -------------------------------------------------------------------------------- /12/Main.vm: -------------------------------------------------------------------------------- 1 | function Main.main 1 2 | push constant 6 3 | call String.new 1 4 | push constant 66 5 | call String.appendChar 2 6 | push constant 108 7 | call String.appendChar 2 8 | push constant 97 9 | call String.appendChar 2 10 | push constant 104 11 | call String.appendChar 2 12 | push constant 58 13 | call String.appendChar 2 14 | push constant 32 15 | call String.appendChar 2 16 | call Keyboard.readInt 1 17 | pop local 0 18 | push constant 0 19 | return 20 | -------------------------------------------------------------------------------- /12/ArrayTest/ArrayTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/ArrayTest/ArrayTest.tst 5 | 6 | load, 7 | output-file ArrayTest.out, 8 | compare-to ArrayTest.cmp, 9 | output-list RAM[8000]%D2.6.1 RAM[8001]%D2.6.1 RAM[8002]%D2.6.1 RAM[8003]%D2.6.1; 10 | 11 | repeat 1000000 { 12 | vmstep; 13 | } 14 | 15 | output; 16 | -------------------------------------------------------------------------------- /07/StackArithmetic/StackTest/SimpleTest.asm: -------------------------------------------------------------------------------- 1 | // push constant 17 2 | @17 3 | D=A 4 | @SP 5 | A=M 6 | M=D 7 | @SP 8 | M=M+1 9 | 10 | // push constant 17 11 | @17 12 | D=A 13 | @SP 14 | A=M 15 | M=D 16 | @SP 17 | M=M+1 18 | 19 | // eq 20 | @SP 21 | A=M 22 | A=A-1 23 | A=A-1 24 | D=M 25 | A=A+1 26 | D=D-M 27 | @SP 28 | M=M-1 29 | M=M-1 30 | @TRUE2 31 | D;JEQ 32 | @SP 33 | A=M 34 | M=0 35 | @END2 36 | 0;JMP 37 | 38 | (TRUE2) 39 | @SP 40 | A=M 41 | M=-1 42 | 43 | (END2) 44 | -------------------------------------------------------------------------------- /07/commands/eq_command.rb: -------------------------------------------------------------------------------- 1 | class EqCommand 2 | def initialize(id, filename, current_function) 3 | @id = id 4 | end 5 | 6 | def emit 7 | <<-ASM 8 | // eq 9 | @SP 10 | A=M 11 | A=A-1 12 | A=A-1 13 | D=M 14 | A=A+1 15 | D=D-M 16 | @SP 17 | M=M-1 18 | M=M-1 19 | @TRUE#{@id} 20 | D;JEQ 21 | @SP 22 | A=M 23 | M=0 24 | @END#{@id} 25 | 0;JMP 26 | 27 | (TRUE#{@id}) 28 | @SP 29 | A=M 30 | M=-1 31 | 32 | (END#{@id}) 33 | @SP 34 | M=M+1 35 | ASM 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /07/commands/gt_command.rb: -------------------------------------------------------------------------------- 1 | class GtCommand 2 | def initialize(id, filename, current_function) 3 | @id = id 4 | end 5 | 6 | def emit 7 | <<-ASM 8 | // gt 9 | @SP 10 | A=M 11 | A=A-1 12 | A=A-1 13 | D=M 14 | A=A+1 15 | D=D-M 16 | @SP 17 | M=M-1 18 | M=M-1 19 | @TRUE#{@id} 20 | D;JGT 21 | @SP 22 | A=M 23 | M=0 24 | @END#{@id} 25 | 0;JMP 26 | 27 | (TRUE#{@id}) 28 | @SP 29 | A=M 30 | M=-1 31 | 32 | (END#{@id}) 33 | @SP 34 | M=M+1 35 | ASM 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /07/commands/lt_command.rb: -------------------------------------------------------------------------------- 1 | class LtCommand 2 | def initialize(id, filename, current_function) 3 | @id = id 4 | end 5 | 6 | def emit 7 | <<-ASM 8 | // lt 9 | @SP 10 | A=M 11 | A=A-1 12 | A=A-1 13 | D=M 14 | A=A+1 15 | D=D-M 16 | @SP 17 | M=M-1 18 | M=M-1 19 | @TRUE#{@id} 20 | D;JLT 21 | @SP 22 | A=M 23 | M=0 24 | @END#{@id} 25 | 0;JMP 26 | 27 | (TRUE#{@id}) 28 | @SP 29 | A=M 30 | M=-1 31 | 32 | (END#{@id}) 33 | @SP 34 | M=M+1 35 | ASM 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /10/nodes/variable_declaration_node.rb: -------------------------------------------------------------------------------- 1 | class VariableDeclarationNode < Struct.new(:name, :type) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | builder.varDec do |xml| 5 | xml.keyword('var') 6 | if Tokenizer::Keywords.include?(type) 7 | xml.keyword(type) 8 | else 9 | xml.identifier(type) 10 | end 11 | xml.identifier(name) 12 | xml.symbol(';') 13 | end 14 | builder.target! 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /11/Pong/Array.vm: -------------------------------------------------------------------------------- 1 | function Array.new 0 2 | push argument 0 3 | push constant 0 4 | gt 5 | not 6 | if-goto IF_TRUE0 7 | goto IF_FALSE0 8 | label IF_TRUE0 9 | push constant 2 10 | call Sys.error 1 11 | pop temp 0 12 | label IF_FALSE0 13 | push argument 0 14 | call Memory.alloc 1 15 | return 16 | function Array.dispose 0 17 | push argument 0 18 | pop pointer 0 19 | push pointer 0 20 | call Memory.deAlloc 1 21 | pop temp 0 22 | push constant 0 23 | return 24 | -------------------------------------------------------------------------------- /07/MemoryAccess/StaticTest/StaticTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/StaticTest/StaticTest.tst 5 | 6 | load StaticTest.asm, 7 | output-file StaticTest.out, 8 | compare-to StaticTest.cmp, 9 | output-list RAM[256]%D1.6.1; 10 | 11 | set RAM[0] 256, 12 | 13 | repeat 200 { 14 | ticktock; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /07/MemoryAccess/StaticTest/StaticTestVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/StaticTest/StaticTestVME.tst 5 | 6 | load StaticTest.vm, 7 | output-file StaticTest.out, 8 | compare-to StaticTest.cmp, 9 | output-list RAM[256]%D1.6.1; 10 | 11 | set sp 256, 12 | 13 | repeat 11 { 14 | vmstep; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /02/Inc16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/Inc16.hdl 5 | 6 | /** 7 | * 16-bit incrementer. out = in + 1 (16-bit addition). 8 | * Overflow is neither detected nor handled. 9 | */ 10 | 11 | CHIP Inc16 { 12 | IN in[16]; 13 | OUT out[16]; 14 | 15 | PARTS: 16 | Add16(a=in, b[0]=true, b[1..15]=false, out=out); 17 | } 18 | -------------------------------------------------------------------------------- /10/nodes/class_variable_declaration_node.rb: -------------------------------------------------------------------------------- 1 | class ClassVariableDeclarationNode < Struct.new(:name, :type, :kind) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | builder.classVarDec do |xml| 5 | xml.keyword(kind) 6 | if Tokenizer::Keywords.include?(type) 7 | xml.keyword(type) 8 | else 9 | xml.identifier(type) 10 | end 11 | xml.identifier(name) 12 | xml.symbol(';') 13 | end 14 | builder.target! 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /11/Seven/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/11/Seven/Main.jack 5 | 6 | /** 7 | * Computes the value of 1 + (2 * 3) and prints the result 8 | * at the top-left of the screen. 9 | */ 10 | class Main { 11 | 12 | function void main() { 13 | do Output.printInt(1 + (2 * 3)); 14 | return; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /11/nodes/do_statement_node.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | class DoStatementNode < Struct.new(:call) 4 | extend Forwardable 5 | 6 | def emit(writer, symbols) 7 | call.emit(writer, symbols) 8 | writer.write_pop(:temp, 0) 9 | end 10 | 11 | def to_xml 12 | builder = Builder::XmlMarkup.new 13 | builder.doStatement do |xml| 14 | xml.keyword('do') 15 | xml << call.to_xml 16 | xml.symbol(';') 17 | end 18 | builder.target! 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /01/DMux.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/DMux.hdl 5 | 6 | /** 7 | * Dmultiplexor. 8 | * {a,b} = {in,0} if sel == 0 9 | * {0,in} if sel == 1 10 | */ 11 | 12 | CHIP DMux { 13 | IN in, sel; 14 | OUT a, b; 15 | 16 | PARTS: 17 | Not(in=sel, out=notsel); 18 | And(a=in, b=notsel, out=a); 19 | And(a=in, b=sel, out=b); 20 | } 21 | -------------------------------------------------------------------------------- /01/Mux.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux.hdl 5 | 6 | /** 7 | * Multiplexor. If sel == 1 then out = b else out = a. 8 | */ 9 | 10 | CHIP Mux { 11 | IN a, b, sel; 12 | OUT out; 13 | 14 | PARTS: 15 | Not(in=sel, out=notsel); 16 | And(a=a, b=notsel, out=t1); 17 | And(a=b, b=sel, out=t2); 18 | Or(a=t1, b=t2, out=out); 19 | } 20 | -------------------------------------------------------------------------------- /07/StackArithmetic/SimpleAdd/SimpleAdd.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/StackArithmetic/SimpleAdd/SimpleAdd.tst 5 | 6 | load SimpleAdd.asm, 7 | output-file SimpleAdd.out, 8 | compare-to SimpleAdd.cmp, 9 | output-list RAM[0]%D2.6.2 RAM[256]%D2.6.2; 10 | 11 | set RAM[0] 256, 12 | 13 | repeat 60 { 14 | ticktock; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /07/StackArithmetic/SimpleAdd/SimpleAddVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/StackArithmetic/SimpleAdd/SimpleAddVME.tst 5 | 6 | load SimpleAdd.vm, 7 | output-file SimpleAdd.out, 8 | compare-to SimpleAdd.cmp, 9 | output-list RAM[0]%D2.6.2 RAM[256]%D2.6.2; 10 | 11 | set RAM[0] 256, 12 | 13 | repeat 3 { 14 | vmstep; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /12/MemoryTest/MemoryTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/MemoryTest/MemoryTest.tst 5 | 6 | load, 7 | output-file MemoryTest.out, 8 | compare-to MemoryTest.cmp, 9 | output-list RAM[8000]%D2.6.1 RAM[8001]%D2.6.1 RAM[8002]%D2.6.1 RAM[8003]%D2.6.1 RAM[8004]%D2.6.1 RAM[8005]%D2.6.1; 10 | 11 | repeat 1000000 { 12 | vmstep; 13 | } 14 | 15 | output; 16 | -------------------------------------------------------------------------------- /08/FunctionCalls/SimpleFunction/SimpleFunction.vm.bak: -------------------------------------------------------------------------------- 1 | / This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm 5 | 6 | // Performs a simple calculation and returns the result. 7 | function SimpleFunction.test 2 8 | push local 0 9 | push local 1 10 | add 11 | not 12 | push argument 0 13 | add 14 | push argument 1 15 | sub 16 | return 17 | -------------------------------------------------------------------------------- /01/Xor.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Xor.hdl 5 | 6 | /** 7 | * Exclusive-or gate: out = !(a == b). 8 | */ 9 | 10 | CHIP Xor { 11 | IN a, b; 12 | OUT out; 13 | 14 | PARTS: 15 | Not(in=a, out=nota); 16 | Not(in=b, out=notb); 17 | 18 | And(a=a, b=notb, out=w1); 19 | And(a=nota, b=b, out=w2); 20 | 21 | Or(a=w1, b=w2, out=out); 22 | } 23 | -------------------------------------------------------------------------------- /08/FunctionCalls/StaticsTest/StaticsTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/StaticsTest/StaticsTest.tst 5 | 6 | load StaticsTest.asm, 7 | output-file StaticsTest.out, 8 | compare-to StaticsTest.cmp, 9 | output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1 RAM[262]%D1.6.1; 10 | 11 | set RAM[0] 256, 12 | 13 | repeat 2500 { 14 | ticktock; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /03/a/Bit.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/a/Bit.hdl 5 | 6 | /** 7 | * 1-bit register. 8 | * If load[t] == 1 then out[t+1] = in[t] 9 | * else out[t+1] = out[t] (no change) 10 | */ 11 | 12 | CHIP Bit { 13 | IN in, load; 14 | OUT out; 15 | 16 | PARTS: 17 | Mux(a=t1, b=in, sel=load, out=w1); 18 | DFF(in=w1, out=t1, out=out); 19 | } 20 | -------------------------------------------------------------------------------- /06/rect/RectL.asm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/06/rect/RectL.asm 5 | 6 | // Symbol-less version of the Rect.asm program. 7 | 8 | @0 9 | D=M 10 | @23 11 | D;JLE 12 | @16 13 | M=D 14 | @16384 15 | D=A 16 | @17 17 | M=D 18 | @17 19 | A=M 20 | M=-1 21 | @17 22 | D=M 23 | @32 24 | D=D+A 25 | @17 26 | M=D 27 | @16 28 | MD=M-1 29 | @10 30 | D;JGT 31 | @23 32 | 0;JMP 33 | -------------------------------------------------------------------------------- /07/MemoryAccess/StaticTest/StaticTest.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/StaticTest/StaticTest.vm 5 | 6 | // Executes pop and push commands using the static segment. 7 | push constant 111 8 | push constant 333 9 | push constant 888 10 | pop static 8 11 | pop static 3 12 | pop static 1 13 | push static 3 14 | push static 1 15 | sub 16 | push static 8 17 | add 18 | -------------------------------------------------------------------------------- /10/nodes/subroutine_body_node.rb: -------------------------------------------------------------------------------- 1 | class SubroutineBodyNode < Struct.new(:vars, :statements) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | builder.subroutineBody do |xml| 5 | xml.symbol('{') 6 | vars.each do |var| 7 | xml << var.to_xml 8 | end 9 | xml.statements do |statements_xml| 10 | statements.each do |statement| 11 | statements_xml << statement.to_xml 12 | end 13 | end 14 | xml.symbol('}') 15 | end 16 | builder.target! 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /11/nodes/return_statement_node.rb: -------------------------------------------------------------------------------- 1 | class ReturnStatementNode < Struct.new(:value_expression) 2 | def emit(writer, symbols) 3 | if value_expression.nil? 4 | writer.write_push(:constant, 0) 5 | else 6 | value_expression.emit(writer, symbols) 7 | end 8 | 9 | writer.write_return 10 | end 11 | 12 | def to_xml 13 | builder = Builder::XmlMarkup.new 14 | builder.returnStatement do |xml| 15 | xml.keyword('return') 16 | xml.symbol(';') 17 | end 18 | builder.target! 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /10/nodes/let_statement_node.rb: -------------------------------------------------------------------------------- 1 | class LetStatementNode < Struct.new(:name, :index_expression, :value_expression) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | builder.letStatement do |xml| 5 | xml.keyword('let') 6 | xml.identifier(name) 7 | xml.symbol('=') 8 | xml.expression do |expression_xml| 9 | expression_xml.term do |term_xml| 10 | term_xml.identifier(value_expression) 11 | end 12 | end 13 | xml.symbol(';') 14 | end 15 | builder.target! 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /07/commands/function_command.rb: -------------------------------------------------------------------------------- 1 | class FunctionCommand 2 | def initialize(id, filename, current_function, function, local_count) 3 | @function = function 4 | @local_count = local_count.to_i 5 | end 6 | 7 | def function_name 8 | @function 9 | end 10 | 11 | def emit 12 | output = <<-ASM 13 | // function #{@function} #{@local_count} 14 | (#{@function}) 15 | ASM 16 | @local_count.times do 17 | output += <<-ASM 18 | @SP 19 | A=M 20 | M=0 21 | @SP 22 | M=M+1 23 | ASM 24 | end 25 | 26 | output 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /08/ProgramFlow/BasicLoop/BasicLoop.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/ProgramFlow/BasicLoop/BasicLoop.tst 5 | 6 | load BasicLoop.asm, 7 | output-file BasicLoop.out, 8 | compare-to BasicLoop.cmp, 9 | output-list RAM[0]%D1.6.1 RAM[256]%D1.6.1; 10 | 11 | set RAM[0] 256, 12 | set RAM[1] 300, 13 | set RAM[2] 400, 14 | set RAM[400] 3, 15 | 16 | repeat 600 { 17 | ticktock; 18 | } 19 | 20 | output; 21 | -------------------------------------------------------------------------------- /01/DMux.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/DMux.tst 5 | 6 | load DMux.hdl, 7 | output-file DMux.out, 8 | compare-to DMux.cmp, 9 | output-list in%B3.1.3 sel%B3.1.3 a%B3.1.3 b%B3.1.3; 10 | 11 | set in 0, 12 | set sel 0, 13 | eval, 14 | output; 15 | 16 | set sel 1, 17 | eval, 18 | output; 19 | 20 | set in 1, 21 | set sel 0, 22 | eval, 23 | output; 24 | 25 | set sel 1, 26 | eval, 27 | output; 28 | -------------------------------------------------------------------------------- /01/Or.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Or.tst 5 | 6 | load Or.hdl, 7 | output-file Or.out, 8 | compare-to Or.cmp, 9 | output-list a%B3.1.3 b%B3.1.3 out%B3.1.3; 10 | 11 | set a 0, 12 | set b 0, 13 | eval, 14 | output; 15 | 16 | set a 0, 17 | set b 1, 18 | eval, 19 | output; 20 | 21 | set a 1, 22 | set b 0, 23 | eval, 24 | output; 25 | 26 | set a 1, 27 | set b 1, 28 | eval, 29 | output; 30 | -------------------------------------------------------------------------------- /08/FunctionCalls/StaticsTest/StaticsTestVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst 5 | 6 | load, // Load all the VM files from the current directory. 7 | output-file StaticsTest.out, 8 | compare-to StaticsTest.cmp, 9 | output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1 RAM[262]%D1.6.1; 10 | 11 | set sp 261, 12 | 13 | repeat 36 { 14 | vmstep; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /08/ProgramFlow/BasicLoop/BasicLoopVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst 5 | 6 | load BasicLoop.vm, 7 | output-file BasicLoop.out, 8 | compare-to BasicLoop.cmp, 9 | output-list RAM[0]%D1.6.1 RAM[256]%D1.6.1; 10 | 11 | set sp 256, 12 | set local 300, 13 | set argument 400, 14 | set argument[0] 3, 15 | 16 | repeat 33 { 17 | vmstep; 18 | } 19 | 20 | output; 21 | -------------------------------------------------------------------------------- /10/nodes/class_node.rb: -------------------------------------------------------------------------------- 1 | class ClassNode < Struct.new(:name, :class_vars, :subroutines) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new(:indent => 2) 4 | builder.class do |xml| 5 | xml.keyword('class') 6 | xml.identifier(name) 7 | xml.symbol('{') 8 | class_vars.each do |class_var| 9 | xml << class_var.to_xml 10 | end 11 | 12 | subroutines.each do |subroutine| 13 | xml << subroutine.to_xml 14 | end 15 | 16 | xml.symbol('}') 17 | end 18 | builder.target! 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /11/nodes/variable_declaration_node.rb: -------------------------------------------------------------------------------- 1 | class VariableDeclarationNode < Struct.new(:name, :type) 2 | def emit(writer, symbols) 3 | symbols.define_local(name, type) 4 | end 5 | 6 | def to_xml 7 | builder = Builder::XmlMarkup.new 8 | builder.varDec do |xml| 9 | xml.keyword('var') 10 | if Tokenizer::Keywords.include?(type) 11 | xml.keyword(type) 12 | else 13 | xml.identifier(type) 14 | end 15 | xml.identifier(name) 16 | xml.symbol(';') 17 | end 18 | builder.target! 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /01/And.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/And.tst 5 | 6 | load And.hdl, 7 | output-file And.out, 8 | compare-to And.cmp, 9 | output-list a%B3.1.3 b%B3.1.3 out%B3.1.3; 10 | 11 | set a 0, 12 | set b 0, 13 | eval, 14 | output; 15 | 16 | set a 0, 17 | set b 1, 18 | eval, 19 | output; 20 | 21 | set a 1, 22 | set b 0, 23 | eval, 24 | output; 25 | 26 | set a 1, 27 | set b 1, 28 | eval, 29 | output; 30 | -------------------------------------------------------------------------------- /01/Xor.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Xor.tst 5 | 6 | load Xor.hdl, 7 | output-file Xor.out, 8 | compare-to Xor.cmp, 9 | output-list a%B3.1.3 b%B3.1.3 out%B3.1.3; 10 | 11 | set a 0, 12 | set b 0, 13 | eval, 14 | output; 15 | 16 | set a 0, 17 | set b 1, 18 | eval, 19 | output; 20 | 21 | set a 1, 22 | set b 0, 23 | eval, 24 | output; 25 | 26 | set a 1, 27 | set b 1, 28 | eval, 29 | output; 30 | -------------------------------------------------------------------------------- /07/StackArithmetic/StackTest/StackTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/StackArithmetic/StackTest/StackTest.tst 5 | 6 | load StackTest.asm, 7 | output-file StackTest.out, 8 | compare-to StackTest.cmp, 9 | output-list RAM[0]%D2.6.2 RAM[256]%D2.6.2 RAM[257]%D2.6.2 10 | RAM[258]%D2.6.2 RAM[259]%D2.6.2; 11 | 12 | set RAM[0] 256, 13 | 14 | repeat 400 { 15 | ticktock; 16 | } 17 | 18 | output; 19 | -------------------------------------------------------------------------------- /07/StackArithmetic/StackTest/StackTestVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/StackArithmetic/StackTest/StackTestVME.tst 5 | 6 | load StackTest.vm, 7 | output-file StackTest.out, 8 | compare-to StackTest.cmp, 9 | output-list RAM[0]%D2.6.2 RAM[256]%D2.6.2 RAM[257]%D2.6.2 10 | RAM[258]%D2.6.2 RAM[259]%D2.6.2; 11 | 12 | set RAM[0] 256, 13 | 14 | repeat 19 { 15 | vmstep; 16 | } 17 | 18 | output; 19 | -------------------------------------------------------------------------------- /05/Rect.hack: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | 1111110000010000 3 | 0000000000010111 4 | 1110001100000110 5 | 0000000000010000 6 | 1110001100001000 7 | 0100000000000000 8 | 1110110000010000 9 | 0000000000010001 10 | 1110001100001000 11 | 0000000000010001 12 | 1111110000100000 13 | 1110111010001000 14 | 0000000000010001 15 | 1111110000010000 16 | 0000000000100000 17 | 1110000010010000 18 | 0000000000010001 19 | 1110001100001000 20 | 0000000000010000 21 | 1111110010011000 22 | 0000000000001010 23 | 1110001100000001 24 | 0000000000010111 25 | 1110101010000111 26 | -------------------------------------------------------------------------------- /06/rect/Rect.hack: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | 1111110000010000 3 | 0000000000010111 4 | 1110001100000110 5 | 0000000000010000 6 | 1110001100001000 7 | 0100000000000000 8 | 1110110000010000 9 | 0000000000010001 10 | 1110001100001000 11 | 0000000000010001 12 | 1111110000100000 13 | 1110111010001000 14 | 0000000000010001 15 | 1111110000010000 16 | 0000000000100000 17 | 1110000010010000 18 | 0000000000010001 19 | 1110001100001000 20 | 0000000000010000 21 | 1111110010011000 22 | 0000000000001010 23 | 1110001100000001 24 | 0000000000010111 25 | 1110101010000111 -------------------------------------------------------------------------------- /06/rect/RectL.hack: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | 1111110000010000 3 | 0000000000010111 4 | 1110001100000110 5 | 0000000000010000 6 | 1110001100001000 7 | 0100000000000000 8 | 1110110000010000 9 | 0000000000010001 10 | 1110001100001000 11 | 0000000000010001 12 | 1111110000100000 13 | 1110111010001000 14 | 0000000000010001 15 | 1111110000010000 16 | 0000000000100000 17 | 1110000010010000 18 | 0000000000010001 19 | 1110001100001000 20 | 0000000000010000 21 | 1111110010011000 22 | 0000000000001010 23 | 1110001100000001 24 | 0000000000010111 25 | 1110101010000111 -------------------------------------------------------------------------------- /04/fill/Fill.hack: -------------------------------------------------------------------------------- 1 | 0110000000000000 2 | 1111110000010000 3 | 0000000000001011 4 | 1110001100000001 5 | 0000000000010000 6 | 1111110000010000 7 | 0100000000000000 8 | 1110000010100000 9 | 1110101010001000 10 | 0000000000010000 11 | 1110101010000111 12 | 0000000000010000 13 | 1111110000010000 14 | 0100000000000000 15 | 1110000010100000 16 | 1110111010001000 17 | 0000000000010000 18 | 1111110111011000 19 | 0010000000000000 20 | 1110010011010000 21 | 0000000000000000 22 | 1110001100000101 23 | 0000000000010000 24 | 1110101010001000 25 | 0000000000000000 26 | 1110101010000111 27 | -------------------------------------------------------------------------------- /07/MemoryAccess/PointerTest/PointerTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/PointerTest/PointerTest.tst 5 | 6 | load PointerTest.asm, 7 | output-file PointerTest.out, 8 | compare-to PointerTest.cmp, 9 | output-list RAM[256]%D1.6.1 RAM[3]%D1.6.1 10 | RAM[4]%D1.6.1 RAM[3032]%D1.6.1 RAM[3046]%D1.6.1; 11 | 12 | set RAM[0] 256, 13 | 14 | repeat 450 { 15 | ticktock; 16 | } 17 | 18 | output; 19 | -------------------------------------------------------------------------------- /07/MemoryAccess/PointerTest/PointerTestVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/PointerTest/PointerTestVME.tst 5 | 6 | load PointerTest.vm, 7 | output-file PointerTest.out, 8 | compare-to PointerTest.cmp, 9 | output-list RAM[256]%D1.6.1 RAM[3]%D1.6.1 RAM[4]%D1.6.1 10 | RAM[3032]%D1.6.1 RAM[3046]%D1.6.1; 11 | 12 | set RAM[0] 256, 13 | 14 | repeat 15 { 15 | vmstep; 16 | } 17 | 18 | output; 19 | -------------------------------------------------------------------------------- /08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst 5 | 6 | load, // Load all the VM files from the current directory 7 | output-file FibonacciElement.out, 8 | compare-to FibonacciElement.cmp, 9 | output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1; 10 | 11 | set sp 261, 12 | 13 | repeat 110 { 14 | vmstep; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /00/And.tst: -------------------------------------------------------------------------------- 1 | // This file is part of the materials accompanying the book 2 | // "The Elements of Computing Systems" by Nisan and Schocken, 3 | // MIT Press. Book site: www.nand2tetris.org 4 | // File name: projects/00/And.tst 5 | 6 | load And.hdl, 7 | output-file And.out, 8 | compare-to And.cmp, 9 | output-list a%B3.1.3 b%B3.1.3 out%B3.1.3; 10 | 11 | set a 0, 12 | set b 0, 13 | eval, 14 | output; 15 | 16 | set a 0, 17 | set b 1, 18 | eval, 19 | output; 20 | 21 | set a 1, 22 | set b 0, 23 | eval, 24 | output; 25 | 26 | set a 1, 27 | set b 1, 28 | eval, 29 | output; -------------------------------------------------------------------------------- /08/FunctionCalls/StaticsTest/Class1.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/StaticsTest/Class1.vm 5 | 6 | // Stores two supplied arguments in static[0] and static[1]. 7 | function Class1.set 0 8 | push argument 0 9 | pop static 0 10 | push argument 1 11 | pop static 1 12 | push constant 0 13 | return 14 | 15 | // Returns static[0] - static[1]. 16 | function Class1.get 0 17 | push static 0 18 | push static 1 19 | sub 20 | return 21 | -------------------------------------------------------------------------------- /08/FunctionCalls/StaticsTest/Class2.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/StaticsTest/Class2.vm 5 | 6 | // Stores two supplied arguments in static[0] and static[1]. 7 | function Class2.set 0 8 | push argument 0 9 | pop static 0 10 | push argument 1 11 | pop static 1 12 | push constant 0 13 | return 14 | 15 | // Returns static[0] - static[1]. 16 | function Class2.get 0 17 | push static 0 18 | push static 1 19 | sub 20 | return 21 | -------------------------------------------------------------------------------- /01/Or8Way.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Or8Way.tst 5 | 6 | load Or8Way.hdl, 7 | output-file Or8Way.out, 8 | compare-to Or8Way.cmp, 9 | output-list in%B2.8.2 out%B2.1.2; 10 | 11 | set in %B00000000, 12 | eval, 13 | output; 14 | 15 | set in %B11111111, 16 | eval, 17 | output; 18 | 19 | set in %B00010000, 20 | eval, 21 | output; 22 | 23 | set in %B00000001, 24 | eval, 25 | output; 26 | 27 | set in %B00100110, 28 | eval, 29 | output; -------------------------------------------------------------------------------- /08/FunctionCalls/FibonacciElement/FibonacciElement.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/FibonacciElement/FibonacciElement.tst 5 | 6 | // FibonacciElement.asm is the result of translating both Main.vm and Sys.vm. 7 | 8 | load FibonacciElement.asm, 9 | output-file FibonacciElement.out, 10 | compare-to FibonacciElement.cmp, 11 | output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1; 12 | 13 | repeat 6000 { 14 | ticktock; 15 | } 16 | 17 | output; 18 | -------------------------------------------------------------------------------- /02/HalfAdder.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/HalfAdder.hdl 5 | 6 | /** 7 | * Half adder. Computes sum, the least significnat bit of a + b, 8 | * and carry, the most significnat bit of a + b. 9 | */ 10 | 11 | CHIP HalfAdder { 12 | IN a, b; // 1-bit inputs 13 | OUT sum, // Right bit of a + b 14 | carry; // Left bit of a + b 15 | 16 | PARTS: 17 | Xor(a=a, b=b, out=sum); 18 | And(a=a, b=b, out=carry); 19 | } 20 | -------------------------------------------------------------------------------- /02/HalfAdder.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/HalfAdder.tst 5 | 6 | load HalfAdder.hdl, 7 | output-file HalfAdder.out, 8 | compare-to HalfAdder.cmp, 9 | output-list a%B3.1.3 b%B3.1.3 sum%B3.1.3 carry%B3.1.3; 10 | 11 | set a 0, 12 | set b 0, 13 | eval, 14 | output; 15 | 16 | set a 0, 17 | set b 1, 18 | eval, 19 | output; 20 | 21 | set a 1, 22 | set b 0, 23 | eval, 24 | output; 25 | 26 | set a 1, 27 | set b 1, 28 | eval, 29 | output; 30 | -------------------------------------------------------------------------------- /11/nodes/while_statement_node.rb: -------------------------------------------------------------------------------- 1 | class WhileStatementNode < Struct.new(:value_expression, :statements) 2 | def emit(writer, symbols) 3 | name = "while_#{SecureRandom.hex}" 4 | loop_name = "#{name}_loop" 5 | end_name = "#{name}_end" 6 | 7 | writer.write_label(loop_name) 8 | value_expression.emit(writer, symbols) 9 | writer.write_arithmetic(:not) 10 | writer.write_if(end_name) 11 | 12 | statements.each do |statement| 13 | statement.emit(writer, symbols) 14 | end 15 | 16 | writer.write_goto(loop_name) 17 | writer.write_label(end_name) 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /09/Square/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/09/Square/Main.jack 5 | 6 | /** 7 | * The Main class initializes a new Square Dance game and starts it. 8 | */ 9 | class Main { 10 | 11 | /** Initializes a new game and starts it. */ 12 | function void main() { 13 | var SquareGame game; 14 | 15 | let game = SquareGame.new(); 16 | do game.run(); 17 | do game.dispose(); 18 | 19 | return; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /10/Square/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/09/Square/Main.jack 5 | 6 | /** 7 | * The Main class initializes a new Square Dance game and starts it. 8 | */ 9 | class Main { 10 | 11 | /** Initializes a new game and starts it. */ 12 | function void main() { 13 | var SquareGame game; 14 | 15 | let game = SquareGame.new(); 16 | do game.run(); 17 | do game.dispose(); 18 | 19 | return; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /11/Pong/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/11/Pong/Main.jack 5 | 6 | /** 7 | * The main class of the Pong game. 8 | */ 9 | class Main { 10 | 11 | /** Initializes the Pong game and starts it. */ 12 | function void main() { 13 | var PongGame game; 14 | 15 | do PongGame.newInstance(); 16 | let game = PongGame.getInstance(); 17 | do game.run(); 18 | do game.dispose(); 19 | 20 | return; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /11/Pong/Main.jack.bak: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/11/pong/Main.jack 5 | 6 | /** 7 | * The main class of the Pong game. 8 | */ 9 | class Main { 10 | 11 | /** Initializes the Pong game and starts it. */ 12 | function void main() { 13 | var PongGame game; 14 | 15 | do PongGame.newInstance(); 16 | let game = PongGame.getInstance(); 17 | do game.run(); 18 | do game.dispose(); 19 | 20 | return; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /11/Square/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/09/Square/Main.jack 5 | 6 | /** 7 | * The Main class initializes a new Square Dance game and starts it. 8 | */ 9 | class Main { 10 | 11 | /** Initializes a new game and starts it. */ 12 | function void main() { 13 | var SquareGame game; 14 | 15 | let game = SquareGame.new(); 16 | do game.run(); 17 | do game.dispose(); 18 | 19 | return; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /01/Or8Way.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Or8Way.hdl 5 | 6 | /** 7 | * 8-way Or gate: out = in[0] Or in[1] Or ... Or in[7]. 8 | */ 9 | 10 | CHIP Or8Way { 11 | IN in[8]; 12 | OUT out; 13 | 14 | PARTS: 15 | Or(a=in[0], b=in[1], out=t1); 16 | Or(a=t1, b=in[2], out=t2); 17 | Or(a=t2, b=in[3], out=t3); 18 | Or(a=t3, b=in[4], out=t4); 19 | Or(a=t4, b=in[5], out=t5); 20 | Or(a=t5, b=in[6], out=t6); 21 | Or(a=t6, b=in[7], out=out); 22 | } 23 | -------------------------------------------------------------------------------- /01/Mux16.out: -------------------------------------------------------------------------------- 1 | | a | b | sel | out | 2 | | 0000000000000000 | 0000000000000000 | 0 | 0000000000000000 | 3 | | 0000000000000000 | 0000000000000000 | 1 | 0000000000000000 | 4 | | 0000000000000000 | 0001001000110100 | 0 | 0000000000000000 | 5 | | 0000000000000000 | 0001001000110100 | 1 | 0001001000110100 | 6 | | 1001100001110110 | 0000000000000000 | 0 | 1001100001110110 | 7 | | 1001100001110110 | 0000000000000000 | 1 | 0000000000000000 | 8 | | 1010101010101010 | 0101010101010101 | 0 | 1010101010101010 | 9 | | 1010101010101010 | 0101010101010101 | 1 | 0101010101010101 | 10 | -------------------------------------------------------------------------------- /02/Inc16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/Inc16.tst 5 | 6 | load Inc16.hdl, 7 | output-file Inc16.out, 8 | compare-to Inc16.cmp, 9 | output-list in%B1.16.1 out%B1.16.1; 10 | 11 | set in %B0000000000000000, // in = 0 12 | eval, 13 | output; 14 | 15 | set in %B1111111111111111, // in = -1 16 | eval, 17 | output; 18 | 19 | set in %B0000000000000101, // in = 5 20 | eval, 21 | output; 22 | 23 | set in %B1111111111111011, // in = -5 24 | eval, 25 | output; 26 | -------------------------------------------------------------------------------- /07/MemoryAccess/PointerTest/PointerTest.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/PointerTest/PointerTest.vm 5 | 6 | // Executes pop and push commands using the 7 | // pointer, this, and that segments. 8 | push constant 3030 9 | pop pointer 0 10 | push constant 3040 11 | pop pointer 1 12 | push constant 32 13 | pop this 2 14 | push constant 46 15 | pop that 6 16 | push pointer 0 17 | push pointer 1 18 | add 19 | push this 2 20 | sub 21 | push that 6 22 | add 23 | -------------------------------------------------------------------------------- /12/MathTest/MathTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/MathTest/MathTest.tst 5 | 6 | load, 7 | output-file MathTest.out, 8 | compare-to MathTest.cmp, 9 | output-list RAM[8000]%D2.6.1 RAM[8001]%D2.6.1 RAM[8002]%D2.6.1 RAM[8003]%D2.6.1 RAM[8004]%D2.6.1 RAM[8005]%D2.6.1 RAM[8006]%D2.6.1 RAM[8007]%D2.6.1 RAM[8008]%D2.6.1 RAM[8009]%D2.6.1 RAM[8010]%D2.6.1 RAM[8011]%D2.6.1 RAM[8012]%D2.6.1 RAM[8013]%D2.6.1; 10 | 11 | repeat 1000000 { 12 | vmstep; 13 | } 14 | 15 | output; 16 | -------------------------------------------------------------------------------- /01/Mux16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | sel | out | 2 | | 0000000000000000 | 0000000000000000 | 0 | 0000000000000000 | 3 | | 0000000000000000 | 0000000000000000 | 1 | 0000000000000000 | 4 | | 0000000000000000 | 0001001000110100 | 0 | 0000000000000000 | 5 | | 0000000000000000 | 0001001000110100 | 1 | 0001001000110100 | 6 | | 1001100001110110 | 0000000000000000 | 0 | 1001100001110110 | 7 | | 1001100001110110 | 0000000000000000 | 1 | 0000000000000000 | 8 | | 1010101010101010 | 0101010101010101 | 0 | 1010101010101010 | 9 | | 1010101010101010 | 0101010101010101 | 1 | 0101010101010101 | 10 | -------------------------------------------------------------------------------- /01/Mux4Way16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux4Way16.hdl 5 | 6 | /** 7 | * 4-way 16-bit multiplexor. 8 | * out = a if sel == 00 9 | * b if sel == 01 10 | * c if sel == 10 11 | * d if sel == 11 12 | */ 13 | 14 | CHIP Mux4Way16 { 15 | IN a[16], b[16], c[16], d[16], sel[2]; 16 | OUT out[16]; 17 | 18 | PARTS: 19 | Mux16(a=a, b=b, sel=sel[0], out=t1); 20 | Mux16(a=c, b=d, sel=sel[0], out=t2); 21 | Mux16(a=t1, b=t2, sel=sel[1], out=out); 22 | } 23 | -------------------------------------------------------------------------------- /01/Not16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Not16.tst 5 | 6 | load Not16.hdl, 7 | output-file Not16.out, 8 | compare-to Not16.cmp, 9 | output-list in%B1.16.1 out%B1.16.1; 10 | 11 | set in %B0000000000000000, 12 | eval, 13 | output; 14 | 15 | set in %B1111111111111111, 16 | eval, 17 | output; 18 | 19 | set in %B1010101010101010, 20 | eval, 21 | output; 22 | 23 | set in %B0011110011000011, 24 | eval, 25 | output; 26 | 27 | set in %B0001001000110100, 28 | eval, 29 | output; -------------------------------------------------------------------------------- /11/nodes/variable_term_node.rb: -------------------------------------------------------------------------------- 1 | class VariableTermNode < Struct.new(:name, :index_expression) 2 | def emit(writer, symbols) 3 | symbol = symbols.lookup(name) 4 | unless symbol.present? 5 | raise "Unable to find symbol #{name}" 6 | end 7 | 8 | kind = symbol.kind 9 | if symbol.kind == :field 10 | kind = :this 11 | end 12 | 13 | writer.write_push(kind, symbol.index) 14 | 15 | if index_expression 16 | index_expression.emit(writer, symbols) 17 | writer.write_arithmetic(:add) 18 | writer.write_pop(:pointer, 1) 19 | writer.write_push(:that, 0) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /01/DMux4Way.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/DMux4Way.hdl 5 | 6 | /** 7 | * 4-way demultiplexor. 8 | * {a,b,c,d} = {in,0,0,0} if sel == 00 9 | * {0,in,0,0} if sel == 01 10 | * {0,0,in,0} if sel == 10 11 | * {0,0,0,in} if sel == 11 12 | */ 13 | 14 | 15 | CHIP DMux4Way { 16 | IN in, sel[2]; 17 | OUT a, b, c, d; 18 | 19 | PARTS: 20 | DMux(in=in, sel=sel[0], a=t1, b=t2); 21 | DMux(in=t1, sel=sel[1], a=a, b=c); 22 | DMux(in=t2, sel=sel[1], a=b, b=d); 23 | } 24 | -------------------------------------------------------------------------------- /08/FunctionCalls/FibonacciElement/Sys.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/FibonacciElement/Sys.vm 5 | 6 | // Pushes n onto the stack and calls the Main.fibonacii function, 7 | // which computes the n'th element of the Fibonacci series. 8 | // The Sys.init function is called "automatically" by the 9 | // bootstrap code. 10 | 11 | function Sys.init 0 12 | push constant 4 13 | call Main.fibonacci 1 // Compute the 4'th fibonacci element 14 | label WHILE 15 | goto WHILE // Loop infinitely 16 | -------------------------------------------------------------------------------- /10/ExpressionlessSquare/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/10/ExpressionlessSquare/Main.jack 5 | 6 | // Expressionless version of Main.jack. 7 | 8 | /** 9 | * The Main class initializes a new Square Dance game and starts it. 10 | */ 11 | class Main { 12 | 13 | // Initializes the square game and starts it. 14 | function void main() { 15 | var SquareGame game; 16 | 17 | let game = game; 18 | do game.run(); 19 | do game.dispose(); 20 | 21 | return; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /00/Xor.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/00/Xor.hdl 5 | 6 | // This file is included here for those who wish to follow the Hardware Simulator Tutorial 7 | // and play with the Xor.hdl implementation. 8 | 9 | /** 10 | * Exclusive-or gate: out = !(a == b). 11 | */ 12 | 13 | CHIP Xor { 14 | 15 | IN a, b; 16 | OUT out; 17 | 18 | PARTS: 19 | Not(in=a, out=nota); 20 | Not(in=b, out=notb); 21 | And(a=a, b=notb, out=w1); 22 | And(a=nota, b=b, out=w2); 23 | Or(a=w1, b=w2, out=out); 24 | } 25 | -------------------------------------------------------------------------------- /04/mult/Mult.asm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/04/Mult.asm 5 | 6 | // Multiplies R0 and R1 and stores the result in R2. 7 | // (R0, R1, R2 refer to RAM[0], RAM[1], and RAM[3], respectively.) 8 | 9 | // Put your code here. 10 | 11 | @i 12 | M=0 13 | @R2 14 | M=0 15 | 16 | (LOOP) 17 | @i 18 | D=M 19 | @R1 20 | D=D-M 21 | @END 22 | D;JGE 23 | 24 | @R0 25 | D=M 26 | @R2 27 | M=D+M 28 | 29 | @i 30 | M=M+1 31 | 32 | @LOOP 33 | 0;JMP 34 | 35 | (END) 36 | @END 37 | 0;JMP 38 | -------------------------------------------------------------------------------- /07/StackArithmetic/StackTest/StackTest.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/StackArithmetic/StackTest/StackTest.vm 5 | 6 | // Executes a sequence of arithmetic and logical operations 7 | // on the stack. 8 | push constant 17 9 | push constant 17 10 | eq 11 | push constant 892 12 | push constant 891 13 | lt 14 | push constant 32767 15 | push constant 32766 16 | gt 17 | push constant 56 18 | push constant 31 19 | push constant 53 20 | add 21 | push constant 112 22 | sub 23 | neg 24 | and 25 | push constant 82 26 | or 27 | 28 | -------------------------------------------------------------------------------- /02/FullAdder.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/FullAdder.hdl 5 | 6 | /** 7 | * Full adder. Computes sum, the least significant bit of 8 | * a + b + c, and carry, the most significant bit of a + b + c. 9 | */ 10 | 11 | CHIP FullAdder { 12 | IN a, b, c; // 1-bit inputs 13 | OUT sum, // Right bit of a + b + c 14 | carry; // Left bit of a + b + c 15 | 16 | PARTS: 17 | HalfAdder(a=a, b=b, sum=w1, carry=c1); 18 | HalfAdder(a=w1, b=c, sum=sum, carry=c2); 19 | Or(a=c1, b=c2, out=carry); 20 | } 21 | -------------------------------------------------------------------------------- /12/Array.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/Array.jack 5 | 6 | /** 7 | * Represents an array. Can be used to hold any type of object. 8 | */ 9 | class Array { 10 | 11 | /** Constructs a new Array of the given size. */ 12 | function Array new(int size) { 13 | var int ptr; 14 | let ptr = Memory.alloc(size); 15 | return ptr; 16 | } 17 | 18 | /** De-allocates the array and frees its space. */ 19 | method void dispose() { 20 | do Memory.deAlloc(this); 21 | return; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /08/FunctionCalls/StaticsTest/Sys.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/StaticsTest/Sys.vm 5 | 6 | // Tests that different functions, stored in two different 7 | // class files, manipulate the static segment correctly. 8 | function Sys.init 0 9 | push constant 6 10 | push constant 8 11 | call Class1.set 2 12 | pop temp 0 // Dumps the return value 13 | push constant 23 14 | push constant 15 15 | call Class2.set 2 16 | pop temp 0 // Dumps the return value 17 | call Class1.get 0 18 | call Class2.get 0 19 | label WHILE 20 | goto WHILE 21 | -------------------------------------------------------------------------------- /12/ArrayTest/Array.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/Array.jack 5 | 6 | /** 7 | * Represents an array. Can be used to hold any type of object. 8 | */ 9 | class Array { 10 | 11 | /** Constructs a new Array of the given size. */ 12 | function Array new(int size) { 13 | var int ptr; 14 | let ptr = Memory.alloc(size); 15 | return ptr; 16 | } 17 | 18 | /** De-allocates the array and frees its space. */ 19 | method void dispose() { 20 | do Memory.deAlloc(this); 21 | return; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /07/MemoryAccess/BasicTest/BasicTestVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/BasicTest/BasicTestVME.tst 5 | 6 | load BasicTest.vm, 7 | output-file BasicTest.out, 8 | compare-to BasicTest.cmp, 9 | output-list RAM[256]%D1.6.1 RAM[300]%D1.6.1 RAM[401]%D1.6.1 10 | RAM[402]%D1.6.1 RAM[3006]%D1.6.1 RAM[3012]%D1.6.1 11 | RAM[3015]%D1.6.1 RAM[11]%D1.6.1; 12 | 13 | set sp 256, 14 | set local 300, 15 | set argument 400, 16 | set this 3000, 17 | set that 3010, 18 | 19 | repeat 25 { 20 | vmstep; 21 | } 22 | 23 | output; 24 | -------------------------------------------------------------------------------- /08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst 5 | 6 | load FibonacciSeries.asm, 7 | output-file FibonacciSeries.out, 8 | compare-to FibonacciSeries.cmp, 9 | output-list RAM[3000]%D1.6.2 RAM[3001]%D1.6.2 RAM[3002]%D1.6.2 10 | RAM[3003]%D1.6.2 RAM[3004]%D1.6.2 RAM[3005]%D1.6.2; 11 | 12 | set RAM[0] 256, 13 | set RAM[1] 300, 14 | set RAM[2] 400, 15 | set RAM[400] 6, 16 | set RAM[401] 3000, 17 | 18 | repeat 1100 { 19 | ticktock; 20 | } 21 | 22 | output; 23 | -------------------------------------------------------------------------------- /00/Xor.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/00/Xor.tst 5 | 6 | // This file is included here for those who wish to follow the Hardware Simulator Tutorial 7 | // and play with the Xor.hdl implementation. 8 | 9 | load Xor.hdl, 10 | output-file Xor.out, 11 | compare-to Xor.cmp, 12 | output-list a%B3.1.3 b%B3.1.3 out%B3.1.3; 13 | 14 | set a 0, 15 | set b 0, 16 | eval, 17 | output; 18 | 19 | set a 0, 20 | set b 1, 21 | eval, 22 | output; 23 | 24 | set a 1, 25 | set b 0, 26 | eval, 27 | output; 28 | 29 | set a 1, 30 | set b 1, 31 | eval, 32 | output; 33 | -------------------------------------------------------------------------------- /07/MemoryAccess/BasicTest/BasicTest.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/BasicTest/BasicTest.tst 5 | 6 | load BasicTest.asm, 7 | output-file BasicTest.out, 8 | compare-to BasicTest.cmp, 9 | output-list RAM[256]%D1.6.1 RAM[300]%D1.6.1 RAM[401]%D1.6.1 10 | RAM[402]%D1.6.1 RAM[3006]%D1.6.1 RAM[3012]%D1.6.1 11 | RAM[3015]%D1.6.1 RAM[11]%D1.6.1; 12 | 13 | set RAM[0] 256, 14 | set RAM[1] 300, 15 | set RAM[2] 400, 16 | set RAM[3] 3000, 17 | set RAM[4] 3010, 18 | 19 | repeat 600 { 20 | ticktock; 21 | } 22 | 23 | output; 24 | -------------------------------------------------------------------------------- /08/ProgramFlow/FibonacciSeries/FibonacciSeriesVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/ProgramFlow/FibonacciSeries/FibonacciSeriesVME.tst 5 | 6 | load FibonacciSeries.vm, 7 | output-file FibonacciSeries.out, 8 | compare-to FibonacciSeries.cmp, 9 | output-list RAM[3000]%D1.6.2 RAM[3001]%D1.6.2 RAM[3002]%D1.6.2 10 | RAM[3003]%D1.6.2 RAM[3004]%D1.6.2 RAM[3005]%D1.6.2; 11 | 12 | set sp 256, 13 | set local 300, 14 | set argument 400, 15 | set argument[0] 6, 16 | set argument[1] 3000, 17 | 18 | repeat 73 { 19 | vmstep; 20 | } 21 | 22 | output; 23 | -------------------------------------------------------------------------------- /09/HelloWorld/Main.vm: -------------------------------------------------------------------------------- 1 | function Main.main 0 2 | push constant 11 3 | call String.new 1 4 | push constant 72 5 | call String.appendChar 2 6 | push constant 101 7 | call String.appendChar 2 8 | push constant 108 9 | call String.appendChar 2 10 | push constant 108 11 | call String.appendChar 2 12 | push constant 111 13 | call String.appendChar 2 14 | push constant 32 15 | call String.appendChar 2 16 | push constant 87 17 | call String.appendChar 2 18 | push constant 111 19 | call String.appendChar 2 20 | push constant 114 21 | call String.appendChar 2 22 | push constant 108 23 | call String.appendChar 2 24 | push constant 100 25 | call String.appendChar 2 26 | call Output.printString 1 27 | pop temp 0 28 | push constant 0 29 | return 30 | -------------------------------------------------------------------------------- /06/rect/Rect.asm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/06/rect/Rect.asm 5 | 6 | // Draws a rectangle at the top-left corner of the screen. 7 | // The rectangle is 16 pixels wide and R0 pixels high. 8 | 9 | @0 10 | D=M 11 | @INFINITE_LOOP 12 | D;JLE 13 | @counter 14 | M=D 15 | @SCREEN 16 | D=A 17 | @address 18 | M=D 19 | (LOOP) 20 | @address 21 | A=M 22 | M=-1 23 | @address 24 | D=M 25 | @32 26 | D=D+A 27 | @address 28 | M=D 29 | @counter 30 | MD=M-1 31 | @LOOP 32 | D;JGT 33 | (INFINITE_LOOP) 34 | @INFINITE_LOOP 35 | 0;JMP 36 | -------------------------------------------------------------------------------- /11/nodes/subroutine_body_node.rb: -------------------------------------------------------------------------------- 1 | class SubroutineBodyNode < Struct.new(:vars, :statements) 2 | def emit(writer, symbols) 3 | vars.each do |var| 4 | var.emit(writer, symbols) 5 | end 6 | 7 | statements.each do |statement| 8 | statement.emit(writer, symbols) 9 | end 10 | end 11 | 12 | def to_xml 13 | builder = Builder::XmlMarkup.new 14 | builder.subroutineBody do |xml| 15 | xml.symbol('{') 16 | vars.each do |var| 17 | xml << var.to_xml 18 | end 19 | xml.statements do |statements_xml| 20 | statements.each do |statement| 21 | statements_xml << statement.to_xml 22 | end 23 | end 24 | xml.symbol('}') 25 | end 26 | builder.target! 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /05/ComputerAdd-external.cmp: -------------------------------------------------------------------------------- 1 | | time |reset|RAM16K[0]|RAM16K[1]|RAM16K[2]| 2 | | 0 | 0 | 0 | 0 | 0 | 3 | | 1 | 0 | 0 | 0 | 0 | 4 | | 2 | 0 | 0 | 0 | 0 | 5 | | 3 | 0 | 0 | 0 | 0 | 6 | | 4 | 0 | 0 | 0 | 0 | 7 | | 5 | 0 | 0 | 0 | 0 | 8 | | 6 | 0 | 5 | 0 | 0 | 9 | | 7 | 1 | 0 | 0 | 0 | 10 | | 8 | 0 | 0 | 0 | 0 | 11 | | 9 | 0 | 0 | 0 | 0 | 12 | | 10 | 0 | 0 | 0 | 0 | 13 | | 11 | 0 | 0 | 0 | 0 | 14 | | 12 | 0 | 0 | 0 | 0 | 15 | | 13 | 0 | 5 | 0 | 0 | 16 | -------------------------------------------------------------------------------- /07/MemoryAccess/BasicTest/BasicTest.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/BasicTest/BasicTest.vm 5 | 6 | // Executes pop & push commands using the virtual memory segments. 7 | push constant 10 8 | pop local 0 9 | push constant 21 10 | push constant 22 11 | pop argument 2 12 | pop argument 1 13 | push constant 36 14 | pop this 6 15 | push constant 42 16 | push constant 45 17 | pop that 5 18 | pop that 2 19 | push constant 510 20 | pop temp 6 21 | push local 0 22 | push that 5 23 | add 24 | push argument 1 25 | sub 26 | push this 6 27 | push this 6 28 | add 29 | sub 30 | push temp 6 31 | add 32 | -------------------------------------------------------------------------------- /07/MemoryAccess/BasicTest/SimpleTest.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/07/MemoryAccess/BasicTest/BasicTest.vm 5 | 6 | // Executes pop & push commands using the virtual memory segments. 7 | push constant 10 8 | pop local 1 9 | push constant 21 10 | push constant 22 11 | pop argument 2 12 | pop argument 1 13 | push constant 36 14 | pop this 6 15 | push constant 42 16 | push constant 45 17 | pop that 5 18 | pop that 2 19 | push constant 510 20 | pop temp 6 21 | push local 0 22 | push that 5 23 | // add 24 | // push argument 1 25 | // sub 26 | // push this 6 27 | // push this 6 28 | // add 29 | // sub 30 | // push temp 6 31 | // add 32 | -------------------------------------------------------------------------------- /11/nodes/if_statement_node.rb: -------------------------------------------------------------------------------- 1 | class IfStatementNode < Struct.new(:value_expression, :statements, :else_statements) 2 | def emit(writer, symbols) 3 | name = "if_#{SecureRandom.hex}" 4 | body_name = "#{name}_body" 5 | else_name = "#{name}_else" 6 | end_name = "#{name}_end" 7 | 8 | value_expression.emit(writer, symbols) 9 | writer.write_if(body_name) 10 | writer.write_goto(else_name) 11 | writer.write_label(body_name) 12 | 13 | statements.each do |statement| 14 | statement.emit(writer, symbols) 15 | end 16 | 17 | writer.write_goto(end_name) 18 | writer.write_label(else_name) 19 | 20 | else_statements.each do |statement| 21 | statement.emit(writer, symbols) 22 | end 23 | 24 | writer.write_label(end_name) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /00/Register.cmp: -------------------------------------------------------------------------------- 1 | | time | in |load | out | 2 | | 0+ | 0 | 0 | 0 | 3 | | 1 | 0 | 0 | 0 | 4 | | 1+ | 0 | 1 | 0 | 5 | | 2 | 0 | 1 | 0 | 6 | | 2+ | -32123 | 0 | 0 | 7 | | 3 | -32123 | 0 | 0 | 8 | | 3+ | 11111 | 0 | 0 | 9 | | 4 | 11111 | 0 | 0 | 10 | | 4+ | -32123 | 1 | 0 | 11 | | 5 | -32123 | 1 | -32123 | 12 | | 5+ | -32123 | 1 | -32123 | 13 | | 6 | -32123 | 1 | -32123 | 14 | | 6+ | -32123 | 0 | -32123 | 15 | | 7 | -32123 | 0 | -32123 | 16 | | 7+ | 12345 | 1 | -32123 | 17 | | 8 | 12345 | 1 | 12345 | 18 | | 8+ | 0 | 0 | 12345 | 19 | | 9 | 0 | 0 | 12345 | 20 | | 9+ | 0 | 1 | 12345 | 21 | | 10 | 0 | 1 | 0 | 22 | -------------------------------------------------------------------------------- /01/DMux4Way.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/DMux4Way.tst 5 | 6 | load DMux4Way.hdl, 7 | output-file DMux4Way.out, 8 | compare-to DMux4Way.cmp, 9 | output-list in%B2.1.2 sel%B2.2.2 a%B2.1.2 b%B2.1.2 c%B2.1.2 d%B2.1.2; 10 | 11 | set in 0, 12 | set sel %B00, 13 | eval, 14 | output; 15 | 16 | set sel %B01, 17 | eval, 18 | output; 19 | 20 | set sel %B10, 21 | eval, 22 | output; 23 | 24 | set sel %B11, 25 | eval, 26 | output; 27 | 28 | set in 1, 29 | set sel %B00, 30 | eval, 31 | output; 32 | 33 | set sel %B01, 34 | eval, 35 | output; 36 | 37 | set sel %B10, 38 | eval, 39 | output; 40 | 41 | set sel %B11, 42 | eval, 43 | output; 44 | -------------------------------------------------------------------------------- /08/ProgramFlow/BasicLoop/BasicLoop.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/ProgramFlow/BasicLoop/BasicLoop.vm 5 | 6 | // Computes the sum 1 + 2 + ... + argument[0] and pushes the 7 | // result onto the stack. Argument[0] is initialized by the test 8 | // script before this code starts running. 9 | push constant 0 10 | pop local 0 // initialize sum = 0 11 | label LOOP_START 12 | push argument 0 13 | push local 0 14 | add 15 | pop local 0 // sum = sum + counter 16 | push argument 0 17 | push constant 1 18 | sub 19 | pop argument 0 // counter-- 20 | push argument 0 21 | if-goto LOOP_START // If counter > 0, goto LOOP_START 22 | push local 0 23 | -------------------------------------------------------------------------------- /02/FullAdder.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/FullAdder.tst 5 | 6 | load FullAdder.hdl, 7 | output-file FullAdder.out, 8 | compare-to FullAdder.cmp, 9 | output-list a%B3.1.3 b%B3.1.3 c%B3.1.3 sum%B3.1.3 carry%B3.1.3; 10 | 11 | set a 0, 12 | set b 0, 13 | set c 0, 14 | eval, 15 | output; 16 | 17 | set c 1, 18 | eval, 19 | output; 20 | 21 | set b 1, 22 | set c 0, 23 | eval, 24 | output; 25 | 26 | set c 1, 27 | eval, 28 | output; 29 | 30 | set a 1, 31 | set b 0, 32 | set c 0, 33 | eval, 34 | output; 35 | 36 | set c 1, 37 | eval, 38 | output; 39 | 40 | set b 1, 41 | set c 0, 42 | eval, 43 | output; 44 | 45 | set c 1, 46 | eval, 47 | output; 48 | -------------------------------------------------------------------------------- /01/Mux.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux.tst 5 | 6 | load Mux.hdl, 7 | output-file Mux.out, 8 | compare-to Mux.cmp, 9 | output-list a%B3.1.3 b%B3.1.3 sel%B3.1.3 out%B3.1.3; 10 | 11 | set a 0, 12 | set b 0, 13 | set sel 0, 14 | eval, 15 | output; 16 | 17 | set sel 1, 18 | eval, 19 | output; 20 | 21 | set a 0, 22 | set b 1, 23 | set sel 0, 24 | eval, 25 | output; 26 | 27 | set sel 1, 28 | eval, 29 | output; 30 | 31 | set a 1, 32 | set b 0, 33 | set sel 0, 34 | eval, 35 | output; 36 | 37 | set sel 1, 38 | eval, 39 | output; 40 | 41 | set a 1, 42 | set b 1, 43 | set sel 0, 44 | eval, 45 | output; 46 | 47 | set sel 1, 48 | eval, 49 | output; 50 | -------------------------------------------------------------------------------- /11/compiler.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'securerandom' 4 | require 'pathname' 5 | require 'bundler' 6 | Bundler.require 7 | 8 | require 'active_support/inflector' 9 | 10 | $LOAD_PATH.unshift(File.expand_path('..', __FILE__)) 11 | 12 | require 'analyzer' 13 | require 'symbol_table' 14 | require 'vm_writer' 15 | 16 | ARGV.each do |infile| 17 | unless File.exist?(infile) 18 | raise "Could not find file #{infile}" 19 | end 20 | 21 | path = Pathname.new(infile) 22 | outfile = path.basename('.jack').to_s + '.vm' 23 | symbols = SymbolTable.new 24 | writer = VMWriter.new(symbols) 25 | 26 | text = File.read(infile) 27 | analyzer = Analyzer.new(text) 28 | class_node = analyzer.compile_class 29 | require 'pp' 30 | pp class_node 31 | class_node.emit(writer, symbols) 32 | 33 | writer.save(outfile) 34 | end 35 | -------------------------------------------------------------------------------- /11/nodes/class_node.rb: -------------------------------------------------------------------------------- 1 | class ClassNode < Struct.new(:name, :class_vars, :subroutines) 2 | def emit(writer, symbols) 3 | symbols.current_class = name 4 | 5 | class_vars.each do |class_var| 6 | class_var.emit(writer, symbols) 7 | end 8 | 9 | subroutines.each do |subroutine| 10 | subroutine.emit(writer, symbols, self) 11 | end 12 | end 13 | 14 | def to_xml 15 | builder = Builder::XmlMarkup.new(:indent => 2) 16 | builder.class do |xml| 17 | xml.keyword('class') 18 | xml.identifier(name) 19 | xml.symbol('{') 20 | class_vars.each do |class_var| 21 | xml << class_var.to_xml 22 | end 23 | 24 | subroutines.each do |subroutine| 25 | xml << subroutine.to_xml 26 | end 27 | 28 | xml.symbol('}') 29 | end 30 | builder.target! 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /08/FunctionCalls/SimpleFunction/SimpleFunction.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst 5 | 6 | load SimpleFunction.asm, 7 | output-file SimpleFunction.out, 8 | compare-to SimpleFunction.cmp, 9 | output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1 10 | RAM[3]%D1.6.1 RAM[4]%D1.6.1 RAM[310]%D1.6.1; 11 | 12 | set RAM[0] 317, 13 | set RAM[1] 317, 14 | set RAM[2] 310, 15 | set RAM[3] 3000, 16 | set RAM[4] 4000, 17 | set RAM[310] 1234, 18 | set RAM[311] 37, 19 | set RAM[312] 1000, 20 | set RAM[313] 305, 21 | set RAM[314] 300, 22 | set RAM[315] 3010, 23 | set RAM[316] 4010, 24 | 25 | repeat 300 { 26 | ticktock; 27 | } 28 | 29 | output; 30 | -------------------------------------------------------------------------------- /11/nodes/binary_operation_node.rb: -------------------------------------------------------------------------------- 1 | class BinaryOperationTermNode < Struct.new(:operator, :left, :right) 2 | def emit(writer, symbols) 3 | left.emit(writer, symbols) 4 | right.emit(writer, symbols) 5 | 6 | case operator 7 | when '&' 8 | writer.write_arithmetic(:and) 9 | when '|' 10 | writer.write_arithmetic(:or) 11 | when '+' 12 | writer.write_arithmetic(:add) 13 | when '-' 14 | writer.write_arithmetic(:sub) 15 | when '*' 16 | writer.write_call('Math.multiply', 2) 17 | when '/' 18 | writer.write_call('Math.divide', 2) 19 | when '=' 20 | writer.write_arithmetic(:eq) 21 | when '<' 22 | writer.write_arithmetic(:lt) 23 | when '>' 24 | writer.write_arithmetic(:gt) 25 | else 26 | raise "Unknown operation #{operator}" 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /07/commands/return_command.rb: -------------------------------------------------------------------------------- 1 | class ReturnCommand 2 | def initialize(id, filename, current_function) 3 | end 4 | 5 | def emit 6 | <<-ASM 7 | // return 8 | @LCL 9 | D=M 10 | @frame 11 | M=D // FRAME = LCL 12 | @5 13 | D=D-A 14 | A=D 15 | D=M 16 | @ret 17 | M=D // RET = *(FRAME-5) 18 | @SP 19 | M=M-1 20 | A=M 21 | D=M 22 | @ARG 23 | A=M 24 | M=D // *ARG = pop 25 | @ARG 26 | D=M+1 27 | @SP 28 | M=D // SP = ARG+1 29 | @frame 30 | D=M 31 | @1 32 | D=D-A 33 | A=D 34 | D=M 35 | @THAT 36 | M=D // THAT = *(FRAME-1) 37 | @frame 38 | D=M 39 | @2 40 | D=D-A 41 | A=D 42 | D=M 43 | @THIS 44 | M=D // THIS = *(FRAME-2) 45 | @frame 46 | D=M 47 | @3 48 | D=D-A 49 | A=D 50 | D=M 51 | @ARG 52 | M=D // ARG = *(FRAME-3) 53 | @frame 54 | D=M 55 | @4 56 | D=D-A 57 | A=D 58 | D=M 59 | @LCL 60 | M=D // LCL = *(FRAME-4) 61 | @ret 62 | A=M 63 | 0;JMP 64 | ASM 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /10/nodes/subroutine_node.rb: -------------------------------------------------------------------------------- 1 | class SubroutineNode < Struct.new(:name, :kind, :return_type, :parameters, :body) 2 | def to_xml 3 | builder = Builder::XmlMarkup.new 4 | builder.subroutineDec do |xml| 5 | xml.keyword(kind) 6 | if Tokenizer::Keywords.include?(return_type) 7 | xml.keyword(return_type) 8 | else 9 | xml.identifier(return_type) 10 | end 11 | xml.identifier(name) 12 | xml.symbol('(') 13 | xml.parameterList do |parameter_list_xml| 14 | parameters.each_with_index do |parameter, i| 15 | parameter_list_xml << parameter.to_xml 16 | if i != parameters.length - 1 17 | parameter_list_xml.symbol(',') 18 | end 19 | end 20 | end 21 | xml.symbol(')') 22 | xml << body.to_xml 23 | end 24 | builder.target! 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /11/nodes/let_statement_node.rb: -------------------------------------------------------------------------------- 1 | class LetStatementNode < Struct.new(:name, :index_expression, :value_expression) 2 | def emit(writer, symbols) 3 | symbol = symbols.lookup(name) 4 | unless symbol.present? 5 | raise "Unable to find symbol #{name} in #{symbols.inspect}" 6 | end 7 | 8 | kind = symbol.kind 9 | if symbol.kind == :field 10 | kind = :this 11 | end 12 | 13 | value_expression.emit(writer, symbols) 14 | 15 | if index_expression.nil? 16 | segment = kind 17 | index = symbol.index 18 | else 19 | writer.write_push(kind, symbol.index) 20 | index_expression.emit(writer, symbols) 21 | writer.write_arithmetic(:add) 22 | writer.write_pop(:pointer, 1) 23 | 24 | segment = :that 25 | index = 0 26 | end 27 | 28 | writer.write_pop(segment, index) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /08/FunctionCalls/SimpleFunction/SimpleFunctionVME.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/SimpleFunction/SimpleFunctionVME.tst 5 | 6 | load SimpleFunction.vm, 7 | output-file SimpleFunction.out, 8 | compare-to SimpleFunction.cmp, 9 | output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1 10 | RAM[3]%D1.6.1 RAM[4]%D1.6.1 RAM[310]%D1.6.1; 11 | 12 | set sp 317, 13 | set local 317, 14 | set argument 310, 15 | set this 3000, 16 | set that 4000, 17 | set argument[0] 1234, 18 | set argument[1] 37, 19 | set argument[2] 9, 20 | set argument[3] 305, 21 | set argument[4] 300, 22 | set argument[5] 3010, 23 | set argument[6] 4010, 24 | 25 | repeat 10 { 26 | vmstep; 27 | } 28 | 29 | output; 30 | -------------------------------------------------------------------------------- /01/Mux8Way16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux8Way16.hdl 5 | 6 | /** 7 | * 8-way 16-bit multiplexor. 8 | * out = a if sel == 000 9 | * b if sel == 001 10 | * etc. 11 | * h if sel == 111 12 | */ 13 | 14 | 15 | CHIP Mux8Way16 { 16 | IN a[16], b[16], c[16], d[16], 17 | e[16], f[16], g[16], h[16], 18 | sel[3]; 19 | OUT out[16]; 20 | 21 | PARTS: 22 | Mux16(a=a, b=b, sel=sel[0], out=t1); 23 | Mux16(a=c, b=d, sel=sel[0], out=t2); 24 | Mux16(a=e, b=f, sel=sel[0], out=t3); 25 | Mux16(a=g, b=h, sel=sel[0], out=t4); 26 | 27 | Mux16(a=t1, b=t2, sel=sel[1], out=t5); 28 | Mux16(a=t3, b=t4, sel=sel[1], out=t6); 29 | 30 | Mux16(a=t5, b=t6, sel=sel[2], out=out); 31 | } 32 | -------------------------------------------------------------------------------- /06/max/Max.asm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/06/max/Max.asm 5 | 6 | // Computes M[2] = max(M[0], M[1]) where M stands for RAM 7 | 8 | @0 9 | D=M // D = first number 10 | @1 11 | D=D-M // D = first number - second number 12 | @OUTPUT_FIRST 13 | D;JGT // if D>0 (first is greater) goto output_first 14 | @1 15 | D=M // D = second number 16 | @OUTPUT_D 17 | 0;JMP // goto output_d 18 | (OUTPUT_FIRST) 19 | @0 20 | D=M // D = first number 21 | (OUTPUT_D) 22 | @2 23 | M=D // M[2] = D (greatest number) 24 | (INFINITE_LOOP) 25 | @INFINITE_LOOP 26 | 0;JMP // infinite loop 27 | -------------------------------------------------------------------------------- /01/Or16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Or16.tst 5 | 6 | load Or16.hdl, 7 | output-file Or16.out, 8 | compare-to Or16.cmp, 9 | output-list a%B1.16.1 b%B1.16.1 out%B1.16.1; 10 | 11 | set a %B0000000000000000, 12 | set b %B0000000000000000, 13 | eval, 14 | output; 15 | 16 | set a %B0000000000000000, 17 | set b %B1111111111111111, 18 | eval, 19 | output; 20 | 21 | set a %B1111111111111111, 22 | set b %B1111111111111111, 23 | eval, 24 | output; 25 | 26 | set a %B1010101010101010, 27 | set b %B0101010101010101, 28 | eval, 29 | output; 30 | 31 | set a %B0011110011000011, 32 | set b %B0000111111110000, 33 | eval, 34 | output; 35 | 36 | set a %B0001001000110100, 37 | set b %B1001100001110110, 38 | eval, 39 | output; -------------------------------------------------------------------------------- /03/a/PC.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/a/PC.hdl 5 | 6 | /** 7 | * 16-bit counter with load and reset controls. 8 | * 9 | * If reset(t-1) then out(t) = 0 10 | * else if load(t-1) then out(t) = in(t-1) 11 | * else if inc(t-1) then out(t) = out(t-1) + 1 (integer addition) 12 | * else out(t) = out(t-1) 13 | */ 14 | 15 | CHIP PC { 16 | IN in[16],load,inc,reset; 17 | OUT out[16]; 18 | 19 | PARTS: 20 | Or8Way(in[0]=load, in[1]=inc, in[2]=reset, in[3..7]=false, out=l1); 21 | 22 | Inc16(in=w1, out=w2); 23 | Mux16(a=w2, b=in, sel=load, out=w3); 24 | Mux16(a=w3, b=false, sel=reset, out=w4); 25 | 26 | Register(in=w4, load=l1, out=w1, out=out); 27 | } 28 | -------------------------------------------------------------------------------- /01/And16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/And16.tst 5 | 6 | load And16.hdl, 7 | output-file And16.out, 8 | compare-to And16.cmp, 9 | output-list a%B1.16.1 b%B1.16.1 out%B1.16.1; 10 | 11 | set a %B0000000000000000, 12 | set b %B0000000000000000, 13 | eval, 14 | output; 15 | 16 | set a %B0000000000000000, 17 | set b %B1111111111111111, 18 | eval, 19 | output; 20 | 21 | set a %B1111111111111111, 22 | set b %B1111111111111111, 23 | eval, 24 | output; 25 | 26 | set a %B1010101010101010, 27 | set b %B0101010101010101, 28 | eval, 29 | output; 30 | 31 | set a %B0011110011000011, 32 | set b %B0000111111110000, 33 | eval, 34 | output; 35 | 36 | set a %B0001001000110100, 37 | set b %B1001100001110110, 38 | eval, 39 | output; -------------------------------------------------------------------------------- /11/nodes/subroutine_call_node.rb: -------------------------------------------------------------------------------- 1 | class SubroutineCallNode < Struct.new(:target, :name, :arguments) 2 | def emit(writer, symbols) 3 | argument_count = arguments.length 4 | call = "#{target}.#{name}" 5 | 6 | if target.nil? 7 | call = "#{symbols.current_class}.#{name}" 8 | argument_count += 1 9 | writer.write_push(:pointer, 0) 10 | else 11 | symbol = symbols.lookup(target) 12 | if symbol.present? 13 | call = "#{symbol.type}.#{name}" 14 | argument_count += 1 15 | 16 | kind = symbol.kind 17 | if symbol.kind == :field 18 | kind = :this 19 | end 20 | 21 | writer.write_push(kind, symbol.index) 22 | end 23 | end 24 | 25 | arguments.each do |argument| 26 | argument.emit(writer, symbols) 27 | end 28 | 29 | writer.write_call(call, argument_count) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /01/DMux8Way.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/DMux8Way.hdl 5 | 6 | /** 7 | * 8-way demultiplexor. 8 | * {a,b,c,d,e,f,g,h} = {in,0,0,0,0,0,0,0} if sel == 000 9 | * {0,in,0,0,0,0,0,0} if sel == 001 10 | * etc. 11 | * {0,0,0,0,0,0,0,in} if sel == 111 12 | */ 13 | 14 | 15 | CHIP DMux8Way { 16 | IN in, sel[3]; 17 | OUT a, b, c, d, e, f, g, h; 18 | 19 | PARTS: 20 | DMux(in=in, sel=sel[0], a=t1, b=t2); 21 | 22 | DMux(in=t1, sel=sel[1], a=t3, b=t5); 23 | DMux(in=t2, sel=sel[1], a=t4, b=t6); 24 | 25 | DMux(in=t3, sel=sel[2], a=a, b=e); 26 | DMux(in=t4, sel=sel[2], a=b, b=f); 27 | DMux(in=t5, sel=sel[2], a=c, b=g); 28 | DMux(in=t6, sel=sel[2], a=d, b=h); 29 | } 30 | -------------------------------------------------------------------------------- /02/Add16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/Add16.tst 5 | 6 | load Add16.hdl, 7 | output-file Add16.out, 8 | compare-to Add16.cmp, 9 | output-list a%B1.16.1 b%B1.16.1 out%B1.16.1; 10 | 11 | set a %B0000000000000000, 12 | set b %B0000000000000000, 13 | eval, 14 | output; 15 | 16 | set a %B0000000000000000, 17 | set b %B1111111111111111, 18 | eval, 19 | output; 20 | 21 | set a %B1111111111111111, 22 | set b %B1111111111111111, 23 | eval, 24 | output; 25 | 26 | set a %B1010101010101010, 27 | set b %B0101010101010101, 28 | eval, 29 | output; 30 | 31 | set a %B0011110011000011, 32 | set b %B0000111111110000, 33 | eval, 34 | output; 35 | 36 | set a %B0001001000110100, 37 | set b %B1001100001110110, 38 | eval, 39 | output; 40 | -------------------------------------------------------------------------------- /01/Not16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Not16.hdl 5 | 6 | /** 7 | * 16-bit Not gate: for i = 0..15: out[i] = Not in[i] 8 | */ 9 | 10 | CHIP Not16 { 11 | IN in[16]; 12 | OUT out[16]; 13 | 14 | PARTS: 15 | Not(in=in[0], out=out[0]); 16 | Not(in=in[1], out=out[1]); 17 | Not(in=in[2], out=out[2]); 18 | Not(in=in[3], out=out[3]); 19 | Not(in=in[4], out=out[4]); 20 | Not(in=in[5], out=out[5]); 21 | Not(in=in[6], out=out[6]); 22 | Not(in=in[7], out=out[7]); 23 | Not(in=in[8], out=out[8]); 24 | Not(in=in[9], out=out[9]); 25 | Not(in=in[10], out=out[10]); 26 | Not(in=in[11], out=out[11]); 27 | Not(in=in[12], out=out[12]); 28 | Not(in=in[13], out=out[13]); 29 | Not(in=in[14], out=out[14]); 30 | Not(in=in[15], out=out[15]); 31 | } 32 | -------------------------------------------------------------------------------- /01/Mux16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux16.tst 5 | 6 | load Mux16.hdl, 7 | output-file Mux16.out, 8 | compare-to Mux16.cmp, 9 | output-list a%B1.16.1 b%B1.16.1 sel%D2.1.2 out%B1.16.1; 10 | 11 | set a 0, 12 | set b 0, 13 | set sel 0, 14 | eval, 15 | output; 16 | 17 | set sel 1, 18 | eval, 19 | output; 20 | 21 | set a %B0000000000000000, 22 | set b %B0001001000110100, 23 | set sel 0, 24 | eval, 25 | output; 26 | 27 | set sel 1, 28 | eval, 29 | output; 30 | 31 | set a %B1001100001110110, 32 | set b %B0000000000000000, 33 | set sel 0, 34 | eval, 35 | output; 36 | 37 | set sel 1, 38 | eval, 39 | output; 40 | 41 | set a %B1010101010101010, 42 | set b %B0101010101010101, 43 | set sel 0, 44 | eval, 45 | output; 46 | 47 | set sel 1, 48 | eval, 49 | output; -------------------------------------------------------------------------------- /01/Mux4Way16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux4Way16.tst 5 | 6 | load Mux4Way16.hdl, 7 | output-file Mux4Way16.out, 8 | compare-to Mux4Way16.cmp, 9 | output-list a%B1.16.1 b%B1.16.1 c%B1.16.1 d%B1.16.1 sel%B2.2.2 out%B1.16.1; 10 | 11 | set a 0, 12 | set b 0, 13 | set c 0, 14 | set d 0, 15 | set sel 0, 16 | eval, 17 | output; 18 | 19 | set sel 1, 20 | eval, 21 | output; 22 | 23 | set sel 2, 24 | eval, 25 | output; 26 | 27 | set sel 3, 28 | eval, 29 | output; 30 | 31 | set a %B0001001000110100, 32 | set b %B1001100001110110, 33 | set c %B1010101010101010, 34 | set d %B0101010101010101, 35 | set sel 0, 36 | eval, 37 | output; 38 | 39 | set sel 1, 40 | eval, 41 | output; 42 | 43 | set sel 2, 44 | eval, 45 | output; 46 | 47 | set sel 3, 48 | eval, 49 | output; 50 | -------------------------------------------------------------------------------- /07/commands/call_command.rb: -------------------------------------------------------------------------------- 1 | class CallCommand 2 | def initialize(id, filename, current_function, function, argument_count) 3 | @id = id 4 | @function = function 5 | @argument_count = argument_count.to_i 6 | end 7 | 8 | def emit 9 | <<-ASM 10 | // call #{@function} #{@argument_count} 11 | @RETURN#{@id} 12 | D=A 13 | @SP 14 | A=M 15 | M=D // push return-address 16 | @SP 17 | M=M+1 18 | @LCL 19 | D=M 20 | @SP 21 | A=M 22 | M=D // push LCL 23 | @SP 24 | M=M+1 25 | @ARG 26 | D=M 27 | @SP 28 | A=M 29 | M=D // push ARG 30 | @SP 31 | M=M+1 32 | @THIS 33 | D=M 34 | @SP 35 | A=M 36 | M=D // push THIS 37 | @SP 38 | M=M+1 39 | @THAT 40 | D=M 41 | @SP 42 | A=M 43 | M=D // push THAT 44 | @SP 45 | M=M+1 46 | D=M 47 | @#{@argument_count} 48 | D=D-A 49 | @5 50 | D=D-A 51 | @ARG 52 | M=D // ARG = SP-n-5 53 | @SP 54 | D=M 55 | @LCL 56 | M=D // LCL = SP 57 | @#{@function} 58 | 0;JMP // goto #{@function} 59 | (RETURN#{@id}) 60 | ASM 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /01/Mux4Way16.out: -------------------------------------------------------------------------------- 1 | | a | b | c | d | sel | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 00 | 0000000000000000 | 3 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 01 | 0000000000000000 | 4 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 10 | 0000000000000000 | 5 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 11 | 0000000000000000 | 6 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 00 | 0001001000110100 | 7 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 01 | 1001100001110110 | 8 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 10 | 1010101010101010 | 9 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 11 | 0101010101010101 | 10 | -------------------------------------------------------------------------------- /11/Average/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/11/Average/Main.jack 5 | 6 | /** Computes the average of a sequence of integers */ 7 | class Main { 8 | function void main() { 9 | var Array a; 10 | var int length; 11 | var int i, sum; 12 | 13 | let length = Keyboard.readInt("How many numbers? "); 14 | let a = Array.new(length); 15 | let i = 0; 16 | 17 | while (i < length) { 18 | let a[i] = Keyboard.readInt("Enter the next number: "); 19 | let i = i + 1; 20 | } 21 | 22 | let i = 0; 23 | let sum = 0; 24 | 25 | while (i < length) { 26 | let sum = sum + a[i]; 27 | let i = i + 1; 28 | } 29 | 30 | do Output.printString("The average is: "); 31 | do Output.printInt(sum / length); 32 | do Output.println(); 33 | 34 | return; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /01/Mux4Way16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | c | d | sel | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 00 | 0000000000000000 | 3 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 01 | 0000000000000000 | 4 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 10 | 0000000000000000 | 5 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 11 | 0000000000000000 | 6 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 00 | 0001001000110100 | 7 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 01 | 1001100001110110 | 8 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 10 | 1010101010101010 | 9 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 0101010101010101 | 11 | 0101010101010101 | 10 | -------------------------------------------------------------------------------- /05/ComputerAdd-external.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/05/ComputerAdd-external.tst 5 | 6 | load Computer.hdl, 7 | output-file ComputerAdd-external.out, 8 | compare-to ComputerAdd-external.cmp, 9 | output-list time%S1.4.1 reset%B2.1.2 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1; 10 | 11 | // Load a program written in the Hack machine language. 12 | // The program adds the two constants 2 and 3 and writes the result in RAM[0]. 13 | ROM32K load Add.hack, 14 | output; 15 | 16 | // First run (at the beginning PC=0) 17 | repeat 6 { 18 | tick, tock, output; 19 | } 20 | 21 | // Reset the PC 22 | set reset 1, 23 | set RAM16K[0] 0, 24 | tick, tock, output; 25 | 26 | 27 | // Second run, to check that the PC was reset correctly. 28 | set reset 0, 29 | 30 | repeat 6 { 31 | tick, tock, output; 32 | } 33 | -------------------------------------------------------------------------------- /05/ComputerRect-external.cmp: -------------------------------------------------------------------------------- 1 | | time | 2 | | 0 | 3 | | 1 | 4 | | 2 | 5 | | 3 | 6 | | 4 | 7 | | 5 | 8 | | 6 | 9 | | 7 | 10 | | 8 | 11 | | 9 | 12 | | 10 | 13 | | 11 | 14 | | 12 | 15 | | 13 | 16 | | 14 | 17 | | 15 | 18 | | 16 | 19 | | 17 | 20 | | 18 | 21 | | 19 | 22 | | 20 | 23 | | 21 | 24 | | 22 | 25 | | 23 | 26 | | 24 | 27 | | 25 | 28 | | 26 | 29 | | 27 | 30 | | 28 | 31 | | 29 | 32 | | 30 | 33 | | 31 | 34 | | 32 | 35 | | 33 | 36 | | 34 | 37 | | 35 | 38 | | 36 | 39 | | 37 | 40 | | 38 | 41 | | 39 | 42 | | 40 | 43 | | 41 | 44 | | 42 | 45 | | 43 | 46 | | 44 | 47 | | 45 | 48 | | 46 | 49 | | 47 | 50 | | 48 | 51 | | 49 | 52 | | 50 | 53 | | 51 | 54 | | 52 | 55 | | 53 | 56 | | 54 | 57 | | 55 | 58 | | 56 | 59 | | 57 | 60 | | 58 | 61 | | 59 | 62 | | 60 | 63 | | 61 | 64 | | 62 | 65 | | 63 | 66 | -------------------------------------------------------------------------------- /10/ArrayTest/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/10/ArrayTest/Main.jack 5 | 6 | /** Computes the average of a sequence of integers. */ 7 | class Main { 8 | function void main() { 9 | var Array a; 10 | var int length; 11 | var int i, sum; 12 | 13 | let length = Keyboard.readInt("HOW MANY NUMBERS? "); 14 | let a = Array.new(length); 15 | let i = 0; 16 | 17 | while (i < length) { 18 | let a[i] = Keyboard.readInt("ENTER THE NEXT NUMBER: "); 19 | let i = i + 1; 20 | } 21 | 22 | let i = 0; 23 | let sum = 0; 24 | 25 | while (i < length) { 26 | let sum = sum + a[i]; 27 | let i = i + 1; 28 | } 29 | 30 | do Output.printString("THE AVERAGE IS: "); 31 | do Output.printInt(sum / length); 32 | do Output.println(); 33 | 34 | return; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /05/ComputerAdd.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/05/ComputerAdd.tst 5 | 6 | load Computer.hdl, 7 | output-file ComputerAdd.out, 8 | compare-to ComputerAdd.cmp, 9 | output-list time%S1.4.1 reset%B2.1.2 ARegister[0]%D1.7.1 DRegister[0]%D1.7.1 PC[]%D0.4.0 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1; 10 | 11 | // Load a program written in the Hack machine language. 12 | // The program adds the two constants 2 and 3 and writes the result in RAM[0]. 13 | ROM32K load Add.hack, 14 | output; 15 | 16 | // First run (at the beginning PC=0) 17 | repeat 6 { 18 | tick, tock, output; 19 | } 20 | 21 | // Reset the PC 22 | set reset 1, 23 | set RAM16K[0] 0, 24 | tick, tock, output; 25 | 26 | 27 | // Second run, to check that the PC was reset correctly. 28 | set reset 0, 29 | 30 | repeat 6 { 31 | tick, tock, output; 32 | } 33 | -------------------------------------------------------------------------------- /05/ComputerRect-external.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/05/ComputerRect-external.tst 5 | 6 | load Computer.hdl, 7 | output-file ComputerRect-external.out, 8 | compare-to ComputerRect-external.cmp, 9 | output-list time%S1.4.1; 10 | 11 | / Load a program written in the Hack machine language. 12 | // The program draws a rectangle of width 16 pixels and 13 | // length RAM[0] at the top left of the screen. 14 | ROM32K load Rect.hack, 15 | 16 | echo "Before running this script, select the 'Screen' option from the 'View' menu"; 17 | 18 | echo "A small rectangle should be drawn at the top left of the screen (the 'Screen' option of the 'View' menu should be selected.)"; 19 | 20 | // draw a rectangle 16 pixels wide and 4 pixels long 21 | set RAM16K[0] 4, 22 | output; 23 | 24 | repeat 63 { 25 | tick, tock, output; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /04/fill/Fill.asm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/04/Fill.asm 5 | 6 | // Runs an infinite loop that listens to the keyboard input. 7 | // When a key is pressed (any key), the program blackens the screen, 8 | // i.e. writes "black" in every pixel. When no key is pressed, the 9 | // program clears the screen, i.e. writes "white" in every pixel. 10 | 11 | // Put your code here. 12 | 13 | (LOOP) 14 | @KBD 15 | D=M 16 | @FILL 17 | D;JGT 18 | 19 | (CLEAR) 20 | @offset 21 | D=M 22 | @SCREEN 23 | A=D+A 24 | M=0 25 | 26 | @INC_OFFSET 27 | 0;JMP 28 | 29 | (FILL) 30 | @offset 31 | D=M 32 | @SCREEN 33 | A=D+A 34 | M=-1 35 | 36 | (INC_OFFSET) 37 | @offset 38 | MD=M+1 39 | @8192 40 | D=D-A 41 | 42 | @LOOP 43 | D;JNE 44 | 45 | (RESET_OFFSET) 46 | @offset 47 | M=0 48 | @LOOP 49 | 0;JMP 50 | -------------------------------------------------------------------------------- /12/SysTest/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/SysTest/Main.jack 5 | 6 | /** Test program for the OS Sys class. */ 7 | class Main { 8 | 9 | /** tests the wait method of the Sys class. */ 10 | function void main() { 11 | var char key; 12 | 13 | do Output.printString("Wait test:"); 14 | do Output.println(); 15 | do Output.printString("Press any key. After 2 seconds, another message will be printed:"); 16 | 17 | while (key = 0) { 18 | let key = Keyboard.keyPressed(); 19 | } 20 | while (~(key = 0)) { 21 | let key = Keyboard.keyPressed(); 22 | } 23 | 24 | do Sys.wait(2000); 25 | 26 | do Output.println(); 27 | do Output.printString("Time is up. Make sure that 2 seconds had passed."); 28 | 29 | return; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /04/mult/Mult.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/04/mult/Mult.tst 5 | 6 | load Mult.hack, 7 | output-file Mult.out, 8 | compare-to Mult.cmp, 9 | output-list RAM[0]%D2.6.2 RAM[1]%D2.6.2 RAM[2]%D2.6.2; 10 | 11 | set RAM[0] 0, 12 | set RAM[1] 0; 13 | repeat 20 { 14 | ticktock; 15 | } 16 | output; 17 | 18 | set PC 0, 19 | set RAM[0] 1, 20 | set RAM[1] 0; 21 | repeat 50 { 22 | ticktock; 23 | } 24 | output; 25 | 26 | set PC 0, 27 | set RAM[0] 0, 28 | set RAM[1] 2; 29 | repeat 80 { 30 | ticktock; 31 | } 32 | output; 33 | 34 | set PC 0, 35 | set RAM[0] 3, 36 | set RAM[1] 1; 37 | repeat 120 { 38 | ticktock; 39 | } 40 | output; 41 | 42 | set PC 0, 43 | set RAM[0] 2, 44 | set RAM[1] 4; 45 | repeat 150 { 46 | ticktock; 47 | } 48 | output; 49 | 50 | set PC 0, 51 | set RAM[0] 6, 52 | set RAM[1] 7; 53 | repeat 210 { 54 | ticktock; 55 | } 56 | output; 57 | -------------------------------------------------------------------------------- /01/Or16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Or16.hdl 5 | 6 | 7 | /** 8 | * 16-bit bitwise Or gate: for i = 0..15 out[i] = a[i] Or b[i]. 9 | */ 10 | 11 | CHIP Or16 { 12 | IN a[16], b[16]; 13 | OUT out[16]; 14 | 15 | PARTS: 16 | Or(a=a[0], b=b[0], out=out[0]); 17 | Or(a=a[1], b=b[1], out=out[1]); 18 | Or(a=a[2], b=b[2], out=out[2]); 19 | Or(a=a[3], b=b[3], out=out[3]); 20 | Or(a=a[4], b=b[4], out=out[4]); 21 | Or(a=a[5], b=b[5], out=out[5]); 22 | Or(a=a[6], b=b[6], out=out[6]); 23 | Or(a=a[7], b=b[7], out=out[7]); 24 | Or(a=a[8], b=b[8], out=out[8]); 25 | Or(a=a[9], b=b[9], out=out[9]); 26 | Or(a=a[10], b=b[10], out=out[10]); 27 | Or(a=a[11], b=b[11], out=out[11]); 28 | Or(a=a[12], b=b[12], out=out[12]); 29 | Or(a=a[13], b=b[13], out=out[13]); 30 | Or(a=a[14], b=b[14], out=out[14]); 31 | Or(a=a[15], b=b[15], out=out[15]); 32 | } 33 | -------------------------------------------------------------------------------- /01/And16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/And16.hdl 5 | 6 | /** 7 | * 16-bit-wise And gate: for i = 0..15: out[i] = a[i] And b[i] 8 | */ 9 | 10 | CHIP And16 { 11 | IN a[16], b[16]; 12 | OUT out[16]; 13 | 14 | PARTS: 15 | And(a=a[0], b=b[0], out=out[0]); 16 | And(a=a[1], b=b[1], out=out[1]); 17 | And(a=a[2], b=b[2], out=out[2]); 18 | And(a=a[3], b=b[3], out=out[3]); 19 | And(a=a[4], b=b[4], out=out[4]); 20 | And(a=a[5], b=b[5], out=out[5]); 21 | And(a=a[6], b=b[6], out=out[6]); 22 | And(a=a[7], b=b[7], out=out[7]); 23 | And(a=a[8], b=b[8], out=out[8]); 24 | And(a=a[9], b=b[9], out=out[9]); 25 | And(a=a[10], b=b[10], out=out[10]); 26 | And(a=a[11], b=b[11], out=out[11]); 27 | And(a=a[12], b=b[12], out=out[12]); 28 | And(a=a[13], b=b[13], out=out[13]); 29 | And(a=a[14], b=b[14], out=out[14]); 30 | And(a=a[15], b=b[15], out=out[15]); 31 | } 32 | -------------------------------------------------------------------------------- /05/ComputerRect.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/05/ComputerRect.tst 5 | 6 | load Computer.hdl, 7 | output-file ComputerRect.out, 8 | compare-to ComputerRect.cmp, 9 | output-list time%S1.4.1 ARegister[]%D1.7.1 DRegister[]%D1.7.1 PC[]%D0.4.0 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1; 10 | 11 | // Load a program written in the Hack machine language. 12 | // The program draws a rectangle of width 16 pixels and 13 | // length RAM[0] at the top left of the screen. 14 | ROM32K load Rect.hack, 15 | 16 | echo "Before running this script, select the 'Screen' option from the 'View' menu"; 17 | 18 | echo "A small rectangle should be drawn at the top-left of the screen (the 'Screen' option of the 'View' menu should be selected.)"; 19 | 20 | // Draws a rectangle 16 pixels wide and 4 pixels long 21 | set RAM16K[0] 4, 22 | output; 23 | 24 | repeat 63 { 25 | tick, tock, output; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /05/ComputerAdd.out: -------------------------------------------------------------------------------- 1 | | time |reset|ARegister|DRegister|PC[]|RAM16K[0]|RAM16K[1]|RAM16K[2]| 2 | | 0 | 0 | 0 | 0 | 0| 0 | 0 | 0 | 3 | | 1 | 0 | 2 | 0 | 1| 0 | 0 | 0 | 4 | | 2 | 0 | 2 | 2 | 2| 0 | 0 | 0 | 5 | | 3 | 0 | 3 | 2 | 3| 0 | 0 | 0 | 6 | | 4 | 0 | 3 | 5 | 4| 0 | 0 | 0 | 7 | | 5 | 0 | 0 | 5 | 5| 0 | 0 | 0 | 8 | | 6 | 0 | 0 | 5 | 6| 5 | 0 | 0 | 9 | | 7 | 1 | 0 | 5 | 0| 0 | 0 | 0 | 10 | | 8 | 0 | 2 | 5 | 1| 0 | 0 | 0 | 11 | | 9 | 0 | 2 | 2 | 2| 0 | 0 | 0 | 12 | | 10 | 0 | 3 | 2 | 3| 0 | 0 | 0 | 13 | | 11 | 0 | 3 | 5 | 4| 0 | 0 | 0 | 14 | | 12 | 0 | 0 | 5 | 5| 0 | 0 | 0 | 15 | | 13 | 0 | 0 | 5 | 6| 5 | 0 | 0 | 16 | -------------------------------------------------------------------------------- /08/FunctionCalls/FibonacciElement/Main.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/FunctionCalls/FibonacciElement/Main.vm 5 | 6 | // Computes the n'th element of the Fibonacci series, recursively. 7 | // n is given in argument[0]. Called by the Sys.init function 8 | // (part of the Sys.vm file), which also pushes the argument[0] 9 | // parameter before this code starts running. 10 | 11 | function Main.fibonacci 0 12 | push argument 0 13 | push constant 2 14 | lt // check if n < 2 15 | if-goto IF_TRUE 16 | goto IF_FALSE 17 | label IF_TRUE // if n<2, return n 18 | push argument 0 19 | return 20 | label IF_FALSE // if n>=2, return fib(n-2)+fib(n-1) 21 | push argument 0 22 | push constant 2 23 | sub 24 | call Main.fibonacci 1 // compute fib(n-2) 25 | push argument 0 26 | push constant 1 27 | sub 28 | call Main.fibonacci 1 // compute fib(n-1) 29 | add // return fib(n-1) + fib(n-2) 30 | return 31 | -------------------------------------------------------------------------------- /11/vm_writer.rb: -------------------------------------------------------------------------------- 1 | class VMWriter 2 | def initialize(symbols) 3 | @symbols = symbols 4 | @commands = [] 5 | end 6 | 7 | def write_function(name, locals_count) 8 | @commands << "function #{name} #{locals_count}" 9 | end 10 | 11 | def write_call(name, argument_count) 12 | @commands << "call #{name} #{argument_count}" 13 | end 14 | 15 | def write_push(segment, index) 16 | @commands << "push #{segment} #{index}" 17 | end 18 | 19 | def write_pop(segment, index) 20 | @commands << "pop #{segment} #{index}" 21 | end 22 | 23 | def write_arithmetic(operation) 24 | @commands << operation 25 | end 26 | 27 | def write_label(label) 28 | @commands << "label #{label}" 29 | end 30 | 31 | def write_if(label) 32 | @commands << "if-goto #{label}" 33 | end 34 | 35 | def write_goto(label) 36 | @commands << "goto #{label}" 37 | end 38 | 39 | def write_return 40 | @commands << "return" 41 | end 42 | 43 | def save(file) 44 | File.open(file, 'w') do |f| 45 | text = @commands.join("\n") 46 | f.write(text) 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /10/ExpressionlessSquare/MainT.xml: -------------------------------------------------------------------------------- 1 | 2 | class 3 | Main 4 | { 5 | function 6 | void 7 | main 8 | ( 9 | ) 10 | { 11 | var 12 | SquareGame 13 | game 14 | ; 15 | let 16 | game 17 | = 18 | game 19 | ; 20 | do 21 | game 22 | . 23 | run 24 | ( 25 | ) 26 | ; 27 | do 28 | game 29 | . 30 | dispose 31 | ( 32 | ) 33 | ; 34 | return 35 | ; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /05/ComputerAdd.cmp: -------------------------------------------------------------------------------- 1 | | time |reset|ARegister|DRegister|PC[]|RAM16K[0]|RAM16K[1]|RAM16K[2]| 2 | | 0 | 0 | 0 | 0 | 0| 0 | 0 | 0 | 3 | | 1 | 0 | 2 | 0 | 1| 0 | 0 | 0 | 4 | | 2 | 0 | 2 | 2 | 2| 0 | 0 | 0 | 5 | | 3 | 0 | 3 | 2 | 3| 0 | 0 | 0 | 6 | | 4 | 0 | 3 | 5 | 4| 0 | 0 | 0 | 7 | | 5 | 0 | 0 | 5 | 5| 0 | 0 | 0 | 8 | | 6 | 0 | 0 | 5 | 6| 5 | 0 | 0 | 9 | | 7 | 1 | 0 | 5 | 0| 0 | 0 | 0 | 10 | | 8 | 0 | 2 | 5 | 1| 0 | 0 | 0 | 11 | | 9 | 0 | 2 | 2 | 2| 0 | 0 | 0 | 12 | | 10 | 0 | 3 | 2 | 3| 0 | 0 | 0 | 13 | | 11 | 0 | 3 | 5 | 4| 0 | 0 | 0 | 14 | | 12 | 0 | 0 | 5 | 5| 0 | 0 | 0 | 15 | | 13 | 0 | 0 | 5 | 6| 5 | 0 | 0 | 16 | -------------------------------------------------------------------------------- /01/DMux8Way.out: -------------------------------------------------------------------------------- 1 | | in | sel | a | b | c | d | e | f | g | h | 2 | | 0 | 00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | | 0 | 01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | | 0 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | | 0 | 00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 7 | | 0 | 01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 9 | | 0 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | | 1 | 00 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 11 | | 1 | 01 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 12 | | 1 | 10 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 13 | | 1 | 11 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 14 | | 1 | 00 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 15 | | 1 | 01 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 16 | | 1 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 17 | | 1 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 18 | -------------------------------------------------------------------------------- /05/ComputerMax-external.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/05/ComputerMax-external.tst 5 | 6 | load Computer.hdl, 7 | output-file ComputerMax-external.out, 8 | compare-to ComputerMax-external.cmp, 9 | output-list time%S1.4.1 reset%B2.1.2 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1; 10 | 11 | // Load a program written in the Hack machine language. 12 | // The program computes the maximum of RAM[0] and RAM[1] 13 | // and writes the result in RAM[2]. 14 | ROM32K load Max.hack, 15 | 16 | // first run: compute max(3,5) 17 | set RAM16K[0] 3, 18 | set RAM16K[1] 5, 19 | output; 20 | 21 | repeat 14 { 22 | tick, tock, output; 23 | } 24 | 25 | // reset the PC 26 | set reset 1, 27 | tick, tock, output; 28 | 29 | // second run: compute max(23456,12345) 30 | set reset 0, 31 | set RAM16K[0] 23456, 32 | set RAM16K[1] 12345, 33 | output; 34 | 35 | // The run on these inputs needs less cycles (different branching) 36 | repeat 10 { 37 | tick, tock, output; 38 | } 39 | -------------------------------------------------------------------------------- /01/DMux8Way.cmp: -------------------------------------------------------------------------------- 1 | | in | sel | a | b | c | d | e | f | g | h | 2 | | 0 | 00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | | 0 | 01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | | 0 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | | 0 | 00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 7 | | 0 | 01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 9 | | 0 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | | 1 | 00 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 11 | | 1 | 01 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 12 | | 1 | 10 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 13 | | 1 | 11 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 14 | | 1 | 00 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 15 | | 1 | 01 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 16 | | 1 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 17 | | 1 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 18 | -------------------------------------------------------------------------------- /05/ComputerMax.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/05/ComputerMax.tst 5 | 6 | load Computer.hdl, 7 | output-file ComputerMax.out, 8 | compare-to ComputerMax.cmp, 9 | output-list time%S1.4.1 reset%B2.1.2 ARegister[]%D1.7.1 DRegister[]%D1.7.1 PC[]%D0.4.0 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1; 10 | 11 | // Load a program written in the Hack machine language. 12 | // The program computes the maximum of RAM[0] and RAM[1] 13 | // and writes the result in RAM[2]. 14 | 15 | ROM32K load Max.hack, 16 | 17 | // first run: compute max(3,5) 18 | set RAM16K[0] 3, 19 | set RAM16K[1] 5, 20 | output; 21 | 22 | repeat 14 { 23 | tick, tock, output; 24 | } 25 | 26 | // reset the PC 27 | set reset 1, 28 | tick, tock, output; 29 | 30 | // second run: compute max(23456,12345) 31 | set reset 0, 32 | set RAM16K[0] 23456, 33 | set RAM16K[1] 12345, 34 | output; 35 | 36 | // The run on these inputs needs less cycles (different branching) 37 | repeat 10 { 38 | tick, tock, output; 39 | } 40 | -------------------------------------------------------------------------------- /01/Mux16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux16.hdl 5 | 6 | /** 7 | * 16-bit multiplexor. If sel == 1 then out = b else out = a. 8 | */ 9 | 10 | CHIP Mux16 { 11 | IN a[16], b[16], sel; 12 | OUT out[16]; 13 | 14 | PARTS: 15 | Mux(a=a[0], b=b[0], sel=sel, out=out[0]); 16 | Mux(a=a[1], b=b[1], sel=sel, out=out[1]); 17 | Mux(a=a[2], b=b[2], sel=sel, out=out[2]); 18 | Mux(a=a[3], b=b[3], sel=sel, out=out[3]); 19 | Mux(a=a[4], b=b[4], sel=sel, out=out[4]); 20 | Mux(a=a[5], b=b[5], sel=sel, out=out[5]); 21 | Mux(a=a[6], b=b[6], sel=sel, out=out[6]); 22 | Mux(a=a[7], b=b[7], sel=sel, out=out[7]); 23 | Mux(a=a[8], b=b[8], sel=sel, out=out[8]); 24 | Mux(a=a[9], b=b[9], sel=sel, out=out[9]); 25 | Mux(a=a[10], b=b[10], sel=sel, out=out[10]); 26 | Mux(a=a[11], b=b[11], sel=sel, out=out[11]); 27 | Mux(a=a[12], b=b[12], sel=sel, out=out[12]); 28 | Mux(a=a[13], b=b[13], sel=sel, out=out[13]); 29 | Mux(a=a[14], b=b[14], sel=sel, out=out[14]); 30 | Mux(a=a[15], b=b[15], sel=sel, out=out[15]); 31 | } 32 | -------------------------------------------------------------------------------- /00/RAM8.cmp: -------------------------------------------------------------------------------- 1 | | time | in |load |address| out | 2 | | 0+ | 0 | 0 | 0 | 0 | 3 | | 1 | 0 | 0 | 0 | 0 | 4 | | 1+ | 0 | 1 | 0 | 0 | 5 | | 2 | 0 | 1 | 0 | 0 | 6 | | 2+ | 11111 | 0 | 0 | 0 | 7 | | 3 | 11111 | 0 | 0 | 0 | 8 | | 3+ | 11111 | 1 | 1 | 0 | 9 | | 4 | 11111 | 1 | 1 | 11111 | 10 | | 4+ | 11111 | 0 | 0 | 0 | 11 | | 5 | 11111 | 0 | 0 | 0 | 12 | | 5+ | 3333 | 0 | 3 | 0 | 13 | | 6 | 3333 | 0 | 3 | 0 | 14 | | 6+ | 3333 | 1 | 3 | 0 | 15 | | 7 | 3333 | 1 | 3 | 3333 | 16 | | 7+ | 3333 | 0 | 3 | 3333 | 17 | | 8 | 3333 | 0 | 3 | 3333 | 18 | | 8 | 3333 | 0 | 1 | 11111 | 19 | | 8+ | 7777 | 0 | 1 | 11111 | 20 | | 9 | 7777 | 0 | 1 | 11111 | 21 | | 9+ | 7777 | 1 | 7 | 0 | 22 | | 10 | 7777 | 1 | 7 | 7777 | 23 | | 10+ | 7777 | 0 | 7 | 7777 | 24 | | 11 | 7777 | 0 | 7 | 7777 | 25 | | 11 | 7777 | 0 | 3 | 3333 | 26 | | 11 | 7777 | 0 | 7 | 7777 | 27 | -------------------------------------------------------------------------------- /05/Memory.out: -------------------------------------------------------------------------------- 1 | | in |load | address | out | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 0 | 0 | 4 | | 0 | 1 | 0 | 0 | 5 | | 0 | 1 | 0 | 0 | 6 | | 4444 | 0 | 0 | 0 | 7 | | 4444 | 0 | 0 | 0 | 8 | | 4444 | 1 | 4444 | 0 | 9 | | 4444 | 1 | 4444 | 4444 | 10 | | 4444 | 0 | 0 | 0 | 11 | | 4444 | 0 | 0 | 0 | 12 | | 13131 | 0 | 13131 | 0 | 13 | | 13131 | 0 | 13131 | 0 | 14 | | 13131 | 1 | 13131 | 0 | 15 | | 13131 | 1 | 13131 | 13131 | 16 | | 13131 | 0 | 13131 | 13131 | 17 | | 13131 | 0 | 13131 | 13131 | 18 | | 13131 | 0 | 4444 | 4444 | 19 | | 16383 | 0 | 4444 | 4444 | 20 | | 16383 | 0 | 4444 | 4444 | 21 | | 16383 | 1 | 16383 | 0 | 22 | | 16383 | 1 | 16383 | 16383 | 23 | | 16383 | 0 | 16383 | 16383 | 24 | | 16383 | 0 | 16383 | 16383 | 25 | | 16383 | 0 | 13131 | 13131 | 26 | | 16383 | 0 | 16383 | 16383 | 27 | | 16383 | 0 | 24576 | 75 | 28 | | -1 | 1 | 20431 | -1 | 29 | | -1 | 1 | 20559 | -1 | 30 | | -1 | 0 | 24576 | 89 | 31 | -------------------------------------------------------------------------------- /03/a/Register.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/a/Register.hdl 5 | 6 | /** 7 | * 16-Bit register. 8 | * If load[t-1]=1 then out[t] = in[t-1] 9 | * else out does not change (out[t] = out[t-1]) 10 | */ 11 | 12 | CHIP Register { 13 | IN in[16], load; 14 | OUT out[16]; 15 | 16 | PARTS: 17 | Bit(in=in[0], load=load, out=out[0]); 18 | Bit(in=in[1], load=load, out=out[1]); 19 | Bit(in=in[2], load=load, out=out[2]); 20 | Bit(in=in[3], load=load, out=out[3]); 21 | Bit(in=in[4], load=load, out=out[4]); 22 | Bit(in=in[5], load=load, out=out[5]); 23 | Bit(in=in[6], load=load, out=out[6]); 24 | Bit(in=in[7], load=load, out=out[7]); 25 | Bit(in=in[8], load=load, out=out[8]); 26 | Bit(in=in[9], load=load, out=out[9]); 27 | Bit(in=in[10], load=load, out=out[10]); 28 | Bit(in=in[11], load=load, out=out[11]); 29 | Bit(in=in[12], load=load, out=out[12]); 30 | Bit(in=in[13], load=load, out=out[13]); 31 | Bit(in=in[14], load=load, out=out[14]); 32 | Bit(in=in[15], load=load, out=out[15]); 33 | } 34 | -------------------------------------------------------------------------------- /10/ExpressionlessSquare/MainT-gen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | class 4 | Main 5 | { 6 | function 7 | void 8 | main 9 | ( 10 | ) 11 | { 12 | var 13 | SquareGame 14 | game 15 | ; 16 | let 17 | game 18 | = 19 | game 20 | ; 21 | do 22 | game 23 | . 24 | run 25 | ( 26 | ) 27 | ; 28 | do 29 | game 30 | . 31 | dispose 32 | ( 33 | ) 34 | ; 35 | return 36 | ; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /10/Square/MainT.xml: -------------------------------------------------------------------------------- 1 | 2 | class 3 | Main 4 | { 5 | function 6 | void 7 | main 8 | ( 9 | ) 10 | { 11 | var 12 | SquareGame 13 | game 14 | ; 15 | let 16 | game 17 | = 18 | SquareGame 19 | . 20 | new 21 | ( 22 | ) 23 | ; 24 | do 25 | game 26 | . 27 | run 28 | ( 29 | ) 30 | ; 31 | do 32 | game 33 | . 34 | dispose 35 | ( 36 | ) 37 | ; 38 | return 39 | ; 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /05/Memory.cmp: -------------------------------------------------------------------------------- 1 | | in |load | address | out | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 0 | 0 | 4 | | 0 | 1 | 0 | 0 | 5 | | 0 | 1 | 0 | 0 | 6 | | 4444 | 0 | 0 | 0 | 7 | | 4444 | 0 | 0 | 0 | 8 | | 4444 | 1 | 4444 | 0 | 9 | | 4444 | 1 | 4444 | 4444 | 10 | | 4444 | 0 | 0 | 0 | 11 | | 4444 | 0 | 0 | 0 | 12 | | 13131 | 0 | 13131 | 0 | 13 | | 13131 | 0 | 13131 | 0 | 14 | | 13131 | 1 | 13131 | 0 | 15 | | 13131 | 1 | 13131 | 13131 | 16 | | 13131 | 0 | 13131 | 13131 | 17 | | 13131 | 0 | 13131 | 13131 | 18 | | 13131 | 0 | 4444 | 4444 | 19 | | 16383 | 0 | 4444 | 4444 | 20 | | 16383 | 0 | 4444 | 4444 | 21 | | 16383 | 1 | 16383 | 0 | 22 | | 16383 | 1 | 16383 | 16383 | 23 | | 16383 | 0 | 16383 | 16383 | 24 | | 16383 | 0 | 16383 | 16383 | 25 | | 16383 | 0 | 13131 | 13131 | 26 | | 16383 | 0 | 16383 | 16383 | 27 | | 16383 | 0 | 24576 | 75 | 28 | | -1 | 1 | 20431 | -1 | 29 | | -1 | 1 | 20559 | -1 | 30 | | -1 | 0 | 24576 | 89 | 31 | -------------------------------------------------------------------------------- /12/Screen.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/Screen.jack 5 | 6 | /** 7 | * Graphic screen library. 8 | */ 9 | class Screen { 10 | 11 | /** Initializes the Screen. */ 12 | function void init() { 13 | } 14 | 15 | /** Erases the whole screen. */ 16 | function void clearScreen() { 17 | } 18 | 19 | /** Sets the color to be used in further draw commands 20 | * where white = false, black = true. */ 21 | function void setColor(boolean b) { 22 | } 23 | 24 | /** Draws the (x, y) pixel. */ 25 | function void drawPixel(int x, int y) { 26 | } 27 | 28 | /** Draws a line from (x1, y1) to (x2, y2). */ 29 | function void drawLine(int x1, int y1, int x2, int y2) { 30 | } 31 | 32 | /** Draws a filled rectangle where the top left corner 33 | * is (x1, y1) and the bottom right corner is (x2, y2). */ 34 | function void drawRectangle(int x1, int y1, int x2, int y2) { 35 | } 36 | 37 | /** Draws a filled circle of radius r around (cx, cy). */ 38 | function void drawCircle(int cx, int cy, int r) { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /12/ScreenTest/Screen.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/Screen.jack 5 | 6 | /** 7 | * Graphic screen library. 8 | */ 9 | class Screen { 10 | 11 | /** Initializes the Screen. */ 12 | function void init() { 13 | } 14 | 15 | /** Erases the whole screen. */ 16 | function void clearScreen() { 17 | } 18 | 19 | /** Sets the color to be used in further draw commands 20 | * where white = false, black = true. */ 21 | function void setColor(boolean b) { 22 | } 23 | 24 | /** Draws the (x, y) pixel. */ 25 | function void drawPixel(int x, int y) { 26 | } 27 | 28 | /** Draws a line from (x1, y1) to (x2, y2). */ 29 | function void drawLine(int x1, int y1, int x2, int y2) { 30 | } 31 | 32 | /** Draws a filled rectangle where the top left corner 33 | * is (x1, y1) and the bottom right corner is (x2, y2). */ 34 | function void drawRectangle(int x1, int y1, int x2, int y2) { 35 | } 36 | 37 | /** Draws a filled circle of radius r around (cx, cy). */ 38 | function void drawCircle(int cx, int cy, int r) { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /01/DMux8Way.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/DMux8Way.tst 5 | 6 | load DMux8Way.hdl, 7 | output-file DMux8Way.out, 8 | compare-to DMux8Way.cmp, 9 | output-list in%B2.1.2 sel%B2.2.2 a%B2.1.2 b%B2.1.2 c%B2.1.2 d%B2.1.2 e%B2.1.2 f%B2.1.2 g%B2.1.2 h%B2.1.2; 10 | 11 | set in 0, 12 | set sel %B000, 13 | eval, 14 | output; 15 | 16 | set sel %B001, 17 | eval, 18 | output; 19 | 20 | set sel %B010, 21 | eval, 22 | output; 23 | 24 | set sel %B011, 25 | eval, 26 | output; 27 | 28 | set sel %B100, 29 | eval, 30 | output; 31 | 32 | set sel %B101, 33 | eval, 34 | output; 35 | 36 | set sel %B110, 37 | eval, 38 | output; 39 | 40 | set sel %B111, 41 | eval, 42 | output; 43 | 44 | set in 1, 45 | set sel %B000, 46 | eval, 47 | output; 48 | 49 | set sel %B001, 50 | eval, 51 | output; 52 | 53 | set sel %B010, 54 | eval, 55 | output; 56 | 57 | set sel %B011, 58 | eval, 59 | output; 60 | 61 | set sel %B100, 62 | eval, 63 | output; 64 | 65 | set sel %B101, 66 | eval, 67 | output; 68 | 69 | set sel %B110, 70 | eval, 71 | output; 72 | 73 | set sel %B111, 74 | eval, 75 | output; 76 | -------------------------------------------------------------------------------- /03/b/RAM16K.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/b/RAM16K.hdl 5 | 6 | /** 7 | * Memory of 16K registers, each 16-bit wide. 8 | * The chip facilitates read and write operations, as follows: 9 | * Read: out(t) = RAM16K[address(t)](t) 10 | * Write: If load(t-1) then RAM16K[address(t-1)](t) = in(t-1) 11 | * In words: the chip always outputs the value stored at the memory 12 | * location specified by address. If load=1, the in value is loaded 13 | * into the memory location specified by address. This value becomes 14 | * available through the out output starting from the next time step. 15 | */ 16 | 17 | CHIP RAM16K { 18 | IN in[16], load, address[14]; 19 | OUT out[16]; 20 | 21 | PARTS: 22 | DMux4Way(in=load, sel=address[12..13], a=l1, b=l2, c=l3, d=l4); 23 | RAM4K(in=in, load=l1, address=address[0..11], out=t1); 24 | RAM4K(in=in, load=l2, address=address[0..11], out=t2); 25 | RAM4K(in=in, load=l3, address=address[0..11], out=t3); 26 | RAM4K(in=in, load=l4, address=address[0..11], out=t4); 27 | Mux4Way16(a=t1, b=t2, c=t3, d=t4, sel=address[12..13], out=out); 28 | } 29 | -------------------------------------------------------------------------------- /00/Mux8Way16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | c | d | e | f | g | h | sel | out | 2 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0 | 0000 | 3 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 1 | 0000 | 4 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 2 | 0000 | 5 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 3 | 0000 | 6 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 4 | 0000 | 7 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 5 | 0000 | 8 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 6 | 0000 | 9 | | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 | 7 | 0000 | 10 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 0 | 1234 | 11 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 1 | 2345 | 12 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 2 | 3456 | 13 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 3 | 4567 | 14 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 4 | 5678 | 15 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 5 | 6789 | 16 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 6 | 789a | 17 | | 1234 | 2345 | 3456 | 4567 | 5678 | 6789 | 789a | 89ab | 7 | 89ab | 18 | -------------------------------------------------------------------------------- /07/MemoryAccess/StaticTest/StaticTest.asm: -------------------------------------------------------------------------------- 1 | // push constant 111 2 | @111 3 | D=A 4 | @SP 5 | A=M 6 | M=D 7 | @SP 8 | M=M+1 9 | 10 | // push constant 333 11 | @333 12 | D=A 13 | @SP 14 | A=M 15 | M=D 16 | @SP 17 | M=M+1 18 | 19 | // push constant 888 20 | @888 21 | D=A 22 | @SP 23 | A=M 24 | M=D 25 | @SP 26 | M=M+1 27 | 28 | // pop static 8 29 | @SP 30 | M=M-1 31 | A=M 32 | D=M 33 | @StaticTest.8 34 | M=D 35 | 36 | // pop static 3 37 | @SP 38 | M=M-1 39 | A=M 40 | D=M 41 | @StaticTest.3 42 | M=D 43 | 44 | // pop static 1 45 | @SP 46 | M=M-1 47 | A=M 48 | D=M 49 | @StaticTest.1 50 | M=D 51 | 52 | // push static 3 53 | @StaticTest.3 54 | D=M 55 | @SP 56 | A=M 57 | M=D 58 | @SP 59 | M=M+1 60 | 61 | // push static 1 62 | @StaticTest.1 63 | D=M 64 | @SP 65 | A=M 66 | M=D 67 | @SP 68 | M=M+1 69 | 70 | // sub 71 | @SP 72 | A=M 73 | A=A-1 74 | A=A-1 75 | D=M 76 | A=A+1 77 | D=D-M 78 | @SP 79 | M=M-1 80 | M=M-1 81 | A=M 82 | M=D 83 | @SP 84 | M=M+1 85 | 86 | // push static 8 87 | @StaticTest.8 88 | D=M 89 | @SP 90 | A=M 91 | M=D 92 | @SP 93 | M=M+1 94 | 95 | // add 96 | @SP 97 | A=M 98 | A=A-1 99 | A=A-1 100 | D=M 101 | A=A+1 102 | D=D+M 103 | @SP 104 | M=M-1 105 | M=M-1 106 | A=M 107 | M=D 108 | @SP 109 | M=M+1 110 | -------------------------------------------------------------------------------- /12/ArrayTest/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/ArrayTest/Main.jack 5 | 6 | /** Test program for the OS Array class. */ 7 | class Main { 8 | 9 | /** Performs several Array manipulations. */ 10 | function void main() { 11 | var Array r; // stores test results 12 | var Array a, b, c; 13 | 14 | let r = 8000; 15 | 16 | let a = Array.new(3); 17 | let a[2] = 222; 18 | let r[0] = a[2]; // RAM[8000] = 222 19 | 20 | let b = Array.new(3); 21 | let b[1] = a[2] - 100; 22 | let r[1] = b[1]; // RAM[8001] = 122 23 | 24 | let c = Array.new(500); 25 | let c[499] = a[2] - b[1]; 26 | let r[2] = c[499]; // RAM[8002] = 100 27 | 28 | do a.dispose(); 29 | do b.dispose(); 30 | 31 | let b = Array.new(3); 32 | let b[0] = c[499] - 90; 33 | let r[3] = b[0]; // RAM[8003] = 10 34 | 35 | do c.dispose(); 36 | do b.dispose(); 37 | 38 | return; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /07/commands/pop_command.rb: -------------------------------------------------------------------------------- 1 | class PopCommand 2 | Segments = { 3 | 'local' => 'LCL', 4 | 'argument' => 'ARG', 5 | 'this' => 'THIS', 6 | 'that' => 'THAT', 7 | } 8 | 9 | def initialize(id, filename, current_function, segment, index) 10 | @segment = segment 11 | @filename = filename 12 | @index = index 13 | end 14 | 15 | def emit 16 | case @segment 17 | when 'pointer' 18 | pointer = (@index == '0') ? 'THIS' : 'THAT' 19 | <<-ASM 20 | // pop #{@segment} #{@index} 21 | @SP 22 | M=M-1 23 | A=M 24 | D=M 25 | @#{pointer} 26 | M=D 27 | ASM 28 | when 'static' 29 | <<-ASM 30 | // pop #{@segment} #{@index} 31 | @SP 32 | M=M-1 33 | A=M 34 | D=M 35 | @#{@filename}.#{@index} 36 | M=D 37 | ASM 38 | when 'temp' 39 | offset = 5 + @index.to_i 40 | <<-ASM 41 | // pop #{@segment} #{@index} 42 | @SP 43 | M=M-1 44 | A=M 45 | D=M 46 | @#{offset} 47 | M=D 48 | ASM 49 | else 50 | <<-ASM 51 | // pop #{@segment} #{@index} 52 | @#{@index} 53 | D=A 54 | @#{Segments[@segment]} 55 | A=M 56 | D=D+A 57 | @#{Segments[@segment]} 58 | M=D 59 | @SP 60 | M=M-1 61 | A=M 62 | D=M 63 | @#{Segments[@segment]} 64 | A=M 65 | M=D 66 | @#{@index} 67 | D=A 68 | @#{Segments[@segment]} 69 | A=M 70 | D=A-D 71 | @#{Segments[@segment]} 72 | M=D 73 | ASM 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /11/symbol_table.rb: -------------------------------------------------------------------------------- 1 | require 'ostruct' 2 | 3 | class SymbolTable 4 | Kinds = [:local, :argument, :field, :static] 5 | 6 | attr_accessor :current_class 7 | 8 | def initialize 9 | @statics = [] 10 | @fields = [] 11 | start_subroutine 12 | end 13 | 14 | def lookup(name) 15 | Kinds.each do |kind| 16 | table = instance_variable_get("@#{kind.to_s.pluralize}") 17 | index = table.index { |entry| entry[:name] == name } 18 | 19 | if index.nil? 20 | next 21 | end 22 | 23 | entry = table[index] 24 | return OpenStruct.new(:present? => true, :index => index, :kind => kind, :type => entry[:type]) 25 | end 26 | 27 | OpenStruct.new(:present? => false) 28 | end 29 | 30 | def start_subroutine 31 | @locals = [] 32 | @arguments = [] 33 | end 34 | 35 | def start_instance_subroutine 36 | start_subroutine 37 | @arguments << {} 38 | end 39 | 40 | Kinds.each do |kind| 41 | define_method("define_#{kind}") do |name, type| 42 | table = instance_variable_get("@#{kind.to_s.pluralize}") 43 | entry = table.find { |entry| entry[:name] == name } 44 | if entry 45 | raise "Variable #{name} is already defined" 46 | else 47 | table << {:name => name, :type => type} 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /07/commands/push_command.rb: -------------------------------------------------------------------------------- 1 | class PushCommand 2 | Segments = { 3 | 'local' => 'LCL', 4 | 'argument' => 'ARG', 5 | 'this' => 'THIS', 6 | 'that' => 'THAT', 7 | } 8 | 9 | def initialize(id, filename, current_function, segment, index) 10 | @segment = segment 11 | @filename = filename 12 | @index = index 13 | end 14 | 15 | def emit 16 | case @segment 17 | when 'pointer' 18 | pointer = (@index == '0') ? 'THIS' : 'THAT' 19 | <<-ASM 20 | // push #{@segment} #{@index} 21 | @#{pointer} 22 | D=M 23 | @SP 24 | A=M 25 | M=D 26 | @SP 27 | M=M+1 28 | ASM 29 | when 'static' 30 | <<-ASM 31 | // push #{@segment} #{@index} 32 | @#{@filename}.#{@index} 33 | D=M 34 | @SP 35 | A=M 36 | M=D 37 | @SP 38 | M=M+1 39 | ASM 40 | when 'temp' 41 | offset = 5 + @index.to_i 42 | <<-ASM 43 | // push #{@segment} #{@index} 44 | @#{offset} 45 | D=M 46 | @SP 47 | A=M 48 | M=D 49 | @SP 50 | M=M+1 51 | ASM 52 | when 'constant' 53 | <<-ASM 54 | // push #{@segment} #{@index} 55 | @#{@index} 56 | D=A 57 | @SP 58 | A=M 59 | M=D 60 | @SP 61 | M=M+1 62 | ASM 63 | else 64 | <<-ASM 65 | // push #{@segment} #{@index} 66 | @#{@index} 67 | D=A 68 | @#{Segments[@segment]} 69 | A=M 70 | D=D+A 71 | A=D 72 | D=M 73 | @SP 74 | A=M 75 | M=D 76 | @SP 77 | M=M+1 78 | ASM 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /00/Register.tst: -------------------------------------------------------------------------------- 1 | // This file is part of the materials accompanying the book 2 | // "The Elements of Computing Systems" by Nisan and Schocken, 3 | // MIT Press. Book site: www.nand2tetris.org 4 | // File name: projects/00/Register.tst 5 | 6 | load Register.hdl, 7 | output-file Register.out, 8 | compare-to Register.cmp, 9 | output-list time%S1.4.1 in%D1.6.1 load%B2.1.2 out%D1.6.1; 10 | 11 | set in 0, 12 | set load 0, 13 | tick, 14 | output; 15 | 16 | tock, 17 | output; 18 | 19 | set in 0, 20 | set load 1, 21 | tick, 22 | output; 23 | 24 | tock, 25 | output; 26 | 27 | set in -32123, 28 | set load 0, 29 | tick, 30 | output; 31 | 32 | tock, 33 | output; 34 | 35 | set in 11111, 36 | set load 0, 37 | tick, 38 | output; 39 | 40 | tock, 41 | output; 42 | 43 | set in -32123, 44 | set load 1, 45 | tick, 46 | output; 47 | 48 | tock, 49 | output; 50 | 51 | set in -32123, 52 | set load 1, 53 | tick, 54 | output; 55 | 56 | tock, 57 | output; 58 | 59 | set in -32123, 60 | set load 0, 61 | tick, 62 | output; 63 | 64 | tock, 65 | output; 66 | 67 | set in 12345, 68 | set load 1, 69 | tick, 70 | output; 71 | 72 | tock, 73 | output; 74 | 75 | set in 0, 76 | set load 0, 77 | tick, 78 | output; 79 | 80 | tock, 81 | output; 82 | 83 | set in 0, 84 | set load 1, 85 | tick, 86 | output; 87 | 88 | tock, 89 | output; 90 | -------------------------------------------------------------------------------- /05/ComputerMax-external.cmp: -------------------------------------------------------------------------------- 1 | | time |reset|RAM16K[0]|RAM16K[1]|RAM16K[2]| 2 | | 0 | 0 | 3 | 5 | 0 | 3 | | 1 | 0 | 3 | 5 | 0 | 4 | | 2 | 0 | 3 | 5 | 0 | 5 | | 3 | 0 | 3 | 5 | 0 | 6 | | 4 | 0 | 3 | 5 | 0 | 7 | | 5 | 0 | 3 | 5 | 0 | 8 | | 6 | 0 | 3 | 5 | 0 | 9 | | 7 | 0 | 3 | 5 | 0 | 10 | | 8 | 0 | 3 | 5 | 0 | 11 | | 9 | 0 | 3 | 5 | 0 | 12 | | 10 | 0 | 3 | 5 | 0 | 13 | | 11 | 0 | 3 | 5 | 0 | 14 | | 12 | 0 | 3 | 5 | 5 | 15 | | 13 | 0 | 3 | 5 | 5 | 16 | | 14 | 0 | 3 | 5 | 5 | 17 | | 15 | 1 | 3 | 5 | 5 | 18 | | 15 | 0 | 23456 | 12345 | 5 | 19 | | 16 | 0 | 23456 | 12345 | 5 | 20 | | 17 | 0 | 23456 | 12345 | 5 | 21 | | 18 | 0 | 23456 | 12345 | 5 | 22 | | 19 | 0 | 23456 | 12345 | 5 | 23 | | 20 | 0 | 23456 | 12345 | 5 | 24 | | 21 | 0 | 23456 | 12345 | 5 | 25 | | 22 | 0 | 23456 | 12345 | 5 | 26 | | 23 | 0 | 23456 | 12345 | 5 | 27 | | 24 | 0 | 23456 | 12345 | 5 | 28 | | 25 | 0 | 23456 | 12345 | 23456 | 29 | -------------------------------------------------------------------------------- /12/MathTest/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/MathTest/Main.jack 5 | 6 | /** Test program for the OS Math class. */ 7 | class Main { 8 | 9 | /** Performs several mathematical operations from the Math class. */ 10 | function void main() { 11 | var Array r; // stores test results; 12 | 13 | let r = 8000; 14 | 15 | let r[0] = 2 * 3; // 6 16 | let r[1] = r[0] * (-30); // 6 * (-30) = -180 17 | let r[2] = r[1] * 100; // (-180) * 100 = -18000 18 | let r[3] = 1 * r[2]; // 1 * (-18000) = -18000 19 | let r[4] = r[3] * 0; // 0 20 | 21 | let r[5] = 9 / 3; // 3 22 | let r[6] = -18000 / 6; // -3000 23 | let r[7] = 32766 / (-32767); // 0 24 | 25 | let r[8] = Math.sqrt(9); // 3 26 | let r[9] = Math.sqrt(32767); // 181 27 | 28 | let r[10] = Math.min(345, 123); // 123 29 | let r[11] = Math.max(123, -345); // 123 30 | let r[12] = Math.abs(27); // 27 31 | let r[13] = Math.abs(-32767); // 32767 32 | 33 | return; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /02/Add16.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/02/Add16.hdl 5 | 6 | /* 7 | * Adds two 16-bit values. 8 | * The most significant carry bit is ignored. 9 | */ 10 | 11 | CHIP Add16 { 12 | IN a[16], b[16]; 13 | OUT out[16]; 14 | 15 | PARTS: 16 | HalfAdder(a=a[0], b=b[0], sum=out[0], carry=c1); 17 | FullAdder(a=a[1], b=b[1], c=c1, sum=out[1], carry=c2); 18 | FullAdder(a=a[2], b=b[2], c=c2, sum=out[2], carry=c3); 19 | FullAdder(a=a[3], b=b[3], c=c3, sum=out[3], carry=c4); 20 | FullAdder(a=a[4], b=b[4], c=c4, sum=out[4], carry=c5); 21 | FullAdder(a=a[5], b=b[5], c=c5, sum=out[5], carry=c6); 22 | FullAdder(a=a[6], b=b[6], c=c6, sum=out[6], carry=c7); 23 | FullAdder(a=a[7], b=b[7], c=c7, sum=out[7], carry=c8); 24 | FullAdder(a=a[8], b=b[8], c=c8, sum=out[8], carry=c9); 25 | FullAdder(a=a[9], b=b[9], c=c9, sum=out[9], carry=c10); 26 | FullAdder(a=a[10], b=b[10], c=c10, sum=out[10], carry=c11); 27 | FullAdder(a=a[11], b=b[11], c=c11, sum=out[11], carry=c12); 28 | FullAdder(a=a[12], b=b[12], c=c12, sum=out[12], carry=c13); 29 | FullAdder(a=a[13], b=b[13], c=c13, sum=out[13], carry=c14); 30 | FullAdder(a=a[14], b=b[14], c=c14, sum=out[14], carry=c15); 31 | FullAdder(a=a[15], b=b[15], c=c15, sum=out[15]); 32 | } 33 | -------------------------------------------------------------------------------- /12/ScreenTest/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/ScreenTest/Main.jack 5 | 6 | /** Test program for the OS Screen class. */ 7 | class Main { 8 | 9 | /** Draws a sample pictue on the screen using lines and circles. */ 10 | function void main() { 11 | 12 | do Screen.drawLine(0,220,511,220); // base line 13 | do Screen.drawRectangle(280,90,410,220); // house 14 | 15 | do Screen.setColor(false); 16 | do Screen.drawRectangle(350,120,390,219); // door 17 | do Screen.drawRectangle(292,120,332,150); // window 18 | 19 | do Screen.setColor(true); 20 | do Screen.drawCircle(360,170,3); // door handle 21 | do Screen.drawLine(280,90,345,35); // roof 22 | do Screen.drawLine(345,35,410,90); // roof 23 | 24 | do Screen.drawCircle(140,60,30); // sun 25 | do Screen.drawLine(140,26, 140, 6); 26 | do Screen.drawLine(163,35,178,20); 27 | do Screen.drawLine(174,60,194,60); 28 | do Screen.drawLine(163,85,178,100); 29 | do Screen.drawLine(140,94,140,114); 30 | do Screen.drawLine(117,85,102,100); 31 | do Screen.drawLine(106,60,86,60); 32 | do Screen.drawLine(117,35,102,20); 33 | 34 | return; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /03/a/RAM8.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/a/RAM8.hdl 5 | 6 | /** 7 | * Memory of 8 registers, each 16-bit wide. 8 | * The chip facilitates read and write operations, as follows: 9 | * Read: out(t) = RAM8[address(t)](t) 10 | * Write: If load(t-1) then RAM8[address(t-1)](t) = in(t-1) 11 | * In words: the chip always outputs the value stored at the memory 12 | * location specified by address. If load == 1, the in value is loaded 13 | * into the memory location specified by address. This value becomes 14 | * available through the out output starting from the next time step. 15 | */ 16 | 17 | CHIP RAM8 { 18 | IN in[16], load, address[3]; 19 | OUT out[16]; 20 | 21 | PARTS: 22 | DMux8Way16(in=in, sel=address, a=t1, b=t2, c=t3, d=t4, e=t5, f=t6, g=t7, h=t8); 23 | DMux8Way(in=load, sel=address, a=l1, b=l2, c=l3, d=l4, e=l5, f=l6, g=l7, h=l8); 24 | Register(in=t1, load=l1, out=w1); 25 | Register(in=t2, load=l2, out=w2); 26 | Register(in=t3, load=l3, out=w3); 27 | Register(in=t4, load=l4, out=w4); 28 | Register(in=t5, load=l5, out=w5); 29 | Register(in=t6, load=l6, out=w6); 30 | Register(in=t7, load=l7, out=w7); 31 | Register(in=t8, load=l8, out=w8); 32 | Mux8Way16(a=w1, b=w2, c=w3, d=w4, e=w5, f=w6, g=w7, h=w8, sel=address, out=out); 33 | } 34 | -------------------------------------------------------------------------------- /12/OutputTest/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/OutputTest/Main.jack 5 | 6 | /** Test program for the OS Output class. */ 7 | class Main { 8 | 9 | /** Outputs the entire character set to the screen using all the 10 | * methods of the Output class. */ 11 | function void main() { 12 | var String s; 13 | 14 | let s = String.new(1); 15 | do s.appendChar(String.doubleQuote()); 16 | 17 | do Output.moveCursor(0, 63); 18 | do Output.printChar(66); 19 | do Output.moveCursor(22, 0); 20 | do Output.printChar(67); 21 | do Output.moveCursor(22, 63); 22 | do Output.printChar(68); 23 | do Output.printChar(65); 24 | 25 | do Output.moveCursor(2, 0); 26 | do Output.printString("0123456789"); 27 | do Output.println(); 28 | 29 | do Output.printString("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"); 30 | do Output.println(); 31 | 32 | do Output.printString("!#$%&'()*+,-./:;<=>?@[\]^_`{|}~"); 33 | do Output.printString(s); 34 | do Output.println(); 35 | 36 | do Output.printInt(-12345); 37 | do Output.backSpace(); 38 | do Output.printInt(6789); 39 | 40 | return; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /00/Mux8Way16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of the materials accompanying the book 2 | // "The Elements of Computing Systems" by Nisan and Schocken, 3 | // MIT Press. Book site: www.nand2tetris.org 4 | // File name: projects/00/Mux8Way16.tst 5 | 6 | load Mux8Way16.hdl, 7 | output-file Mux8Way16.out, 8 | compare-to Mux8Way16.cmp, 9 | output-list a%X1.4.1 b%X1.4.1 c%X1.4.1 d%X1.4.1 e%X1.4.1 f%X1.4.1 g%X1.4.1 h%X1.4.1 sel%D2.1.2 out%X1.4.1; 10 | 11 | set a 0, 12 | set b 0, 13 | set c 0, 14 | set d 0, 15 | set e 0, 16 | set f 0, 17 | set g 0, 18 | set h 0, 19 | set sel 0, 20 | eval, 21 | output; 22 | 23 | set sel 1, 24 | eval, 25 | output; 26 | 27 | set sel 2, 28 | eval, 29 | output; 30 | 31 | set sel 3, 32 | eval, 33 | output; 34 | 35 | set sel 4, 36 | eval, 37 | output; 38 | 39 | set sel 5, 40 | eval, 41 | output; 42 | 43 | set sel 6, 44 | eval, 45 | output; 46 | 47 | set sel 7, 48 | eval, 49 | output; 50 | 51 | set a %X1234, 52 | set b %X2345, 53 | set c %X3456, 54 | set d %X4567, 55 | set e %X5678, 56 | set f %X6789, 57 | set g %X789a, 58 | set h %X89ab, 59 | set sel 0, 60 | eval, 61 | output; 62 | 63 | set sel 1, 64 | eval, 65 | output; 66 | 67 | set sel 2, 68 | eval, 69 | output; 70 | 71 | set sel 3, 72 | eval, 73 | output; 74 | 75 | set sel 4, 76 | eval, 77 | output; 78 | 79 | set sel 5, 80 | eval, 81 | output; 82 | 83 | set sel 6, 84 | eval, 85 | output; 86 | 87 | set sel 7, 88 | eval, 89 | output; 90 | -------------------------------------------------------------------------------- /07/translator.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'pathname' 4 | require 'active_support/inflector' 5 | 6 | $LOAD_PATH.unshift(File.expand_path('..', __FILE__)) 7 | 8 | require 'commands/bootstrap_command.rb' 9 | 10 | if ARGV.length != 1 11 | $stderr.puts "Must provide a VM file to translate" 12 | exit(1) 13 | end 14 | 15 | all_commands = [] 16 | all_commands << BootstrapCommand.new 17 | 18 | id = 0 19 | current_function = '' 20 | infiles = Dir.glob("*.vm") 21 | infiles.each do |infile| 22 | path = Pathname.new(infile) 23 | basename = path.basename('.vm') 24 | 25 | lines = File.readlines(infile) 26 | lines.map! { |line| line.gsub(/(\/\/.*)$/, '') } 27 | lines.map!(&:strip) 28 | lines.reject!(&:empty?) 29 | commands = lines.map do |line| 30 | parts = line.split(' ') 31 | command = parts.shift.gsub('-', '_') 32 | filename = "#{command}_command" 33 | klass = filename.camelize 34 | unless Kernel.const_defined?(klass) 35 | require "commands/#{filename}" 36 | end 37 | 38 | id += 1 39 | instance = klass.constantize.new(id, basename, current_function, *parts) 40 | if instance.is_a?(FunctionCommand) 41 | current_function = instance.function_name 42 | end 43 | instance 44 | end.compact 45 | all_commands.concat(commands) 46 | end 47 | 48 | outfile = ARGV[0] + '.asm' 49 | 50 | parts = all_commands.map(&:emit) 51 | output = parts.join("\n") 52 | puts output 53 | File.open(outfile, "w") do |file| 54 | file.write(output) 55 | end 56 | -------------------------------------------------------------------------------- /08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm 5 | 6 | // Puts the first argument[0] elements of the Fibonacci series 7 | // in the memory, starting in the address given in argument[1]. 8 | // Argument[0] and argument[1] are initialized by the test script 9 | // before this code starts running. 10 | 11 | push argument 1 12 | pop pointer 1 // that = argument[1] 13 | 14 | push constant 0 15 | pop that 0 // first element = 0 16 | push constant 1 17 | pop that 1 // second element = 1 18 | 19 | push argument 0 20 | push constant 2 21 | sub 22 | pop argument 0 // num_of_elements -= 2 (first 2 elements are set) 23 | 24 | label MAIN_LOOP_START 25 | 26 | push argument 0 27 | if-goto COMPUTE_ELEMENT // if num_of_elements > 0, goto COMPUTE_ELEMENT 28 | goto END_PROGRAM // otherwise, goto END_PROGRAM 29 | 30 | label COMPUTE_ELEMENT 31 | 32 | push that 0 33 | push that 1 34 | add 35 | pop that 2 // that[2] = that[0] + that[1] 36 | 37 | push pointer 1 38 | push constant 1 39 | add 40 | pop pointer 1 // that += 1 41 | 42 | push argument 0 43 | push constant 1 44 | sub 45 | pop argument 0 // num_of_elements-- 46 | 47 | goto MAIN_LOOP_START 48 | 49 | label END_PROGRAM 50 | -------------------------------------------------------------------------------- /00/RAM8.tst: -------------------------------------------------------------------------------- 1 | // This file is part of the materials accompanying the book 2 | // "The Elements of Computing Systems" by Nisan and Schocken, 3 | // MIT Press. Book site: www.nand2tetris.org 4 | // File name: projects/00/RAM8.tst 5 | 6 | load RAM8.hdl, 7 | output-file RAM8.output, 8 | compare-to RAM8.cmp, 9 | output-list time%S1.4.1 in%D1.6.1 load%B2.1.2 address%D3.1.3 out%D1.6.1; 10 | 11 | set in 0, 12 | set load 0, 13 | set address 0, 14 | tick, 15 | output; 16 | tock, 17 | output; 18 | 19 | set load 1, 20 | tick, 21 | output; 22 | tock, 23 | output; 24 | 25 | set in 11111, 26 | set load 0, 27 | tick, 28 | output; 29 | tock, 30 | output; 31 | 32 | set load 1, 33 | set address 1, 34 | tick, 35 | output; 36 | tock, 37 | output; 38 | 39 | set load 0, 40 | set address 0, 41 | tick, 42 | output; 43 | tock, 44 | output; 45 | 46 | set in 3333, 47 | set address 3, 48 | tick, 49 | output; 50 | tock, 51 | output; 52 | 53 | set load 1, 54 | tick, 55 | output; 56 | tock, 57 | output; 58 | 59 | set load 0, 60 | tick, 61 | output; 62 | tock, 63 | output; 64 | 65 | set address 1, 66 | eval, 67 | output; 68 | 69 | set in 7777, 70 | tick, 71 | output; 72 | tock, 73 | output; 74 | 75 | set load 1, 76 | set address 7, 77 | tick, 78 | output; 79 | tock, 80 | output; 81 | 82 | set load 0, 83 | tick, 84 | output; 85 | tock, 86 | output; 87 | 88 | set address 3, 89 | eval, 90 | output; 91 | 92 | set address 7, 93 | eval, 94 | output; 95 | -------------------------------------------------------------------------------- /12/MemoryTest/Main.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/MemoryTest/Main.jack 5 | 6 | /** Test program for the OS Memory class. */ 7 | class Main { 8 | 9 | /** Performs several memory manipulations. */ 10 | function void main() { 11 | var int temp; 12 | var Array a, b, c; 13 | 14 | do Memory.poke(8000, 333); // RAM[8000] = 333 15 | let temp = Memory.peek(8000); 16 | do Memory.poke(8001, temp + 1); // RAM[8001] = 334 17 | 18 | let a = Array.new(3); // uses Memory.alloc 19 | let a[2] = 222; 20 | do Memory.poke(8002, a[2]); // RAM[8002] = 222 21 | 22 | let b = Array.new(3); 23 | let b[1] = a[2] - 100; 24 | do Memory.poke(8003, b[1]); // RAM[8003] = 122 25 | 26 | let c = Array.new(500); 27 | let c[499] = a[2] - b[1]; 28 | do Memory.poke(8004, c[499]); // RAM[8004] = 100 29 | 30 | do a.dispose(); // uses Memory.deAlloc 31 | do b.dispose(); 32 | 33 | let b = Array.new(3); 34 | let b[0] = c[499] - 90; 35 | do Memory.poke(8005, b[0]); // RAM[8005] = 10 36 | 37 | do c.dispose(); 38 | do b.dispose(); 39 | 40 | return; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /03/a/PC.out: -------------------------------------------------------------------------------- 1 | | time | in |reset|load | inc | out | 2 | | 0+ | 0 | 0 | 0 | 0 | 0 | 3 | | 1 | 0 | 0 | 0 | 0 | 0 | 4 | | 1+ | 0 | 0 | 0 | 1 | 0 | 5 | | 2 | 0 | 0 | 0 | 1 | 1 | 6 | | 2+ | -32123 | 0 | 0 | 1 | 1 | 7 | | 3 | -32123 | 0 | 0 | 1 | 2 | 8 | | 3+ | -32123 | 0 | 1 | 1 | 2 | 9 | | 4 | -32123 | 0 | 1 | 1 | -32123 | 10 | | 4+ | -32123 | 0 | 0 | 1 | -32123 | 11 | | 5 | -32123 | 0 | 0 | 1 | -32122 | 12 | | 5+ | -32123 | 0 | 0 | 1 | -32122 | 13 | | 6 | -32123 | 0 | 0 | 1 | -32121 | 14 | | 6+ | 12345 | 0 | 1 | 0 | -32121 | 15 | | 7 | 12345 | 0 | 1 | 0 | 12345 | 16 | | 7+ | 12345 | 1 | 1 | 0 | 12345 | 17 | | 8 | 12345 | 1 | 1 | 0 | 0 | 18 | | 8+ | 12345 | 0 | 1 | 1 | 0 | 19 | | 9 | 12345 | 0 | 1 | 1 | 12345 | 20 | | 9+ | 12345 | 1 | 1 | 1 | 12345 | 21 | | 10 | 12345 | 1 | 1 | 1 | 0 | 22 | | 10+ | 12345 | 0 | 0 | 1 | 0 | 23 | | 11 | 12345 | 0 | 0 | 1 | 1 | 24 | | 11+ | 12345 | 1 | 0 | 1 | 1 | 25 | | 12 | 12345 | 1 | 0 | 1 | 0 | 26 | | 12+ | 0 | 0 | 1 | 1 | 0 | 27 | | 13 | 0 | 0 | 1 | 1 | 0 | 28 | | 13+ | 0 | 0 | 0 | 1 | 0 | 29 | | 14 | 0 | 0 | 0 | 1 | 1 | 30 | | 14+ | 22222 | 1 | 0 | 0 | 1 | 31 | | 15 | 22222 | 1 | 0 | 0 | 0 | 32 | -------------------------------------------------------------------------------- /12/Sys.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/Sys.jack 5 | 6 | /** 7 | * A library of basic system services. 8 | */ 9 | class Sys { 10 | 11 | /** Performs all the initializations required by the OS. */ 12 | function void init() { 13 | do Keyboard.init(); 14 | do Math.init(); 15 | do Memory.init(); 16 | do Output.init(); 17 | do Screen.init(); 18 | do Main.main(); 19 | do Sys.halt(); 20 | return; 21 | } 22 | 23 | /** Halts execution. */ 24 | function void halt() { 25 | while (true) { 26 | } 27 | return; 28 | } 29 | 30 | /** Waits approximately duration milliseconds and then returns. */ 31 | function void wait(int duration) { 32 | var int i; 33 | while (duration > 1000) { 34 | while (i < (1000 * 20)) { 35 | let i = i + 1; 36 | } 37 | let duration = duration - 1000; 38 | } 39 | 40 | let i = 0; 41 | while (i < (duration * 20)) { 42 | let i = i + 1; 43 | } 44 | 45 | return; 46 | } 47 | 48 | /** Prints the given error code in the form "ERR", and halts. */ 49 | function void error(int errorCode) { 50 | do Output.printString("ERR"); 51 | do Output.printInt(errorCode); 52 | do Sys.halt(); 53 | return; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /12/SysTest/Sys.jack: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/12/Sys.jack 5 | 6 | /** 7 | * A library of basic system services. 8 | */ 9 | class Sys { 10 | 11 | /** Performs all the initializations required by the OS. */ 12 | function void init() { 13 | do Keyboard.init(); 14 | do Math.init(); 15 | do Memory.init(); 16 | do Output.init(); 17 | do Screen.init(); 18 | do Main.main(); 19 | do Sys.halt(); 20 | return; 21 | } 22 | 23 | /** Halts execution. */ 24 | function void halt() { 25 | while (true) { 26 | } 27 | return; 28 | } 29 | 30 | /** Waits approximately duration milliseconds and then returns. */ 31 | function void wait(int duration) { 32 | var int i; 33 | while (duration > 1000) { 34 | while (i < (1000 * 20)) { 35 | let i = i + 1; 36 | } 37 | let duration = duration - 1000; 38 | } 39 | 40 | let i = 0; 41 | while (i < (duration * 20)) { 42 | let i = i + 1; 43 | } 44 | 45 | return; 46 | } 47 | 48 | /** Prints the given error code in the form "ERR", and halts. */ 49 | function void error(int errorCode) { 50 | do Output.printString("ERR"); 51 | do Output.printInt(errorCode); 52 | do Sys.halt(); 53 | return; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /03/a/PC.cmp: -------------------------------------------------------------------------------- 1 | | time | in |reset|load | inc | out | 2 | | 0+ | 0 | 0 | 0 | 0 | 0 | 3 | | 1 | 0 | 0 | 0 | 0 | 0 | 4 | | 1+ | 0 | 0 | 0 | 1 | 0 | 5 | | 2 | 0 | 0 | 0 | 1 | 1 | 6 | | 2+ | -32123 | 0 | 0 | 1 | 1 | 7 | | 3 | -32123 | 0 | 0 | 1 | 2 | 8 | | 3+ | -32123 | 0 | 1 | 1 | 2 | 9 | | 4 | -32123 | 0 | 1 | 1 | -32123 | 10 | | 4+ | -32123 | 0 | 0 | 1 | -32123 | 11 | | 5 | -32123 | 0 | 0 | 1 | -32122 | 12 | | 5+ | -32123 | 0 | 0 | 1 | -32122 | 13 | | 6 | -32123 | 0 | 0 | 1 | -32121 | 14 | | 6+ | 12345 | 0 | 1 | 0 | -32121 | 15 | | 7 | 12345 | 0 | 1 | 0 | 12345 | 16 | | 7+ | 12345 | 1 | 1 | 0 | 12345 | 17 | | 8 | 12345 | 1 | 1 | 0 | 0 | 18 | | 8+ | 12345 | 0 | 1 | 1 | 0 | 19 | | 9 | 12345 | 0 | 1 | 1 | 12345 | 20 | | 9+ | 12345 | 1 | 1 | 1 | 12345 | 21 | | 10 | 12345 | 1 | 1 | 1 | 0 | 22 | | 10+ | 12345 | 0 | 0 | 1 | 0 | 23 | | 11 | 12345 | 0 | 0 | 1 | 1 | 24 | | 11+ | 12345 | 1 | 0 | 1 | 1 | 25 | | 12 | 12345 | 1 | 0 | 1 | 0 | 26 | | 12+ | 0 | 0 | 1 | 1 | 0 | 27 | | 13 | 0 | 0 | 1 | 1 | 0 | 28 | | 13+ | 0 | 0 | 0 | 1 | 0 | 29 | | 14 | 0 | 0 | 0 | 1 | 1 | 30 | | 14+ | 22222 | 1 | 0 | 0 | 1 | 31 | | 15 | 22222 | 1 | 0 | 0 | 0 | 32 | -------------------------------------------------------------------------------- /03/a/RAM64.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/a/RAM64.hdl 5 | 6 | /** 7 | * Memory of 64 registers, each 16-bit wide. 8 | * The chip facilitates read and write operations, as follows: 9 | * Read: out(t) = RAM64[address(t)](t) 10 | * Write: If load(t-1) then RAM64[address(t-1)](t) = in(t-1) 11 | * In words: the chip always outputs the value stored at the memory 12 | * location specified by address. If load == 1, the in value is loaded 13 | * into the memory location specified by address. This value becomes 14 | * available through the out output starting from the next time step. 15 | */ 16 | 17 | CHIP RAM64 { 18 | IN in[16], load, address[6]; 19 | OUT out[16]; 20 | 21 | PARTS: 22 | DMux8Way(in=load, sel=address[3..5], a=l1, b=l2, c=l3, d=l4, e=l5, f=l6, g=l7, h=l8); 23 | RAM8(in=in, load=l1, address=address[0..2], out=t1); 24 | RAM8(in=in, load=l2, address=address[0..2], out=t2); 25 | RAM8(in=in, load=l3, address=address[0..2], out=t3); 26 | RAM8(in=in, load=l4, address=address[0..2], out=t4); 27 | RAM8(in=in, load=l5, address=address[0..2], out=t5); 28 | RAM8(in=in, load=l6, address=address[0..2], out=t6); 29 | RAM8(in=in, load=l7, address=address[0..2], out=t7); 30 | RAM8(in=in, load=l8, address=address[0..2], out=t8); 31 | Mux8Way16(a=t1, b=t2, c=t3, d=t4, e=t5, f=t6, g=t7, h=t8, sel=address[3..5], out=out); 32 | } 33 | -------------------------------------------------------------------------------- /01/Mux8Way16.tst: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/01/Mux8Way16.tst 5 | 6 | load Mux8Way16.hdl, 7 | output-file Mux8Way16.out, 8 | compare-to Mux8Way16.cmp, 9 | output-list a%B1.16.1 b%B1.16.1 c%B1.16.1 d%B1.16.1 e%B1.16.1 f%B1.16.1 g%B1.16.1 h%B1.16.1 sel%B2.3.2 out%B1.16.1; 10 | 11 | set a 0, 12 | set b 0, 13 | set c 0, 14 | set d 0, 15 | set e 0, 16 | set f 0, 17 | set g 0, 18 | set h 0, 19 | set sel 0, 20 | eval, 21 | output; 22 | 23 | set sel 1, 24 | eval, 25 | output; 26 | 27 | set sel 2, 28 | eval, 29 | output; 30 | 31 | set sel 3, 32 | eval, 33 | output; 34 | 35 | set sel 4, 36 | eval, 37 | output; 38 | 39 | set sel 5, 40 | eval, 41 | output; 42 | 43 | set sel 6, 44 | eval, 45 | output; 46 | 47 | set sel 7, 48 | eval, 49 | output; 50 | 51 | set a %B0001001000110100, 52 | set b %B0010001101000101, 53 | set c %B0011010001010110, 54 | set d %B0100010101100111, 55 | set e %B0101011001111000, 56 | set f %B0110011110001001, 57 | set g %B0111100010011010, 58 | set h %B1000100110101011, 59 | set sel 0, 60 | eval, 61 | output; 62 | 63 | set sel 1, 64 | eval, 65 | output; 66 | 67 | set sel 2, 68 | eval, 69 | output; 70 | 71 | set sel 3, 72 | eval, 73 | output; 74 | 75 | set sel 4, 76 | eval, 77 | output; 78 | 79 | set sel 5, 80 | eval, 81 | output; 82 | 83 | set sel 6, 84 | eval, 85 | output; 86 | 87 | set sel 7, 88 | eval, 89 | output; 90 | -------------------------------------------------------------------------------- /03/b/RAM512.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/b/RAM512.hdl 5 | 6 | /** 7 | * Memory of 512 registers, each 16-bit wide. 8 | * The chip facilitates read and write operations, as follows: 9 | * Read: out(t) = RAM512[address(t)](t) 10 | * Write: If load(t-1) then RAM512[address(t-1)](t) = in(t-1) 11 | * In words: the chip always outputs the value stored at the memory 12 | * location specified by address. If load == 1, the in value is loaded 13 | * into the memory location specified by address. This value becomes 14 | * available through the out output starting from the next time step. 15 | */ 16 | 17 | CHIP RAM512 { 18 | IN in[16], load, address[9]; 19 | OUT out[16]; 20 | 21 | PARTS: 22 | DMux8Way(in=load, sel=address[6..8], a=l1, b=l2, c=l3, d=l4, e=l5, f=l6, g=l7, h=l8); 23 | RAM64(in=in, load=l1, address=address[0..5], out=t1); 24 | RAM64(in=in, load=l2, address=address[0..5], out=t2); 25 | RAM64(in=in, load=l3, address=address[0..5], out=t3); 26 | RAM64(in=in, load=l4, address=address[0..5], out=t4); 27 | RAM64(in=in, load=l5, address=address[0..5], out=t5); 28 | RAM64(in=in, load=l6, address=address[0..5], out=t6); 29 | RAM64(in=in, load=l7, address=address[0..5], out=t7); 30 | RAM64(in=in, load=l8, address=address[0..5], out=t8); 31 | Mux8Way16(a=t1, b=t2, c=t3, d=t4, e=t5, f=t6, g=t7, h=t8, sel=address[6..8], out=out); 32 | } 33 | -------------------------------------------------------------------------------- /03/b/RAM4K.hdl: -------------------------------------------------------------------------------- 1 | // This file is part of www.nand2tetris.org 2 | // and the book "The Elements of Computing Systems" 3 | // by Nisan and Schocken, MIT Press. 4 | // File name: projects/03/b/RAM4K.hdl 5 | 6 | /** 7 | * Memory of 4K registers, each 16-bit wide. 8 | * The chip facilitates read and write operations, as follows: 9 | * Read: out(t) = RAM4K[address(t)](t) 10 | * Write: If load(t-1) then RAM4K[address(t-1)](t) = in(t-1) 11 | * In words: the chip always outputs the value stored at the memory 12 | * location specified by address. If load == 1, the in value is loaded 13 | * into the memory location specified by address. This value becomes 14 | * available through the out output starting from the next time step. 15 | */ 16 | 17 | CHIP RAM4K { 18 | IN in[16], load, address[12]; 19 | OUT out[16]; 20 | 21 | PARTS: 22 | DMux8Way(in=load, sel=address[9..11], a=l1, b=l2, c=l3, d=l4, e=l5, f=l6, g=l7, h=l8); 23 | RAM512(in=in, load=l1, address=address[0..8], out=t1); 24 | RAM512(in=in, load=l2, address=address[0..8], out=t2); 25 | RAM512(in=in, load=l3, address=address[0..8], out=t3); 26 | RAM512(in=in, load=l4, address=address[0..8], out=t4); 27 | RAM512(in=in, load=l5, address=address[0..8], out=t5); 28 | RAM512(in=in, load=l6, address=address[0..8], out=t6); 29 | RAM512(in=in, load=l7, address=address[0..8], out=t7); 30 | RAM512(in=in, load=l8, address=address[0..8], out=t8); 31 | Mux8Way16(a=t1, b=t2, c=t3, d=t4, e=t5, f=t6, g=t7, h=t8, sel=address[9..11], out=out); 32 | } 33 | -------------------------------------------------------------------------------- /11/nodes/subroutine_node.rb: -------------------------------------------------------------------------------- 1 | class SubroutineNode < Struct.new(:name, :kind, :return_type, :parameters, :body) 2 | def emit(writer, symbols, class_node) 3 | if kind == 'method' 4 | symbols.start_instance_subroutine 5 | else 6 | symbols.start_subroutine 7 | end 8 | 9 | parameters.each do |parameter| 10 | parameter.emit(writer, symbols) 11 | end 12 | 13 | writer.write_function("#{class_node.name}.#{name}", body.vars.length) 14 | 15 | case kind 16 | when 'constructor' 17 | field_count = class_node.class_vars.select { |var| var.kind.to_sym == :field }.count 18 | writer.write_push(:constant, field_count) 19 | writer.write_call('Memory.alloc', 1) 20 | writer.write_pop(:pointer, 0) 21 | when 'method' 22 | writer.write_push(:argument, 0) 23 | writer.write_pop(:pointer, 0) 24 | end 25 | 26 | body.emit(writer, symbols) 27 | end 28 | 29 | def to_xml 30 | builder = Builder::XmlMarkup.new 31 | builder.subroutineDec do |xml| 32 | xml.keyword(kind) 33 | if Tokenizer::Keywords.include?(return_type) 34 | xml.keyword(return_type) 35 | else 36 | xml.identifier(return_type) 37 | end 38 | xml.identifier(name) 39 | xml.symbol('(') 40 | xml.parameterList do |parameter_list_xml| 41 | parameters.each_with_index do |parameter, i| 42 | parameter_list_xml << parameter.to_xml 43 | if i != parameters.length - 1 44 | parameter_list_xml.symbol(',') 45 | end 46 | end 47 | end 48 | xml.symbol(')') 49 | xml << body.to_xml 50 | end 51 | builder.target! 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /11/Pong/Sys.vm: -------------------------------------------------------------------------------- 1 | function Sys.init 0 2 | call Memory.init 0 3 | pop temp 0 4 | call Math.init 0 5 | pop temp 0 6 | call Screen.init 0 7 | pop temp 0 8 | call Output.init 0 9 | pop temp 0 10 | call Keyboard.init 0 11 | pop temp 0 12 | call Main.main 0 13 | pop temp 0 14 | call Sys.halt 0 15 | pop temp 0 16 | push constant 0 17 | return 18 | function Sys.halt 0 19 | label WHILE_EXP0 20 | push constant 0 21 | not 22 | not 23 | if-goto WHILE_END0 24 | goto WHILE_EXP0 25 | label WHILE_END0 26 | push constant 0 27 | return 28 | function Sys.wait 1 29 | push argument 0 30 | push constant 0 31 | lt 32 | if-goto IF_TRUE0 33 | goto IF_FALSE0 34 | label IF_TRUE0 35 | push constant 1 36 | call Sys.error 1 37 | pop temp 0 38 | label IF_FALSE0 39 | label WHILE_EXP0 40 | push argument 0 41 | push constant 0 42 | gt 43 | not 44 | if-goto WHILE_END0 45 | push constant 50 46 | pop local 0 47 | label WHILE_EXP1 48 | push local 0 49 | push constant 0 50 | gt 51 | not 52 | if-goto WHILE_END1 53 | push local 0 54 | push constant 1 55 | sub 56 | pop local 0 57 | goto WHILE_EXP1 58 | label WHILE_END1 59 | push argument 0 60 | push constant 1 61 | sub 62 | pop argument 0 63 | goto WHILE_EXP0 64 | label WHILE_END0 65 | push constant 0 66 | return 67 | function Sys.error 0 68 | push constant 3 69 | call String.new 1 70 | push constant 69 71 | call String.appendChar 2 72 | push constant 82 73 | call String.appendChar 2 74 | push constant 82 75 | call String.appendChar 2 76 | call Output.printString 1 77 | pop temp 0 78 | push argument 0 79 | call Output.printInt 1 80 | pop temp 0 81 | call Sys.halt 0 82 | pop temp 0 83 | push constant 0 84 | return 85 | -------------------------------------------------------------------------------- /12/SysTest/Sys.vm: -------------------------------------------------------------------------------- 1 | function Sys.init 0 2 | call Keyboard.init 0 3 | pop temp 0 4 | call Math.init 0 5 | pop temp 0 6 | call Memory.init 0 7 | pop temp 0 8 | call Output.init 0 9 | pop temp 0 10 | call Screen.init 0 11 | pop temp 0 12 | call Main.main 0 13 | pop temp 0 14 | call Sys.halt 0 15 | pop temp 0 16 | push constant 0 17 | return 18 | function Sys.halt 0 19 | label WHILE_EXP0 20 | push constant 0 21 | not 22 | not 23 | if-goto WHILE_END0 24 | goto WHILE_EXP0 25 | label WHILE_END0 26 | push constant 0 27 | return 28 | function Sys.wait 1 29 | label WHILE_EXP0 30 | push argument 0 31 | push constant 1000 32 | gt 33 | not 34 | if-goto WHILE_END0 35 | label WHILE_EXP1 36 | push local 0 37 | push constant 1000 38 | push constant 20 39 | call Math.multiply 2 40 | lt 41 | not 42 | if-goto WHILE_END1 43 | push local 0 44 | push constant 1 45 | add 46 | pop local 0 47 | goto WHILE_EXP1 48 | label WHILE_END1 49 | push argument 0 50 | push constant 1000 51 | sub 52 | pop argument 0 53 | goto WHILE_EXP0 54 | label WHILE_END0 55 | push constant 0 56 | pop local 0 57 | label WHILE_EXP2 58 | push local 0 59 | push argument 0 60 | push constant 20 61 | call Math.multiply 2 62 | lt 63 | not 64 | if-goto WHILE_END2 65 | push local 0 66 | push constant 1 67 | add 68 | pop local 0 69 | goto WHILE_EXP2 70 | label WHILE_END2 71 | push constant 0 72 | return 73 | function Sys.error 0 74 | push constant 3 75 | call String.new 1 76 | push constant 69 77 | call String.appendChar 2 78 | push constant 82 79 | call String.appendChar 2 80 | push constant 82 81 | call String.appendChar 2 82 | call Output.printString 1 83 | pop temp 0 84 | push argument 0 85 | call Output.printInt 1 86 | pop temp 0 87 | call Sys.halt 0 88 | pop temp 0 89 | push constant 0 90 | return 91 | -------------------------------------------------------------------------------- /03/a/DMux8Way16.hdl: -------------------------------------------------------------------------------- 1 | CHIP DMux8Way16 { 2 | IN in[16], 3 | sel[3]; 4 | OUT a[16], b[16], c[16], d[16], 5 | e[16], f[16], g[16], h[16]; 6 | 7 | PARTS: 8 | DMux8Way(in=in[0], sel=sel, a=a[0], b=b[0], c=c[0], d=d[0], e=e[0], f=f[0], g=g[0], h=h[0]); 9 | DMux8Way(in=in[1], sel=sel, a=a[1], b=b[1], c=c[1], d=d[1], e=e[1], f=f[1], g=g[1], h=h[1]); 10 | DMux8Way(in=in[2], sel=sel, a=a[2], b=b[2], c=c[2], d=d[2], e=e[2], f=f[2], g=g[2], h=h[2]); 11 | DMux8Way(in=in[3], sel=sel, a=a[3], b=b[3], c=c[3], d=d[3], e=e[3], f=f[3], g=g[3], h=h[3]); 12 | DMux8Way(in=in[4], sel=sel, a=a[4], b=b[4], c=c[4], d=d[4], e=e[4], f=f[4], g=g[4], h=h[4]); 13 | DMux8Way(in=in[5], sel=sel, a=a[5], b=b[5], c=c[5], d=d[5], e=e[5], f=f[5], g=g[5], h=h[5]); 14 | DMux8Way(in=in[6], sel=sel, a=a[6], b=b[6], c=c[6], d=d[6], e=e[6], f=f[6], g=g[6], h=h[6]); 15 | DMux8Way(in=in[7], sel=sel, a=a[7], b=b[7], c=c[7], d=d[7], e=e[7], f=f[7], g=g[7], h=h[7]); 16 | DMux8Way(in=in[8], sel=sel, a=a[8], b=b[8], c=c[8], d=d[8], e=e[8], f=f[8], g=g[8], h=h[8]); 17 | DMux8Way(in=in[9], sel=sel, a=a[9], b=b[9], c=c[9], d=d[9], e=e[9], f=f[9], g=g[9], h=h[9]); 18 | DMux8Way(in=in[10], sel=sel, a=a[10], b=b[10], c=c[10], d=d[10], e=e[10], f=f[10], g=g[10], h=h[10]); 19 | DMux8Way(in=in[11], sel=sel, a=a[11], b=b[11], c=c[11], d=d[11], e=e[11], f=f[11], g=g[11], h=h[11]); 20 | DMux8Way(in=in[12], sel=sel, a=a[12], b=b[12], c=c[12], d=d[12], e=e[12], f=f[12], g=g[12], h=h[12]); 21 | DMux8Way(in=in[13], sel=sel, a=a[13], b=b[13], c=c[13], d=d[13], e=e[13], f=f[13], g=g[13], h=h[13]); 22 | DMux8Way(in=in[14], sel=sel, a=a[14], b=b[14], c=c[14], d=d[14], e=e[14], f=f[14], g=g[14], h=h[14]); 23 | DMux8Way(in=in[15], sel=sel, a=a[15], b=b[15], c=c[15], d=d[15], e=e[15], f=f[15], g=g[15], h=h[15]); 24 | } 25 | --------------------------------------------------------------------------------