module examples::modules::Checker
rascal-0.40.16
typepal-0.14.8
Usage
import examples::modules::Checker;
Source code
http://github.com/usethesource/typepal/src/examples/modules/Checker.rsc
Dependencies
import examples::modules::Syntax;
import IO;
import String;
extend analysis::typepal::TypePal;
extend analysis::typepal::TestFramework;
syntax ConsId
lexical ConsId = "$" ([a-z A-Z 0-9 _] !<< [a-z A-Z _][a-z A-Z 0-9 _]* !>> [a-z A-Z 0-9 _])\Reserved;
data AType
data AType
= structType(str name)
| moduleType()
;
data IdRole
data IdRole
= structId()
| moduleId()
;
data PathRole
data PathRole
= importPath()
;
function prettyPrintAType
str prettyPrintAType(structType(name)) = "structType(<name>)";
str prettyPrintAType(moduleType()) = "moduleType()";
function project
private loc project(loc file) {
assert file.scheme == "project";
return |project://<file.authority>|;
}
data PathConfig
data PathConfig
= pathConfig(list[loc] srcs = [], list[loc] libs = [])
;
function pathConfig
PathConfig pathConfig(loc file) {
assert file.scheme == "project";
p = project(file);
return pathConfig(srcs = [ p + "src/lang/modules"]);
}
function getFileName
str getFileName((ModuleId) `<{Id "::"}+ moduleName>`) = replaceAll("<moduleName>.modules", "::", "/");
function lookupModule
tuple[bool, loc] lookupModule(str name, PathConfig pcfg) {
for (s <- pcfg.srcs + pcfg.libs) {
result = (s + replaceAll(name, "::", "/"))[extension = "modules"];
println(result);
if (exists(result)) {
return <true, result>;
}
}
return <false, |invalid:///|>;
}
function collect
void collect(current:(Import) `import <ModuleId moduleName>`, Collector c) {
c.addPathToDef(moduleName, {moduleId()}, importPath());
c.push(__MODULES_IMPORT_QUEUE, "<moduleName>");
}
function handleImports
void handleImports(Collector c, Tree root, PathConfig pcfg) {
set[str] imported = {};
while (list[str] modulesToImport := c.getStack(__MODULES_IMPORT_QUEUE) && modulesToImport != []) {
c.clearStack(__MODULES_IMPORT_QUEUE);
for (m <- modulesToImport, m notin imported) {
if (<true, l> := lookupModule(m, pcfg)) {
collect(parse(#start[Program], l).top, c);
}
else {
c.report(error(root, "Cannot find module %v in %v or %v", m, pcfg.srcs, pcfg.libs));
}
imported += m;
}
}
}
function collect
void collect(current: (Program) `module <ModuleId moduleName> <Import* imports> <TopLevelDecl* decls>`, Collector c){
c.define("<moduleName>", moduleId(), current, defType(moduleType()));
c.enterScope(current); {
collect(imports, c);
collect(decls, c);
}
c.leaveScope(current);
}
void collect(current:(TopLevelDecl) `struct <Id id> { <DeclInStruct* decls> }`, Collector c) {
c.define("<id>", structId(), current, defType(structType("<id>")));
c.enterScope(current); {
collect(decls, c);
}
c.leaveScope(current);
}
void collect(current:(DeclInStruct) `<Type ty>`, Collector c) {
collect(ty, c);
}
void collect(current: (Type) `<Id name>`, Collector c){
c.use(name, {structId()});
}
function modulesTModelFromTree
TModel modulesTModelFromTree(Tree pt){
if (pt has top) pt = pt.top;
c = newCollector("modules", pt, config=getModulesConfig(debug = debug));
collect(pt, c);
handleImports(c, pt, pathConfig(pt@\loc));
return newSolver(pt, c.run()).run();
}
function modulesGetTypeNameAndRole
tuple[list[str] typeNames, set[IdRole] idRoles] modulesGetTypeNameAndRole(structType(str name)) = <[name], {structId()}>;
tuple[list[str] typeNames, set[IdRole] idRoles] modulesGetTypeNameAndRole(AType t) = <[], {}>;
function getModulesConfig
private TypePalConfig getModulesConfig() = tconfig(
getTypeNamesAndRole = modulesGetTypeNameAndRole
//verbose=debug
//logTModel = debug
//logAttempts = debug,
//logSolverIterations= debug
);
function sampleModules
public start[Program] sampleModules(str name) = parse(#start[Program], |project://typepal/src/examples/modules/<name>.modules|);
function runModules
list[Message] runModules(str name, bool debug = false) {
Tree pt = sampleModules(name);
TModel tm = modulesTModelFromTree(pt, debug = debug);
return tm.messages;
}
function testModules
bool testModules(int n, bool debug = false, set[str] runOnly = {}) {
return runTests([|project://modules-core/src/lang/modules/modules<"<n>">.ttl|], #start[Program], TModel (Tree t) {
return modulesTModelFromTree(t, debug=debug);
}, runOnly = runOnly);
}