-
Notifications
You must be signed in to change notification settings - Fork 0
/
interpreter.js
86 lines (70 loc) · 2.58 KB
/
interpreter.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
const { tokens } = require('./tokens.js');
const { Lexer } = require('./lexer.js');
/////////////////////////////////////////////////////
// Parser / Interpreter code /
/////////////////////////////////////////////////////
class Interpreter {
constructor(lexer) {
this.lexer = lexer;
this.currentToken = this.lexer.getNextToken(); // Default to the first token
}
error() {
throw 'Invalid Syntax';
}
eat(tokenType) { // "Eat" the current token and go on to the next
if (this.currentToken.type === tokenType) {
this.currentToken = this.lexer.getNextToken();
} else {
this.error();
}
}
factor() { // Return an integer value from the current token
const token = this.currentToken;
if (token.type == 'INTEGER') {
this.eat('INTEGER');
return token.value;
} else if (token.type == 'LPAREN') {
this.eat('LPAREN');
const result = this.expr();
this.eat('RPAREN');
return result;
} else {
this.error();
}
}
term() { // Perform any multiplications/divisions first
let result = this.factor();
// While the current token is MUL or DIV, loop the arithmetic
while (this.currentToken.type == 'MUL' || this.currentToken.type == 'DIV') {
const operator = this.currentToken.type;
if (operator == 'MUL') {
this.eat('MUL');
result *= this.factor(); // Continuously multiply/divide to the previous integer
} else if (operator == 'DIV') {
this.eat('DIV');
result /= this.factor();
}
}
return result;
}
expr() {
// Set the first token to any multiplication/division results present
let result = this.term()
// While the current token is ADD or SUB, loop the arithmetic
while (this.currentToken.type == 'ADD' || this.currentToken.type == 'SUB') {
const operator = this.currentToken.type;
if (operator == 'ADD') {
this.eat('ADD');
result += this.term(); // Continuously add/subtract to the previous product/quotient
} else if (operator == 'SUB') {
this.eat('SUB');
result -= this.term();
}
}
return result;
}
}
const lexer = new Lexer('5 * (6 + (4 / 10 * (3 + 3)))', tokens);
const interpreter = new Interpreter(lexer);
console.log(interpreter.expr());
// Expected output: 46