Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
14 changes: 3 additions & 11 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/ADTandGrammar.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -194,20 +194,11 @@ tuple[TModel, ModuleStatus] addGrammar(str qualifiedModuleName, set[str] imports
}
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 @@ -250,7 +241,7 @@ tuple[TModel, ModuleStatus] addGrammar(str qualifiedModuleName, set[str] 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 @@ -365,7 +356,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
43 changes: 18 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(_, AType bnd):
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 @@ -440,8 +428,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 @@ -464,8 +450,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 Down Expand Up @@ -496,7 +480,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 @@ -707,8 +691,11 @@ AType alub(l:aadt("Tree", _, _), AType r) = l
AType alub(AType l, r:aadt("Tree", _, _)) = r
when l is \achar-class || l is seq || l is opt || l is alt || l is iter || l is \iter-star || l is \iter-seps || l is \iter-star-seps;

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(AType r, sr)) = \start(alub(l, r), sr);
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 @@ -781,6 +768,12 @@ 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(AType b, sr)) = \start(aglb(a, b), sr);
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 @@ -334,12 +334,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
31 changes: 13 additions & 18 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/ATypeUtils.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,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 @@ -225,8 +225,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 @@ -486,7 +485,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 @@ -1061,7 +1060,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 _)) = isADTAType(s);
default bool isADTAType(AType _) = false;

@doc{Create a new parameterized ADT type with the given type parameters}
Expand All @@ -1074,7 +1073,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 @@ -1084,7 +1083,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 @@ -1342,7 +1341,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 @@ -1361,11 +1360,11 @@ bool isNonParameterizedNonTerminalType(AType t) = isNonTerminalAType(t) && (t ha

// start
bool isStartNonTerminalType(aparameter(_,AType tvb)) = isStartNonTerminalType(tvb);
bool isStartNonTerminalType(AType::\start(_)) = true;
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;
AType getStartNonTerminalType(AType::\start(AType s, _)) = s;
default AType getStartNonTerminalType(AType s) {
throw rascalCheckerInternalError("<prettyAType(s)> is not a start non-terminal type");
}
Expand All @@ -1376,7 +1375,7 @@ 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, _)) = false;

bool isLexicalAType(AType:alit(str string)) = true;
bool isLexicalAType(AType:acilit(str string)) = true;
Expand Down Expand Up @@ -1524,13 +1523,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 @@ -1561,4 +1556,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 @@ -574,6 +574,7 @@ void collect(current: (Expression) `<Expression expression> ( <{Expression ","}*
}

AType texp = s.getType(expression);

if(isStrAType(texp)){
return computeExpressionNodeType(scope, actuals, keywordArguments, s);
}
Expand All @@ -592,6 +593,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 @@ -671,8 +673,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 @@ -1007,9 +1007,6 @@ private void requireAssignmentSubType(Tree current, AType a, AType b, FailMessag
private AType computeFieldAssignableType(Statement current, AType receiverType, Tree field, str operator, AType rhs, loc scope, Solver s){
//println("computeFieldAssignableType: <current>");
fieldName = unescape("<field>");
if(isNonTerminalAType(receiverType) && fieldName == "top"){
return isStartNonTerminalType(receiverType) ? getStartNonTerminalType(receiverType) : receiverType;
}
fieldType = s.getTypeInType(receiverType, field, {fieldId(), keywordFieldId()}, scope);
updatedFieldType = computeAssignmentRhsType(current, fieldType, operator, rhs, s);
requireAssignmentSubType(current, updatedFieldType, fieldType, error(current, "Field %q requires %t, found %t", fieldName, fieldType, updatedFieldType), s);
Expand Down
Loading