Fixed nonlocal declaration errors

master
Apoorva Ranade 3 years ago
parent e47bc2df75
commit 31201bcf33

@ -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;
}
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(
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(
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

Loading…
Cancel
Save