Added class analyze method
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user