Fixed nonlocal declaration errors
This commit is contained in:
@@ -28,6 +28,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
firstPass = true;
|
||||
errors = errors0;
|
||||
globals = sym;
|
||||
// Symbol table entry for object class
|
||||
ClassVType cvt = new ClassVType("object"), obj = cvt;
|
||||
FuncType init = new FuncType(Type.OBJECT_TYPE);
|
||||
init.parameters.add(Type.OBJECT_TYPE);
|
||||
@@ -35,6 +36,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
cvt_scope.put("init",init);
|
||||
cvt.scope=cvt_scope;
|
||||
sym.put("object", cvt);
|
||||
//Symbol table entry for int class
|
||||
cvt = new ClassVType("int");
|
||||
cvt.super_class = obj;
|
||||
init = new FuncType(Type.INT_TYPE);
|
||||
@@ -43,6 +45,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
cvt_scope.put("init",init);
|
||||
cvt.scope=cvt_scope;
|
||||
sym.put("int", cvt);
|
||||
//Symbol table entry for str class
|
||||
cvt = new ClassVType("str");
|
||||
cvt.super_class = obj;
|
||||
init = new FuncType(Type.STR_TYPE);
|
||||
@@ -51,6 +54,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
cvt_scope.put("init",init);
|
||||
cvt.scope=cvt_scope;
|
||||
sym.put("str", cvt);
|
||||
//Symbol table entry for bool class
|
||||
cvt = new ClassVType("bool");
|
||||
cvt.super_class = obj;
|
||||
init = new FuncType(Type.BOOL_TYPE);
|
||||
@@ -59,24 +63,25 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
cvt_scope.put("init",init);
|
||||
cvt.scope=cvt_scope;
|
||||
sym.put("bool", cvt);
|
||||
|
||||
//Symbol table entry for None return type
|
||||
cvt = new ClassVType("<None>");
|
||||
cvt.super_class = obj;
|
||||
sym.put("<None>", cvt);
|
||||
|
||||
//Symbol table entry for inbuilt print function
|
||||
ArrayList<ValueType> param = new ArrayList<ValueType>();
|
||||
param.add(Type.OBJECT_TYPE);
|
||||
sym.put("print", new FuncType(param, Type.NONE_TYPE));
|
||||
|
||||
//Symbol table entry for inbuilt len function
|
||||
param = new ArrayList<ValueType>();
|
||||
param.add(Type.OBJECT_TYPE);
|
||||
sym.put("len", new FuncType(param, Type.INT_TYPE));
|
||||
|
||||
//Symbol table entry for inbuilt input function
|
||||
sym.put("input", new FuncType(new ArrayList<>(), Type.STR_TYPE));
|
||||
typeChecker = new TypeChecker(globals, errors);
|
||||
}
|
||||
|
||||
public DeclarationAnalyzer(Errors errors0, TypeChecker typeChecker, SymbolTable<Type> globals){
|
||||
public DeclarationAnalyzer(Errors errors0, TypeChecker typeChecker, SymbolTable<Type> globals)
|
||||
{
|
||||
firstPass = false;
|
||||
this.typeChecker = typeChecker;
|
||||
errors = errors0;
|
||||
@@ -86,27 +91,18 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
{
|
||||
return globals;
|
||||
}
|
||||
private void putSymChecked(Node node, String name, Type ty){
|
||||
if (ty == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
private void putSymChecked(Node node, String name, Type ty)
|
||||
{
|
||||
if (ty == null)
|
||||
return;
|
||||
|
||||
if (globals.get(name)!= null && !(ty instanceof ClassVType) && globals.get(name) instanceof ClassVType) //class names are only in global scope
|
||||
{
|
||||
errors.semError(node, "Cannot shadow class name: %s", name);
|
||||
}
|
||||
else if (sym.declares(name))
|
||||
{
|
||||
errors.semError(
|
||||
if (globals.get(name)!= null && !(ty instanceof ClassVType) && globals.get(name) instanceof ClassVType) //class names are only in global scope
|
||||
errors.semError(node, "Cannot shadow class name: %s", name);
|
||||
else if (sym.declares(name))
|
||||
errors.semError(
|
||||
node, "Duplicate declaration of identifier in same scope: %s", name);
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sym.put(name, ty);
|
||||
}
|
||||
else
|
||||
sym.put(name, ty);
|
||||
}
|
||||
@Override
|
||||
public Type analyze(Program program)
|
||||
@@ -116,8 +112,6 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
Identifier id = decl.getIdentifier();
|
||||
String name = id.name;
|
||||
Type type = decl.dispatch(this);
|
||||
|
||||
|
||||
}
|
||||
// Check for return statements at top
|
||||
for (Stmt stmt : program.statements)
|
||||
@@ -130,11 +124,13 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type analyze(FuncDef node) {
|
||||
public Type analyze(FuncDef node)
|
||||
{
|
||||
Type fTy = globals.get(node.name.name);
|
||||
FuncType current_func=null;
|
||||
|
||||
if(!(fTy instanceof FuncType)){
|
||||
if(!(fTy instanceof FuncType))
|
||||
{
|
||||
if(fTy == null)
|
||||
{
|
||||
current_func = new FuncType(new ArrayList<ValueType>(),
|
||||
@@ -187,7 +183,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
else
|
||||
otherDefs.add(decl);
|
||||
for (Declaration decl : varDefs)
|
||||
if(decl instanceof VarDef)
|
||||
if(decl instanceof VarDef||decl instanceof NonLocalDecl)
|
||||
decl.dispatch(this);
|
||||
else
|
||||
decl.dispatch(typeChecker);
|
||||
@@ -200,7 +196,8 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
return current_func;
|
||||
}
|
||||
|
||||
public boolean compare_functions(FuncType fun1, FuncType fun2) {
|
||||
public boolean compare_functions(FuncType fun1, FuncType fun2)
|
||||
{
|
||||
if (fun1.returnType.equals(fun2.returnType)==false)
|
||||
return false;
|
||||
if (fun1.parameters.size() != fun2.parameters.size())
|
||||
@@ -305,7 +302,27 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
putSymChecked(node.name, node.name.name, cvt);
|
||||
return cvt;
|
||||
}
|
||||
|
||||
boolean isVariableType(Type ty)
|
||||
{
|
||||
return ty.isSpecialType() || ty.equals(Type.OBJECT_TYPE);
|
||||
}
|
||||
@Override
|
||||
public Type analyze(NonLocalDecl node)
|
||||
{
|
||||
SymbolTable<Type> curr_sym=sym;
|
||||
while(curr_sym.getParent()!=null)
|
||||
{
|
||||
if (curr_sym.declares(node.variable.name) && isVariableType(sym.get(node.variable.name)))
|
||||
{
|
||||
sym.put(node.variable.name, sym.get(node.variable.name));
|
||||
return sym.get(node.variable.name);
|
||||
}
|
||||
curr_sym=curr_sym.getParent();
|
||||
}
|
||||
errors.semError(
|
||||
node.variable, "Not a nonlocal variable: %s", node.variable.name);
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Type analyze(VarDef node)
|
||||
{
|
||||
@@ -332,10 +349,12 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
return var_type;
|
||||
}
|
||||
|
||||
public void setScope(SymbolTable<Type> currentScope) {
|
||||
public void setScope(SymbolTable<Type> currentScope)
|
||||
{
|
||||
sym = currentScope;
|
||||
}
|
||||
public void setCurrClass(ClassVType current_class){
|
||||
public void setCurrClass(ClassVType current_class)
|
||||
{
|
||||
this.current_class = current_class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import static chocopy.common.analysis.types.Type.OBJECT_TYPE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.text.StyledEditorKit.BoldAction;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonInject.Value;
|
||||
|
||||
/**
|
||||
@@ -31,7 +33,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
private boolean returned = false, member = false;
|
||||
/** Collector for errors. */
|
||||
private final Errors errors;
|
||||
|
||||
private Boolean assign = false;
|
||||
/**
|
||||
* Creates a type checker using GLOBALSYMBOLS for the initial global symbol table and ERRORS0 to
|
||||
* receive semantic errors.
|
||||
@@ -87,6 +89,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
Type tr = node.value.dispatch(this);
|
||||
Type tl;
|
||||
boolean error = false;
|
||||
assign=true;
|
||||
for (Expr ex : node.targets)
|
||||
{
|
||||
tl = ex.dispatch(this);
|
||||
@@ -114,6 +117,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
assign=false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -317,7 +321,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
public Type analyze(NoneLiteral node) {
|
||||
return node.setInferredType(Type.NONE_TYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public Type analyze(NonLocalDecl node) {
|
||||
SymbolTable<Type> parent = currentScope.getParent();
|
||||
@@ -337,7 +341,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
*/
|
||||
@Override
|
||||
public Type analyze(ReturnStmt node) {
|
||||
if(node.value != null)
|
||||
@@ -472,10 +476,13 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
public Type analyze(Identifier id) {
|
||||
String varName = id.name;
|
||||
Type varType = currentScope.get(varName);
|
||||
if(varType!=null && !currentScope.getDeclaredSymbols().contains(varName)){
|
||||
err(id, "Cannot assign to variable that is not explicitly declared in this scope: %s", varName);
|
||||
if(varType!=null)
|
||||
{
|
||||
if(assign==true && !currentScope.getDeclaredSymbols().contains(varName))
|
||||
err(id, "Cannot assign to variable that is not explicitly declared in this scope: %s", varName);
|
||||
else if(assign==false && currentScope.get(varName)==null)
|
||||
err(id, "Variable not declared in scope: %s", varName);
|
||||
}
|
||||
|
||||
if (varType != null && varType.isValueType()) {
|
||||
return id.setInferredType(varType);
|
||||
}
|
||||
@@ -488,16 +495,14 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
public Type analyze(GlobalDecl node)
|
||||
{
|
||||
Type ty = sym.get(node.variable.name);
|
||||
if (sym.declares(node.variable.name)==false ||
|
||||
!isVariableType(ty)
|
||||
)
|
||||
if (sym.declares(node.variable.name)==false || !isVariableType(ty))
|
||||
{
|
||||
errors.semError(
|
||||
err(
|
||||
node.variable, "Not a global variable: %s", node.variable.name);
|
||||
return null;
|
||||
}
|
||||
else if(currentScope.getDeclaredSymbols().contains(node.variable.name)){
|
||||
errors.semError(
|
||||
err(
|
||||
node.variable, "Duplicate declaration of identifier in same scope: %s", node.variable.name);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user