diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc index ea35002c..5c82bde1 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDataDeclaration.rsc @@ -24,6 +24,8 @@ void collect (current: (Declaration) ` data < void collect (current: (Declaration) ` data = <{Variant "|"}+ variants> ;`, Collector c) = dataDeclaration(tags, current, [v | v <- variants], c); +int dataCounter = 0; + void dataDeclaration(Tags tags, Declaration current, list[Variant] variants, Collector c){ userType = current.user; adtName = prettyPrintName(userType.name); @@ -41,7 +43,8 @@ void dataDeclaration(Tags tags, Declaration current, list[Variant] variants, Col dt = isEmpty(typeParameters) ? defType(aadt(adtName, [], dataSyntax())) : defType(typeParameters, AType(Solver s) { return aadt(adtName, [ s.getType(tp)[closed=true] | tp <- typeParameters], dataSyntax()); }); - dt.md5 = md5Hash(""); + dt.md5 = md5Hash(""); + dataCounter += 1; if(!isEmpty(commonKeywordParameterList)) dt.commonKeywordFields = commonKeywordParameterList; c.define(adtName, dataId(), current, dt); @@ -64,42 +67,45 @@ void dataDeclaration(Tags tags, Declaration current, list[Variant] variants, Col AType(Solver) makeFieldType(str fieldName, Tree fieldType) = AType(Solver s) { return s.getType(fieldType)[alabel=fieldName]; }; +int variantCounter = 0; + void collect(current:(Variant) ` ( <{TypeArg ","}* arguments> )`, Collector c){ - formals = getFormals(current); - kwFormals = getKwFormals(current); - declaredFieldNames = {}; - - // Define all fields in the outer scope of the data declaration in order to be easily found there. - - for(ta <- formals){ - if(ta is named){ - fieldName = prettyPrintName(ta.name); - if(fieldName in declaredFieldNames) c.report(error(ta, "Double declaration of field `%v`", fieldName)); + if( := c.top(currentAdt) + && str currentModuleName := c.top(key_current_module) + && str adtName := "" + ){ + formals = getFormals(current); + kwFormals = getKwFormals(current); + + declaredFieldNames = {}; + + // Define all fields in the outer scope of the data declaration in order to be easily found there. + + for(ta <- formals){ + if(ta is named){ + fieldName = prettyPrintName(ta.name); + if(fieldName in declaredFieldNames) c.report(error(ta, "Double declaration of field `%v`", fieldName)); + declaredFieldNames += fieldName; + fieldType = ta.\type; + dt = defType([fieldType], makeFieldType(fieldName, fieldType)); + dt.md5 = md5Hash(""); + c.define(fieldName, fieldId(), ta.name, dt); + } + } + + for(KeywordFormal kwf <- kwFormals){ + fieldName = prettyPrintName(kwf.name); + if(fieldName in declaredFieldNames) c.report(error(kwf, "Double declaration of field `%v`", fieldName)); declaredFieldNames += fieldName; - fieldType = ta.\type; - dt = defType([fieldType], makeFieldType(fieldName, fieldType)); - dt.md5 = md5Hash(""); - c.define(fieldName, fieldId(), ta.name, dt); + kwfType = kwf.\type; + dt = defType([kwfType], makeFieldType(fieldName, kwfType)); + dt.md5 = md5Hash(""); + c.define(fieldName, keywordFieldId(), kwf.name, dt); + c.requireSubType(kwf.expression, kwfType, error(kwf, "Default expression of type %t expected, found %t", kwfType, kwf.expression)); } - } - - for(KeywordFormal kwf <- kwFormals){ - fieldName = prettyPrintName(kwf.name); - if(fieldName in declaredFieldNames) c.report(error(kwf, "Double declaration of field `%v`", fieldName)); - declaredFieldNames += fieldName; - kwfType = kwf.\type; - dt = defType([kwfType], makeFieldType(fieldName, kwfType)); - dt.md5 = md5Hash(""); - c.define(fieldName, keywordFieldId(), kwf.name, dt); - c.requireSubType(kwf.expression, kwfType, error(kwf, "Default expression of type %t expected, found %t", kwfType, kwf.expression)); - - } - - scope = c.getScope(); - if( := c.top(currentAdt) && - str currentModuleName := c.top(key_current_module)){ + scope = c.getScope(); c.enterScope(current); c.defineInScope(adtParentScope, prettyPrintName(name), constructorId(), name, defType(adt + formals + kwFormals + commonKwFormals, AType(Solver s){ @@ -107,7 +113,8 @@ void collect(current:(Variant) ` ( <{TypeArg ","}* arguments> (")]); + variantCounter += 1; c.fact(current, name); beginUseTypeParameters(c, closed=false); // The standard rules would declare arguments and kwFormals as variableId(); diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc index a939ab73..bfa88834 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc @@ -37,6 +37,9 @@ import util::Reflective; void collect(Module current: (Module) `
`, Collector c){ + dataCounter = 0; + variantCounter = 0; + mloc = getLoc(current); mname = prettyPrintName(header.name); checkModuleName(getLoc(current), header.name, c); @@ -220,6 +223,8 @@ void collect(current: (FunctionDeclaration) ``, Collec c.report(info(current, "Ignoring function declaration for ``")); return; } + c.push(currentFunction, ppfname); + md5Contrib = md5Contrib4signature(signature); = getExpected(decl.tags); if(expected){ @@ -260,6 +265,7 @@ void collect(current: (FunctionDeclaration) ``, Collec if("default" in modifiers){ ft.isDefault = true; + md5Contrib = "default" + md5Contrib; } if("test" in modifiers){ @@ -287,11 +293,7 @@ void collect(current: (FunctionDeclaration) ``, Collec if(!isEmpty(tagsMap)) dt.tags = tagsMap; alwaysSucceeds = all(pat <- getFormals(signature.parameters), pat is typedVariable) && !(decl is conditional) && !(decl is \default && /(Statement) `fail ;` := decl.body); if(!alwaysSucceeds) dt.canFail = true; - dt.md5 = md5Hash(""); - if(!isEmpty(modifiers)) dt.modifiers = modifiers; - - c.defineInScope(parentScope, prettyPrintName(fname), functionId(), current, dt); beginUseBoundedTypeParameters(tpbounds, c); @@ -319,6 +321,9 @@ void collect(current: (FunctionDeclaration) ``, Collec if(!myReturnsViaAllPath && "" != "void"){ c.report(error(decl.signature, "Missing return statement")); } + if(!alwaysSucceeds){ + md5Contrib += ""; + } } if(decl is expression || decl is conditional){ @@ -333,6 +338,8 @@ void collect(current: (FunctionDeclaration) ``, Collec } if(decl is conditional){ conditions = [cond | cond <- decl.conditions]; + + md5Contrib += ""; storeAllowUseBeforeDef(decl, decl.expression, c); c.require("when conditions", decl.conditions, conditions, void (Solver s){ @@ -351,13 +358,23 @@ void collect(current: (FunctionDeclaration) ``, Collec endUseBoundedTypeParameters(c); + surroundingFuns = c.getStack(currentFunction); + + dt.md5 = md5Hash(size(surroundingFuns) == 1 ? md5Contrib : ""); + c.defineInScope(parentScope, prettyPrintName(fname), functionId(), current, dt); + c.leaveScope(decl); + c.pop(currentFunction); } void collect(current: (FunctionBody) `{ }`, Collector c){ collect(statements, c); } +str md5Contrib4signature(Signature signature){ + return ""; +} + tuple[set[str], rel[str,Type]] collectSignature(Signature signature, Collector c){ returnType = signature.\type; parameters = signature.parameters; diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc index 43a76b64..447cd18e 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc @@ -987,9 +987,14 @@ void collect(current:(Expression)` [ <{Expression ","}+ i // that here by treating it as avalue(), which is comparable to all other types and will // thus work when calculating the type below. - for(e <- indexList, (Expression)`_` := e){ - c.fact(e, avalue()); + for(e <- indexList){ + if((Expression)`_` := e){ + c.fact(e, avalue()); + } else { + collect(e, c); + } } + collect(expression, c); c.calculate("subscription", current, expression + indexList, AType(Solver s){ @@ -997,7 +1002,6 @@ void collect(current:(Expression)` [ <{Expression ","}+ i for(e <- indexList) checkNonVoid(e, s, "Subscript"); return computeSubscriptionType(current, s.getType(expression), [s.getType(e) | e <- indexList], indexList, s); }); - collect(expression, indices, c); } // ---- slice diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectSyntaxDeclaration.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectSyntaxDeclaration.rsc index 9e7c15e9..e255d20a 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectSyntaxDeclaration.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectSyntaxDeclaration.rsc @@ -35,6 +35,7 @@ void collect (current: (SyntaxDefinition) ` syntax = < } int nalternatives = 0; +int syndefCounter = 0; void declareSyntax(SyntaxDefinition current, SyntaxRole syntaxRole, IdRole idRole, Collector c, Vis vis=publicVis()){ //println("declareSyntax: "); @@ -52,7 +53,8 @@ void declareSyntax(SyntaxDefinition current, SyntaxRole syntaxRole, IdRole idRol dt = defType(nonterminalType); dt.vis = vis; - dt.md5 = md5Hash(""); + dt.md5 = md5Hash(""); + syndefCounter += 1; // Define the syntax symbol itself and all labelled alternatives as constructors c.define(adtName, idRole, current, dt); diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/ScopeInfo.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/ScopeInfo.rsc index a24fe0b4..640841b1 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/ScopeInfo.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/ScopeInfo.rsc @@ -12,8 +12,9 @@ import lang::rascal::\syntax::Rascal; public /*const*/ str patternContainer = "patternContainer"; public /*const*/ str patternNames = "patternNames"; -public /*const*/ str currentAdt = "currentAdt"; // used to mark data declarations -public /*const*/ str inAlternative = "inAlternative"; // used to mark top-level alternative in syntax declaration +public /*const*/ str currentAdt = "currentAdt"; // used to mark data declarations +public /*const*/ str currentFunction = "currentFunction"; // used to mark function declarations +public /*const*/ str inAlternative = "inAlternative"; // used to mark top-level alternative in syntax declaration public /*const*/ str typeContainer = "typeContainer"; public /*const*/ str inConcreteLiteral = "concreteLiteral"; // used to mark that we are inside a concrete literal diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst4.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst4.rsc index 214f17f2..c76a01d0 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst4.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst4.rsc @@ -1,24 +1,14 @@ module lang::rascalcore::compile::Examples::Tst4 -//alias T = tuple[int, str]; -void main() { - //set[tuple[int, str]] r = {}; - - // Error - // `Initialization of `ts1` should be subtype of `rel[int, str]`, found `rel[value, value]`` - //set[tuple[int, str]] ts1 = {t | t: <- r}; - - set[str] a = {}; - set[str] b = { x| t: x <- a}; - - //// No errors - //set[T] ts2 = {t | t <- r}; - //set[T] ts3 = {t | T t:<_, _> <- r}; - //set[T] ts4 = { | <- r}; - //set[T] ts5 = {t | t: <- r}; +int outer1(){ + int f(int n) = n; + return f(3); } -//value main() = _f(3); +int outer2(){ + int f(int n) = n; + return f(4); +} //data Tree; //anno set[int] Tree@messages;