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

finish all node_type

parent c4129b1d
No related branches found
No related tags found
No related merge requests found
Pipeline #44 passed with warnings with stages
in 3 minutes and 24 seconds
...@@ -55,6 +55,8 @@ public abstract class SymbolType { ...@@ -55,6 +55,8 @@ public abstract class SymbolType {
@JsonIgnore @JsonIgnore
public boolean isListType() { public boolean isListType() {
if(this == EMPTY_TYPE)
return true;
return false; return false;
} }
......
...@@ -38,6 +38,30 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -38,6 +38,30 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
errors.semError(node, message, args); errors.semError(node, message, args);
} }
///////////////////////////// Program //////////////////////////////////////
@Override
public SymbolType analyze(Program program) {
for (Declaration decl : program.declarations) {
String name = decl.getIdentifier().name;
SymbolType type = decl.dispatch(this);
System.out.println("decl type " + type.toString());
// recolic: what's the teacher willing to do???
if (type == null) {
continue;
}
// TODO: DO NOT throw on duplicate id. generate a compiler error.
sym.put(name, type);
}
for (Stmt stmt : program.statements) {
stmt.dispatch(this);
}
return null;
}
///////////////////////////// Def&decl s //////////////////////////////////////
@Override @Override
public SymbolType analyze(VarDef varDef) { public SymbolType analyze(VarDef varDef) {
SymbolType lType = varDef.value.dispatch(this); SymbolType lType = varDef.value.dispatch(this);
...@@ -53,6 +77,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -53,6 +77,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
classDef.memberMap = new HashMap<>(); classDef.memberMap = new HashMap<>();
assert classDef.memberMap != null; assert classDef.memberMap != null;
// My-name already pushed to symbolMap
classDef.name.dispatch(this);
classDef.superClass.dispatch(this);
ClassValueType result_type = new ClassValueType(classDef.name.name); ClassValueType result_type = new ClassValueType(classDef.name.name);
SymbolTable<SymbolType> symLayer = new SymbolTable<>(sym); SymbolTable<SymbolType> symLayer = new SymbolTable<>(sym);
symLayer.put("self", result_type); symLayer.put("self", result_type);
...@@ -121,42 +149,9 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -121,42 +149,9 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
return T; return T;
} }
// Just a helper..
@Override
public SymbolType analyze(TypedVar node) {
return ValueType.annotationToValueType(node.type);
}
///////// end ///////// end
@Override ///////////////////////////// Literals //////////////////////////////////////
public SymbolType analyze(Program program) {
for (Declaration decl : program.declarations) {
String name = decl.getIdentifier().name;
SymbolType type = decl.dispatch(this);
System.out.println("decl type " + type.toString());
// recolic: what's the teacher willing to do???
if (type == null) {
continue;
}
// TODO: DO NOT throw on duplicate id. generate a compiler error.
sym.put(name, type);
}
for (Stmt stmt : program.statements) {
stmt.dispatch(this);
}
return null;
}
@Override
public SymbolType analyze(ExprStmt s) {
s.expr.dispatch(this);
return null;
}
@Override @Override
public SymbolType analyze(IntegerLiteral node) { public SymbolType analyze(IntegerLiteral node) {
return node.setInferredType(INT_TYPE); return node.setInferredType(INT_TYPE);
...@@ -174,6 +169,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -174,6 +169,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
return node.setInferredType(BOOL_TYPE); return node.setInferredType(BOOL_TYPE);
} }
///////////////////////////// Statements //////////////////////////////////////
@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);
...@@ -201,9 +197,64 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -201,9 +197,64 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
err(node, "Syntax error: implicit type convertion failed."); err(node, "Syntax error: implicit type convertion failed.");
} }
} }
return left_type; //return left_type;
return null; // silly ta is not willing to use `a = (b = c) => a = something` reduction. It's ugly and buggy and complex but let him go.
}
@Override
public SymbolType analyze(ForStmt node) {
SymbolType iterType = node.iterable.dispatch(this);
if(!(iterType.isListType() || iterType.equals(STR_TYPE))) {
err(node, "for target is not iterable.");
}
SymbolType ident = node.identifier.dispatch(this);
for(Stmt stmt : node.body) {
stmt.dispatch(this);
}
return null;
}
@Override
public SymbolType analyze(IfStmt node) {
SymbolType conditionType = node.condition.dispatch(this);
if(!conditionType.equals(BOOL_TYPE)) {
err(node, "if statement condition should be BOOL");
}
for(Stmt stmt : node.thenBody) {
stmt.dispatch(this);
}
for(Stmt stmt : node.elseBody) {
stmt.dispatch(this);
}
return null;
}
@Override
public SymbolType analyze(ExprStmt node) {
node.expr.dispatch(this);
return null;
}
@Override
public SymbolType analyze(ReturnStmt node) {
node.value.dispatch(this);
return null;
}
@Override
public SymbolType analyze(WhileStmt node) {
SymbolType conditionType = node.condition.dispatch(this);
if(!conditionType.equals(BOOL_TYPE)) {
err(node, "while statement condition should be BOOL");
}
for(Stmt stmt : node.body) {
stmt.dispatch(this);
}
return null;
} }
///////////////////////////// Expressions //////////////////////////////////////
@Override @Override
public SymbolType analyze(BinaryExpr node) { public SymbolType analyze(BinaryExpr node) {
String op = node.operator; String op = node.operator;
...@@ -410,6 +461,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -410,6 +461,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
return funcType.returnType; return funcType.returnType;
} }
///////////////////////////// Others //////////////////////////////////////
@Override @Override
public SymbolType analyze(Identifier id) { public SymbolType analyze(Identifier id) {
String varName = id.name; String varName = id.name;
...@@ -424,6 +476,20 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -424,6 +476,20 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
return id.setInferredType(ValueType.OBJECT_TYPE); return id.setInferredType(ValueType.OBJECT_TYPE);
} }
@Override
public SymbolType analyze(TypedVar node) {
return ValueType.annotationToValueType(node.type);
}
@Override
public SymbolType analyze(ClassType node) {
return new ClassValueType(node.className);
}
@Override
public SymbolType analyze(ListType node) {
SymbolType elementType = node.elementType.dispatch(this);
return new ListValueType(elementType);
}
private boolean typeConvertible(SymbolType from, SymbolType to) { private boolean typeConvertible(SymbolType from, SymbolType to) {
if(from == null || to == null) if(from == null || to == null)
throw new RuntimeException("debug: SymbolType can not be null"); throw new RuntimeException("debug: SymbolType can not be null");
...@@ -454,4 +520,5 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -454,4 +520,5 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
return l; return l;
return OBJECT_TYPE; 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