[07] Almost done with BasicTest implementation

This commit is contained in:
Nemo 2020-06-02 01:42:15 +05:30
parent 3fa5a5c07a
commit 9782ba7e4d
3 changed files with 311 additions and 10 deletions

View File

@ -0,0 +1,224 @@
@10 // push constant 10
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 10
@SP // pop
A=M-1
D=M
@LCL
A=M // Read @LCL to A
M=D // Write D to *A
@21 // push constant 21
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 21
@22 // push constant 22
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 22
@ARG // argument 2
D=M
@2 // write 2 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @ARG+2 to R13
@SP // pop
A=M-1
D=M
@R13
A=M // Read @R13 to A
M=D // Write D to *A
@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
@SP // pop
A=M-1
D=M
@R13
A=M // Read @R13 to A
M=D // Write D to *A
@36 // push constant 36
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 36
@THIS // this 6
D=M
@6 // write 6 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @THIS+6 to R13
@SP // pop
A=M-1
D=M
@R13
A=M // Read @R13 to A
M=D // Write D to *A
@42 // push constant 42
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 42
@45 // push constant 45
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 45
@THAT // that 5
D=M
@5 // write 5 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @THAT+5 to R13
@SP // pop
A=M-1
D=M
@R13
A=M // Read @R13 to A
M=D // Write D to *A
@THAT // that 2
D=M
@2 // write 2 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @THAT+2 to R13
@SP // pop
A=M-1
D=M
@R13
A=M // Read @R13 to A
M=D // Write D to *A
@510 // push constant 510
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 510
@LCL // local 0
D=M
@0 // write 0 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @LCL+0 to R13
@R13
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push local 0
@THAT // that 5
D=M
@5 // write 5 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @THAT+5 to R13
@R13
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push that 5
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1
@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
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push argument 1
@SP // ==== sub ====
A=M-1
D=M
A=A-1
M=M-D
@SP
M=M-1
@THIS // this 6
D=M
@6 // write 6 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @THIS+6 to R13
@R13
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push this 6
@THIS // this 6
D=M
@6 // write 6 to A
D=D+A // D = segment+index
@R13 // save it to R13
M=D // write @THIS+6 to R13
@R13
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push this 6
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1
@SP // ==== sub ====
A=M-1
D=M
A=A-1
M=M-D
@SP
M=M-1
@R11 // temp 6
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push temp 6
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1
@223
0;JMP

View File

@ -0,0 +1,2 @@
|RAM[256]|RAM[300]|RAM[401]|RAM[402]|RAM[3006|RAM[3012|RAM[3015|RAM[11] |
| 10 | 10 | 22 | 22 | 36 | 45 | 45 | 0 |

View File

@ -216,19 +216,94 @@ class CodeWriter {
"@$index // push $segment $index", "@$index // push $segment $index",
// Write it to D // Write it to D
"D=A", "D=A",
// A=SP ]);
"@SP", break;
"A=M", case 'argument':
// Write D to SP case 'local':
"M=D", case 'this':
// Bump Stack Pointer case 'that':
"@SP", $this->resolveSegmentToR13($segment, $index);
"M=M+1 // end push $segment $index", $this->write([
"@R13",
"D=M",
]);
break;
case 'temp':
// Temp section starts from R5;
$tempBase = 5;
$ramAddress = $tempBase + $index;
$register = "@R$ramAddress";
$this->write([
"$register // temp $index",
"D=M"
]); ]);
break; break;
default: default:
throw new Exception("Not Implemented $segment", 1); throw new \Exception("Not Implemented $segment", 1);
break;
}
$this->write([
// A=SP
"@SP",
"A=M",
// Write D to SP
"M=D",
// Bump Stack Pointer
"@SP",
"M=M+1 // end push $segment $index",
]);
}
private function segmentToRegister(String $segment) {
return [
'local' => '@LCL',
'argument' => '@ARG',
'this' => '@THIS',
'that' => '@THAT',
][$segment];
}
private function resolveSegmentToR13(string $segment, Int $index) {
$register = $this->segmentToRegister($segment);
$this->write([
"$register // $segment $index" ,
"D=M",
"@$index // write $index to A",
"D=D+A // D = segment+index",
"@R13 // save it to R13",
"M=D // write $register+$index to R13",
]);
}
private function writePop(String $segment, Int $index) {
switch ($segment) {
// The address is given by LCL+INDEX
case 'local':
case 'argument':
case 'this':
case 'that':
if($index !== 0) {
$this->resolveSegmentToR13($segment, $index);
$lookupRegister = '@R13';
} else {
$lookupRegister = $this->segmentToRegister($segment);
}
$this->write([
"@SP // pop",
"A=M-1",
"D=M",
$lookupRegister,
"A=M // Read $lookupRegister to A",
"M=D // Write D to *A",
]);
break;
default:
# code...
break; break;
} }
} }
@ -240,7 +315,7 @@ class CodeWriter {
break; break;
case CommandType::POP: case CommandType::POP:
$this->writePop($segment, $index);
break; break;
default: default:
throw new Exception("Invalid Command Type", 1); throw new Exception("Invalid Command Type", 1);