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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
package semanticanalysis;
import ast.types.*;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Class representing a symbol table. It's a list of hash table symbol table. We
* keep track of a ArrayList of HashMap called `symbolTable` and an array of
* integer called `offset`.
*/
public class SymbolTable {
private final ArrayList<HashMap<String, STentry>> symbolTable;
private final ArrayList<Integer> offset;
public SymbolTable() {
this.symbolTable = new ArrayList<>();
this.offset = new ArrayList<>();
}
/**
* Returns the nesting level.
*/
public Integer nesting() {
return this.symbolTable.size() - 1;
}
/**
* Check out if an `id` is into the symbol table. Returns an STentry object
* or null if the `id` is not found.
*
* @param id is the identifier of the STentry to find.
*/
public STentry lookup(String id) {
int n = this.symbolTable.size() - 1;
boolean found = false;
STentry T = null;
while ((n >= 0) && !found) {
HashMap<String, STentry> H = this.symbolTable.get(n);
T = H.get(id);
if (T != null) {
found = true;
} else {
n = n - 1;
}
}
return T;
}
/**
* Return the position of a STentry given the `id`, if it exists. Otherwise
* return `-1`. We start the search from the last inserted hashmap.
*
* @param id is the identifier of the STentry to find.
*/
public Integer nslookup(String id) {
int n = this.symbolTable.size() - 1;
boolean found = false;
while ((n >= 0) && !found) {
HashMap<String, STentry> H = this.symbolTable.get(n);
if (H.get(id) != null) {
found = true;
} else {
n = n - 1;
}
}
return n;
}
/**
* Add an hashmap to the given symbol table and increase the offset level.
* We start from 2 because we have FP and AL before all.
*
* @param H is an hashmap that is must be added into the symbol table
*/
public void add(HashMap<String, STentry> H) {
this.symbolTable.add(H);
this.offset.add(1);
}
/**
* Remove the last level for the symbol table.
*/
public void remove() {
int x = this.symbolTable.size();
this.symbolTable.remove(x - 1);
this.offset.remove(x - 1);
}
/**
* Return `true` if the `id` is present in the last inseted hashmap.
* Otherwise return `false`.
*
* @param id is the identifier of the STentry to find.
*/
public boolean top_lookup(String id) {
int n = symbolTable.size() - 1;
STentry T;
HashMap<String, STentry> H = symbolTable.get(n);
T = H.get(id);
return (T != null);
}
/**
* Insert a new entry into the symbol table.
*
* @param id
* @param type
* @param _nesting
* @param _label
*/
public void insert(String id, Type type, int _nesting, String _label) {
int n = symbolTable.size() - 1;
HashMap<String, STentry> H = this.symbolTable.get(n);
this.symbolTable.remove(n);
int offs = this.offset.get(n);
this.offset.remove(n);
STentry idtype = new STentry(type, offs, _nesting, _label);
H.put(id, idtype);
this.symbolTable.add(H);
// We always increment the offset by 1 otherwise we need ad-hoc bytecode
// operations
offs = offs + 1;
this.offset.add(offs);
}
/**
* Increase the offset level.
*/
public void increaseOffset() {
int n = this.offset.size() - 1;
int offs = this.offset.get(n);
this.offset.remove(n);
offs = offs + 1;
this.offset.add(offs);
}
/**
* Decrease the offset level.
*/
public void decreaseOffset() {
int n = this.offset.size() - 1;
int offs = this.offset.get(n);
this.offset.remove(n);
offs = offs - 1;
this.offset.add(offs);
}
@Override
public String toString() {
// Print the symbol table
String str = "ST ";
for (int i = 0; i < this.symbolTable.size(); i++) {
str += "Level " + i + "\n";
HashMap<String, STentry> H = this.symbolTable.get(i);
for (String key : H.keySet()) {
STentry T = H.get(key);
str += key + " -> " + T.toString() + "\n";
}
}
return str;
}
@Override
public SymbolTable clone() throws CloneNotSupportedException {
Object obj = super.clone();
return (SymbolTable) obj;
}
}
|