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

use 2-phrase now!

parent 93907a9c
No related branches found
No related tags found
No related merge requests found
Pipeline #45 passed with warnings with stages
in 3 minutes and 45 seconds
...@@ -5,6 +5,7 @@ import java.util.List; ...@@ -5,6 +5,7 @@ import java.util.List;
import chocopy.common.analysis.NodeAnalyzer; import chocopy.common.analysis.NodeAnalyzer;
import chocopy.common.analysis.SymbolTable; import chocopy.common.analysis.SymbolTable;
import chocopy.common.analysis.types.SymbolType; import chocopy.common.analysis.types.SymbolType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java_cup.runtime.ComplexSymbolFactory.Location; import java_cup.runtime.ComplexSymbolFactory.Location;
/** Def statements. */ /** Def statements. */
...@@ -22,6 +23,7 @@ public class FuncDef extends Declaration { ...@@ -22,6 +23,7 @@ public class FuncDef extends Declaration {
public final List<Stmt> statements; public final List<Stmt> statements;
// recolic // recolic
@JsonIgnore
public SymbolTable<SymbolType> symTable = null; public SymbolTable<SymbolType> symTable = null;
/** The AST for /** The AST for
......
...@@ -22,10 +22,14 @@ public class StudentAnalysis { ...@@ -22,10 +22,14 @@ public class StudentAnalysis {
// declarationAnalyzer.getGlobals(); // declarationAnalyzer.getGlobals();
SymbolTable<SymbolType> globalSym = new SymbolTable<>(); SymbolTable<SymbolType> globalSym = new SymbolTable<>();
if (!program.hasErrors()) { //if (!program.hasErrors()) {
TypeChecker typeChecker = TypeChecker typeChecker = new TypeChecker(globalSym, program.errors, true);
new TypeChecker(globalSym, program.errors); program.dispatch(typeChecker);
program.dispatch(typeChecker); //}
if(!program.hasErrors()) {
TypeChecker next_time = new TypeChecker(typeChecker.getGlobals(), program.errors, false);
program.dispatch(next_time);
} }
return program; return program;
......
...@@ -18,17 +18,24 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -18,17 +18,24 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
// private SymbolTable<SymbolType> sym; // private SymbolTable<SymbolType> sym;
/** Current symbol table. Changes with new declarative region. */ /** Current symbol table. Changes with new declarative region. */
private SymbolTable<SymbolType> sym = new SymbolTable<>(); private SymbolTable<SymbolType> sym;
/** Global symbol table. */ /** Global symbol table. */
private final SymbolTable<SymbolType> globals = sym; private final SymbolTable<SymbolType> globals;
/** Collector for errors. */ /** Collector for errors. */
private Errors errors; private Errors errors;
private boolean isFirstRun;
/** Creates a type checker using GLOBALSYMBOLS for the initial global /** Creates a type checker using GLOBALSYMBOLS for the initial global
* symbol table and ERRORS0 to receive semantic errors. */ * symbol table and ERRORS0 to receive semantic errors. */
public TypeChecker(SymbolTable<SymbolType> globalSymbols, Errors errors0) { public TypeChecker(SymbolTable<SymbolType> globalSymbols, Errors errors0, boolean firstRun) {
sym = globalSymbols; sym = globalSymbols;
globals = sym;
errors = errors0; errors = errors0;
isFirstRun = firstRun;
}
public SymbolTable<SymbolType> getGlobals() {
return globals;
} }
/** Inserts an error message in NODE if there isn't one already. /** Inserts an error message in NODE if there isn't one already.
...@@ -53,7 +60,8 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -53,7 +60,8 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
} }
// TODO: DO NOT throw on duplicate id. generate a compiler error. // TODO: DO NOT throw on duplicate id. generate a compiler error.
sym.put(name, type); if(isFirstRun)
sym.put(name, type);
} }
for (Stmt stmt : program.statements) { for (Stmt stmt : program.statements) {
stmt.dispatch(this); stmt.dispatch(this);
...@@ -73,8 +81,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -73,8 +81,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
@Override @Override
public SymbolType analyze(ClassDef classDef) { public SymbolType analyze(ClassDef classDef) {
assert classDef.memberMap == null; if(isFirstRun) {
classDef.memberMap = new HashMap<>(); assert classDef.memberMap == null;
classDef.memberMap = new HashMap<>();
}
assert classDef.memberMap != null; assert classDef.memberMap != null;
// My-name already pushed to symbolMap // My-name already pushed to symbolMap
...@@ -89,7 +99,8 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -89,7 +99,8 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
for(Declaration decl : classDef.declarations) { for(Declaration decl : classDef.declarations) {
String name = decl.getIdentifier().name; String name = decl.getIdentifier().name;
SymbolType type = decl.dispatch(this); SymbolType type = decl.dispatch(this);
classDef.memberMap.put(name, type); if(isFirstRun)
classDef.memberMap.put(name, type);
} }
sym = sym.getParent(); sym = sym.getParent();
...@@ -98,9 +109,12 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -98,9 +109,12 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
@Override @Override
public SymbolType analyze(FuncDef funcDef) { public SymbolType analyze(FuncDef funcDef) {
System.out.println("debug: start funcDef: " + funcDef.getClass().getName()); if(isFirstRun) {
assert funcDef.symTable == null; assert funcDef.symTable == null;
sym = funcDef.symTable = new SymbolTable<SymbolType>(sym); sym = funcDef.symTable = new SymbolTable<SymbolType>(sym);
}
else
sym = funcDef.symTable;
assert funcDef.symTable != null; // may suck if partial-compiling happens... assert funcDef.symTable != null; // may suck if partial-compiling happens...
// Func parameter list // Func parameter list
...@@ -108,14 +122,20 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -108,14 +122,20 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
for(TypedVar param : funcDef.params) { for(TypedVar param : funcDef.params) {
String name = param.identifier.name; String name = param.identifier.name;
ValueType type = ValueType.annotationToValueType(param.type); ValueType type = ValueType.annotationToValueType(param.type);
sym.put(name, type); if(isFirstRun)
sym.put(name, type);
args.add(type); args.add(type);
} }
for(Declaration decl : funcDef.declarations) { for(Declaration decl : funcDef.declarations) {
String name = decl.getIdentifier().name; String name = decl.getIdentifier().name;
SymbolType type = decl.dispatch(this); SymbolType type = decl.dispatch(this);
sym.put(name, type); if(isFirstRun)
sym.put(name, type);
}
for(Stmt stmt : funcDef.statements) {
stmt.dispatch(this);
} }
// function scope ends.. backtracking... // function scope ends.. backtracking...
...@@ -340,11 +360,11 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -340,11 +360,11 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
SymbolType funcType = sym.get(node.function.name); SymbolType funcType = sym.get(node.function.name);
if(funcType == null) { if(funcType == null) {
err(node, "calling undeclared function " + node.function.name); err(node, "calling undeclared function " + node.function.name);
return OBJECT_TYPE; return null;
} }
if(!funcType.isFuncType()) { if(!funcType.isFuncType()) {
err(node, "calling non-function variable " + node.function.name); err(node, "calling non-function variable " + node.function.name);
return OBJECT_TYPE; return null;
} }
FuncType fType = (FuncType)funcType; FuncType fType = (FuncType)funcType;
List<SymbolType> args_type = new ArrayList<SymbolType>(); List<SymbolType> args_type = new ArrayList<SymbolType>();
...@@ -354,6 +374,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -354,6 +374,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
if(!fType.parameters.equals(args_type)) { if(!fType.parameters.equals(args_type)) {
err(node, "function parameter type list mismatch: " + node.function.name + ". Expected " + fType.parameters.toString() + ", got " + args_type.toString()); err(node, "function parameter type list mismatch: " + node.function.name + ". Expected " + fType.parameters.toString() + ", got " + args_type.toString());
} }
System.out.println("debug: callexpr set type = " + fType.returnType.toString());
return node.setInferredType(fType.returnType); return node.setInferredType(fType.returnType);
} }
...@@ -466,6 +487,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { ...@@ -466,6 +487,10 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
public SymbolType analyze(Identifier id) { public SymbolType analyze(Identifier id) {
String varName = id.name; String varName = id.name;
SymbolType varType = sym.get(varName); SymbolType varType = sym.get(varName);
if(varType == null) {
err(id, "undefined id " + varName);
return null;
}
System.out.println("var " + varName + "->" + varType.toString()); System.out.println("var " + varName + "->" + varType.toString());
if (varType != null && varType.isValueType()) { if (varType != null && varType.isValueType()) {
......
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