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) + ", "); } 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 addAttribute(String arg) { String str = this.active.get(TypeEnum.classname); ClassInstance cls = this.getClass(str); TypeInstance attr = this.getType(arg); attr.setScope(cls); cls.addAttribute(attr); } 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 } public void addLocal(String lvar) { String str = this.active.get(TypeEnum.method); MethodInstance mtd = this.getMethod(str); TypeInstance var = this.getType(lvar); var.setScope(mtd); mtd.addArgument(var); } /** * 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; } }