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

bug fix. WARNING: EMPTY_TYPE === List<NoneType>. SILLY TA

parent 7016b3e6
No related branches found
No related tags found
No related merge requests found
Pipeline #41 passed with warnings with stages
in 2 minutes and 49 seconds
...@@ -42,9 +42,9 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -42,9 +42,9 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
public SymbolType analyze(VarDef varDef) { public SymbolType analyze(VarDef varDef) {
SymbolType lType = varDef.value.dispatch(this); SymbolType lType = varDef.value.dispatch(this);
SymbolType vType = varDef.var.dispatch(this); SymbolType vType = varDef.var.dispatch(this);
if(!vType.equals(lType)) if(!(vType.equals(lType) || lType.equals(NONE_TYPE)))
err(varDef, "incorrect initialization type"); err(varDef, "incorrect initialization type");
return lType; return vType;
} }
@Override @Override
...@@ -177,31 +177,25 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -177,31 +177,25 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
@Override @Override
public SymbolType analyze(AssignStmt node) { public SymbolType analyze(AssignStmt node) {
SymbolType right_type = node.value.dispatch(this); SymbolType right_type = node.value.dispatch(this);
SymbolType left_type = null;
if(right_type == null) if(right_type == null)
right_type = NONE_TYPE; right_type = NONE_TYPE;
if(node.targets.size() == 1) { for(Expr target : node.targets) {
String target = node.targets.get(0).toString(); Identifier id = (Identifier) target;
System.out.println("debug: assign to target " + target); if(id == null) {
SymbolType left_type = sym.get(target); err(node, "assign to non-identifier expr.");
return NONE_TYPE;
}
left_type = id.dispatch(this);
if(left_type == null) { if(left_type == null) {
err(node, "Syntax error: assign to non-declared variable."); err(node, "Syntax error: assign to non-declared variable: " + id.name);
return OBJECT_TYPE; return NONE_TYPE;
} }
if(!left_type.equals(right_type)) { if(!typeConvertible(right_type, left_type)) {
err(node, "Syntax error: implicit type convertion not allowed."); err(node, "Syntax error: implicit type convertion failed.");
} }
return right_type;
}
else {
if(!right_type.isListType()) {
err(node, "Syntax error: assign non-list type to list targets");
return OBJECT_TYPE;
}
ListValueType right_ls_type = (ListValueType) right_type;
// TODO: assign list to list
err(node, "Not implemented error: assign list to list");
return OBJECT_TYPE;
} }
return left_type;
} }
@Override @Override
...@@ -363,11 +357,15 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -363,11 +357,15 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
SymbolType this_type = expr.dispatch(this); SymbolType this_type = expr.dispatch(this);
if(elementType == null) if(elementType == null)
elementType = this_type; elementType = this_type;
if(!this_type.equals(elementType)) if(!typeConvertible(this_type, elementType)) {
err(node, "list elements must have the same type."); //err(node, "list elements must have the same type.");
elementType = calcCommonType(this_type, elementType);
}
} }
ListValueType resultType = new ListValueType(elementType); if(elementType == null)
return node.setInferredType(resultType); return node.setInferredType(EMPTY_TYPE);
else
return node.setInferredType(new ListValueType(elementType));
} }
@Override @Override
...@@ -415,4 +413,35 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -415,4 +413,35 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
err(id, "Not a variable: %s", varName); err(id, "Not a variable: %s", varName);
return id.setInferredType(ValueType.OBJECT_TYPE); return id.setInferredType(ValueType.OBJECT_TYPE);
} }
private boolean typeConvertible(SymbolType from, SymbolType to) {
if(from == null || to == null)
throw new RuntimeException("debug: SymbolType can not be null");
if(from.equals(NONE_TYPE) || to.equals(OBJECT_TYPE))
return true;
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()) {
return from.equals(to);
}
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 SymbolType calcCommonType(SymbolType another, SymbolType preferred) {
SymbolType l = another, r = preferred;
if(l == null || r == null)
throw new RuntimeException("debug: SymbolType can not be null");
if(l.equals(NONE_TYPE))
return r;
if(r.equals(NONE_TYPE))
return l;
if(typeConvertible(l, r))
return r;
if(typeConvertible(r, l))
return l;
return OBJECT_TYPE;
}
} }
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