-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathairthmetic-code-writer.js
96 lines (87 loc) · 3.67 KB
/
airthmetic-code-writer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import CodeWriter from "./code-writer.js";
const binaryOperations = [ 'add', 'sub', 'and', 'or', 'eq', 'lt', 'gt' ];
export default class ArithmeticCodeWriter extends CodeWriter {
constructor(fileHandle) {
super(fileHandle);
this._labelIndex = 0;
this._inputFileName = '';
this._fileHandle = fileHandle;
}
async write(command) {
if (binaryOperations.includes(command.arg1)) {
await this.writeBinaryOperation(command);
} else {
await this.writeUnaryOperation(command);
}
}
async writeUnaryOperation(command) {
await this.writeDecrementStackPointer(`// ${command.type} ${command.arg1} ${command.arg2}`);
await this.writeLine('A=M');
if (command.arg1 == 'neg') {
await this.writeLine('M=-M');
} else if (command.arg1 == 'not') {
await this.writeLine('M=!M');
}
await this.writeIncrementStackPointer();
}
async writeBinaryOperation(command) {
await this.writeDecrementStackPointer(`// ${command.type} ${command.arg1} ${command.arg2}`);
await this.writeLine('A=M');
await this.writeLine('D=M');
await this.writeDecrementStackPointer();
// Address is already set to SP
await this.writeLine('A=M');
if (command.arg1 == 'add') {
await this.writeLine('M=D+M');
} else if (command.arg1 == 'sub') {
await this.writeLine('M=M-D');
} else if (command.arg1 == 'and') {
await this.writeLine('M=D&M');
} else if (command.arg1 == 'or') {
await this.writeLine('M=D|M');
} else if (command.arg1 == 'eq') {
await this.writeLine('D=D-M')
await this.writeLine(`@eq.${++this._labelIndex}`);
await this.writeLine('D;JEQ');
await this.writeLine('@SP');
await this.writeLine('A=M');
await this.writeLine('M=0');
await this.writeLine(`@endeq.${this._labelIndex}`);
await this.writeLine('0;JMP');
await this.writeLine(`(eq.${this._labelIndex})`);
await this.writeLine('@SP');
await this.writeLine('A=M');
await this.writeLine('M=-1');
await this.writeLine(`(endeq.${this._labelIndex})`);
} else if (command.arg1 == 'lt') {
await this.writeLine('D=M-D')
await this.writeLine(`@lt.${++this._labelIndex}`);
await this.writeLine('D;JLT');
await this.writeLine('@SP');
await this.writeLine('A=M');
await this.writeLine('M=0');
await this.writeLine(`@endlt.${this._labelIndex}`);
await this.writeLine('0;JMP');
await this.writeLine(`(lt.${this._labelIndex})`);
await this.writeLine('@SP');
await this.writeLine('A=M');
await this.writeLine('M=-1');
await this.writeLine(`(endlt.${this._labelIndex})`);
} else if (command.arg1 == 'gt') {
await this.writeLine('D=M-D')
await this.writeLine(`@gt.${++this._labelIndex}`);
await this.writeLine('D;JGT');
await this.writeLine('@SP');
await this.writeLine('A=M');
await this.writeLine('M=0');
await this.writeLine(`@endgt.${this._labelIndex}`);
await this.writeLine('0;JMP');
await this.writeLine(`(gt.${this._labelIndex})`);
await this.writeLine('@SP');
await this.writeLine('A=M');
await this.writeLine('M=-1');
await this.writeLine(`(endgt.${this._labelIndex})`);
}
await this.writeIncrementStackPointer();
}
}