Skip to content
Snippets Groups Projects
Verified Commit 2cf77637 authored by Recolic Keghart's avatar Recolic Keghart
Browse files

fix class inherit problems, fix type conversion, fix class member, fix some expr infer, etc

parent 0afe8c44
No related branches found
No related tags found
No related merge requests found
Pipeline #49 passed with warnings with stages
in 3 minutes and 30 seconds
......@@ -18,12 +18,20 @@ public class ClassValueType extends ValueType {
@JsonIgnore
public Map<String, SymbolType> memberMap = null;
@JsonIgnore
public ClassValueType parent = OBJECT_TYPE;
/** A class type for the class named CLASSNAME. */
@JsonCreator
public ClassValueType(@JsonProperty String className) {
this.className = className;
}
public ClassValueType(String className, ClassValueType parentType) {
this.className = className;
parent = parentType;
}
/** A class type for the class referenced by CLASSTYPEANNOTATION. */
public ClassValueType(ClassType classTypeAnnotation) {
this.className = classTypeAnnotation.className;
......
......@@ -102,6 +102,8 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
// My-name already pushed to symbolMap
// TA doesn't like this: // classDef.name.dispatch(this);
// TA doesn't like this: // classDef.superClass.dispatch(this);
ClassValueType superType = (ClassValueType) classDef.superClass.dispatch(this);
classDef.superClass.setInferredType(null); // make TA happy
// Append parent to child if not exist.
if(!classDef.superClass.name.equals("object")) {
......@@ -115,7 +117,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
}
}
ClassValueType result_type = new ClassValueType(classDef.name.name);
ClassValueType result_type = new ClassValueType(classDef.name.name, superType);
result_type.memberMap = classDef.memberMap;
SymbolTable<SymbolType> symLayer = new SymbolTable<>(sym);
// TODO: Maybe this is not necessary. I'm a cxx programmer.
......@@ -245,6 +247,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
Identifier id = (Identifier) target;
left_type = id.dispatch(this);
}
else if(target instanceof MemberExpr) {
MemberExpr memberExpr = (MemberExpr) target;
left_type = memberExpr.dispatch(this);
}
else {
err(node, "Not implemented assignStmt, target=" + target.getClass().getName());
}
......@@ -512,7 +518,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
err(node, "undefined identifier " + node.member.name + " as object member.");
return NONE_TYPE;
}
return resultType;
return node.setInferredType(resultType);
}
@Override
......@@ -525,13 +531,31 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
FuncType funcType = (FuncType) methodType;
List<SymbolType> args_type = new ArrayList<>();
if(node.method instanceof MemberExpr) {
args_type.add(((MemberExpr)node.method).object.getInferredType());
}
for(Expr expr : node.args) {
args_type.add(expr.dispatch(this));
}
if(!args_type.equals(funcType.parameters)) {
err(node, "function/method parameter list mismatch");
if(!matchArgList(args_type, funcType.parameters)) {
err(node, "function/method parameter list mismatch. Got " + args_type.toString() + ",expecting " + funcType.parameters);
}
return node.setInferredType(funcType.returnType);
}
private boolean matchArgList(List<SymbolType> got, List<ValueType> expect) {
System.out.println("debug> match arg> " + got + " -> " + expect + ", size " + got.size() + expect.size());
if(got.size() != expect.size())
return false;
for(int cter = 0; cter < got.size(); ++cter) {
System.out.println("debug> match arg> " + got.get(cter).toString() + " -> " + expect.get(cter).toString());
if(typeConvertible(got.get(cter), expect.get(cter)))
continue; // ok
else
return false;
}
return funcType.returnType;
System.out.println("debug> SUCC match arg> " + got + " -> " + expect + ", size " + got.size() + expect.size());
return true;
}
///////////////////////////// Others //////////////////////////////////////
......@@ -587,14 +611,44 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
if(from.equals(EMPTY_TYPE)) from = new ListValueType(NONE_TYPE);
if(to.equals(EMPTY_TYPE)) to = new ListValueType(NONE_TYPE);
if(!from.isListType() || !to.isListType()) {
// Cast class to parent
if(from instanceof ClassValueType && to instanceof ClassValueType) {
if(_typeConvertible_calcClassInheritChainCommonNode((ClassValueType) from, (ClassValueType) to).equals(to))
return true; // Can cast from->to
}
return from.equals(to);
}
// Convert list to list:
ListValueType lsFrom = (ListValueType) from, lsTo = (ListValueType) to;
if(lsFrom.elementType == null || lsFrom.elementType.equals(NONE_TYPE))
return true;
return typeConvertible(lsFrom.elementType, lsTo.elementType);
}
private ClassValueType _typeConvertible_calcClassInheritChainCommonNode(ClassValueType l, ClassValueType r) {
int l_depth = 1, r_depth = 1;
ClassValueType l_curr = l, r_curr = r;
while(!l_curr.equals(OBJECT_TYPE)) {
++l_depth;
l_curr = l_curr.parent;
}
while(!r_curr.equals(OBJECT_TYPE)) {
++r_depth;
r_curr = r_curr.parent;
}
l_curr = l;
r_curr = r;
for(;l_depth > r_depth; --l_depth)
l_curr = l_curr.parent;
for(;r_depth > l_depth; --r_depth)
r_curr = r_curr.parent;
while(!l_curr.equals(r_curr)) { // NOTE: Use reference compare
l_curr = l_curr.parent;
r_curr = r_curr.parent;
}
if(l_curr == null) return OBJECT_TYPE;
else return l_curr;
}
private SymbolType calcCommonType(SymbolType another, SymbolType preferred) {
SymbolType l = another, r = preferred;
if(l == null || r == null)
......@@ -607,6 +661,9 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
return r;
if(typeConvertible(r, l))
return l;
if(another instanceof ClassValueType && preferred instanceof ClassValueType) {
return _typeConvertible_calcClassInheritChainCommonNode((ClassValueType) another, (ClassValueType) preferred);
}
return OBJECT_TYPE;
}
private boolean typeIsUserDefinedClass(SymbolType type) {
......@@ -622,13 +679,11 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
}
private ValueType fixClassTypeProblem(ValueType valType) {
if(typeIsUserDefinedClass(valType)) {
System.out.println("debug: annotation class name resolved." + valType.className());
ClassValueType realType = (ClassValueType)sym.get(valType.className());
if(realType == null) {
System.out.println("FIXME: annotation uses an unknown class type. Unable to assign member map.");
return valType;
}
System.out.println("debug: -m- " + realType.memberMap);
return realType;
}
else
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment