-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScopeAnalyzer.java
More file actions
119 lines (107 loc) · 3.08 KB
/
ScopeAnalyzer.java
File metadata and controls
119 lines (107 loc) · 3.08 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
class ScopeAnalyzer extends DepthFirstVisitor {
SymbolTable _symTab;
ScopeAnalyzer() {
_symTab = new SymbolTable();
}
private void def(Symbol sym) {
if (_symTab.contains(sym.name())) {
ErrorPrinter.print(sym.loc(),
"Duplicate definition of '" + sym.name() + "'");
ErrorPrinter.print(_symTab.get(sym.name()).loc(),
"... previous definition of '" + sym.name() + "'");
} else {
_symTab.def(sym);
}
}
// ---------------- top-level ----------------
Object visit(FunDef ast) {
FunSym sym = new FunSym(_symTab._current, ast);
def(sym);
ast._heldScope = new Scope(ast, _symTab._current);
_symTab.push(ast._heldScope);
ast._type.accept(this);
for (Symbol formal : ast._type._formals._heldScope._symbols.values()) {
FieldSym field = (FieldSym)formal;
VarSym var = new VarSym(ast._heldScope, field._def);
_symTab.def(var);
}
ast._body._needsScope = false;
ast._body.accept(this);
_symTab.pop(ast._heldScope);
return null;
}
// ---------------- types ----------------
Object visit(RecordType ast) {
ast._heldScope = new Scope(ast, _symTab._current);
_symTab.push(ast._heldScope);
for (FieldType f : ast._fields)
f.accept(this);
_symTab.pop(ast._heldScope);
return null;
}
Object visit(FieldType ast) {
FieldSym sym = new FieldSym(_symTab._current, ast);
def(sym);
ast._field.accept(this);
ast._type.accept(this);
return null;
}
// ---------------- statements ----------------
Object visit(VarDef ast) {
VarSym sym = new VarSym(_symTab._current, ast);
def(sym);
ast._var.accept(this);
ast._rhs.accept(this);
return null;
}
Object visit(BlockStmt ast) {
if (ast._needsScope) {
ast._heldScope = new Scope(ast, _symTab._current);
_symTab.push(ast._heldScope);
}
for (Stmt s : ast._stmts) {
if (s instanceof BlockStmt)
((BlockStmt)s)._needsScope = true;
s.accept(this);
}
if (ast._needsScope)
_symTab.pop(ast._heldScope);
return null;
}
Object visit(ForStmt ast) {
ast._heldScope = new Scope(ast, _symTab._current);
_symTab.push(ast._heldScope);
VarSym sym = new VarSym(_symTab._current, ast);
def(sym);
ast._var.accept(this);
ast._expr.accept(this);
ast._body._needsScope = false;
ast._body.accept(this);
_symTab.pop(ast._heldScope);
return null;
}
Object visit(IfStmt ast) {
ast._thenBranch._needsScope = true;
return super.visit(ast);
}
Object visit(WhileStmt ast) {
ast._body._needsScope = true;
return super.visit(ast);
}
// ---------------- literals ----------------
Object visit(RecordLit ast) {
ast._heldScope = new Scope(ast, _symTab._current);
_symTab.push(ast._heldScope);
for (FieldLit f : ast._fields)
f.accept(this);
_symTab.pop(ast._heldScope);
return null;
}
Object visit(FieldLit ast) {
FieldSym sym = new FieldSym(_symTab._current, ast);
def(sym);
ast._field.accept(this);
ast._expr.accept(this);
return null;
}
}