Skip to main content

module examples::dataModel::Checker

rascal-0.40.16
typepal-0.14.8

Usage

import examples::dataModel::Checker;

Source code

http://github.com/usethesource/typepal/src/examples/dataModel/Checker.rsc

Dependencies

import examples::dataModel::Syntax;
extend analysis::typepal::TypePal;

data AType

data AType  
= intType()
| strType()
| setType(AType elm)
| entityType(str name)
| fieldType(str name)
;

function prettyAType

str prettyAType(intType()) = "int";

str prettyAType(strType()) = "str";

str prettyAType(setType(AType tp)) = "Set\<<prettyAType(tp)>\>";

str prettyAType(entityType(str name)) = name;

str prettyAType(fieldType(str name)) = name;

str prettyAType(functionType(AType from, AType to)) = "fun <prettyAType(from)> -\> <prettyAType(to)>";

data IdRole

data IdRole  
= entityId()
| fieldId()
;

function dmGetTypeNamesAndRole

tuple[list[str] typeNames, set[IdRole] idRoles] dmGetTypeNamesAndRole(entityType(str name)){
return <[name], {entityId()}>;
}

default tuple[list[str] typeNames, set[IdRole] idRoles] dmGetTypeNamesAndRole(AType t){
return <[], {}>;
}

function dmConfig

TypePalConfig dmConfig() =
tconfig(getTypeNamesAndRole = dmGetTypeNamesAndRole);

function collect

void collect(current: (Program) `<Declaration+ decls>`, Collector c){
collect(decls, c);
}

void collect(current: (Declaration) `entity <Id name> { <Field+ fields> }`, Collector c){
c.define("<name>", entityId(), current, defType(entityType("<name>")));
c.enterScope(current);
collect(fields, c);
c.leaveScope(current);
}

void collect(current: (Field) `<Id name> -\> <Type typ> inverse <Id ref> :: <Id attr>`, Collector c){
c.define("<name>", fieldId(), current, defType(typ));
c.use(ref, {entityId()});
c.useViaType(ref, attr, {fieldId()});
c.require("check inverse", current, [attr],
void(Solver s){
field_type = s.getType(typ);
attr_type = s.getType(attr);
ref_type = s.getType(ref);

if(setType(elm_type) := field_type){
s.requireEqual(elm_type, ref_type, error(attr, "Field type %t does not match reference type %t", typ, ref));
} else {
s.requireEqual(ref_type, field_type, error(attr, "Field type %t should be equal to reference type %t", field_type, ref_type));
}
});
collect(typ, ref, attr, c);
}

void collect(current: (Type) `int`, Collector c){
c.fact(current, intType());
}

void collect(current: (Type) `str`, Collector c){
c.fact(current, strType());
}

void collect(current: (Type) `<Id tp>`, Collector c){
c.use(tp, {entityId(), fieldId()});
}

void collect(current: (Type) `Set \< <Type tp> \>`, Collector c){
c.calculate("set type", current, [tp], AType (Solver s) { return setType(s.getType(tp)); });
collect(tp, c);
}