-
Notifications
You must be signed in to change notification settings - Fork 1
/
SymTab.cpp
100 lines (85 loc) · 2.52 KB
/
SymTab.cpp
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
/*
* Created by Tyler Gearing 3/14/19
*
*/
#include "SymTab.hpp"
// Uncomment the line below to enable debugging
// #define DEBUG 1
#define RETURN "retVal"
void SymTab::setValueFor(std::string const &vName,
std::shared_ptr<TypeDescriptor> rDesc) {
// Define a variable by setting its initial value.
if(scope.empty())
global[vName] = std::move(rDesc);
else
scope.back()[vName] = std::move(rDesc);
}
void SymTab::increment(std::string const &vName, int increment) {
// Define a variable by setting its initial value.
auto rDesc = dynamic_cast<NumberDescriptor *>
( getValueFor(vName).get() );
if( rDesc == nullptr ) {
std::cout << "SymTab::increment error casting TypeDescriptor\n";
exit(1);
}
if( rDesc->type() != TypeDescriptor::INTEGER) {
std::cout << "SymTab::increment only supports integers\n";
exit(1);
} else
rDesc->value.intValue += increment;
}
bool SymTab::isDefined(std::string const &vName) {
return isDefinedGlobal(vName) || isDefinedScope(vName);
}
bool SymTab::isDefinedGlobal(std::string const &vName) {
return global.find(vName) != global.end();
}
bool SymTab::isDefinedScope(std::string const &vName) {
if(scope.empty())
return false;
return scope.back().find(vName) != scope.back().end();
}
std::shared_ptr<TypeDescriptor> SymTab::getValueFor(std::string const &vName) {
if(scope.empty()) {
if( !isDefinedGlobal(vName) ) {
std::cout << "SymTab::getValueFor: " << vName;
std::cout << " has not been defined.\n";
exit(1);
}
return global.find(vName)->second;
} else {
if(isDefinedScope(vName))
return scope.back().find(vName)->second;
else if (isDefinedGlobal(vName))
return global.find(vName)->second;
else {
std::cout << "SymTab::getValueFor: " << vName;
std::cout << " has not been defined.\n";
exit(1);
}
}
}
void SymTab::openScope(std::vector<std::string> params,
std::vector<std::shared_ptr<TypeDescriptor>> args) {
std::map<std::string, std::shared_ptr<TypeDescriptor>> newScope;
for(unsigned i = 0; i < params.size(); ++i)
newScope[params[i]] = args[i];
scope.push_back(newScope);
}
void SymTab::setReturnValue(std::shared_ptr<TypeDescriptor> ret) {
global[RETURN] = ret;
}
std::shared_ptr<TypeDescriptor> SymTab::getReturnValue() {
if( !isDefinedGlobal(RETURN) ) {
std::cout << "SymTab::getReturnValue: returnVal";
std::cout << " has not been defined.\n";
exit(1);
}
return global.find(RETURN)->second;
}
void SymTab::closeScope() {
scope.pop_back();
}
void SymTab::removeReturn() {
global.erase(RETURN);
}