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

bug fix. pass one more

parent e27c8047
No related branches found
No related tags found
No related merge requests found
Pipeline #40 passed with warnings with stages
in 2 minutes and 59 seconds
......@@ -13,6 +13,8 @@ elif [[ "$task" = type ]]; then
java -cp "$classPath" chocopy.ChocoPy --pass=.s --out "$output" "$input"
elif [[ "$task" = ass ]]; then
java -cp "$classPath" chocopy.ChocoPy --pass=.s --dir src/test/data/pa2/sample --test
elif [[ "$task" = build ]]; then
mvn clean package > /dev/null 2>&1 && echo success || echo failed
fi
exit $?
......
......@@ -15,11 +15,12 @@ public class StudentAnalysis {
return program;
}
DeclarationAnalyzer declarationAnalyzer =
new DeclarationAnalyzer(program.errors);
program.dispatch(declarationAnalyzer);
SymbolTable<SymbolType> globalSym =
declarationAnalyzer.getGlobals();
//DeclarationAnalyzer declarationAnalyzer =
// new DeclarationAnalyzer(program.errors);
//program.dispatch(declarationAnalyzer);
//SymbolTable<SymbolType> globalSym =
// declarationAnalyzer.getGlobals();
SymbolTable<SymbolType> globalSym = new SymbolTable<>();
if (!program.hasErrors()) {
TypeChecker typeChecker =
......
......@@ -15,11 +15,15 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
/** The current symbol table (changes depending on the function
* being analyzed). */
private SymbolTable<SymbolType> sym;
// private SymbolTable<SymbolType> sym;
/** Current symbol table. Changes with new declarative region. */
private SymbolTable<SymbolType> sym = new SymbolTable<>();
/** Global symbol table. */
private final SymbolTable<SymbolType> globals = sym;
/** Collector for errors. */
private Errors errors;
/** Creates a type checker using GLOBALSYMBOLS for the initial global
* symbol table and ERRORS0 to receive semantic errors. */
public TypeChecker(SymbolTable<SymbolType> globalSymbols, Errors errors0) {
......@@ -34,10 +38,112 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
errors.semError(node, message, args);
}
@Override
public SymbolType analyze(VarDef varDef) {
SymbolType lType = varDef.value.dispatch(this);
SymbolType vType = varDef.var.dispatch(this);
if(!vType.equals(lType))
err(varDef, "incorrect initialization type");
return lType;
}
@Override
public SymbolType analyze(ClassDef classDef) {
assert classDef.memberMap == null;
classDef.memberMap = new HashMap<>();
assert classDef.memberMap != null;
ClassValueType result_type = new ClassValueType(classDef.name.name);
SymbolTable<SymbolType> symLayer = new SymbolTable<>(sym);
symLayer.put("self", result_type);
sym = symLayer;
for(Declaration decl : classDef.declarations) {
String name = decl.getIdentifier().name;
SymbolType type = decl.dispatch(this);
classDef.memberMap.put(name, type);
}
sym = sym.getParent();
return new ClassValueType(classDef.name.name);
}
@Override
public SymbolType analyze(FuncDef funcDef) {
System.out.println("debug: start funcDef: " + funcDef.getClass().getName());
assert funcDef.symTable == null;
sym = funcDef.symTable = new SymbolTable<SymbolType>(sym);
assert funcDef.symTable != null; // may suck if partial-compiling happens...
// Func parameter list
List<ValueType> args = new ArrayList<>();
for(TypedVar param : funcDef.params) {
String name = param.identifier.name;
ValueType type = ValueType.annotationToValueType(param.type);
sym.put(name, type);
args.add(type);
}
for(Declaration decl : funcDef.declarations) {
String name = decl.getIdentifier().name;
SymbolType type = decl.dispatch(this);
sym.put(name, type);
}
// function scope ends.. backtracking...
sym = sym.getParent();
if(sym == null)
throw new RuntimeException("logic error: sym parent is null while returning..");
FuncType funcT = new FuncType(args, ValueType.annotationToValueType(funcDef.returnType));
return funcT;
}
@Override
public SymbolType analyze(GlobalDecl globalDecl) {
String name = globalDecl.variable.name;
SymbolType T = globals.get(name);
if(T == null)
errors.semError(globalDecl, "global id '" + name + "' not found in global scope..");
if(sym == globals) // ref equal
errors.semError(globalDecl, "global declaration '" + name + "' not allowed in global scope.");
//sym.put(name, T);
return T;
}
@Override
public SymbolType analyze(NonLocalDecl nonLocalDecl) {
String name = nonLocalDecl.variable.name;
SymbolType T = sym.get(name); // auto-iterate through the tree.
if(T == null)
errors.semError(nonLocalDecl, "nonlocal id '" + name + "' not found in parent scope..");
if(sym == globals)
errors.semError(nonLocalDecl, "nonlocal declaration '" + name + "' not allowed in global scope.");
return T;
}
// Just a helper..
@Override
public SymbolType analyze(TypedVar node) {
return ValueType.annotationToValueType(node.type);
}
///////// end
@Override
public SymbolType analyze(Program program) {
for (Declaration decl : program.declarations) {
decl.dispatch(this);
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);
......@@ -52,12 +158,12 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
}
@Override
public SymbolType analyze(IntegerLiteral i) {
return i.setInferredType(SymbolType.INT_TYPE);
public SymbolType analyze(IntegerLiteral node) {
return node.setInferredType(INT_TYPE);
}
@Override
public SymbolType analyze(StringLiteral node) {
return node.setInferredType(SymbolType.STR_TYPE);
return node.setInferredType(STR_TYPE);
}
@Override
public SymbolType analyze(NoneLiteral node) {
......@@ -65,7 +171,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
}
@Override
public SymbolType analyze(BooleanLiteral node) {
return node.setInferredType(SymbolType.BOOL_TYPE);
return node.setInferredType(BOOL_TYPE);
}
@Override
......@@ -117,18 +223,19 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
case "<":
case ">=":
case "<=":
if(left_type != ValueType.INT_TYPE || right_type != ValueType.INT_TYPE) {
if(!(left_type.equals(INT_TYPE) && right_type.equals(INT_TYPE))) {
System.out.println("debug: left=" + left_type.toString() + ", right=" + right_type.toString());
err(node, "Syntax Error: operand should be INT");
}
break;
case "and":
case "or":
if(left_type != ValueType.BOOL_TYPE || right_type != ValueType.BOOL_TYPE) {
if(!(left_type.equals(BOOL_TYPE) && right_type.equals(BOOL_TYPE))) {
err(node, "Syntax Error: operand should be BOOL");
}
break;
case "+":
if(left_type != ValueType.INT_TYPE && left_type != ValueType.STR_TYPE && ! left_type.isListType()) {
if(!(left_type.equals(INT_TYPE) || left_type.equals(STR_TYPE) || left_type.isListType())) {
err(node, "Syntax Error: operand of + should be INT or STR or LIST");
}
// fallthrough: do left-right match check.
......@@ -233,10 +340,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
public SymbolType analyze(IndexExpr node) {
SymbolType list_type = node.list.dispatch(this);
SymbolType index_type = node.index.dispatch(this);
if(index_type != INT_TYPE) {
if(!index_type.equals(INT_TYPE)) {
err(node, "index_type should be int.");
}
if(list_type == STR_TYPE) {
if(list_type.equals(STR_TYPE)) {
return node.setInferredType(STR_TYPE);
}
else if(list_type.isListType()) {
......@@ -256,7 +363,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
SymbolType this_type = expr.dispatch(this);
if(elementType == null)
elementType = this_type;
if(this_type != elementType)
if(!this_type.equals(elementType))
err(node, "list elements must have the same type.");
}
ListValueType resultType = new ListValueType(elementType);
......@@ -299,6 +406,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
public SymbolType analyze(Identifier id) {
String varName = id.name;
SymbolType varType = sym.get(varName);
System.out.println("var " + varName + "->" + varType.toString());
if (varType != null && varType.isValueType()) {
return id.setInferredType(varType);
......
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