[08] Optimized function starts a little
This commit is contained in:
parent
6bdbec501a
commit
5160559eff
|
@ -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
|
||||||
|
|
|
@ -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';
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue