Added class analyze method

master
Apoorva Ranade 3 years ago
parent 92e6688289
commit 79be979e13

@ -0,0 +1,56 @@
package chocopy.common.analysis.types;
import chocopy.common.astnodes.ClassType;
import chocopy.common.astnodes.Identifier;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import chocopy.common.analysis.SymbolTable;
import java.util.Objects;
/** Represents the semantic value of a simple class reference. */
public class ClassVType extends ValueType {
/** The name of the class. */
private final String className;
public SymbolTable<Type> scope;
public Identifier super_class;
/** A class type for the class named CLASSNAME. */
@JsonCreator
public ClassVType(@JsonProperty String className) {
this.className = className;
}
/** A class type for the class referenced by CLASSTYPEANNOTATION. */
public ClassVType(ClassType classTypeAnnotation) {
this.className = classTypeAnnotation.className;
}
@Override
@JsonProperty
public String className() {
return className;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ClassVType classType = (ClassVType) o;
return Objects.equals(className, classType.className);
}
@Override
public int hashCode() {
return Objects.hash(className);
}
@Override
public String toString() {
return className;
}
}

@ -8,11 +8,9 @@ import java.util.List;
/** Semantic information for a function or method. */ /** Semantic information for a function or method. */
public class FuncType extends Type { public class FuncType extends Type {
/** Function's name. */
//public final String name;
/** Types of parameters. */ /** Types of parameters. */
public List<ValueType> parameters; public final List<ValueType> parameters;
/** Function's return type. */ /** Function's return type. */
public final ValueType returnType; public final ValueType returnType;

@ -0,0 +1,49 @@
package chocopy.common.analysis.types;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.ArrayList;
import java.util.List;
/** Semantic information for a function or method. */
public class FuncValueType extends Type {
/** Function's name. */
//public final String name;
/** Types of parameters. */
public List<ValueType> parameters;
/** Function's return type. */
public final ValueType returnType;
/** Create a FuncType returning RETURNTYPE0, initially parameterless. */
public FuncValueType(ValueType returnType0) {
this(new ArrayList<>(), returnType0);
}
/**
* Create a FuncType for NAME0 with formal parameter types PARAMETERS0, returning type
* RETURNTYPE0.
*/
@JsonCreator
public FuncValueType(List<ValueType> parameters0, ValueType returnType0) {
this.parameters = parameters0;
this.returnType = returnType0;
}
@Override
public boolean isFuncType() {
return true;
}
/** Return the type of the K-th parameter. */
public ValueType getParamType(int k) {
return parameters.get(k);
}
@Override
public String toString() {
return "<function>";
}
}

@ -6,7 +6,8 @@ import chocopy.common.analysis.types.*;
import chocopy.common.astnodes.*; import chocopy.common.astnodes.*;
/** 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>
{
/** Current symbol table. Changes with new declarative region. */ /** Current symbol table. Changes with new declarative region. */
private SymbolTable<Type> sym = new SymbolTable<>(); private SymbolTable<Type> sym = new SymbolTable<>();
@ -16,33 +17,63 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
private final Errors errors; private final Errors errors;
/** A new declaration analyzer sending errors to ERRORS0. */ /** A new declaration analyzer sending errors to ERRORS0. */
public DeclarationAnalyzer(Errors errors0) { public DeclarationAnalyzer(Errors errors0)
{
errors = errors0; errors = errors0;
ClassVType cvt = new ClassVType("object");
FuncValueType init = new FuncValueType(Type.OBJECT_TYPE);
init.parameters.add(Type.OBJECT_TYPE);
sym.put("object", cvt);
cvt = new ClassVType("int");
init = new FuncValueType(Type.INT_TYPE);
init.parameters.add(Type.INT_TYPE);
sym.put("int", cvt);
cvt = new ClassVType("str");
init = new FuncValueType(Type.STR_TYPE);
init.parameters.add(Type.STR_TYPE);
sym.put("str", cvt);
cvt = new ClassVType("bool");
init = new FuncValueType(Type.BOOL_TYPE);
init.parameters.add(Type.BOOL_TYPE);
sym.put("bool", cvt);
} }
public SymbolTable<Type> getGlobals() { public SymbolTable<Type> getGlobals()
{
return globals; return globals;
} }
@Override @Override
public Type analyze(Program program) { public Type analyze(Program program)
for (Declaration decl : program.declarations) { {
for (Declaration decl : program.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 (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 { }
else
{
sym.put(name, type); sym.put(name, type);
} }
} }
// Check for return statements at top
for (Stmt stmt : program.statements)
{
if (stmt instanceof ReturnStmt)
errors.semError(
stmt, "Return statement cannot appear at the top level");
}
return null; return null;
} }
@ -52,7 +83,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
} }
@Override @Override
public Type analyze(FuncDef node) { public Type analyze(FuncDef node) {
FuncType current_func=new FuncType((ValueType) node.returnType.dispatch(this)); FuncValueType current_func=new FuncValueType((ValueType) node.returnType.dispatch(this));
SymbolTable current_scope=new SymbolTable<>(sym); SymbolTable current_scope=new SymbolTable<>(sym);
sym=current_scope; sym=current_scope;
for (TypedVar param : node.params) for (TypedVar param : node.params)
@ -64,21 +95,21 @@ 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)
{ {
System.out.println("Error:"+sym.get(param.identifier.name)); System.out.println("Error:"+sym.get(param.identifier.name));
errors.semError( errors.semError(
node.name, "Parameter shadows class name: %s", param.identifier.name); node.name, "Parameter shadows class name: %s", param.identifier.name);
continue; continue;
}*/ }
Type p = param.dispatch(this); Type p = param.dispatch(this);
current_func.parameters.add((ValueType)p); current_func.parameters.add((ValueType)p);
sym.put(param.identifier.name, p); sym.put(param.identifier.name, p);
} }
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);
@ -109,4 +140,47 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
} }
return globals.get(node.variable.name); return globals.get(node.variable.name);
} }
@Override
public Type analyze(ClassDef node)
{
ClassVType cvt=new ClassVType(node.name.name);
SymbolTable current_scope=new SymbolTable<>(sym);
sym=current_scope;
Type super_class = sym.get(node.superClass.name);
cvt.super_class = node.superClass;
if (super_class == null)
{
errors.semError(
node.name, "Super-class not defined: %s", node.superClass.name);
}
else if ((super_class instanceof ClassVType)==false)
{
errors.semError(
node.name, "Super-class must be a class: %s", node.superClass.name);
}
else if (node.superClass.name.equals("int") || node.superClass.name.equals("bool") || node.superClass.name.equals("str"))
{
errors.semError(
node.name, "Cannot extend special class: %s", node.superClass.name);
}
else
{
for (Declaration decl : node.declarations)
{
Identifier id = decl.getIdentifier();
String name = id.name;
Type type = decl.dispatch(this);
if (sym.declares(name)) {
errors.semError(
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
}
else
{
sym.put(name, type);
}
}
}
sym = sym.getParent();
return cvt;
}
} }

Loading…
Cancel
Save