diff --git a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm index 6059cf7..91ca140 100644 --- a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm +++ b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm @@ -1,3 +1,15 @@ +@256 // init starts +D=A +@SP +M=D // initialized SP to 256 +@300 +D=A +@LCL +M=D // initialized @LCL to 300 +@400 +D=A +@ARG +M=D // initialized @ARG to 400, init ends @ARG // argument 1 D=M @1 // write 1 to A @@ -192,5 +204,5 @@ M=D // end pop argument 0 (L26) @__GLOBAL__.MAIN_LOOP_START 0;JMP // end goto MAIN_LOOP_START (L27) (__GLOBAL__.END_PROGRAM) // end label END_PROGRAM (L28) -@195 +@207 0;JMP diff --git a/vm/CodeWriter.php b/vm/CodeWriter.php index 253d64a..3ca924c 100644 --- a/vm/CodeWriter.php +++ b/vm/CodeWriter.php @@ -10,6 +10,9 @@ class CodeWriter { // We aren't inside a function by default $this->fn = null; + + // Write the preamble for the assembler + $this->writeInit(); } public function writeReturn() { @@ -76,18 +79,35 @@ class CodeWriter { ]); } + /** + * Translates the "function" start. + * function $name $args + */ public function writeFunction($name, $numArgs) { + // This is used for labels within the current function $this->fn = $name; + $this->write([ "($name) // function $name $numArgs", ]); + + // We write this once at the top + // And for subsequent loops, we can re-use + // the @SP call at the end where we bump the stack by 1 + if ($numArgs > 0) { + $this->write([ + // This is only required for the first argument + "@SP", "A=M" + ]); + } + + // For every argument in the function + // push a zero to the stack for($i=0;$i<$numArgs;$i++) { $this->write([ + "M=0", "@SP", - "A=M", - "M=D", - "@SP", - "M=M+1" + "AM=M+1", ]); } } @@ -97,7 +117,7 @@ class CodeWriter { */ private function writeInit() { $this->write([ - "@256", + "@256 // init starts", "D=A", "@SP", "M=D // initialized SP to 256", @@ -108,7 +128,10 @@ class CodeWriter { "@400", "D=A", "@ARG", - "M=D // initialized @ARG to 400", + "M=D // initialized @ARG to 400, init ends", + // We jump to Sys.init + "@Sys.init", + "0;JMP" ]); } @@ -486,6 +509,9 @@ class CodeWriter { } } + /** + * Resolves pointer [0|1] to the this|that register + */ private function resolvePointer(Int $index) { return $index == 0 ? '@THIS' : '@THAT'; } diff --git a/vm/VMTranslator.php b/vm/VMTranslator.php index 5f1c2d8..eb7e14d 100644 --- a/vm/VMTranslator.php +++ b/vm/VMTranslator.php @@ -27,11 +27,14 @@ class VMTranslator { */ function translate() { foreach ($this->files as $file) { + $parser = new Parser($file); $this->writer->setInputFileName($file); foreach ($parser->commands() as $command) { + $commandType = CommandType::fromName($command); + switch ($commandType) { case CommandType::ARITHMETIC: $this->writer->writeArithmetic($command);