-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSymbolTable.java
More file actions
130 lines (112 loc) · 3.55 KB
/
Copy pathSymbolTable.java
File metadata and controls
130 lines (112 loc) · 3.55 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
import java.util.*;
import absyn.*;
class Sym {
String name;
Dec def;
int scope;
public Sym(String name, Dec def, int scope) {
this.name = name;
this.def = def;
this.scope = scope;
}
public String toString() {
StringBuilder s = new StringBuilder();
if (def instanceof FunctionDec) {
FunctionDec funcDef = (FunctionDec) def;
s.append("Function");
if (funcDef.body instanceof NilExp) {
s.append(" Prototype");
}
s.append(": " + name + "(");
VarDecList params = funcDef.params;
while (params != null) {
if (params.head instanceof SimpleDec) {
SimpleDec simpleDec = (SimpleDec) params.head;
s.append(simpleDec.typ.toString());
} else if (params.head instanceof ArrayDec) {
ArrayDec arrayDec = (ArrayDec) params.head;
s.append(arrayDec.typ.toString() + "[" + arrayDec.size + "]");
}
if (params.tail != null)
s.append(", ");
params = params.tail;
}
s.append(") -> " + funcDef.typ.toString());
} else if (def instanceof SimpleDec) {
SimpleDec simpleDef = (SimpleDec) def;
s.append(name + ": " + simpleDef.typ.toString());
} else if (def instanceof ArrayDec) {
ArrayDec simpleDef = (ArrayDec) def;
s.append(name + ": " + simpleDef.typ.toString() + "[]");
} else {
s.append("Error");
}
return s.toString();
}
public Dec getDef() {
return def;
}
}
class SymbolTable {
final static int SPACES = 4;
// Each scope has two separate maps: one for variables and one for functions
Stack<HashMap<String, Sym>> variableScopes = new Stack<>();
HashMap<String, Sym> functionScopes = new HashMap<>();
void enterScope() {
variableScopes.push(new HashMap<>());
}
void exitScope() {
variableScopes.pop();
}
boolean addVariable(Sym symbol) {
if (variableScopes.peek().containsKey(symbol.name)) {
return false;
}
variableScopes.peek().put(symbol.name, symbol);
return true;
}
boolean addFunction(Sym functionSymbol) {
// @formatter:off
if (functionScopes.containsKey(functionSymbol.name) && (
((FunctionDec) functionSymbol.def).body instanceof NilExp // passed in function prototype cant overwrite existing prototype
|| !(((FunctionDec) lookupFunction(functionSymbol.name).def).body instanceof NilExp) // making sure the found definition is a prototype
|| !(((FunctionDec) lookupFunction(functionSymbol.name).def).params
.equals(((FunctionDec) functionSymbol.def).params)) // making sure the parameters are the same as the prototype
)) {
return false;
}
// @formatter:on
Sym fuc = lookupFunction(functionSymbol.name);
if (fuc != null) {
((FunctionDec) fuc.def).body = ((FunctionDec) functionSymbol.def).body;
((FunctionDec) fuc.def).params = ((FunctionDec) functionSymbol.def).params;
((FunctionDec) fuc.def).funaddr = ((FunctionDec) functionSymbol.def).funaddr;
} else
functionScopes.put(functionSymbol.name, functionSymbol);
return true;
}
public Sym lookupVariable(String name) {
for (int i = variableScopes.size() - 1; i >= 0; i--) {
if (variableScopes.get(i).containsKey(name)) {
return variableScopes.get(i).get(name);
}
}
return null; // Not found
}
public Sym lookupFunction(String name) {
return functionScopes.get(name);
}
void printTopScope(int level) {
String space = "";
for (int i = 0; i < level * SPACES; i++)
space += " ";
for (Sym symbol : variableScopes.peek().values()) {
System.out.println(space + symbol.toString());
}
if (variableScopes.size() == 1) {
for (Sym symbol : functionScopes.values()) {
System.out.println(space + symbol.toString());
}
}
}
}