module examples::struct::Checker
rascal-0.40.16
typepal-0.14.8
Usage
import examples::struct::Checker;
Source code
http://github.com/usethesource/typepal/src/examples/struct/Checker.rsc
Dependencies
import examples::struct::Syntax;
extend analysis::typepal::TypePal;
data AType
data AType
= intType()
| strType()
| structType(str name)
;
data IdRole
data IdRole
= fieldId()
| structId()
;
function prettyAType
str prettyAType(intType()) = "int";
str prettyAType(strType()) = "str";
str prettyAType(structType(name)) = "struct <name>";
function structGetTypeNamesAndRole
tuple[list[str] typeNames, set[IdRole] idRoles] structGetTypeNamesAndRole(structType(str name)){
return <[name], {structId()}>;
}
default tuple[list[str] typeNames, set[IdRole] idRoles] structGetTypeNamesAndRole(AType t){
return <[], {}>;
}
function structConfig
TypePalConfig structConfig() =
tconfig(getTypeNamesAndRole = structGetTypeNamesAndRole);
function collect
void collect(current:(Declaration)`<Type typ> <Id id> = <Expression exp> ;`, Collector c) {
c.define("<id>", variableId(), current, defType(typ));
c.requireEqual(typ, exp, error(exp, "Incorrect initialization, expected %t, found %t", typ, exp));
collect(typ, exp, c);
}
void collect(current:(Declaration)`struct <Id name> { <{Field ","}* fields> };`, Collector c) {
c.define("<name>", structId(), current, defType(structType("<name>")));
c.enterScope(current);
collect(fields, c);
c.leaveScope(current);
}
void collect(current:(Field)`<Type typ> <Id name>`, Collector c) {
c.define("<name>", fieldId(), current, defType(typ));
collect(typ, 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 name>`, Collector c) {
c.use(current, {structId()});
}
void collect(current:(Expression) `new <Id name>`, Collector c){
c.use(name, {structId()});
c.fact(current, structType("<name>"));
}
void collect(current:(Expression)`<Expression lhs> . <Id fieldName>`, Collector c) {
c.useViaType(lhs, fieldName, {fieldId()});
c.fact(current, fieldName);
collect(lhs, c);
}
void collect(current:(Expression)`<Integer _>`, Collector c) {
c.fact(current, intType());
}
void collect(current:(Expression)`<String _>`, Collector c) {
c.fact(current, strType());
}
void collect(current:(Expression)`<Id use>`, Collector c) {
c.use(use, {variableId()});
}