package st; import java.util.*; /** * Class which provides methods for interacting with and managing * the symbol table. Maintains context-awareness to keep the state * of each symbol consistent. */ public class SymbolTable { private HashMap symt; // the mapping of ids to Instances private HashMap active; // the current scope of the visitor (class, method) public SymbolTable() { this.symt = new HashMap<>(); this.active = new HashMap<>(); } public String toString() { StringBuilder mapAsString = new StringBuilder("{"); for (String key : this.symt.keySet()) { mapAsString.append(key + ":" + this.symt.get(key).getType() + ", "); } mapAsString.delete(mapAsString.length()-2, mapAsString.length()).append("}"); return mapAsString.toString(); } /** * Methods intended to be used during the first pass */ public void put(String id, AbstractInstance symbol) { this.symt.put(id, symbol); } /** * Methods intended to be used during the second pass */ public void setActive(TypeEnum type, String id) { this.active.put(type, id); } public void removeActive(TypeEnum type) { this.active.remove(type); } public void setExtend(String arg) { String str = this.active.get(TypeEnum.classname); ClassInstance cls = this.getClass(str); ClassInstance ext = this.getClass(arg); cls.setExtend(ext); // for (TypeInstance : ext.attrs) //FIXME add the extended classes' stuff // cls.add } public void addLocal(String lvar) { TypeInstance var = this.getType(lvar); if (this.active.get(TypeEnum.method) != null) { // we are in a method String str = this.active.get(TypeEnum.method); MethodInstance mtd = this.getMethod(str); mtd.addLocal(var); var.setScope(mtd); } else { String str = this.active.get(TypeEnum.classname); ClassInstance cls = this.getClass(str); cls.addLocal(var); var.setScope(cls); } } public void addMethod(String mtd) { String str = this.active.get(TypeEnum.classname); ClassInstance cls = this.getClass(str); MethodInstance lmtd = this.getMethod(mtd); lmtd.setScope(cls); cls.addMethod(lmtd); } public void addParameter(String arg) { String str = this.active.get(TypeEnum.method); MethodInstance mtd = this.getMethod(str); TypeInstance para = this.getType(arg); para.setScope(mtd); mtd.addArgument(para); // also adds to local vars } /** * Methods to safely retrieve differentiable types * in `typecheck', `vaporize' libraries */ public TypeInstance getType(String id) { AbstractInstance symbol; return ((symbol = this.symt.get(id)) != null && symbol.getType() != TypeEnum.classname && symbol.getType() != TypeEnum.method) ? (TypeInstance) symbol : null; } public MethodInstance getMethod(String id) { AbstractInstance symbol; return ((symbol = this.symt.get(id)) != null && symbol.getType() == TypeEnum.method) ? (MethodInstance) symbol : null; } public ClassInstance getClass(String id) { AbstractInstance symbol; return ((symbol = this.symt.get(id)) != null && symbol.getType() == TypeEnum.classname) ? (ClassInstance) symbol : null; } }