[08] Optimized function starts a little

This commit is contained in:
Nemo 2020-06-04 01:25:06 +05:30
parent 6bdbec501a
commit 5160559eff
3 changed files with 48 additions and 7 deletions

View File

@ -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 @ARG // argument 1
D=M D=M
@1 // write 1 to A @1 // write 1 to A
@ -192,5 +204,5 @@ M=D // end pop argument 0 (L26)
@__GLOBAL__.MAIN_LOOP_START @__GLOBAL__.MAIN_LOOP_START
0;JMP // end goto MAIN_LOOP_START (L27) 0;JMP // end goto MAIN_LOOP_START (L27)
(__GLOBAL__.END_PROGRAM) // end label END_PROGRAM (L28) (__GLOBAL__.END_PROGRAM) // end label END_PROGRAM (L28)
@195 @207
0;JMP 0;JMP

View File

@ -10,6 +10,9 @@ class CodeWriter {
// We aren't inside a function by default // We aren't inside a function by default
$this->fn = null; $this->fn = null;
// Write the preamble for the assembler
$this->writeInit();
} }
public function writeReturn() { public function writeReturn() {
@ -76,18 +79,35 @@ class CodeWriter {
]); ]);
} }
/**
* Translates the "function" start.
* function $name $args
*/
public function writeFunction($name, $numArgs) { public function writeFunction($name, $numArgs) {
// This is used for labels within the current function
$this->fn = $name; $this->fn = $name;
$this->write([ $this->write([
"($name) // function $name $numArgs", "($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++) { for($i=0;$i<$numArgs;$i++) {
$this->write([ $this->write([
"M=0",
"@SP", "@SP",
"A=M", "AM=M+1",
"M=D",
"@SP",
"M=M+1"
]); ]);
} }
} }
@ -97,7 +117,7 @@ class CodeWriter {
*/ */
private function writeInit() { private function writeInit() {
$this->write([ $this->write([
"@256", "@256 // init starts",
"D=A", "D=A",
"@SP", "@SP",
"M=D // initialized SP to 256", "M=D // initialized SP to 256",
@ -108,7 +128,10 @@ class CodeWriter {
"@400", "@400",
"D=A", "D=A",
"@ARG", "@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) { private function resolvePointer(Int $index) {
return $index == 0 ? '@THIS' : '@THAT'; return $index == 0 ? '@THIS' : '@THAT';
} }

View File

@ -27,11 +27,14 @@ class VMTranslator {
*/ */
function translate() { function translate() {
foreach ($this->files as $file) { foreach ($this->files as $file) {
$parser = new Parser($file); $parser = new Parser($file);
$this->writer->setInputFileName($file); $this->writer->setInputFileName($file);
foreach ($parser->commands() as $command) { foreach ($parser->commands() as $command) {
$commandType = CommandType::fromName($command); $commandType = CommandType::fromName($command);
switch ($commandType) { switch ($commandType) {
case CommandType::ARITHMETIC: case CommandType::ARITHMETIC:
$this->writer->writeArithmetic($command); $this->writer->writeArithmetic($command);