[08] Implement Return/Function/Init
Return isn't functional (yet) Init isn't called (yet)
This commit is contained in:
parent
2fbdba0cf2
commit
b052ab617c
|
@ -0,0 +1,98 @@
|
||||||
|
(SimpleFunction.test) // function SimpleFunction.test 2
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1
|
||||||
|
@LCL
|
||||||
|
A=M
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push local 0 (L1)
|
||||||
|
@LCL // local 1
|
||||||
|
D=M
|
||||||
|
@1 // write 1 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @LCL+1 to R13
|
||||||
|
@R13
|
||||||
|
A=M
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push local 1 (L2)
|
||||||
|
@SP // ==== add ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=D+M
|
||||||
|
@SP
|
||||||
|
M=M-1 // end add (L3)
|
||||||
|
@SP // ==== not ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
M=!M // end not (L4)
|
||||||
|
@ARG
|
||||||
|
A=M
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push argument 0 (L5)
|
||||||
|
@SP // ==== add ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=D+M
|
||||||
|
@SP
|
||||||
|
M=M-1 // end add (L6)
|
||||||
|
@ARG // argument 1
|
||||||
|
D=M
|
||||||
|
@1 // write 1 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @ARG+1 to R13
|
||||||
|
@R13
|
||||||
|
A=M
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push argument 1 (L7)
|
||||||
|
@SP // ==== sub ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=M-D
|
||||||
|
@SP
|
||||||
|
M=M-1 // end sub (L8)
|
||||||
|
@ARG
|
||||||
|
D=M+1
|
||||||
|
@SP
|
||||||
|
M=D // @SP = ARG+1
|
||||||
|
@LCL
|
||||||
|
D=M // D=@LCL
|
||||||
|
@THAT
|
||||||
|
MD=D-1 // THAT = LCL-1
|
||||||
|
@THIS
|
||||||
|
MD=D-1 // THIS = LCL-2
|
||||||
|
@ARG
|
||||||
|
MD=D-1 // ARG = LCL-3
|
||||||
|
@LCL
|
||||||
|
MD=D-1 // LCL = LCL-4
|
||||||
|
A=D-1 // A = LCL-5
|
||||||
|
0;JMP // Jump to *(LCL-5)
|
||||||
|
@97
|
||||||
|
0;JMP
|
|
@ -0,0 +1 @@
|
||||||
|
| RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] |RAM[310]|
|
|
@ -1,2 +0,0 @@
|
||||||
|RAM[3000]|RAM[3001]|RAM[3002]|RAM[3003]|RAM[3004]|RAM[3005]|
|
|
||||||
| 0 | 1 | 1 | 2 | 3 | 5 |
|
|
|
@ -12,6 +12,68 @@ class CodeWriter {
|
||||||
$this->fn = null;
|
$this->fn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function writeReturn() {
|
||||||
|
$this->write([
|
||||||
|
// SP=ARG+1
|
||||||
|
"@ARG",
|
||||||
|
"D=M+1",
|
||||||
|
"@SP",
|
||||||
|
"M=D // @SP = ARG+1",
|
||||||
|
// THAT = LCL-1
|
||||||
|
"@LCL",
|
||||||
|
"D=M // D=@LCL",
|
||||||
|
"@THAT",
|
||||||
|
"MD=D-1 // THAT = LCL-1",
|
||||||
|
// THIS = LCL-2
|
||||||
|
"@THIS",
|
||||||
|
"MD=D-1 // THIS = LCL-2",
|
||||||
|
// ARG = LCL-3
|
||||||
|
"@ARG",
|
||||||
|
"MD=D-1 // ARG = LCL-3",
|
||||||
|
// LCL = LCL-4
|
||||||
|
"@LCL",
|
||||||
|
"MD=D-1 // LCL = LCL-4",
|
||||||
|
"A=D-1 // A = LCL-5",
|
||||||
|
"0;JMP // Jump to *(LCL-5)",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function writeFunction($name, $numArgs) {
|
||||||
|
$this->fn = $name;
|
||||||
|
$this->write([
|
||||||
|
"($name) // function $name $numArgs",
|
||||||
|
]);
|
||||||
|
for($i=0;$i<$numArgs;$i++) {
|
||||||
|
$this->write([
|
||||||
|
"@SP",
|
||||||
|
"A=M",
|
||||||
|
"M=D",
|
||||||
|
"@SP",
|
||||||
|
"M=M+1"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the preable to initialize the VM
|
||||||
|
*/
|
||||||
|
private function writeInit() {
|
||||||
|
$this->write([
|
||||||
|
"@256",
|
||||||
|
"D=A",
|
||||||
|
"@SP",
|
||||||
|
"M=D // initialized SP to 256",
|
||||||
|
"@16000",
|
||||||
|
"D=A",
|
||||||
|
"@LCL",
|
||||||
|
"M=D // initialized @LCL to 16000",
|
||||||
|
"@16500",
|
||||||
|
"D=A",
|
||||||
|
"@ARG",
|
||||||
|
"M=D // initialized @ARG to 16500",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
function setInputFileName($inputFileName) {
|
function setInputFileName($inputFileName) {
|
||||||
$this->vm = basename($inputFileName, ".vm");
|
$this->vm = basename($inputFileName, ".vm");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,12 @@ namespace captn3m0\NandToTetris;
|
||||||
class CommandType {
|
class CommandType {
|
||||||
const PUSH = 1;
|
const PUSH = 1;
|
||||||
const POP = 2;
|
const POP = 2;
|
||||||
|
|
||||||
// Program Flow Commands
|
// Program Flow Commands
|
||||||
const LABEL= 3;
|
const LABEL= 3;
|
||||||
const GOTO= 4;
|
const GOTO= 4;
|
||||||
const IF= 5;
|
const IF= 5;
|
||||||
|
|
||||||
// Function Calling Commands
|
// Function Calling Commands
|
||||||
const FUNC= 6;
|
const FUNC= 6;
|
||||||
const RETURN= 7;
|
const RETURN= 7;
|
||||||
|
|
|
@ -21,6 +21,10 @@ class VMTranslator {
|
||||||
$this->writer = new CodeWriter($outputFile);
|
$this->writer = new CodeWriter($outputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the main entry point for the VM Translator
|
||||||
|
* and starts the translate sequence
|
||||||
|
*/
|
||||||
function translate() {
|
function translate() {
|
||||||
foreach ($this->files as $file) {
|
foreach ($this->files as $file) {
|
||||||
$parser = new Parser($file);
|
$parser = new Parser($file);
|
||||||
|
@ -55,6 +59,16 @@ class VMTranslator {
|
||||||
$this->writer->writeGoto($label);
|
$this->writer->writeGoto($label);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CommandType::FUNC:
|
||||||
|
$functionName = $parser->arg1();
|
||||||
|
$numberOfArgs = $parser->arg2();
|
||||||
|
$this->writer->writeFunction($functionName, $numberOfArgs);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CommandType::RETURN:
|
||||||
|
$this->writer->writeReturn();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new \Exception("Not Implemented $command", 1);
|
throw new \Exception("Not Implemented $command", 1);
|
||||||
break;
|
break;
|
||||||
|
@ -66,6 +80,10 @@ class VMTranslator {
|
||||||
$this->writer->close();
|
$this->writer->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an output file name
|
||||||
|
* for the VM. Same as the Directory.asm
|
||||||
|
*/
|
||||||
private function outputFile() {
|
private function outputFile() {
|
||||||
$dir = dirname($this->files[0]);
|
$dir = dirname($this->files[0]);
|
||||||
$name = basename($dir);
|
$name = basename($dir);
|
||||||
|
|
Loading…
Reference in New Issue