|
|
@ -2,15 +2,14 @@ package chocopy.pa2;
|
|
|
|
|
|
|
|
|
|
|
|
import chocopy.common.analysis.AbstractNodeAnalyzer;
|
|
|
|
import chocopy.common.analysis.AbstractNodeAnalyzer;
|
|
|
|
import chocopy.common.analysis.SymbolTable;
|
|
|
|
import chocopy.common.analysis.SymbolTable;
|
|
|
|
import chocopy.common.analysis.types.Type;
|
|
|
|
import chocopy.common.analysis.types.*;
|
|
|
|
import chocopy.common.analysis.types.ValueType;
|
|
|
|
|
|
|
|
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 final SymbolTable<Type> sym = new SymbolTable<>();
|
|
|
|
private SymbolTable<Type> sym = new SymbolTable<>();
|
|
|
|
/** Global symbol table. */
|
|
|
|
/** Global symbol table. */
|
|
|
|
private final SymbolTable<Type> globals = sym;
|
|
|
|
private final SymbolTable<Type> globals = sym;
|
|
|
|
/** Receiver for semantic error messages. */
|
|
|
|
/** Receiver for semantic error messages. */
|
|
|
@ -30,7 +29,6 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
|
|
|
|
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) {
|
|
|
@ -52,4 +50,63 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
|
|
|
|
public Type analyze(VarDef varDef) {
|
|
|
|
public Type analyze(VarDef varDef) {
|
|
|
|
return ValueType.annotationToValueType(varDef.var.type);
|
|
|
|
return ValueType.annotationToValueType(varDef.var.type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Type analyze(FuncDef node) {
|
|
|
|
|
|
|
|
FuncType current_func=new FuncType((ValueType) node.returnType.dispatch(this));
|
|
|
|
|
|
|
|
SymbolTable current_scope=new SymbolTable<>(sym);
|
|
|
|
|
|
|
|
sym=current_scope;
|
|
|
|
|
|
|
|
for (TypedVar param : node.params)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sym.declares(param.identifier.name))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
errors.semError(
|
|
|
|
|
|
|
|
node.name, "Duplicate declaration of identifier in same " + "scope: %s", param.identifier.name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
else if (sym.get(param.identifier.name)!= null)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
System.out.println("Error:"+sym.get(param.identifier.name));
|
|
|
|
|
|
|
|
errors.semError(
|
|
|
|
|
|
|
|
node.name, "Parameter shadows class name: %s", param.identifier.name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Type p = param.dispatch(this);
|
|
|
|
|
|
|
|
current_func.parameters.add((ValueType)p);
|
|
|
|
|
|
|
|
sym.put(param.identifier.name, p);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (Declaration decl : node.declarations) {
|
|
|
|
|
|
|
|
Identifier id = decl.getIdentifier();
|
|
|
|
|
|
|
|
String name = id.name;
|
|
|
|
|
|
|
|
Type type = decl.dispatch(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type == null) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 current_func;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Type analyze(GlobalDecl node)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (globals.declares(node.variable.name)==false)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
errors.semError(
|
|
|
|
|
|
|
|
node.variable, "Not a global variable: %s", node.variable.name);
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return globals.get(node.variable.name);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|