Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

starting to add syntax and semantics of syntax role modifiers #15

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
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
41 changes: 41 additions & 0 deletions src/org/rascalmpl/core/library/lang/rascalcore/check/AType.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ bool asubtype(achar(int c), \achar-class(list[ACharRange] ranges)) {
}
bool asubtype(l:\achar-class(list[ACharRange] _), achar(int c)) = l == \achar-class([arange(c,c)]);

// amodifyTo (presumes normalizing rewrite rules have been applied from ATypeBase)
bool asubtype(amodifyTo(x, role), amodifyTo(y, role)) = amodifyTo(x, y);
bool asubtype(amodifyTo(l, rx), r:aadt(_, rx)) = asubtype(l, r);
bool asubtype(l:aadt(_, _, rx), amodifyTo(r, rx)) = asubtype(l, r);

// Utilities

bool asubtype(atypeList(list[AType] l), atypeList(list[AType] r)) = asubtype(l, r);
Expand Down Expand Up @@ -371,6 +376,10 @@ AType addADTLabel(AType a1, AType a2, AType adt){
return adt;
}

// JV: TODO remove acons as a type. We don't have it fully working in the runtime-type system either and
// it has a confusing relationship with afunc. The type of a constructor function's name. ConstructorType
// in vallang should also be removed from the type hierarchy and simply become `Constructor` or `Production`.
// should be a function type: `ADT (parameters, keywordparams)`
//AType alub(acons(AType la, list[AType] _, list[Keyword] _), acons(AType ra, list[AType] _, list[Keyword] _)) = alub(la,ra);
AType alub(acons(AType lr, list[AType] lp, list[Keyword] lkw), acons(AType rr, list[AType] rp, list[Keyword] rkw)) {
if(/*lr == rr && */size(lp) == size(rp)){
Expand Down Expand Up @@ -408,6 +417,38 @@ AType alub(AType l, aparameter(str _, AType bound)) = alub(l, bound) when aparam
AType alub(areified(AType l), areified(AType r)) = areified(alub(l,r));
AType alub(areified(AType l), anode(_)) = anode([]);

// note that lub on modifyTo works under assumptions of normals forms affected by rewrite rules on modifyTo(..) terms
AType alub(amodifyTo(AType l, SyntaxRole sr), amodifyTo(AType r, sr))
= amodifyTo(alub(l, r), sr);

AType alub(amodifyTo(AType l, SyntaxRole sr), amodifyTo(AType r, sr))
= amodifyTo(alub(l, r), sr);

AType alub(amodifyTo(AType l, contextFreeSyntax()), amodifyTo(AType r, dataSyntax())) = anode([]);
AType alub(amodifyTo(AType l, contextFreeSyntax()), amodifyTo(AType r, lexicalSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, contextFreeSyntax()), amodifyTo(AType r, keywordSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, contextFreeSyntax()), amodifyTo(AType r, layoutSyntax())) = aadt("Tree", [], dataSyntax());

AType alub(amodifyTo(AType l, dataSyntax()), amodifyTo(AType r, contextFreeSyntax())) = anode([]);
AType alub(amodifyTo(AType l, dataSyntax()), amodifyTo(AType r, lexicalSyntax())) = anode([]);
AType alub(amodifyTo(AType l, dataSyntax()), amodifyTo(AType r, keywordSyntax())) = anode([]);
AType alub(amodifyTo(AType l, dataSyntax()), amodifyTo(AType r, layoutSyntax())) = anode([]);

AType alub(amodifyTo(AType l, lexicalSyntax()), amodifyTo(AType r, dataSyntax())) = anode([]);
AType alub(amodifyTo(AType l, lexicalSyntax()), amodifyTo(AType r, contextFreeSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, lexicalSyntax()), amodifyTo(AType r, keywordSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, lexicalSyntax()), amodifyTo(AType r, layoutSyntax())) = aadt("Tree", [], dataSyntax());

AType alub(amodifyTo(AType l, keywordSyntax()), amodifyTo(AType r, dataSyntax())) = anode([]);
AType alub(amodifyTo(AType l, keywordSyntax()), amodifyTo(AType r, contextFreeSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, keywordSyntax()), amodifyTo(AType r, lexicalSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, keywordSyntax()), amodifyTo(AType r, layoutSyntax())) = aadt("Tree", [], dataSyntax());

AType alub(amodifyTo(AType l, layoutSyntax()), amodifyTo(AType r, dataSyntax())) = anode([]);
AType alub(amodifyTo(AType l, layoutSyntax()), amodifyTo(AType r, contextFreeSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, layoutSyntax()), amodifyTo(AType r, lexicalSyntax())) = aadt("Tree", [], dataSyntax());
AType alub(amodifyTo(AType l, layoutSyntax()), amodifyTo(AType r, keywordSyntax())) = aadt("Tree", [], dataSyntax());

AType alub(l:\achar-class(_), r:\achar-class(_)) = union(l, r);
AType alub(l:aadt("Tree", _, _), \achar-class(_)) = l;
AType alub(\achar-class(_), r:aadt("Tree", _, _)) = r;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ data AType (str alabel = "")

| anode(list[AType] fields)
| aadt(str adtName, list[AType] parameters, SyntaxRole syntaxRole)
| amodifyTo(AType atype, SyntaxRole syntaxRole)
| acons(AType adt, list[AType] fields, list[Keyword] kwFields)
| aprod(AProduction production)

Expand Down Expand Up @@ -439,6 +440,10 @@ public AGrammar compose(AGrammar g1, AGrammar g2) {
return grammar(g1.starts, reduced_rules);
}

@synopsis{Semantics of syntax role modifiers}
// with nested modification the outermost (last applied) role wins
AType amodifyTo(amodifyTo(t, _), SyntaxRole to) = amodifyTo(t, to);


// syntax role modification preserves the name and the parameters
AType amodifyTo(aadt(name, ps, _), SyntaxRole to) = aadt(name, ps, to);

Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,22 @@ public Bindings matchRascalTypeParams0(AType r, AType s, Bindings b) {
for (idx <- index(rparams)) b = matchRascalTypeParams0(rparams[idx], sparams[idx], b);
return b;
}


// parametrized role modifiers match ADTs with the same syntax role!
if (amodifyTo(aparameter(n,_), sr) := r && aadt(_,_,sr) := s) {
b[n] = s;
return b;
}

// two parametrized role modifiers can match if their parameters can match and they have the same role
if (amodifyTo(t1:aparameter(_,_), sr) := r && amodifyTo(t2:aparameter(_,_), sr) := s) {
b = matchRascalTypeParams0(t1, t2, b);
return b;
}

// nested amodifyTo's are rewritten, also if applied to aadt's they are rewritten.
// all the other amodifyTo applications do not match anything because they don't have semantics (yet)

// For constructors, match when the constructor name, ADT name, and arity are the same, then we can check params
if ( isConstructorType(r) && isConstructorType(s) && getADTName(r) == getADTName(s)) {
b = matchRascalTypeParams0(getConstructorArgumentTypesAsTuple(r), getConstructorArgumentTypesAsTuple(s), b);
Expand Down Expand Up @@ -190,6 +205,8 @@ AType instantiateRascalTypeParams(AType pt:aparameter(str s, AType t), Bindings
= pt when s notin bindings;
AType instantiateRascalTypeParams(a: aadt(str s, list[AType] ps, SyntaxRole sr), Bindings bindings)
= aadt(s, [instantiateRascalTypeParams(p,bindings) | p <- ps], sr);
AType instantiateRascalTypeParams(a: amodifyTo(t, SyntaxRole sr), Bindings bindings)
= amodifyTo(instantiateRascalTypeParams(t, bindings), sr);
AType instantiateRascalTypeParams(acons(AType a, /*str name,*/ list[AType/*NamedField*/] fields, list[Keyword] kwFields, alabel=consName), Bindings bindings) =
//acons(instantiateRascalTypeParams(a,bindings), /*name,*/ [<fn, instantiateRascalTypeParams(ft,bindings)> | <fn, ft> <- fields], [<fn, instantiateRascalTypeParams(ft,bindings), de> | <fn, ft, de> <- kwFields], alabel=consName);
acons(instantiateRascalTypeParams(a,bindings), /*name,*/ [instantiateRascalTypeParams(ft,bindings) | ft <- fields], [<instantiateRascalTypeParams(ft,bindings), de> | <ft, de> <- kwFields], alabel=consName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
module lang::rascalcore::check::CollectType

extend lang::rascalcore::check::ATypeInstantiation;
extend lang::rascalcore::check::CheckerCommon;

import lang::rascal::\syntax::Rascal;
import lang::rascalcore::grammar::definition::Symbols;
import lang::rascalcore::grammar::definition::Characters;
import lang::rascalcore::grammar::definition::Literals;
import lang::rascalcore::check::ScopeInfo;

import IO;
import List;
import Node;
import Set;
Expand Down Expand Up @@ -101,6 +101,57 @@ public list[&T] dup(list[&T] lst) {
}
}

// ---- role modifiers
void collect(current:(Type)`syntax[<Type t>]`, Collector c){
collect(t, c);

try {
c.fact(current, amodifyTo(c.getType(targs[0]), contextFreeSyntax()));
} catch TypeUnavailable():{
c.calculate("role modifier", current, targs, AType(Solver s){ return amodifyTo(c.getType(targs[0]), syntaxRole()); });
}
}

void collect(current:(Type)`data[<Type t>]`, Collector c){
collect(t, c);

try {
c.fact(current, amodifyTo(c.getType(targs[0]), dataSyntax()));
} catch TypeUnavailable():{
c.calculate("role modifier", current, targs, AType(Solver s){ return amodifyTo(c.getType(targs[0]), dataRole()); });
}
}

void collect(current:(Type)`lexical[<Type t>]`, Collector c){
collect(t, c);

try {
c.fact(current, amodifyTo(c.getType(targs[0]), lexicalSyntax()));
} catch TypeUnavailable():{
c.calculate("role modifier", current, targs, AType(Solver s){ return amodifyTo(c.getType(targs[0]), lexicalRole()); });
}
}

void collect(current:(Type)`layout[<Type t>]`, Collector c){
collect(t, c);

try {
c.fact(current, amodifyTo(c.getType(targs[0]), layoutSyntax()));
} catch TypeUnavailable():{
c.calculate("role modifier", current, targs, AType(Solver s){ return amodifyTo(c.getType(targs[0]), layoutRole()); });
}
}

void collect(current:(Type)`keyword[<Type t>]`, Collector c){
collect(t, c);

try {
c.fact(current, amodifyTo(c.getType(targs[0]), keywordSyntax()));
} catch TypeUnavailable():{
c.calculate("role modifier", current, targs, AType(Solver s){ return amodifyTo(c.getType(targs[0]), keywordSyntax()); });
}
}

// ---- list

void collect(current:(Type)`list [ < {TypeArg ","}+ tas > ]`, Collector c){
Expand Down