Progress on class def node analyzer
This commit is contained in:
@@ -12,9 +12,9 @@ import java.util.Objects;
|
|||||||
public class ClassVType extends ValueType {
|
public class ClassVType extends ValueType {
|
||||||
|
|
||||||
/** The name of the class. */
|
/** The name of the class. */
|
||||||
private final String className;
|
public final String className;
|
||||||
public SymbolTable<Type> scope;
|
public SymbolTable<Type> scope;
|
||||||
public Identifier super_class;
|
public ClassVType super_class;
|
||||||
/** A class type for the class named CLASSNAME. */
|
/** A class type for the class named CLASSNAME. */
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public ClassVType(@JsonProperty String className) {
|
public ClassVType(@JsonProperty String className) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import chocopy.common.analysis.AbstractNodeAnalyzer;
|
|||||||
import chocopy.common.analysis.SymbolTable;
|
import chocopy.common.analysis.SymbolTable;
|
||||||
import chocopy.common.analysis.types.*;
|
import chocopy.common.analysis.types.*;
|
||||||
import chocopy.common.astnodes.*;
|
import chocopy.common.astnodes.*;
|
||||||
|
import java.util.*;
|
||||||
/** Analyzes declarations to create a top-level symbol table. */
|
/** Analyzes declarations to create a top-level symbol table. */
|
||||||
public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||||
{
|
{
|
||||||
@@ -15,7 +15,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
private final SymbolTable<Type> globals = sym;
|
private final SymbolTable<Type> globals = sym;
|
||||||
/** Receiver for semantic error messages. */
|
/** Receiver for semantic error messages. */
|
||||||
private final Errors errors;
|
private final Errors errors;
|
||||||
|
private ClassVType current_class=null;
|
||||||
/** A new declaration analyzer sending errors to ERRORS0. */
|
/** A new declaration analyzer sending errors to ERRORS0. */
|
||||||
public DeclarationAnalyzer(Errors errors0)
|
public DeclarationAnalyzer(Errors errors0)
|
||||||
{
|
{
|
||||||
@@ -23,18 +23,30 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
ClassVType cvt = new ClassVType("object");
|
ClassVType cvt = new ClassVType("object");
|
||||||
FuncValueType init = new FuncValueType(Type.OBJECT_TYPE);
|
FuncValueType init = new FuncValueType(Type.OBJECT_TYPE);
|
||||||
init.parameters.add(Type.OBJECT_TYPE);
|
init.parameters.add(Type.OBJECT_TYPE);
|
||||||
|
SymbolTable<Type> cvt_scope=new SymbolTable<>(sym);
|
||||||
|
cvt_scope.put("init",init);
|
||||||
|
cvt.scope=cvt_scope;
|
||||||
sym.put("object", cvt);
|
sym.put("object", cvt);
|
||||||
cvt = new ClassVType("int");
|
cvt = new ClassVType("int");
|
||||||
init = new FuncValueType(Type.INT_TYPE);
|
init = new FuncValueType(Type.INT_TYPE);
|
||||||
init.parameters.add(Type.INT_TYPE);
|
init.parameters.add(Type.INT_TYPE);
|
||||||
|
cvt_scope=new SymbolTable<>(sym);
|
||||||
|
cvt_scope.put("init",init);
|
||||||
|
cvt.scope=cvt_scope;
|
||||||
sym.put("int", cvt);
|
sym.put("int", cvt);
|
||||||
cvt = new ClassVType("str");
|
cvt = new ClassVType("str");
|
||||||
init = new FuncValueType(Type.STR_TYPE);
|
init = new FuncValueType(Type.STR_TYPE);
|
||||||
init.parameters.add(Type.STR_TYPE);
|
init.parameters.add(Type.STR_TYPE);
|
||||||
|
cvt_scope=new SymbolTable<>(sym);
|
||||||
|
cvt_scope.put("init",init);
|
||||||
|
cvt.scope=cvt_scope;
|
||||||
sym.put("str", cvt);
|
sym.put("str", cvt);
|
||||||
cvt = new ClassVType("bool");
|
cvt = new ClassVType("bool");
|
||||||
init = new FuncValueType(Type.BOOL_TYPE);
|
init = new FuncValueType(Type.BOOL_TYPE);
|
||||||
init.parameters.add(Type.BOOL_TYPE);
|
init.parameters.add(Type.BOOL_TYPE);
|
||||||
|
cvt_scope=new SymbolTable<>(sym);
|
||||||
|
cvt_scope.put("init",init);
|
||||||
|
cvt.scope=cvt_scope;
|
||||||
sym.put("bool", cvt);
|
sym.put("bool", cvt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +73,13 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
{
|
{
|
||||||
errors.semError(
|
errors.semError(
|
||||||
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
|
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
|
||||||
}
|
}
|
||||||
|
else if (sym.get(name)!= null && sym.get(name) instanceof ClassVType)
|
||||||
|
{
|
||||||
|
errors.semError(
|
||||||
|
id, "Cannot shadow class name: %s", name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym.put(name, type);
|
sym.put(name, type);
|
||||||
@@ -76,11 +94,6 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type analyze(VarDef varDef) {
|
|
||||||
return ValueType.annotationToValueType(varDef.var.type);
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public Type analyze(FuncDef node) {
|
public Type analyze(FuncDef node) {
|
||||||
FuncValueType current_func=new FuncValueType((ValueType) node.returnType.dispatch(this));
|
FuncValueType current_func=new FuncValueType((ValueType) node.returnType.dispatch(this));
|
||||||
@@ -95,11 +108,10 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
node.name, "Duplicate declaration of identifier in same " + "scope: %s", param.identifier.name);
|
node.name, "Duplicate declaration of identifier in same " + "scope: %s", param.identifier.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (sym.get(param.identifier.name)!= null && sym.get(param.identifier.name) instanceof ClassVType)
|
else if (sym.get(param.identifier.name)!= null && sym.get(param.identifier.name) instanceof ClassVType)
|
||||||
{
|
{
|
||||||
System.out.println("Error:"+sym.get(param.identifier.name));
|
|
||||||
errors.semError(
|
errors.semError(
|
||||||
node.name, "Parameter shadows class name: %s", param.identifier.name);
|
param.identifier, "Cannot shadow class name: %s", param.identifier.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,18 +126,29 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
String name = id.name;
|
String name = id.name;
|
||||||
Type type = decl.dispatch(this);
|
Type type = decl.dispatch(this);
|
||||||
|
|
||||||
|
if (type == null)
|
||||||
if (type == null) {
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym.declares(name)) {
|
if (sym.declares(name))
|
||||||
|
{
|
||||||
errors.semError(
|
errors.semError(
|
||||||
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
|
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
|
else if (sym.get(name)!= null && sym.get(name) instanceof ClassVType)
|
||||||
|
{
|
||||||
|
errors.semError(id, "Cannot shadow class name: %s", name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sym.put(name, type);
|
sym.put(name, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*for(String s:sym.getDeclaredSymbols())
|
||||||
|
System.out.println(" "+s);*/
|
||||||
sym = sym.getParent();
|
sym = sym.getParent();
|
||||||
return current_func;
|
return current_func;
|
||||||
}
|
}
|
||||||
@@ -140,14 +163,27 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
}
|
}
|
||||||
return globals.get(node.variable.name);
|
return globals.get(node.variable.name);
|
||||||
}
|
}
|
||||||
|
public boolean compare_functions(FuncValueType fun1, FuncValueType fun2) {
|
||||||
|
if (fun1.returnType.equals(fun2.returnType)==false)
|
||||||
|
return false;
|
||||||
|
if (fun1.parameters.size() != fun2.parameters.size())
|
||||||
|
return false;
|
||||||
|
for (int i=1; i<fun1.parameters.size(); i++)
|
||||||
|
if (fun1.parameters.get(i).equals(fun2.parameters.get(i))==false)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public Type analyze(ClassDef node)
|
public Type analyze(ClassDef node)
|
||||||
{
|
{
|
||||||
ClassVType cvt=new ClassVType(node.name.name);
|
ClassVType cvt=new ClassVType(node.name.name);
|
||||||
SymbolTable current_scope=new SymbolTable<>(sym);
|
SymbolTable<Type> current_scope=new SymbolTable<>(sym);
|
||||||
sym=current_scope;
|
sym=current_scope;
|
||||||
|
current_class=cvt;
|
||||||
Type super_class = sym.get(node.superClass.name);
|
Type super_class = sym.get(node.superClass.name);
|
||||||
cvt.super_class = node.superClass;
|
cvt.super_class = (ClassVType)super_class;
|
||||||
|
SymbolTable<Type> super_scope=null;
|
||||||
|
Set<String> super_syms=null;
|
||||||
if (super_class == null)
|
if (super_class == null)
|
||||||
{
|
{
|
||||||
errors.semError(
|
errors.semError(
|
||||||
@@ -165,22 +201,79 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
super_scope = cvt.super_class.scope;
|
||||||
|
super_syms = super_scope.getDeclaredSymbols();
|
||||||
for (Declaration decl : node.declarations)
|
for (Declaration decl : node.declarations)
|
||||||
{
|
{
|
||||||
Identifier id = decl.getIdentifier();
|
Identifier id = decl.getIdentifier();
|
||||||
String name = id.name;
|
String name = id.name;
|
||||||
Type type = decl.dispatch(this);
|
Type type = decl.dispatch(this);
|
||||||
if (sym.declares(name)) {
|
|
||||||
|
if (type == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sym.declares(name))
|
||||||
|
{
|
||||||
errors.semError(
|
errors.semError(
|
||||||
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
|
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
|
||||||
}
|
}
|
||||||
else
|
if (type instanceof ClassVType || type instanceof ListValueType)
|
||||||
{
|
{//Check for attribute type
|
||||||
sym.put(name, type);
|
if (super_syms.contains(name))
|
||||||
|
{//Check for redefined superclass attribute
|
||||||
|
errors.semError(
|
||||||
|
id, "Cannot re-define attribute: %s", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sym.put(name, type);
|
||||||
}
|
}
|
||||||
|
else if(type instanceof FuncValueType)
|
||||||
|
{//For function declarations
|
||||||
|
List<ValueType> params = ((FuncValueType)type).parameters;
|
||||||
|
if(params.size() < 1 || (params.get(0) instanceof ClassVType==false) || ((ClassVType)params.get(0)).className.equals(current_class.className)==false)
|
||||||
|
errors.semError(
|
||||||
|
id, "First parameter of method must be of same class: %s", name);
|
||||||
|
if (super_syms.contains(name))
|
||||||
|
{
|
||||||
|
if ((super_scope.get(id.name) instanceof FuncValueType)==false)
|
||||||
|
errors.semError(id, "Cannot re-define attribute: %s" + name);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FuncValueType super_func = (FuncValueType) super_scope.get(id.name);
|
||||||
|
FuncValueType current_func = (FuncValueType) type;
|
||||||
|
if (compare_functions(super_func, current_func))
|
||||||
|
sym.put(name, type);
|
||||||
|
else
|
||||||
|
errors.semError(
|
||||||
|
id, "Method overridden with different type signature: %s" + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sym.put(name, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (String super_sym : super_syms)
|
||||||
|
{
|
||||||
|
if (sym.getDeclaredSymbols().contains(super_sym)==false)
|
||||||
|
sym.put(super_sym, super_scope.get(super_sym));
|
||||||
|
}
|
||||||
sym = sym.getParent();
|
sym = sym.getParent();
|
||||||
|
current_class=null;
|
||||||
return cvt;
|
return cvt;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public Type analyze(VarDef node)
|
||||||
|
{
|
||||||
|
Type var_type = sym.get(node.var.identifier.name);
|
||||||
|
if (node.var.identifier.name!=current_class.className && var_type==null)
|
||||||
|
errors.semError(
|
||||||
|
node, "Cannot re-define attribute: %s", node.var.identifier.name);
|
||||||
|
return ValueType.annotationToValueType(node.var.type);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Type analyze(ListType node)
|
||||||
|
{
|
||||||
|
return ValueType.annotationToValueType(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user