Homework 4

This commit is contained in:
Carlos Galindo 2020-01-15 22:34:57 +01:00
commit 72cc3206c4
Signed by: kauron
GPG key ID: 83E68706DEE119A3
125 changed files with 4200 additions and 1636 deletions

View 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;
}
}