package chocopy.pa2; import chocopy.common.analysis.SymbolTable; import chocopy.common.analysis.types.ClassVType; import chocopy.common.analysis.types.ClassValueType; import chocopy.common.analysis.types.Type; import chocopy.common.analysis.types.ValueType; import chocopy.common.astnodes.ClassType; import chocopy.common.astnodes.Program; import java.util.ArrayList; /** Top-level class for performing semantic analysis. */ public class StudentAnalysis { /** * Perform semantic analysis on PROGRAM, adding error messages and type annotations. Provide * debugging output iff DEBUG. Returns modified tree. */ public static boolean subClassOf(Type p, Type c, SymbolTable sym){ String pName = p.className(); if(pName!=null && pName.equals("object")) return true; if(c instanceof ClassValueType) c = sym.get(c.className()); if(c instanceof ClassVType){ ClassVType child = (ClassVType) c; String typename = child.className; while(typename!=null){ if(typename.equals(pName)) return true; child = child.super_class; if(child!=null) typename = child.className; else return false; } return false; } else return p.equals(c); } private static void extractInhPath(Type ty, ArrayList res){ if(ty == null) { res.add(Type.OBJECT_TYPE); return; } if(ty instanceof ClassVType){ ClassVType t1 = (ClassVType) ty; String typename = t1.className; while(typename!=null){ res.add(new ClassValueType(typename)); t1 = t1.super_class; if(t1 != null) typename = t1.className(); else break; } } else res.add(ty); if(!res.get(res.size() - 1).equals(Type.OBJECT_TYPE)) res.add(Type.OBJECT_TYPE); } public static Type lowestCommonType(Type p, Type c, SymbolTable sym){ if(p instanceof ClassValueType) p = sym.get(p.className()); if(c instanceof ClassValueType) c = sym.get(c.className()); ArrayList inhPath1 = new ArrayList(), inhPath2 = new ArrayList(); extractInhPath(p, inhPath1); extractInhPath(c, inhPath2); int l1 = inhPath1.size(), l2 = inhPath2.size(), len = l1 < l2 ? l1 : l2; int i = 1; for(; i <= len; ++ i){ if(!inhPath1.get(l1 - i).equals(inhPath2.get(l2 - i))) break; } return inhPath1.get(l1 - i + 1); } public static Program process(Program program, boolean debug) { if (program.hasErrors()) { return program; } DeclarationAnalyzer declarationAnalyzer = new DeclarationAnalyzer(program.errors); program.dispatch(declarationAnalyzer); SymbolTable globalSym = declarationAnalyzer.getGlobals(); if (!program.hasErrors()) { TypeChecker typeChecker = new TypeChecker(globalSym, program.errors); program.dispatch(typeChecker); } //System.out.println(program); return program; } }