You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ChocoPy/src/main/java/chocopy/pa2/StudentAnalysis.java

97 lines
3.3 KiB

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<Type> 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<Type> 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<Type> sym){
if(p instanceof ClassValueType)
p = sym.get(p.className());
if(c instanceof ClassValueType)
c = sym.get(c.className());
ArrayList<Type> inhPath1 = new ArrayList<Type>(),
inhPath2 = new ArrayList<Type>();
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<Type> globalSym = declarationAnalyzer.getGlobals();
if (!program.hasErrors()) {
TypeChecker typeChecker = new TypeChecker(globalSym, program.errors);
program.dispatch(typeChecker);
}
// System.out.println(program);
return program;
}
}