Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ import lang::rascalcore::check::ATypeUtils;
public AGrammar layouts(AGrammar g, AType l, set[AType] others) {

res = top-down-break visit (g) {
case p: prod(\start(aadt(_, list[AType] _, contextFreeSyntax())), [x]) => p[atypes=[l, x, l]]

case p: prod(aadt(_, list[AType] _, contextFreeSyntax()), list[AType] lhs) => p[atypes=intermix(lhs, l, others)]
case p: prod(aadt(_, list[AType] _, contextFreeSyntax()), list[AType] lhs) => p[atypes=intermix(lhs, l, others)]
case p: prod(\start(AType topSymbol, SyntaxRole _), [topSymbol]) => p[atypes=[l, topSymbol, l]]
}
//iprintln(res);

return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public AType sym2AType(Sym sym) {
case lang::rascal::\syntax::Rascal::nonterminal(Nonterminal n) :
return AType::aadt("<n>", [], dataSyntax());
case \start(Nonterminal n) :
return \start(AType::aadt("<n>", [], dataSyntax()));
return \start(AType::aadt("<n>", [], contextFreeSyntax()), contextFreeSyntax());
case literal(StringConstant l):
return AType::alit(unescapeLiteral(l));
case caseInsensitiveLiteral(CaseInsensitiveStringConstant l):
Expand Down Expand Up @@ -124,7 +124,7 @@ public AType defsym2AType(Sym sym, SyntaxRole sr) {
return AType::aadt("<n>",separgs2ATypes(syms), sr);

case \start(Nonterminal n) :
return \start(AType::aadt("<n>", [], sr));
return \start(AType::aadt("<n>", [], sr), contextFreeSyntax());

default: {
iprintln(sym);
Expand Down
17 changes: 5 additions & 12 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/ADTandGrammar.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -192,24 +192,16 @@ tuple[bool, TModel, ModuleStatus] addGrammar(MODID moduleId, set[MODID] imports,

definedProductions += {<p.def, p> | loc k <- prodLocs2, aprod(p) := facts[k] };

allStarts += { t | loc k <- facts, \start(t) := facts[k] };
allStarts += { t | loc k <- facts, \start(t, _) := facts[k] };
}

allStarts = uncloseTypeParams(allStarts);
rel[AType,AProduction] allProductions = uncloseTypeParams(definedProductions);

allProductions = visit(allProductions){
case p:prod(\start(a:aadt(_,_,_)),defs) => p[def=a]
case \start(a:aadt(_,_,_)) => a
}

set[AType] allLayouts = {};
set[AType] allManualLayouts = {};
map[AType,AProduction] syntaxDefinitions = ();

for(AType adtType <- domain(allProductions)){
if(\start(adtType2) := adtType){
adtType = adtType2;
}
productions = allProductions[adtType];
syntaxDefinitions[adtType] = achoice(adtType, productions);
//println("syntaxDefinitions, for <adtType> add <achoice(adtType, productions)>");
Expand Down Expand Up @@ -252,7 +244,7 @@ tuple[bool, TModel, ModuleStatus] addGrammar(MODID moduleId, set[MODID] imports,
// Add start symbols

for(AType adtType <- allStarts){
syntaxDefinitions[\start(adtType)] = achoice(\start(adtType), { prod(\start(adtType), [definedLayout, adtType[alabel="top"], definedLayout]) });
syntaxDefinitions[\start(adtType, contextFreeSyntax())] = achoice(\start(adtType, contextFreeSyntax()), { prod(\start(adtType, contextFreeSyntax()), [definedLayout, adtType[alabel="top"], definedLayout]) });
}

// Add auxiliary rules for instantiated syntactic ADTs outside the grammar rules
Expand Down Expand Up @@ -367,7 +359,8 @@ TModel checkKeywords(rel[AType, AProduction] allProductions, TModel tm){
}
}
}
for(AType adtType <- domain(allProductions), ((\start(t) := adtType) ? t.syntaxRole : adtType.syntaxRole) == keywordSyntax()){

for(AType adtType <- domain(allProductions), adtType.syntaxRole == keywordSyntax()){
for(p:prod(AType _, list[AType] asymbols) <- allProductions[adtType]){
if(size(asymbols) != 1){
tm.messages += [warning(size(asymbols) == 0 ? "One symbol needed in keyword declaration, found none" : "Keyword declaration should consist of one symbol", p.src)];
Expand Down
45 changes: 20 additions & 25 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/AType.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ default bool asubtype(AType l, AType r){
return l is aint || l is areal || l is arat || l is anum;
case aalias(str _, list[AType] _, AType aliased):
return asubtype(l, aliased);
case \start(AType t):
return asubtype(l, t);
case aprod(p):
return asubtype(l, p.def);
case \iter(AType t):
Expand Down Expand Up @@ -192,8 +190,6 @@ bool asubtype(ac:acons(AType a, list[AType] ap, list[Keyword] _), AType b){
return true;
case afunc(AType b, list[AType] bp, list[Keyword] _):
return asubtype(a, b) && comparableList(ap, bp);
case \start(AType t):
return asubtype(ac, t);
case avalue():
return true;
}
Expand All @@ -202,10 +198,8 @@ bool asubtype(ac:acons(AType a, list[AType] ap, list[Keyword] _), AType b){

bool asubtype(ap: aprod(AProduction p), AType b){
switch(b){
case aprod(AProduction q):
case aprod(AProduction q):
return asubtype(p.def, q.def);
case \start(AType t):
return asubtype(ap, t);
case conditional(AType t, _):
return asubtype(ap, t);
case AType t:
Expand All @@ -228,8 +222,6 @@ bool asubtype(adt:aadt(str n, list[AType] l, SyntaxRole sr), AType b){
return asubtypeList(l, r);
case aadt("Tree", _, _):
if(isConcreteSyntaxRole(sr)) return true;
case \start(AType t):
if(isConcreteSyntaxRole(sr)) return asubtype(adt, t);
case avalue():
return true;
case p:aparameter(_, _):
Expand All @@ -238,7 +230,11 @@ bool asubtype(adt:aadt(str n, list[AType] l, SyntaxRole sr), AType b){
fail;
}

bool asubtype(\start(AType a), AType b) = asubtype(a, b);
// start non-terminals behave just like parameterized non-terminals.
// but note that this code is currently unreachable since we can't type `start[&T]`
bool asubtype(\start(AType a, SyntaxRole sr), \start(AType b, sr)) = asubtype(a, b);
bool asubtype(\start(AType a, SyntaxRole _sr), aadt("Tree", [], dataSyntax())) = true;
bool asubtype(\start(AType a, SyntaxRole _sr), anode(_)) = true;

bool asubtype(i:\iter(AType s), AType b){
switch(b){
Expand All @@ -254,8 +250,6 @@ bool asubtype(i:\iter(AType s), AType b){
return asubtype(s,t) && isEmpty(removeLayout(seps));
case \iter-star-seps(AType t, list[AType] seps):
return asubtype(s,t) && isEmpty(removeLayout(seps));
case \start(AType t):
return asubtype(i, t);
case avalue():
return true;
}
Expand All @@ -276,8 +270,6 @@ bool asubtype(i:\iter-seps(AType s, list[AType] seps), AType b){
return asubtype(s,t) && isEmpty(removeLayout(seps));
case \iter-star-seps(AType t, list[AType] seps2):
return asubtype(s,t) && asubtypeList(removeLayout(seps), removeLayout(seps2));
case \start(AType t):
return asubtype(i, t);
case avalue():
return true;
}
Expand All @@ -294,8 +286,6 @@ bool asubtype(i:\iter-star(AType s), AType b){
return asubtype(s, t);
case \iter-star-seps(AType t, list[AType] seps):
return asubtype(s,t) && isEmpty(removeLayout(seps));
case \start(AType t):
return asubtype(i, t);
case avalue():
return true;
}
Expand All @@ -310,8 +300,6 @@ bool asubtype(i:\iter-star-seps(AType s, list[AType] seps), AType b){
return true;
case \iter-star-seps(AType t, list[AType] seps2):
return asubtype(s,t) && asubtypeList(removeLayout(seps), removeLayout(seps2));
case \start(AType t):
return asubtype(i, t);
case avalue():
return true;
}
Expand Down Expand Up @@ -441,8 +429,6 @@ bool asubtype(a:anode(list[AType] l), AType b){
return true;
case anode(list[AType] r):
return l <= r;
case \start(t):
return asubtype(a, t);
case avalue():
return true;
}
Expand All @@ -465,8 +451,6 @@ bool asubtype(l:\achar-class(_), AType r){
}
case aadt("Tree", _, _):
return true; // characters are Tree instances
case \start(t):
return asubtype(l, t);
case avalue():
return true;
}
Expand All @@ -492,7 +476,7 @@ bool isLayoutAType(aparameter(_,AType tvb)) = isLayoutAType(tvb);

bool isLayoutAType(\conditional(AType ss,_)) = isLayoutAType(ss);
bool isLayoutAType(t:aadt(adtName,_,SyntaxRole sr)) = sr == layoutSyntax();
bool isLayoutAType(\start(AType ss)) = isLayoutAType(ss);
bool isLayoutAType(\start(AType _, SyntaxRole _)) = false;
bool isLayoutAType(\iter(AType s)) = isLayoutAType(s);
bool isLayoutAType(\iter-star(AType s)) = isLayoutAType(s);
bool isLayoutAType(\iter-seps(AType s,_)) = isLayoutAType(s);
Expand Down Expand Up @@ -706,8 +690,12 @@ AType alub(l:aadt("Tree", _, _), AType r) = l
AType alub(AType l, r:aadt("Tree", _, _)) = r
when isSyntaxConstructor(r);

AType alub(\start(AType l) , AType r) = alub(l, r);
AType alub(AType l, \start(AType r)) = alub(l, r);
AType alub(\start(AType l, SyntaxRole sr) , \start(l, sr)) = \start(l, sr);
AType alub(\start(AType l, SyntaxRole sr) , \start(!l, sr)) = aadt("Tree", [], dataSyntax());
AType alub(\start(AType l, SyntaxRole _sr) , aadt("Tree", [], dataSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(aadt("Tree", [], dataSyntax()), \start(AType l, SyntaxRole _sr)) = aadt("Tree", [], dataSyntax());
AType alub(anode(list[AType] ps), \start(AType l, SyntaxRole _sr)) = anode(ps);
AType alub(\start(AType l, SyntaxRole _sr), anode(list[AType] ps)) = anode(ps);

AType alub(conditional(AType l, _), AType r) = alub(l, r);
AType alub(AType l, conditional(AType r, _)) = alub(l, r);
Expand Down Expand Up @@ -780,6 +768,13 @@ public AType aglb(aset(AType s), aset(AType t)) = aset(aglb(s, t));
public AType aglb(aset(AType s), arel(AType t)) = aset(aglb(s,atuple(t)));
public AType aglb(arel(AType s), aset(AType t)) = aset(aglb(atuple(s), t));

AType aglb(\start(AType a, SyntaxRole sr), \start(a, sr)) = \start(a, sr);
AType aglb(\start(AType a, SyntaxRole sr), \start(!a, sr)) = \avoid();
AType aglb(aadt("Tree", [], dataSyntax()), \start(AType b, SyntaxRole sr)) = \start(b, sr);
AType aglb(\start(AType a, SyntaxRole sr), aadt("Tree", [], dataSyntax())) = \start(a, sr);
AType aglb(\anode(_), \start(AType b, SyntaxRole sr)) = \start(b, sr);
AType aglb(\start(AType a, SyntaxRole sr), \anode(_)) = \start(a, sr);

AType aglb(arel(atypeList(list[AType] l)), arel(atypeList(list[AType] r))) = size(l) == size(r) ? arel(atypeList(aglbList(l, r))) : aset(avalue());

AType aglb(overloadedAType(overloads), AType t2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,9 @@ data AType
| \iter-star-seps(AType atype, list[AType] separators, bool isLexical = false) // <16>
| \alt(set[AType] alternatives) // <17>
| \seq(list[AType] atypes) // <18>
| \start(AType atype)
| \start(AType atype, SyntaxRole syntaxRole)
;

//public AType \iter-seps(AType atype, []) = \iter(atype);
//public AType \iter-star-seps(AType atype, []) = \iter-star(atype);

// flattening rules
public AType seq([*AType a, seq(list[AType] b), *AType c]) = AType::seq(a + b + c);

Expand Down
42 changes: 12 additions & 30 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/ATypeUtils.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ str prettyAType(cc: \achar-class(list[ACharRange] ranges)) {
return cc == anyCharType ? "![]" : "[<intercalate(" ", [ "<stringChar(r.begin)>-<stringChar(r.end)>" | r <- ranges ])>]";
}

str prettyAType(\start(AType symbol)) = "start[<prettyAType(symbol)>]";
str prettyAType(\start(AType symbol, SyntaxRole _)) = "start[<prettyAType(symbol)>]";

// regular symbols
str prettyAType(\aempty()) = "()";
Expand Down Expand Up @@ -228,8 +228,7 @@ Symbol atype2symbol1(acilit(str string)) = Symbol::\cilit(string);
//Symbol atype2symbol1("lit"(str string)) = Symbol::\lit(string);
//Symbol atype2symbol1("cilit"(str string)) = Symbol::\cilit(string);
Symbol atype2symbol1(\achar-class(list[ACharRange] ranges)) = Symbol::\char-class([range(r.begin, r.end) | r <- ranges ]);

Symbol atype2symbol1(\start(AType symbol)) = Symbol::\start(atype2symbol(symbol));
Symbol atype2symbol1(\start(AType symbol, SyntaxRole _)) = Symbol::\start(atype2symbol(symbol));

// regular symbols
Symbol atype2symbol1(\aempty()) = Symbol::\empty();
Expand Down Expand Up @@ -489,7 +488,7 @@ AType symbol2atype1(Symbol::\seq(list[Symbol] symbols))
= AType::seq(symbol2atype(symbols));

AType symbol2atype1(Symbol::\start(Symbol symbol))
= AType::\start(symbol2atype1(symbol));
= AType::\start(symbol2atype1(symbol), contextFreeSyntax());

list[AType] symbol2atype(list[Symbol] symbols) = [ symbol2atype(s) | s <- symbols ];

Expand Down Expand Up @@ -1064,7 +1063,7 @@ Determine if the given type is an Abstract Data Type (ADT).
bool isADTAType(aparameter(_,AType tvb)) = isADTAType(tvb);
bool isADTAType(aadt(_,_,_)) = true;
bool isADTAType(areified(_)) = true;
bool isADTAType(\start(AType s)) = isADTAType(s);
bool isADTAType(\start(AType s, SyntaxRole _)) = true;
default bool isADTAType(AType _) = false;

@doc{Create a new parameterized ADT type with the given type parameters}
Expand All @@ -1077,7 +1076,7 @@ AType makeADTType(str n) = aadt(n,[], dataSyntax());
str getADTName(AType t) {
if (aadt(n,_,_) := unwrapAType(t)) return n;
if (acons(a,_,_) := unwrapAType(t)) return getADTName(a);
if (\start(ss) := unwrapAType(t)) return getADTName(ss);
if (\start(ss, _) := unwrapAType(t)) return "start[<getADTName(ss)>]";
if (areified(_) := unwrapAType(t)) return "type";
if (aprod(prod(AType def, list[AType] _)) := unwrapAType(t)) return getADTName(def);
throw rascalCheckerInternalError("getADTName, invalid type given: <prettyAType(t)>");
Expand All @@ -1087,7 +1086,7 @@ str getADTName(AType t) {
list[AType] getADTTypeParameters(AType t) {
if (aadt(_,ps,_) := unwrapAType(t)) return ps;
if (acons(a,_,_) := unwrapAType(t)) return getADTTypeParameters(a);
if (\start(ss) := unwrapAType(t)) return getADTTypeParameters(ss);
if (\start(ss, _) := unwrapAType(t)) return [ss];
if (areified(_) := unwrapAType(t)) return [];
if (aprod(prod(AType def, list[AType] _)) := unwrapAType(t)) return getADTTypeParameters(def);
throw rascalCheckerInternalError("getADTTypeParameters given non-ADT type <prettyAType(t)>");
Expand Down Expand Up @@ -1284,7 +1283,7 @@ bool isNonTerminalAType(aparameter(_,AType tvb)) = isNonTerminalAType(tvb);
bool isNonTerminalAType(AType::\conditional(AType ss,_)) = isNonTerminalAType(ss);
bool isNonTerminalAType(t:aadt(adtName,_,SyntaxRole sr)) = isConcreteSyntaxRole(sr);
bool isNonTerminalAType(acons(AType adt, list[AType] _, list[Keyword] _)) = isNonTerminalAType(adt);
bool isNonTerminalAType(AType::\start(AType ss)) = isNonTerminalAType(ss);
bool isNonTerminalAType(AType::\start(AType ss, SyntaxRole _)) = true;
bool isNonTerminalAType(AType::aprod(AProduction p)) = isNonTerminalAType(p.def);

bool isNonTerminalAType(AType::\iter(AType t)) = isNonTerminalAType(t);
Expand All @@ -1301,24 +1300,11 @@ bool isParameterizedNonTerminalType(AType t) = isNonTerminalAType(t) && t has pa

bool isNonParameterizedNonTerminalType(AType t) = isNonTerminalAType(t) && (t has parameters ==> isEmpty(t.parameters));

// start
bool isStartNonTerminalType(aparameter(_,AType tvb)) = isStartNonTerminalType(tvb);
bool isStartNonTerminalType(AType::\start(_)) = true;
default bool isStartNonTerminalType(AType s) = false;

AType getStartNonTerminalType(aparameter(_,AType tvb)) = getStartNonTerminalType(tvb);
AType getStartNonTerminalType(AType::\start(AType s)) = s;
default AType getStartNonTerminalType(AType s) {
throw rascalCheckerInternalError("<prettyAType(s)> is not a start non-terminal type");
}

//TODO labelled

bool isLexicalAType(aparameter(_,AType tvb)) = isLexicalAType(tvb);
bool isLexicalAType(AType::\conditional(AType ss,_)) = isLexicalAType(ss);
bool isLexicalAType(t:aadt(adtName,_,SyntaxRole sr)) = sr == lexicalSyntax() || sr == layoutSyntax();
bool isLexicalAType(acons(AType adt, list[AType] fields, list[Keyword] kwFields)) = isLexicalAType(adt);
bool isLexicalAType(AType::\start(AType ss)) = isLexicalAType(ss);
bool isLexicalAType(AType::\start(AType ss, SyntaxRole sr)) = sr == lexicalSyntax();

bool isLexicalAType(AType:alit(str string)) = true;
bool isLexicalAType(AType:acilit(str string)) = true;
Expand Down Expand Up @@ -1357,7 +1343,7 @@ bool isLayoutAType(aparameter(_,AType tvb)) = isLayoutAType(tvb);

bool isLayoutAType(AType::\conditional(AType ss,_)) = isLayoutAType(ss);
bool isLayoutAType(t:aadt(adtName,_,SyntaxRole sr)) = sr == layoutSyntax();
bool isLayoutAType(AType::\start(AType ss)) = isLayoutAType(ss);
bool isLayoutAType(AType::\start(AType ss, _)) = false;
bool isLayoutAType(AType::\iter(AType s)) = isLayoutAType(s);
bool isLayoutAType(AType::\iter-star(AType s)) = isLayoutAType(s);
bool isLayoutAType(AType::\iter-seps(AType s,_)) = isLayoutAType(s);
Expand Down Expand Up @@ -1466,13 +1452,9 @@ default list[AType] getSeqTypes(AType t){

//AType getSyntaxType(AType t, Solver _) = t;

AType getSyntaxType(AType t, Solver _) = stripStart(removeConditional(t));

AType getSyntaxType(Tree tree, Solver s) = stripStart(removeConditional(s.getType(tree)));

AType stripStart(AType nt) = isStartNonTerminalType(nt) ? getStartNonTerminalType(nt) : nt;
AType getSyntaxType(AType t, Solver _) = removeConditional(t);

AType stripStart(aprod(AProduction production)) = production.def;
AType getSyntaxType(Tree tree, Solver s) = removeConditional(s.getType(tree));

AType removeConditional(cnd:conditional(AType s, set[ACondition] _)) = cnd.alabel? ? s[alabel=cnd.alabel] : s;
default AType removeConditional(AType s) = s;
Expand Down Expand Up @@ -1503,4 +1485,4 @@ public AType filterOverloads(overloadedAType(rel[loc, IdRole, AType] overloads),
if({<_,_,t>} := reduced) return t;
return overloadedAType(reduced);
}
public default AType filterOverloads(AType t, set[IdRole] roles) = t;
public default AType filterOverloads(AType t, set[IdRole] roles) = t;
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ void collect(current: (Expression) `<Expression expression> ( <{Expression ","}*
}

AType texp = s.getType(expression);

if(isStrAType(texp)){
return computeExpressionNodeType(scope, actuals, keywordArguments, s);
}
Expand All @@ -587,6 +588,7 @@ void collect(current: (Expression) `<Expression expression> ( <{Expression ","}*

if(isConstructorAType(texp) && getConstructorResultType(texp).adtName == "Tree" && expression is qualifiedName){
<qualifier, base> = splitQualifiedName(expression.qualifiedName);

if (base == "char" && (isEmpty(qualifier) || qualifier == "Tree")){
nactuals = size(actuals);
if(nactuals != 1){
Expand Down Expand Up @@ -666,8 +668,7 @@ void collect(current: (Expression) `<Expression expression> ( <{Expression ","}*
return res;
}
if(acons(ret:aadt(adtName, list[AType] _,_), list[AType] fields, list[Keyword] kwFields) := texp){
res = computeADTType(expression, adtName, scope, ret, fields, kwFields, actuals, keywordArguments, [true | int _ <- index(fields)], s);
return res;
return computeADTType(expression, adtName, scope, ret, fields, kwFields, actuals, keywordArguments, [true | int _ <- index(fields)], s);
}
reportCallError(current, expression, actuals, keywordArguments, s);
return avalue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,9 +580,6 @@ void computeMatchPattern(Expression current, Pattern pat, str operator, Expressi
AType(Solver s) {
subjectType = s.getType(expression);
checkNonVoid(expression, subjectType, s, "Second argument of match operator _ := _");
if(isStartNonTerminalType(subjectType)){
subjectType = getStartNonTerminalType(subjectType);
}
patType = getPatternType(pat, subjectType, scope, s);
s.instantiate(subjectType);
instantiateAndCompare(current, patType, subjectType, s);
Expand Down
Loading
Loading