├── 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 |
--------------------------------------------------------------------------------