[07] StackTest passes
This commit is contained in:
parent
be69ac321d
commit
3fa5a5c07a
13
README.md
13
README.md
|
@ -92,10 +92,19 @@ Counting number of instructions by `wc -l $file.hack`
|
|||
|
||||
## [Project 6: Virtual Machine I - Stack Arithmetic](https://www.nand2tetris.org/project07)
|
||||
|
||||
Final hack instruction set count in brackets. Calculated by running:
|
||||
|
||||
|
||||
```
|
||||
php file.vm > file.asm
|
||||
ruby assembler.rb file.vm > file.hack
|
||||
wc -l file.hack
|
||||
```
|
||||
|
||||
### Arithmetic Commands
|
||||
|
||||
- [ ] SimpleAdd.vm
|
||||
- [ ] StackTest.vm
|
||||
- [x] SimpleAdd.vm (21)
|
||||
- [x] StackTest.vm (334)
|
||||
|
||||
### Memory Access Commands
|
||||
|
||||
|
|
|
@ -0,0 +1,334 @@
|
|||
@17 // push constant 17
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 17
|
||||
@17 // push constant 17
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 17
|
||||
@SP // ==== eq ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@27
|
||||
D;JEQ
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@17 // push constant 17
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 17
|
||||
@16 // push constant 16
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 16
|
||||
@SP // ==== eq ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@56
|
||||
D;JEQ
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@16 // push constant 16
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 16
|
||||
@17 // push constant 17
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 17
|
||||
@SP // ==== eq ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@85
|
||||
D;JEQ
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@892 // push constant 892
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 892
|
||||
@891 // push constant 891
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 891
|
||||
@SP // ==== lt ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@114
|
||||
D;JLT
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@891 // push constant 891
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 891
|
||||
@892 // push constant 892
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 892
|
||||
@SP // ==== lt ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@143
|
||||
D;JLT
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@891 // push constant 891
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 891
|
||||
@891 // push constant 891
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 891
|
||||
@SP // ==== lt ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@172
|
||||
D;JLT
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@32767 // push constant 32767
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 32767
|
||||
@32766 // push constant 32766
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 32766
|
||||
@SP // ==== gt ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@201
|
||||
D;JGT
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@32766 // push constant 32766
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 32766
|
||||
@32767 // push constant 32767
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 32767
|
||||
@SP // ==== gt ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@230
|
||||
D;JGT
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@32766 // push constant 32766
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 32766
|
||||
@32766 // push constant 32766
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 32766
|
||||
@SP // ==== gt ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
D=M-D
|
||||
M=0
|
||||
M=M-1
|
||||
@259
|
||||
D;JGT
|
||||
@SP
|
||||
A=M-1
|
||||
A=A-1
|
||||
M=0
|
||||
@SP
|
||||
M=M-1
|
||||
@57 // push constant 57
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 57
|
||||
@31 // push constant 31
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 31
|
||||
@53 // push constant 53
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 53
|
||||
@SP // ==== add ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
M=D+M
|
||||
@SP
|
||||
M=M-1
|
||||
@112 // push constant 112
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 112
|
||||
@SP // ==== sub ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
M=M-D
|
||||
@SP
|
||||
M=M-1
|
||||
@SP // ==== neg ====
|
||||
A=M-1
|
||||
D=M
|
||||
M=-M
|
||||
@SP // ==== and ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
M=D&M
|
||||
@SP
|
||||
M=M-1
|
||||
@82 // push constant 82
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1 // end push constant 82
|
||||
@SP // ==== or ====
|
||||
A=M-1
|
||||
D=M
|
||||
A=A-1
|
||||
M=D|M
|
||||
@SP
|
||||
M=M-1
|
||||
@SP // ==== not ====
|
||||
A=M-1
|
||||
D=M
|
||||
M=!M
|
||||
@333
|
||||
0;JMP
|
|
@ -0,0 +1,4 @@
|
|||
| RAM[0] | RAM[256] | RAM[257] | RAM[258] | RAM[259] | RAM[260] |
|
||||
| 266 | -1 | 0 | 0 | 0 | -1 |
|
||||
| RAM[261] | RAM[262] | RAM[263] | RAM[264] | RAM[265] |
|
||||
| 0 | -1 | 0 | 0 | -91 |
|
|
@ -76,49 +76,128 @@ class CodeWriter {
|
|||
fclose($this->file);
|
||||
}
|
||||
|
||||
function close() {
|
||||
$endJump = $this->ic+1;
|
||||
$this->write([
|
||||
"@$endJump",
|
||||
"0;JMP"
|
||||
]);
|
||||
}
|
||||
|
||||
function writeArithmetic(String $command ) {
|
||||
$stackDecrease=true;
|
||||
// Read top of stack to D
|
||||
$this->write([
|
||||
"// ==== $command ====",
|
||||
"// pop starts",
|
||||
"@SP",
|
||||
"@SP // ==== $command ====",
|
||||
"A=M-1",
|
||||
"D=M",
|
||||
"// pop ends",
|
||||
"// inner $command starts",
|
||||
'A=A-1',
|
||||
"D=M"
|
||||
]);
|
||||
|
||||
switch ($command) {
|
||||
case 'sub':
|
||||
$this->write([
|
||||
'A=A-1',
|
||||
"M=M-D",
|
||||
]);
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
// But add it to previous D this time
|
||||
$this->write([
|
||||
"M=D+M"
|
||||
'A=A-1',
|
||||
'M=D+M'
|
||||
]);
|
||||
break;
|
||||
|
||||
case 'neg':
|
||||
$this->write([
|
||||
'M=-M',
|
||||
]);
|
||||
$stackDecrease = false;
|
||||
break;
|
||||
|
||||
|
||||
case 'not':
|
||||
$this->write([
|
||||
'M=!M',
|
||||
]);
|
||||
$stackDecrease = false;
|
||||
break;
|
||||
|
||||
case 'and':
|
||||
$this->write([
|
||||
'A=A-1',
|
||||
'M=D&M',
|
||||
]);
|
||||
break;
|
||||
|
||||
case 'or':
|
||||
$this->write([
|
||||
'A=A-1',
|
||||
'M=D|M',
|
||||
]);
|
||||
break;
|
||||
|
||||
case 'lt':
|
||||
$jumpPointer = $this->ic+10;
|
||||
$this->write([
|
||||
'A=A-1',
|
||||
'D=M-D',
|
||||
'M=0',
|
||||
'M=M-1',
|
||||
"@$jumpPointer",
|
||||
"D;JLT",
|
||||
"@SP",
|
||||
"A=M-1",
|
||||
"A=A-1",
|
||||
"M=0",
|
||||
]);
|
||||
break;
|
||||
|
||||
case 'gt':
|
||||
$jumpPointer = $this->ic+10;
|
||||
$this->write([
|
||||
'A=A-1',
|
||||
'D=M-D',
|
||||
'M=0',
|
||||
'M=M-1',
|
||||
"@$jumpPointer",
|
||||
"D;JGT",
|
||||
"@SP",
|
||||
"A=M-1",
|
||||
"A=A-1",
|
||||
"M=0",
|
||||
]);
|
||||
break;
|
||||
|
||||
case 'eq':
|
||||
$jumpPointer = $this->ic+5;
|
||||
$jumpPointer = $this->ic+10;
|
||||
$this->write([
|
||||
'D=M-D', // ic
|
||||
'M=0', // set M=0, in case they aren't equal
|
||||
"@{jumpPointer}",
|
||||
'D;JEQ', //ic+2
|
||||
'M=0', //ic+3
|
||||
'M=M-1', //ic+4
|
||||
// set M=-1 (TRUE), in case they are equal
|
||||
// *SP=-1 = true
|
||||
'A=A-1',
|
||||
'D=M-D',
|
||||
'M=0',
|
||||
'M=M-1',
|
||||
"@{$jumpPointer}",
|
||||
'D;JEQ',
|
||||
"@SP",
|
||||
"A=M-1",
|
||||
"A=A-1",
|
||||
"M=0",
|
||||
]);
|
||||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
throw new \Exception("$command not Implemented", 1);
|
||||
|
||||
}
|
||||
|
||||
if ($stackDecrease) {
|
||||
$this->write([
|
||||
'@SP',
|
||||
'M=M-1'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function write(Array $lines) {
|
||||
foreach ($lines as $line) {
|
||||
|
@ -133,9 +212,8 @@ class CodeWriter {
|
|||
switch ($segment) {
|
||||
case 'constant':
|
||||
$this->write([
|
||||
"// push $segment $index",
|
||||
// Take the constant
|
||||
"@$index",
|
||||
"@$index // push $segment $index",
|
||||
// Write it to D
|
||||
"D=A",
|
||||
// A=SP
|
||||
|
@ -145,8 +223,7 @@ class CodeWriter {
|
|||
"M=D",
|
||||
// Bump Stack Pointer
|
||||
"@SP",
|
||||
"M=M+1",
|
||||
"// end push $segment $index"
|
||||
"M=M+1 // end push $segment $index",
|
||||
]);
|
||||
break;
|
||||
|
||||
|
@ -213,6 +290,7 @@ class VMTranslator {
|
|||
}
|
||||
}
|
||||
}
|
||||
$this->writer->close();
|
||||
}
|
||||
|
||||
private function outputFile() {
|
||||
|
|
Loading…
Reference in New Issue