Skip to content

Commit

Permalink
Merge pull request #20 from wildmaples/fibonacci-element-2
Browse files Browse the repository at this point in the history
Implement `FibonacciElement` and `StaticsTest`
  • Loading branch information
wildmaples authored Apr 13, 2024
2 parents 5f4bb7e + 49d4008 commit 24bd4b9
Show file tree
Hide file tree
Showing 15 changed files with 1,191 additions and 12 deletions.
10 changes: 7 additions & 3 deletions bin/vm-translator
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

require_relative '../lib/vm_translator'

vm_translator = VMTranslator.new(STDOUT)

if File.file?(ARGV[0])
input_file = File.open(ARGV[0])
puts VMTranslator.new.translate(input_file)
vm_translator.translate(input_file)
elsif File.directory?(ARGV[0])
vm_files = Dir[ARGV[0] + "/*.vm"]
vm_translator = VMTranslator.new
vm_translator.bootstrap
vm_files.each do |f|
input_file = File.open(f)
puts vm_translator.translate(input_file)
vm_translator.translate(input_file)
end
else
raise ArgumentError.new("Make sure your input is a folder or .vm file")
end

vm_translator.close
30 changes: 30 additions & 0 deletions examples/FibonacciElement/Main.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/08/FunctionCalls/FibonacciElement/Main.vm

// Computes the n'th element of the Fibonacci series, recursively.
// n is given in argument[0]. Called by the Sys.init function
// (part of the Sys.vm file), which also pushes the argument[0]
// parameter before this code starts running.

function Main.fibonacci 0
push argument 0
push constant 2
lt // checks if n<2
if-goto IF_TRUE
goto IF_FALSE
label IF_TRUE // if n<2, return n
push argument 0
return
label IF_FALSE // if n>=2, returns fib(n-2)+fib(n-1)
push argument 0
push constant 2
sub
call Main.fibonacci 1 // computes fib(n-2)
push argument 0
push constant 1
sub
call Main.fibonacci 1 // computes fib(n-1)
add // returns fib(n-1) + fib(n-2)
return
15 changes: 15 additions & 0 deletions examples/FibonacciElement/Sys.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/08/FunctionCalls/FibonacciElement/Sys.vm

// Pushes a constant, say n, onto the stack, and calls the Main.fibonacii
// function, which computes the n'th element of the Fibonacci series.
// Note that by convention, the Sys.init function is called "automatically"
// by the bootstrap code.

function Sys.init 0
push constant 4
call Main.fibonacci 1 // computes the 4'th fibonacci element
label WHILE
goto WHILE // loops infinitely
20 changes: 20 additions & 0 deletions examples/StaticsTest/Class1.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/08/FunctionCalls/StaticsTest/Class1.vm

// Stores two supplied arguments in static[0] and static[1].
function Class1.set 0
push argument 0
pop static 0
push argument 1
pop static 1
push constant 0
return

// Returns static[0] - static[1].
function Class1.get 0
push static 0
push static 1
sub
return
20 changes: 20 additions & 0 deletions examples/StaticsTest/Class2.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/08/FunctionCalls/StaticsTest/Class2.vm

// Stores two supplied arguments in static[0] and static[1].
function Class2.set 0
push argument 0
pop static 0
push argument 1
pop static 1
push constant 0
return

// Returns static[0] - static[1].
function Class2.get 0
push static 0
push static 1
sub
return
20 changes: 20 additions & 0 deletions examples/StaticsTest/Sys.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/08/FunctionCalls/StaticsTest/Sys.vm

// Tests that different functions, stored in two different
// class files, manipulate the static segment correctly.
function Sys.init 0
push constant 6
push constant 8
call Class1.set 2
pop temp 0 // Dumps the return value
push constant 23
push constant 15
call Class2.set 2
pop temp 0 // Dumps the return value
call Class1.get 0
call Class2.get 0
label WHILE
goto WHILE
8 changes: 6 additions & 2 deletions lib/code_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def write_call(function_name, num_args)
EOF
write_push_D_register

["LCL", "ARG", "THIS", "THAT"].each do |label|
%w[LCL ARG THIS THAT].each do |label|
@out.puts <<~EOF
@#{label}
D=M
Expand All @@ -170,7 +170,11 @@ def write_call(function_name, num_args)
M=D
EOF

write_goto(function_name)
@out.puts <<~EOF
@#{function_name}
0;JMP
EOF

write_label("return-address#{@label_counter}")
@label_counter += 1
end
Expand Down
16 changes: 11 additions & 5 deletions lib/vm_translator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
require 'stringio'

class VMTranslator
def initialize
# TODO: Add bootstrap code
def initialize(out)
@out = out
@code_writer = CodeWriter.new(out)
end

def bootstrap
code_writer.write_init
end

attr_reader :out, :code_writer

def translate(input_file)
out = StringIO.new
code_writer = CodeWriter.new(out)
parser = Parser.new(input_file)
file_name = File.basename(input_file.path, ".vm")

Expand Down Expand Up @@ -37,8 +42,9 @@ def translate(input_file)
warn("Unknown command type passed into VMTranslator")
end
end
end

def close
code_writer.close
out.string
end
end
Loading

0 comments on commit 24bd4b9

Please sign in to comment.