Skip to main content

module examples::modules::Checker

rascal-0.34.0
typepal-0.8.10

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, bool debug = false){
if (pt has top) pt = pt.top;
c = newCollector("collectAndSolve", pt, config=getModulesConfig(debug = debug)); // TODO get more meaningfull name
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(bool debug = false) = tconfig(
getTypeNamesAndRole = modulesGetTypeNameAndRole,
verbose=debug,
logTModel = debug,
logAttempts = debug,
logSolverIterations= debug,
logSolverSteps = 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);
}