Final bug fixes.
Worklog. Added test diff.py demonstrating the differences between the reference compiler.
This commit is contained in:
@@ -4,7 +4,11 @@ import chocopy.common.analysis.AbstractNodeAnalyzer;
|
||||
import chocopy.common.analysis.SymbolTable;
|
||||
import chocopy.common.analysis.types.*;
|
||||
import chocopy.common.astnodes.*;
|
||||
import java_cup.runtime.Symbol;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonInject.Value;
|
||||
/** Analyzes declarations to create a top-level symbol table. */
|
||||
public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
{
|
||||
@@ -22,61 +26,51 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
// In the second pass, typeAnalyzer will call declanalyzer to
|
||||
// analyze local vars/func/class defs and create sub-scope symtable.
|
||||
private ClassVType current_class=null;
|
||||
private boolean postCheck = false;
|
||||
private String classDefError = null;
|
||||
/** A new declaration analyzer sending errors to ERRORS0. */
|
||||
public void initScope(SymbolTable<Type> s){
|
||||
// Symbol table entry for object class
|
||||
ClassVType cvt = new ClassVType("object"), obj = cvt;
|
||||
s.put("object", cvt);
|
||||
//Symbol table entry for int class
|
||||
cvt = new ClassVType("int");
|
||||
cvt.super_class = obj;
|
||||
s.put("int", cvt);
|
||||
//Symbol table entry for str class
|
||||
cvt = new ClassVType("str");
|
||||
cvt.super_class = obj;
|
||||
s.put("str", cvt);
|
||||
//Symbol table entry for bool class
|
||||
cvt = new ClassVType("bool");
|
||||
cvt.super_class = obj;
|
||||
s.put("bool", cvt);
|
||||
//Symbol table entry for None return type
|
||||
cvt = new ClassVType("<None>");
|
||||
cvt.super_class = obj;
|
||||
s.put("<None>", cvt);
|
||||
//Symbol table entry for inbuilt print function
|
||||
ArrayList<ValueType> param = new ArrayList<ValueType>();
|
||||
param.add(Type.OBJECT_TYPE);
|
||||
s.put("print", new FuncType(param, Type.NONE_TYPE));
|
||||
//Symbol table entry for inbuilt len function
|
||||
param = new ArrayList<ValueType>();
|
||||
param.add(Type.OBJECT_TYPE);
|
||||
s.put("len", new FuncType(param, Type.INT_TYPE));
|
||||
//Symbol table entry for inbuilt input function
|
||||
s.put("input", new FuncType(new ArrayList<>(), Type.STR_TYPE));
|
||||
}
|
||||
public SymbolTable<Type> createScope(SymbolTable<Type> s){
|
||||
SymbolTable<Type> newScope = new SymbolTable<>(s);
|
||||
initScope(newScope);
|
||||
return newScope;
|
||||
}
|
||||
public DeclarationAnalyzer(Errors errors0)
|
||||
{
|
||||
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);
|
||||
SymbolTable<Type> cvt_scope=new SymbolTable<>(sym);
|
||||
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);
|
||||
init.parameters.add(Type.INT_TYPE);
|
||||
cvt_scope=new SymbolTable<>(sym);
|
||||
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);
|
||||
init.parameters.add(Type.STR_TYPE);
|
||||
cvt_scope=new SymbolTable<>(sym);
|
||||
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);
|
||||
init.parameters.add(Type.BOOL_TYPE);
|
||||
cvt_scope=new SymbolTable<>(sym);
|
||||
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));
|
||||
initScope(sym);
|
||||
typeChecker = new TypeChecker(globals, errors);
|
||||
}
|
||||
|
||||
@@ -91,10 +85,10 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
{
|
||||
return globals;
|
||||
}
|
||||
private void putSymChecked(Node node, String name, Type ty)
|
||||
private boolean putSymChecked(Node node, String name, Type ty)
|
||||
{
|
||||
if (ty == null)
|
||||
return;
|
||||
return false;
|
||||
|
||||
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);
|
||||
@@ -102,7 +96,11 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
errors.semError(
|
||||
node, "Duplicate declaration of identifier in same scope: %s", name);
|
||||
else
|
||||
{
|
||||
sym.put(name, ty);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Type analyze(Program program)
|
||||
@@ -126,42 +124,53 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
@Override
|
||||
public Type analyze(FuncDef node)
|
||||
{
|
||||
Type fTy = globals.get(node.name.name);
|
||||
FuncType current_func=null;
|
||||
if(!postCheck){
|
||||
Type fTy = null;
|
||||
if(sym.declares(node.name.name))
|
||||
fTy = sym.get(node.name.name);
|
||||
|
||||
if(!(fTy instanceof FuncType))
|
||||
{
|
||||
if(fTy == null)
|
||||
FuncType current_func=null;
|
||||
|
||||
if(!(fTy instanceof FuncType))
|
||||
{
|
||||
current_func = new FuncType(new ArrayList<ValueType>(),
|
||||
ValueType.annotationToValueType(node.returnType));
|
||||
|
||||
for (TypedVar param : node.params)
|
||||
if(fTy == null)
|
||||
{
|
||||
Type p = ValueType.annotationToValueType(param.type);
|
||||
current_func.parameters.add((ValueType)p);
|
||||
}
|
||||
sym.put(node.name.name, current_func);
|
||||
if(!firstPass)
|
||||
{
|
||||
SymbolTable<Type> parent = sym.getParent();
|
||||
if(parent!=null && parent != globals){
|
||||
parent.put(node.name.name, current_func);
|
||||
current_func = new FuncType(new ArrayList<ValueType>(),
|
||||
ValueType.annotationToValueType(node.returnType));
|
||||
|
||||
for (TypedVar param : node.params)
|
||||
{
|
||||
ValueType p = ValueType.annotationToValueType(param.type);
|
||||
current_func.parameters.add(p);
|
||||
if(classDefError != null && p.className().equals(classDefError))
|
||||
errors.semError(param.type, "Invalid type annotation; there is no class named: %s", classDefError);
|
||||
}
|
||||
sym.put(node.name.name, current_func);
|
||||
if(!firstPass)
|
||||
{
|
||||
SymbolTable<Type> parent = sym.getParent();
|
||||
if(parent!=null && parent != globals){
|
||||
parent.put(node.name.name, current_func);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(fTy instanceof ClassVType)
|
||||
errors.semError(node.name, "Cannot shadow class name: %s", node.name.name);
|
||||
else
|
||||
errors.semError(
|
||||
node.name, "Duplicate declaration of identifier in same scope: %s", node.name.name);
|
||||
|
||||
}
|
||||
else if(fTy instanceof ClassVType)
|
||||
errors.semError(node.name, "Cannot shadow class name: %s", node.name.name);
|
||||
else
|
||||
else if(firstPass || sym.declares(node.name.name))
|
||||
errors.semError(
|
||||
node.name, "Duplicate declaration of identifier in same scope: %s", node.name.name);
|
||||
if(!firstPass){
|
||||
|
||||
}
|
||||
return current_func;
|
||||
} else {
|
||||
postCheck = false;
|
||||
|
||||
}
|
||||
else if(firstPass || sym.declares(node.name.name))
|
||||
errors.semError(
|
||||
node.name, "Duplicate declaration of identifier in same scope: %s", node.name.name);
|
||||
|
||||
if(!firstPass){
|
||||
ValueType returnType = ValueType.annotationToValueType(node.returnType);
|
||||
if(returnType!=null && !returnType.isSpecialType() && !returnType.isListType() && !(globals.get(returnType.className()) instanceof ClassVType))
|
||||
errors.semError(
|
||||
@@ -187,13 +196,14 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
decl.dispatch(this);
|
||||
else
|
||||
decl.dispatch(typeChecker);
|
||||
for(Declaration decl : otherDefs)
|
||||
decl.dispatch(this);
|
||||
for(Declaration decl : otherDefs)
|
||||
if(decl instanceof FuncDef)
|
||||
decl.dispatch(typeChecker);
|
||||
else
|
||||
decl.dispatch(this);
|
||||
return null;
|
||||
|
||||
}
|
||||
return current_func;
|
||||
}
|
||||
|
||||
public boolean compare_functions(FuncType fun1, FuncType fun2)
|
||||
@@ -212,7 +222,10 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
public Type analyze(ClassDef node)
|
||||
{
|
||||
ClassVType cvt=new ClassVType(node.name.name);
|
||||
SymbolTable<Type> current_scope=new SymbolTable<>(sym);
|
||||
if(!putSymChecked(node.name, node.name.name, cvt))
|
||||
classDefError = node.name.name;
|
||||
|
||||
SymbolTable<Type> current_scope=createScope(sym);
|
||||
sym=current_scope;
|
||||
current_class=cvt;
|
||||
Type super_class = sym.get(node.superClass.name);
|
||||
@@ -262,9 +275,10 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
errors.semError(id, "Method overridden with different type signature: __init__");
|
||||
else
|
||||
sym.put(name, current_func);
|
||||
if(params.size() < 1 || (params.get(0) instanceof ClassValueType==false) || ((ClassValueType)params.get(0)).className().equals(current_class.className)==false)
|
||||
if(params.size() < 1 || !(params.get(0) instanceof ClassValueType) || !((ClassValueType)params.get(0)).className().equals(current_class.className))
|
||||
errors.semError(
|
||||
id, "First parameter of the following method must be of the enclosing class: %s", name);
|
||||
|
||||
if(curr_syms.contains(name)){
|
||||
errors.semError(id, "Duplicate declaration of identifier in same scope: %s", name);
|
||||
}
|
||||
@@ -303,7 +317,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
sym = sym.getParent();
|
||||
current_class.scope = current_scope;
|
||||
current_class=null;
|
||||
putSymChecked(node.name, node.name.name, cvt);
|
||||
classDefError = null;
|
||||
return cvt;
|
||||
}
|
||||
boolean isVariableType(Type ty)
|
||||
@@ -343,7 +357,8 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
Type varVType = sym.get(className);
|
||||
if(!(className != null && varVType instanceof ClassVType))
|
||||
errors.semError(node.var.type, "Invalid type annotation; there is no class named: %s", (className!=null?className:""));
|
||||
else if(val_type!=Type.NONE_TYPE && !StudentAnalysis.subClassOf(varVType,val_type, sym))
|
||||
else if((!val_type.equals(Type.NONE_TYPE) && !StudentAnalysis.subClassOf(varVType,val_type, sym))||
|
||||
val_type.equals(Type.NONE_TYPE) && var_type.isSpecialType())
|
||||
errors.semError(node, "Expected type `%s`; got type `%s`", varVType, val_type);
|
||||
}
|
||||
return var_type;
|
||||
@@ -357,4 +372,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
||||
{
|
||||
this.current_class = current_class;
|
||||
}
|
||||
public void setPostCheck(){
|
||||
postCheck = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class StudentAnalysis {
|
||||
TypeChecker typeChecker = new TypeChecker(globalSym, program.errors);
|
||||
program.dispatch(typeChecker);
|
||||
}
|
||||
//System.out.println(program);
|
||||
// System.out.println(program);
|
||||
return program;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import static chocopy.common.analysis.types.Type.INT_TYPE;
|
||||
import static chocopy.common.analysis.types.Type.OBJECT_TYPE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.swing.text.StyledEditorKit.BoldAction;
|
||||
|
||||
@@ -33,7 +34,9 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
private boolean returned = false, member = false;
|
||||
/** Collector for errors. */
|
||||
private final Errors errors;
|
||||
private Boolean assign = false;
|
||||
private boolean assign = false;
|
||||
private boolean declAnalyzed = false;
|
||||
private final HashMap<FuncDef, SymbolTable<Type>> funcScopes;
|
||||
/**
|
||||
* Creates a type checker using GLOBALSYMBOLS for the initial global symbol table and ERRORS0 to
|
||||
* receive semantic errors.
|
||||
@@ -44,14 +47,23 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
errors = errors0;
|
||||
currReturnType = null;
|
||||
declAnalyzer = new DeclarationAnalyzer(errors0, this, globalSymbols);
|
||||
funcScopes = new HashMap<>();
|
||||
}
|
||||
/**
|
||||
* Inserts an error message in NODE if there isn't one already. The message is constructed with
|
||||
* MESSAGE and ARGS as for String.format.
|
||||
*/
|
||||
boolean isVariableType(Type ty){
|
||||
private boolean isVariableType(Type ty){
|
||||
return ty.isSpecialType() || ty.equals(Type.OBJECT_TYPE);
|
||||
}
|
||||
public boolean pushDeclAnalyzed() {
|
||||
boolean orig = declAnalyzed;
|
||||
declAnalyzed = true;
|
||||
return orig;
|
||||
}
|
||||
public void popDeclAnalyzed(boolean orig) {
|
||||
declAnalyzed = orig;
|
||||
}
|
||||
private Type declAnalyze(Node node){
|
||||
//if(currentScope != sym)
|
||||
declAnalyzer.setScope(currentScope);
|
||||
@@ -129,20 +141,37 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
public Type analyze(BooleanLiteral node) {
|
||||
return node.setInferredType(Type.BOOL_TYPE);
|
||||
}
|
||||
public void dispatchFuncDef(FuncDef node, SymbolTable<Type> scope, boolean declAnalyzed){
|
||||
boolean prevDeclAnalyzed = this.declAnalyzed;
|
||||
this.declAnalyzed = declAnalyzed;
|
||||
SymbolTable<Type> origScope = currentScope;
|
||||
currentScope = scope;
|
||||
node.dispatch(this);
|
||||
currentScope = origScope;
|
||||
this.declAnalyzed = prevDeclAnalyzed;
|
||||
}
|
||||
@Override
|
||||
public Type analyze(FuncDef node) {
|
||||
returned = false;
|
||||
Type prevReturnType = this.currReturnType;
|
||||
currentScope = new SymbolTable<>(currentScope);
|
||||
this.currReturnType = ValueType.annotationToValueType(node.returnType);
|
||||
declAnalyze(node);
|
||||
for(Stmt st : node.statements)
|
||||
st.dispatch(this);
|
||||
SymbolTable<Type> origScope = currentScope;
|
||||
if(funcScopes.get(node) != null)
|
||||
System.out.println("error");
|
||||
{
|
||||
currentScope = declAnalyzer.createScope(currentScope);
|
||||
funcScopes.put(node, currentScope);
|
||||
declAnalyzer.setPostCheck();
|
||||
declAnalyze(node);
|
||||
//currentScope = funcScopes.get(node);
|
||||
returned = false;
|
||||
Type prevReturnType = this.currReturnType;
|
||||
this.currReturnType = ValueType.annotationToValueType(node.returnType);
|
||||
for(Stmt st : node.statements)
|
||||
st.dispatch(this);
|
||||
|
||||
if(currReturnType != null && currReturnType.isSpecialType() && !returned)
|
||||
err(node.name, "All paths in this function/method must have a return statement: %s", node.name.name);
|
||||
this.currReturnType = prevReturnType;
|
||||
currentScope = currentScope.getParent();
|
||||
if(currReturnType != null && currReturnType.isSpecialType() && !returned)
|
||||
err(node.name, "All paths in this function/method must have a return statement: %s", node.name.name);
|
||||
this.currReturnType = prevReturnType;
|
||||
}
|
||||
currentScope = origScope;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -274,7 +303,7 @@ public class TypeChecker extends AbstractNodeAnalyzer<Type> {
|
||||
ty = currentScope.get(((ClassValueType) ty).className());
|
||||
if(ty instanceof ClassVType){
|
||||
ClassVType classTy = (ClassVType) ty;
|
||||
Type type = classTy.scope.get(node.member.name);
|
||||
Type type = classTy.scope == null? null:classTy.scope.get(node.member.name);
|
||||
if(type != null)
|
||||
return node.setInferredType(type);
|
||||
else
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
{
|
||||
"kind" : "Program",
|
||||
"location" : [ 1, 1, 13, 8 ],
|
||||
"declarations" : [ {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 1, 1, 1, 9 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 1, 1, 1, 5 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 1, 1, 1, 1 ],
|
||||
"name" : "x"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 1, 3, 1, 5 ],
|
||||
"className" : "int"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 1, 9, 1, 9 ],
|
||||
"value" : 1
|
||||
}
|
||||
}, {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 2, 1, 2, 9 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 2, 1, 2, 5 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 2, 1, 2, 1 ],
|
||||
"name" : "x"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 2, 3, 2, 5 ],
|
||||
"className" : "int"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 2, 9, 2, 9 ],
|
||||
"value" : 2
|
||||
}
|
||||
}, {
|
||||
"kind" : "FuncDef",
|
||||
"location" : [ 6, 1, 13, 0 ],
|
||||
"name" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 6, 5, 6, 9 ],
|
||||
"name" : "fun_1"
|
||||
},
|
||||
"params" : [ ],
|
||||
"returnType" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 6, 16, 6, 19 ],
|
||||
"className" : "bool"
|
||||
},
|
||||
"declarations" : [ ],
|
||||
"statements" : [ {
|
||||
"kind" : "IfStmt",
|
||||
"location" : [ 7, 5, 13, 0 ],
|
||||
"condition" : {
|
||||
"kind" : "BooleanLiteral",
|
||||
"location" : [ 7, 8, 7, 11 ],
|
||||
"value" : true
|
||||
},
|
||||
"thenBody" : [ {
|
||||
"kind" : "IfStmt",
|
||||
"location" : [ 8, 9, 13, 0 ],
|
||||
"condition" : {
|
||||
"kind" : "BooleanLiteral",
|
||||
"location" : [ 8, 12, 8, 15 ],
|
||||
"value" : true
|
||||
},
|
||||
"thenBody" : [ {
|
||||
"kind" : "ReturnStmt",
|
||||
"location" : [ 9, 13, 9, 23 ],
|
||||
"value" : {
|
||||
"kind" : "BooleanLiteral",
|
||||
"location" : [ 9, 20, 9, 23 ],
|
||||
"value" : true
|
||||
}
|
||||
} ],
|
||||
"elseBody" : [ ]
|
||||
} ],
|
||||
"elseBody" : [ ]
|
||||
} ]
|
||||
} ],
|
||||
"statements" : [ {
|
||||
"kind" : "ExprStmt",
|
||||
"location" : [ 13, 1, 13, 7 ],
|
||||
"expr" : {
|
||||
"kind" : "CallExpr",
|
||||
"location" : [ 13, 1, 13, 7 ],
|
||||
"function" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 13, 1, 13, 5 ],
|
||||
"name" : "fun_1"
|
||||
},
|
||||
"args" : [ ]
|
||||
}
|
||||
} ],
|
||||
"errors" : {
|
||||
"errors" : [ {
|
||||
"kind" : "CompilerError",
|
||||
"location" : [ 6, 1, 6, 3 ],
|
||||
"message" : "Parse error near token DEF: def",
|
||||
"syntax" : true
|
||||
} ],
|
||||
"kind" : "Errors",
|
||||
"location" : [ 0, 0, 0, 0 ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"kind" : "Program",
|
||||
"location" : [ 1, 1, 5, 20 ],
|
||||
"declarations" : [ {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 1, 1, 1, 12 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 1, 1, 1, 5 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 1, 1, 1, 1 ],
|
||||
"name" : "x"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 1, 3, 1, 5 ],
|
||||
"className" : "int"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "BooleanLiteral",
|
||||
"location" : [ 1, 9, 1, 12 ],
|
||||
"value" : true
|
||||
}
|
||||
} ],
|
||||
"statements" : [ {
|
||||
"kind" : "ExprStmt",
|
||||
"location" : [ 2, 1, 2, 7 ],
|
||||
"expr" : {
|
||||
"kind" : "BinaryExpr",
|
||||
"location" : [ 2, 1, 2, 7 ],
|
||||
"left" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 2, 1, 2, 1 ],
|
||||
"name" : "x"
|
||||
},
|
||||
"operator" : "+",
|
||||
"right" : {
|
||||
"kind" : "ListExpr",
|
||||
"location" : [ 2, 5, 2, 7 ],
|
||||
"elements" : [ {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 2, 6, 2, 6 ],
|
||||
"value" : 1
|
||||
} ]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"kind" : "AssignStmt",
|
||||
"location" : [ 4, 3, 4, 14 ],
|
||||
"targets" : [ {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 4, 3, 4, 6 ],
|
||||
"name" : "bool"
|
||||
} ],
|
||||
"value" : {
|
||||
"kind" : "BooleanLiteral",
|
||||
"location" : [ 4, 10, 4, 14 ],
|
||||
"value" : false
|
||||
}
|
||||
}, {
|
||||
"kind" : "AssignStmt",
|
||||
"location" : [ 5, 1, 5, 19 ],
|
||||
"targets" : [ {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 5, 1, 5, 1 ],
|
||||
"name" : "x"
|
||||
}, {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 5, 5, 5, 5 ],
|
||||
"name" : "y"
|
||||
}, {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 5, 9, 5, 9 ],
|
||||
"name" : "z"
|
||||
} ],
|
||||
"value" : {
|
||||
"kind" : "StringLiteral",
|
||||
"location" : [ 5, 13, 5, 19 ],
|
||||
"value" : "Error"
|
||||
}
|
||||
} ],
|
||||
"errors" : {
|
||||
"errors" : [ {
|
||||
"kind" : "CompilerError",
|
||||
"location" : [ 4, 2, 4, 2 ],
|
||||
"message" : "Parse error near token COLON: :",
|
||||
"syntax" : true
|
||||
} ],
|
||||
"kind" : "Errors",
|
||||
"location" : [ 0, 0, 0, 0 ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
x : int = 0
|
||||
y : int = 5
|
||||
z : Foo = None
|
||||
class Foo(object):
|
||||
x : int = 3
|
||||
def foo(x : int) -> int:
|
||||
y : str = "test"
|
||||
def foo2() -> str:
|
||||
nonlocal y
|
||||
return y
|
||||
nonlocal x # The reference compiler prioritized for duplicate declaration
|
||||
# error and stopped compilation.
|
||||
# But our implementation prioritized this for an invalid nonlocal
|
||||
# and recovered the complation process.
|
||||
return x
|
||||
x = 1 and 2
|
||||
foo(y, 5)
|
||||
@@ -0,0 +1,260 @@
|
||||
{
|
||||
"kind" : "Program",
|
||||
"location" : [ 1, 1, 17, 10 ],
|
||||
"declarations" : [ {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 1, 1, 1, 11 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 1, 1, 1, 7 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 1, 1, 1, 1 ],
|
||||
"name" : "x"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 1, 5, 1, 7 ],
|
||||
"className" : "int"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 1, 11, 1, 11 ],
|
||||
"value" : 0
|
||||
}
|
||||
}, {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 2, 1, 2, 11 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 2, 1, 2, 7 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 2, 1, 2, 1 ],
|
||||
"name" : "y"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 2, 5, 2, 7 ],
|
||||
"className" : "int"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 2, 11, 2, 11 ],
|
||||
"value" : 5
|
||||
}
|
||||
}, {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 3, 1, 3, 14 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 3, 1, 3, 7 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 3, 1, 3, 1 ],
|
||||
"name" : "z"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 3, 5, 3, 7 ],
|
||||
"className" : "Foo"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "NoneLiteral",
|
||||
"location" : [ 3, 11, 3, 14 ]
|
||||
}
|
||||
}, {
|
||||
"kind" : "ClassDef",
|
||||
"location" : [ 4, 1, 5, 16 ],
|
||||
"name" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 4, 7, 4, 9 ],
|
||||
"name" : "Foo"
|
||||
},
|
||||
"superClass" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 4, 11, 4, 16 ],
|
||||
"name" : "object"
|
||||
},
|
||||
"declarations" : [ {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 5, 5, 5, 15 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 5, 5, 5, 11 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 5, 5, 5, 5 ],
|
||||
"name" : "x"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 5, 9, 5, 11 ],
|
||||
"className" : "int"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 5, 15, 5, 15 ],
|
||||
"value" : 3
|
||||
}
|
||||
} ]
|
||||
}, {
|
||||
"kind" : "FuncDef",
|
||||
"location" : [ 6, 1, 15, 13 ],
|
||||
"name" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 6, 5, 6, 7 ],
|
||||
"name" : "foo"
|
||||
},
|
||||
"params" : [ {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 6, 9, 6, 15 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 6, 9, 6, 9 ],
|
||||
"name" : "x"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 6, 13, 6, 15 ],
|
||||
"className" : "int"
|
||||
}
|
||||
} ],
|
||||
"returnType" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 6, 21, 6, 23 ],
|
||||
"className" : "int"
|
||||
},
|
||||
"declarations" : [ {
|
||||
"kind" : "VarDef",
|
||||
"location" : [ 7, 5, 7, 20 ],
|
||||
"var" : {
|
||||
"kind" : "TypedVar",
|
||||
"location" : [ 7, 5, 7, 11 ],
|
||||
"identifier" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 7, 5, 7, 5 ],
|
||||
"name" : "y"
|
||||
},
|
||||
"type" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 7, 9, 7, 11 ],
|
||||
"className" : "str"
|
||||
}
|
||||
},
|
||||
"value" : {
|
||||
"kind" : "StringLiteral",
|
||||
"location" : [ 7, 15, 7, 20 ],
|
||||
"value" : "test"
|
||||
}
|
||||
}, {
|
||||
"kind" : "FuncDef",
|
||||
"location" : [ 8, 5, 10, 17 ],
|
||||
"name" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 8, 9, 8, 12 ],
|
||||
"name" : "foo2"
|
||||
},
|
||||
"params" : [ ],
|
||||
"returnType" : {
|
||||
"kind" : "ClassType",
|
||||
"location" : [ 8, 19, 8, 21 ],
|
||||
"className" : "str"
|
||||
},
|
||||
"declarations" : [ {
|
||||
"kind" : "NonLocalDecl",
|
||||
"location" : [ 9, 9, 9, 18 ],
|
||||
"variable" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 9, 18, 9, 18 ],
|
||||
"name" : "y"
|
||||
}
|
||||
} ],
|
||||
"statements" : [ {
|
||||
"kind" : "ReturnStmt",
|
||||
"location" : [ 10, 9, 10, 16 ],
|
||||
"value" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 10, 16, 10, 16 ],
|
||||
"name" : "y"
|
||||
}
|
||||
} ]
|
||||
}, {
|
||||
"kind" : "NonLocalDecl",
|
||||
"location" : [ 11, 5, 11, 14 ],
|
||||
"variable" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 11, 14, 11, 14 ],
|
||||
"errorMsg" : "Duplicate declaration of identifier in same scope: x",
|
||||
"name" : "x"
|
||||
}
|
||||
} ],
|
||||
"statements" : [ {
|
||||
"kind" : "ReturnStmt",
|
||||
"location" : [ 15, 5, 15, 12 ],
|
||||
"value" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 15, 12, 15, 12 ],
|
||||
"name" : "x"
|
||||
}
|
||||
} ]
|
||||
} ],
|
||||
"statements" : [ {
|
||||
"kind" : "AssignStmt",
|
||||
"location" : [ 16, 1, 16, 11 ],
|
||||
"targets" : [ {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 16, 1, 16, 1 ],
|
||||
"name" : "x"
|
||||
} ],
|
||||
"value" : {
|
||||
"kind" : "BinaryExpr",
|
||||
"location" : [ 16, 5, 16, 11 ],
|
||||
"left" : {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 16, 5, 16, 5 ],
|
||||
"value" : 1
|
||||
},
|
||||
"operator" : "and",
|
||||
"right" : {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 16, 11, 16, 11 ],
|
||||
"value" : 2
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"kind" : "ExprStmt",
|
||||
"location" : [ 17, 1, 17, 9 ],
|
||||
"expr" : {
|
||||
"kind" : "CallExpr",
|
||||
"location" : [ 17, 1, 17, 9 ],
|
||||
"function" : {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 17, 1, 17, 3 ],
|
||||
"name" : "foo"
|
||||
},
|
||||
"args" : [ {
|
||||
"kind" : "Identifier",
|
||||
"location" : [ 17, 5, 17, 5 ],
|
||||
"name" : "y"
|
||||
}, {
|
||||
"kind" : "IntegerLiteral",
|
||||
"location" : [ 17, 8, 17, 8 ],
|
||||
"value" : 5
|
||||
} ]
|
||||
}
|
||||
} ],
|
||||
"errors" : {
|
||||
"errors" : [ {
|
||||
"kind" : "CompilerError",
|
||||
"location" : [ 11, 14, 11, 14 ],
|
||||
"message" : "Duplicate declaration of identifier in same scope: x"
|
||||
} ],
|
||||
"kind" : "Errors",
|
||||
"location" : [ 0, 0, 0, 0 ]
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user