Homework 4
This commit is contained in:
parent
0afc86ceeb
commit
72cc3206c4
125 changed files with 4200 additions and 1636 deletions
76
src/cd/frontend/semantic/SymTable.java
Normal file
76
src/cd/frontend/semantic/SymTable.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
package cd.frontend.semantic;
|
||||
|
||||
import cd.frontend.semantic.SemanticFailure.Cause;
|
||||
import cd.ir.Symbol;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple symbol table, with a pointer to the enclosing scope.
|
||||
* Used by {@link TypeChecker} to store the various scopes for
|
||||
* local, parameter, and field lookup. */
|
||||
public class SymTable<S extends Symbol> {
|
||||
|
||||
private final Map<String, S> map = new HashMap<String, S>();
|
||||
|
||||
private final SymTable<S> parent;
|
||||
|
||||
public SymTable(SymTable<S> parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void add(S sym) {
|
||||
// check that the symbol is not already declared *at this level*
|
||||
if (containsLocally(sym.name))
|
||||
throw new SemanticFailure(Cause.DOUBLE_DECLARATION);
|
||||
map.put(sym.name, sym);
|
||||
}
|
||||
|
||||
public Collection<S> localSymbols() {
|
||||
return this.map.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if there is a declaration with the given name at any
|
||||
* level in the symbol table
|
||||
*/
|
||||
public boolean contains(String name) {
|
||||
return get(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if there is a declaration at THIS level in the symbol
|
||||
* table; may return {@code false} even if a declaration exists
|
||||
* in some enclosing scope
|
||||
*/
|
||||
public boolean containsLocally(String name) {
|
||||
return this.map.containsKey(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base method: returns {@code null} if no symbol by that
|
||||
* name can be found, in this table or in its parents */
|
||||
public S get(String name) {
|
||||
S res = map.get(name);
|
||||
if (res != null)
|
||||
return res;
|
||||
if (parent == null)
|
||||
return null;
|
||||
return parent.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the symbol with the given name, or fails with a
|
||||
* NO_SUCH_TYPE error. Only really makes sense to use this
|
||||
* if S == TypeSymbol, but we don't strictly forbid it... */
|
||||
public S getType(String name) {
|
||||
S res = get(name);
|
||||
if (res == null)
|
||||
throw new SemanticFailure(
|
||||
Cause.NO_SUCH_TYPE,
|
||||
"No type '%s' was found", name);
|
||||
return res;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue