-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterpreter.cpp
More file actions
160 lines (146 loc) · 3.51 KB
/
Copy pathinterpreter.cpp
File metadata and controls
160 lines (146 loc) · 3.51 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <string>
#include <iostream>
#include "interpreter.h"
using namespace std;
Interpreter::Interpreter(Parser p): p(p) {
}
void Interpreter::interpret() {
// Assuming start symbol is 'statementList'
visit(p.statementList());
}
int Interpreter::visit(ASTNode* n) {
switch(n->nodeType) {
case NODE_COMPOUND:
return visitCompound(n);
case NODE_NUM:
return visitNum(n);
break;
case NODE_NEG:
return visitUnaryOperator(n);
break;
case NODE_ADD:
case NODE_SUB:
case NODE_MULT:
case NODE_DIV:
case NODE_LESS_THAN:
case NODE_GREATER_THAN:
case NODE_EQUAL_TO:
return visitBinaryOperator(n);
break;
case NODE_ASSIGN:
return visitAssignOperator(n);
break;
case NODE_NOOP:
break;
case NODE_ID:
return visitVar(n);
break;
case NODE_CONDITIONAL:
return visitConditional(n);
break;
case NODE_LOOP:
return visitLoop(n);
break;
case NODE_PRINT:
return visitPrint(n);
break;
default:
throw UNEXPECTED_TOKEN;
break;
}
}
// visit and evaluate child nodes from left to right. Return value isnt used
int Interpreter::visitCompound(ASTNode* n) {
for(int child = 0; child < n->children.size(); child++) {
visit(n->children[child]);
}
return 0;
}
// Return value isn't used
int Interpreter::visitLoop(ASTNode* n) {
int conditionalIsTrue = visit(n->children[0]) != 0;
while(conditionalIsTrue) {
visit(n->children[1]);
conditionalIsTrue = visit(n->children[0]) != 0;
}
return 0;
}
// 0 if conditonal evaluated to true, otherwise return value
int Interpreter::visitConditional(ASTNode* n) {
int conditionalIsTrue = visit(n->children[0]) != 0;
if(conditionalIsTrue) {
visit(n->children[1]);
} else {
visit(n->children[2]);
}
return conditionalIsTrue;
}
int Interpreter::visitBinaryOperator(ASTNode* n) {
int leftVal = visit(n->children[0]);
int rightVal = visit(n->children[1]);
switch(n->nodeType) {
case NODE_ADD:
return leftVal + rightVal;
break;
case NODE_SUB:
return leftVal - rightVal;
break;
case NODE_MULT:
return leftVal * rightVal;
break;
case NODE_DIV:
return leftVal / rightVal;
break;
case NODE_LESS_THAN:
return leftVal < rightVal;
break;
case NODE_GREATER_THAN:
return leftVal > rightVal;
break;
case NODE_EQUAL_TO:
return leftVal == rightVal;
break;
default:
throw UNEXPECTED_TOKEN;
break;
}
}
int Interpreter::visitUnaryOperator(ASTNode* n) {
int childVal = visit(n->children[0]);
switch(n->nodeType) {
case NODE_NEG:
return -1 * childVal;
default:
throw UNEXPECTED_TOKEN;
break;
}
}
int Interpreter::visitAssignOperator(ASTNode* n) {
string varName = n->children[0]->id;
int rightVal = visit(n->children[1]);
symbolTable[varName] = rightVal;
return rightVal;
}
int Interpreter::visitNum(ASTNode* n) {
return n->num;
}
int Interpreter::visitVar(ASTNode* n) {
string varName = n->id;
if(symbolTable.find(varName) == symbolTable.end())
throw UNKNOWN_SYMBOL;
return symbolTable[varName];
}
// Return value isn't used
int Interpreter::visitPrint(ASTNode* n) {
int printVal = visit(n->children[0]);
// TODO: add ability to print characters
cout << printVal << endl;
return 0;
}
int Interpreter::getRuntimeValue(string variable) {
if(symbolTable.find(variable) == symbolTable.end()) {
cerr << "unkown symbol " << variable << " encountered during runtime" << endl;
throw UNKNOWN_SYMBOL;
}
return symbolTable[variable];
}