Skip to main content

module examples::splitstruct::Checker

rascal-0.40.16
typepal-0.14.8

Usage

import examples::splitstruct::Checker;

Source code

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

Dependencies

import examples::splitstruct::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 subtype

bool subtype(AType a, a) = true;

bool subtype(AType a, overloadedAType(rel[loc, IdRole, AType] overloads)) = a in overloads<2>;

bool subtype(overloadedAType(rel[loc, IdRole, AType] overloads), AType b) = all(x <- overloads<2>, subtype(x, b));

default bool subtype(AType a, AType b) = false;

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 splitRecordMayOverload

bool splitRecordMayOverload(set[loc] defs, map[loc, Define] defines){
return all(def <- defs, defines[def].idRole == structId());
}

function splitstructConfig

TypePalConfig splitstructConfig() =
tconfig(
getTypeNamesAndRole = structGetTypeNamesAndRole,
mayOverload = splitRecordMayOverload,
isSubType = subtype
);

function collect

void collect(current:(Declaration)`<Type typ> <Id id> = <Expression exp> ;`, Collector c) {
c.define("<id>", variableId(), current, defType(typ));
c.requireSubType(typ, exp, error(exp, "Incorrect initialization, expected %t, found %t", typ, exp)); /* use subtype instrad of equal */
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()});
}