"[ { \"project\" : \"program\" ,\n \"version\" : \"0.0.0\" ,\n \"unit\" : \"struct\" ,\n \"info\" : \"...\" ,\n \"comment\" : \"Add the unit flag `system_target`!!\" } ,\n { \"unit\" : \"doc\" ,\n \"header\" : \"**Programs: scripts, standard modules and node modules**\" ,\n \"info\" : \"# Introduction\\n\\nLet us here define a __program__ as some (ECMAScript) code in a file.\\n\\nThere are three important program formats for ECMAScript/JavaScript:\\n\\n* Originally and for many years, every program was a __script__, i.e. a file with mostly and many a sequence of declarations, that define some properties in the global object. And maybe, some additional actions and side effects.\\n\\n* Then there was the __node module__ as part of the NodeJs system. Actually, the format that NodeJs adopted, was the [CommonJS](http://www.commonjs.org/) specification. The typical way for including node modules is the `require(id)` call.\\n\\n* With the evolution to ES6, we also have __standard (ECMAScript) modules__, now. This is going to be the future and overall standard.\\n\\nMaybe, there is a fourth important format, namely [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD), the _Asynchronous Module Definition_, which was also implemented by some frameworks. But we will not need AMD, so we omit this here.\\n\\n# Three types of Programs\\n\\n* `Program.SCRIPT`\\n* `Program.MODULE`\\n* `Program.NODE_MODULE`\\n\\n# A unified version of the main functions on programs\\n\\n
.............................IMPLEMENT THIS.................................
\\n\\nIn each case `i` is either a script, standard module or node module.\\n\\n* `resolve(i) : Type.or (System.FILEPATH) (NULL)` returns a `System.FILEPATH` value or `null`\\n* `code(i) : ECMAScript.CODE` return the code of the file that belongs to `i`\\n* `load(i) : NULL` evaluates the program and simply returns a `null` when everyhting is done.\\n* `value(i) : ANYTHING`\\n* `include(i)({name_1: alias_1, ..., name_n: alias_n})`\\n* `keys(i)` returns a list the identifiers that are defined by `i` or which are properties of `i`\\n\" } ,\n { \"unit\" : \"struct\" ,\n \"name\" : \"Program\" } ,\n { \"unit\" : \"doc\" ,\n \"name\" : \"Program\" ,\n \"header\" : \"(Global) scripts\" } ,\n { \"unit\" : \"type\" ,\n \"name\" : \"Program.SCRIPT\" ,\n \"value\" : \"Type.subType (System.FILEPATH) (function (fp) {\\n if (System.Path.isFile (fp)) {\\n try {\\n var s = System.File.read (fp);\\n } catch (e) {\\n return (\\\"The content of `\\\" + fp + \\\"` could not be read properly:\\\\n\\\" + e);\\n }\\n var c = Type.complain (EcmaScript.SCRIPT);\\n if (c) { return (\\\"The content of `\\\" + fp + \\\"` is not a well-formed script:\\\\n\\\" + e); }\\n else { return ''; }\\n } else {\\n return (\\\"A file `\\\" + fp + \\\"` does not exist.\\\");\\n }\\n})\" ,\n \"info\" : \"`Program.SCRIPT` is the type of all the file paths, that refer to a well-defined ES6 script.\\nOf course, this type is very much dependent on the context, and in particular the current working directory.\\n\\nNote the difference between\\n\\n* `Program.SCRIPT` is the type of all the file paths, that refer to well-defined ES6 script file.\\n\\n* `EcmaScript.SCRIPT` is the type of all strings, that make well-defined ES6 code.\" } ,\n { \"unit\" : \"struct\" ,\n \"name\" : \"Program.Script\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.Script.code\" ,\n \"type\" : \"Type.fun ([Program.SCRIPT, EcmaScript.SCRIPT])\" ,\n \"value\" : \"function (fp) {\\n if (System.Path.isFile (fp)) {\\n try {\\n var script = System.File.read (fp);\\n } catch (e) {\\n throw Error (\\\"Could not read `\\\" + fp + \\\"`:\\\\n\\\" + e);\\n }\\n try {\\n var tree = EcmaScript.Code.scriptTree (script);\\n } catch (e) {\\n throw Error (\\\"The content of `\\\" + fp + \\\"` is not a well-defined ECMAScript (version 6) script:\\\\n\\\" + e);\\n }\\n return script;\\n } else {\\n throw Error (\\\"The file `\\\" + fp + \\\"` does not exist.\\\")\\n }\\n}\" ,\n \"info\" : \"...\\n\\nNote, that `Program.Script.code (fp)` throws an error, if\\n\\n* `fp` is not a proper file or its content is not readable, or\\n* the file content is not well-defined ES6 script code.\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.Script.load\" ,\n \"type\" : \"Type.fun ([Program.SCRIPT, NULL])\" ,\n \"value\" : \"function (fp) {\\n if (System.Path.isFile (fp)) {\\n try {\\n var script = System.File.read (fp);\\n } catch (e) {\\n throw Error (\\\"Could not read `\\\" + fp + \\\"`:\\\\n\\\" + e);\\n }\\n try {\\n var tree = EcmaScript.Code.scriptTree (script);\\n } catch (e) {\\n throw Error (\\\"The content of `\\\" + fp + \\\"` is not a well-defined ECMAScript (version 6) script:\\\\n\\\" + e);\\n }\\n try {\\n eval (script);\\n } catch (e) {\\n throw Error (\\\"Could not evalute the content of `\\\" + fp + \\\"`:\\\\n\\\" + e);\\n }\\n return null;\\n } else {\\n throw Error (\\\"The file `\\\" + fp + \\\"` does not exist.\\\")\\n }\\n}\" ,\n \"info\" : \"....\\n\\nNote, that `Program.Script.load(fp)` not simply loads the code from `fp`, but performs a syntax check before evaluation, and it throws an error if the code is not a well-formed script.\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.Script.loadList\" ,\n \"type\" : \"Type.fun ([Type.list (Program.SCRIPT), NULL])\" ,\n \"value\" : \"function (fpL) {\\n var totalScript = '';\\n for (var i = 0; i < fpL.length; i++) {\\n if (System.Path.isFile (fpL [i])) {\\n try {\\n var script = File.read (fpL [i]);\\n } catch (e) {\\n throw Error (\\\"Could not read `\\\" + fpL[i] + \\\"`:\\\\n\\\" + e);\\n }\\n try {\\n var tree = EcmaScript.Code.scriptTree (script);\\n } catch (e) {\\n throw Error (\\\"The content of `\\\" + fpL[i] + \\\"` is not a well-defined ECMAScript (version 6) script:\\\\n\\\" + e);\\n }\\n totalScript += \\\"// // // `\\\" + fpL[i] + \\\"` begin // // //\\\\n\\\";\\n totalScript += script + '\\\\n';\\n totalScript += \\\"// // '' `\\\" + fpL[i] + \\\"` end // // //\\\\n\\\";\\n } else {\\n throw Error (\\\"The \\\" + i + \\\"-th file path `\\\" + fpL[i] + \\\"` in the given list does not refer to an existing file.\\\")\\n }\\n }\\n try {\\n eval (totalScript);\\n } catch (e) {\\n throw Error (\\\"Could not evaluate (the concatenation of) the given scripts:\\\\n\\\" + e);\\n }\\n return null;\\n}\" ,\n \"info\" : \"...\" } ,\n { \"unit\" : \"doc\" ,\n \"name\" : \"Program\" ,\n \"header\" : \"Standard ES6 modules\" } ,\n { \"unit\" : \"type\" ,\n \"name\" : \"Program.MODULE\" ,\n \"value\" : \"Type.subType (EcmaScript.MODULE_IDENTIFIER) (function (fp) {\\n if (System.Path.isFile (fp)) {\\n try {\\n var s = System.File.read (fp);\\n } catch (e) {\\n return (\\\"The content of `\\\" + fp + \\\"` could not be read properly:\\\\n\\\" + e);\\n }\\n var c = Type.complain (EcmaScript.MODULE);\\n if (c) { return (\\\"The content of `\\\" + fp + \\\"` is not a well-formed ES6 module:\\\\n\\\" + e); }\\n else { return ''; }\\n } else {\\n return (\\\"A file `\\\" + fp + \\\"` does not exist.\\\");\\n }\\n})\" ,\n \"info\" : \"`Program.MODULE` is the subtype of all module identifiers that refer to a proper module code file.\\nOf course, this type depends on the context of the current system.\\n\\nNote the difference between these three type definitions:\\n\\n* `EcmaScript.MODULE_IDENTIFIER` is the type of all the module identifiers, as they are used in import statements such as `import * from \\\"exampleModuleIdentifier\\\"`.\\n\\n* `EcmaScript.MODULE` which comprises all the ECMAScript code that is well-defined module code, i.e. programs with `export` statements.\\n\\n* `Program.MODULE` which is a subtype of `EcmaScript.MODULE_IDENTIFIER`, namely the module identifiers that refer to a well-defined file in the current context of the given system.\" ,\n \"comment\" : \"Maybe, the implementation has to be updated. At the moment it acts only correctly if the module identifier is a file path.\\nBut I may also need to try adding extensions like `.js`.\" } ,\n { \"unit\" : \"struct\" ,\n \"name\" : \"Program.Module\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.Module.code\" ,\n \"type\" : \"Type.fun ([EcmaScript.MODULE_IDENTIFIER, EcmaScript.MODULE])\" ,\n \"value\" : \"function (mId) {\\n throw Error (\\\"............................Program.Module.code(mId)...........................................\\\")\\n}\" ,\n \"info\" : \"....\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.Module.value\" ,\n \"type\" : \"Type.fun ([EcmaScript.MODULE_IDENTIFIER, ANYTHING])\" ,\n \"value\" : \"function (mId) {\\n throw Error (\\\"............................Program.Module.value(mId)...........................................\\\")\\n}\" ,\n \"info\" : \"...\" } ,\n { \"unit\" : \"doc\" ,\n \"name\" : \"Program\" ,\n \"header\" : \"Node modules (i.e. CommonJS modules)\" } ,\n { \"unit\" : \"type\" ,\n \"name\" : \"Program.NODE_MODULE\" ,\n \"value\" : \"Type.fromRecord ({\\n name:\\n 'Program.NODE_MODULE',\\n complain:\\n function (x) {\\n if (Type.chi (NodeModule.IDENTIFIER) (x)) {\\n if (List.member (NodeModule.theCoreModules(null)) (x)) {\\n return '';\\n } else {\\n if (NodeModule.resolve (x) === null) {\\n return (\\\"The given node module identifier `\\\" + x + \\\"` is not an available module on this system.\\\");\\n } else {\\n return '';\\n }\\n }\\n } else {\\n return (\\\"The given value is not even a node module identifier:\\\\n\\\" + x);\\n }\\n },\\n members:\\n function () { return null; }\\n})\" ,\n \"info\" : \"A node module identifier (see [Program.NodeModule.IDENTIFIER](#Program.NodeModule.IDENTIFER))) `mId` is a `Program.NODE_MODULE` value, if it can be loaded properly, i.e. if the NodeJS call `require(mId)` does not result in an error message.\\n\\nFor example, `'fs'` is the identifier for a core module, so\\n\\n > Type.chi (Program.NODE_MODULE) ('fs')\\n true\\n\\nWhen the TofJs suite is implemented, the [`Esprima`](https://github.com/jquery/esprima) is implicitly implemented, so\\n\\n > Type.chi (Program.NODE_MODULE) ('esprima')\\n true\\n\\nwhereas\\n\\n > Type.chi (Program.NODE_MODULE) ('this_is_not_implemented')\\n false\\n\\nEach NodeJS module, i.e. the members of `Program.NODE_MODULE`, is a member of at least one of the following three sets:\\n\\n1) The set of all __core modules__. These are the 27 or so members of `Program.NodeModule.theCoreModules(null)`, i.e. `['assert', 'buffer', 'child_process', ..., 'zlib']`.\\n\\n2a) The set of all __modules locally installed by NPM__ on the current system. This list is also available as a return value of a `Program.NodeModule.theLocallyInstalledModules(null)` call and the result call also be obtained from a shell call `npm list` (or `npm list --parseable`).\\n\\n2b) The set of all __modules globally installed by NPM__ on the current system. This can also be obtained from a shell call `npm -g list` (or `npm -g list --parseable`).\\n\\n3) The set of all other __loadable module files other than the core or NPM installed ones__. Potentially, this can be any text file on the current system. We did not implement this file list as a separate value, because it would be too ineffective to implement. But there is a subset\\n\\n 3a) The set of all actually __loaded modules__, because this list is registrered by and available from NodeJS (by a `require.cached` call).\\n This list is the result of a `Program.NodeModule.theLoadedModules(null)` call.\\n\\nThe `Program.NODE_MODULE` type comprises the sets 1, 2a, 2b and 3. But we only have the values for 1, 2a and 3a available. Therefore, the members list for `Program.NODE_MODULE` is not implemented, i.e. calling `Type.members (Program.NODE_MODULE)` returns `null`, not a list of NodeJS module identifiers.\\n\\n > Type.members (Program.NODE_MODULE)\\n null\\n\" } ,\n { \"unit\" : \"struct\" ,\n \"name\" : \"Program.NodeModule\" } ,\n { \"unit\" : \"type\" ,\n \"name\" : \"Program.NodeModule.IDENTIFIER\" ,\n \"value\" : \"Type.synonym (STRING)\" ,\n \"info\" : \"A Module Identifier is described in the [CommonJS specs](http://www.commonjs.org/specs/modules/1.0/) as follows:\\n\\n* A module identifier is a String of \\\"terms\\\" delimited by forward slashes.\\n* A term must be a camelCase identifier, \\\".\\\", or \\\"..\\\".\\n* Module identifiers may not have file-name extensions like \\\".js\\\".\\n* Module identifiers may be \\\"relative\\\" or \\\"top-level\\\". A module identifier is \\\"relative\\\" if the first term is \\\".\\\" or \\\"..\\\".\\n* Top-level identifiers are resolved off the conceptual module name space root.\\n* Relative identifiers are resolved relative to the identifier of the module in which \\\"require\\\" is written and called.\\n\\n......\" ,\n \"comment\" : \"The implementation is a dummy!! Improve that!!\" } ,\n { \"unit\" : \"type\" ,\n \"name\" : \"Program.NodeModule.theCoreModules\" ,\n \"value\" : \"function () {\\n return ([\\n 'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net', 'os',\\n 'path', 'punycode', 'querystring', 'readline', 'repl', 'stream', 'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib'\\n ]);\\n}\" ,\n \"info\" : \"`Program.Node.Module.theCoreModules(null)` is an ordered version of zeke's [node-core-module-names](https://github.com/zeke/node-core-module-names) list.\\n\\n > Program.NodeModule.theCoreModules(null)\\n [ 'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net', 'os',\\n 'path', 'punycode', 'querystring', 'readline', 'repl', 'stream', 'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib' ]\\n\" } ,\n { \"unit\" : \"type\" ,\n \"name\" : \"Program.NodeModule.theLocallyInstalledModules\" ,\n \"type\" : \"Type.fun ([NULL, Type.list (IDENTIFIER)])\" ,\n \"value\" : \"function () {\\n var cmd = 'npm list --parseable';\\n var str = require ('child_process') . execSync (cmd, {encoding: 'utf8'});\\n var pathL = str.split (/\\\\s+/g);\\n pathL = pathL.map (function (fp) { return require('path') . basename (fp); })\\n pathL = pathL.filter (function (fp) { return (resolve (fp) !== null); });\\n pathL = List.uniq (pathL);\\n return pathL;\\n}\" ,\n \"info\" : \"`Program.NodeModule.theLocallyInstalledModules(null)` is a list of all NPM-installed modules currently and locally installed on the system.\\nEvery module identifier in this list is a well-defined argument for a `require()` call.\\nThe list does not include the core modules (see/use [`Program.NodeModule.theCoreModules(null)`](#Program.NodeModule.theCoreModules) instead).\\n\\nFor example, I currently get this\\n\\n > Program.NodeModule.theLocallyInstalledModules(null);\\n [ 'escodegen', 'esprima' ]\\n\" } ,\n { \"unit\" : \"type\" ,\n \"name\" : \"Program.NodeModule.theLoadedModules\" ,\n \"type\" : \"Type.fun ([NULL, Type.list (IDENTIFIER)])\" ,\n \"value\" : \"function () {\\n var pathL = Object.keys (require.cache);\\n var pathL = pathL.map (function (fp) { return './' + (require ('path') . relative (process.cwd(), fp)); });\\n return pathL;\\n}\" ,\n \"info\" : \"`Program.NodeModule.theLoadedModules(null)` returns a list of all currently loaded NodeJS modules, but it does not include the core modules.\\n\\nFor example, I currently get this\\n\\n > Program.NodeModule.theLoadedModules(null);\\n [ './tofus/value.tofm.js',\\n './tofus/type.tofm.js',\\n './tofus/global.tofm.js',\\n './tofus/estools.tofm.js',\\n './tofus/ecmascript.tofm.js',\\n './tofus/toffee.tofm.js',\\n './tofus/json.tofm.js',\\n './tofus/tofscript.tofm.js',\\n './tofus/thegoodparts.tofm.js',\\n './tofus/system.tofm.js',\\n './tofus/data.tofm.js',\\n '../../../node_modules/esprima/esprima.js' ]\" } ,\n { \"unit\" : \"doc\" ,\n \"name\" : \"Program.NodeModule\" ,\n \"header\" : \"The main functions\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.NodeModule.resolve\" ,\n \"type\" : \"Type.fun ([IDENTIFIER, Type.nullify (Program.System.FILE)])\" ,\n \"value\" : \"function (mId) {\\n if (List.member (theCoreModules(null)) (mId)) {\\n return null;\\n } else {\\n try {\\n var fp = require.resolve (mId);\\n return fp;\\n } catch (e) {\\n return null; // i.e. `require.resolve(mId)` threw an error, because `mId` couldn't be found\\n }\\n }\\n}\" ,\n \"info\" : \"`Program.NodeModule.resolve (mId)` tries to find the file associated with the module identifier `mId`. It returns\\n\\n* `null`, if a `mId` is a core module (a member of `Program.NodeModule.theCoreModules(null)`),\\n* a file path pointing to a node module file, if `mId` is a proper, non-core node module, and\\n* `null`, if `mId` cannot be found among the modules in the current NodeJs/NPM system.\\n\\nFor example,\\n\\n > Program.NodeModule.resolve ('esprima')\\n '/home/buc/node_modules/esprima/esprima.js'\\n\\n > Program.NodeModule.resolve ('this/is/nonsense.really')\\n null\\n\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.NodeModule.code\" ,\n \"type\" : \"Type.fun ([Program.NodeModule.IDENTIFIER, EcmaScript.CODE])\" ,\n \"value\" : \"function (mId) {\\n var fp = resolve (mId);\\n if (fp === null) {\\n throw Error (\\\"Cannot resolve the module identifier `\\\" + mId + \\\"` to find the according file.\\\");\\n } else {\\n try {\\n var code = System.File.read (fp);\\n return code;\\n } catch (e) {\\n throw Error (\\\"Cannot retrieve the content of `\\\" + fp + \\\"`, which was found to be the file for the module identifier `\\\" + mId + \\\"`:\\\\n\\\" + e);\\n }\\n }\\n}\" ,\n \"info\" : \"`Program.NodeModule.code (mId)` returns the code of the module file to which the module identifier `mId` is referring.\\nIf `mId` does not refer to a NodeJS/CommonJS module, i.e. if it is not a `Program.NODE_MODULE` value, an error message is thrown.\" } ,\n { \"unit\" : \"function\" ,\n \"name\" : \"Program.NodeModule.value\" ,\n \"type\" : \"Type.fun ([Program.NodeModule.IDENTIFIER, ANYTHING])\" ,\n \"value\" : \"function (mId) {\\n return require ('mId');\\n}\" ,\n \"info\" : \"`Program.NodeModule.value(mId)` loads the module `mId` and returns its value.\\n\\nActually, `Program.NodeModule.value(mId)` returns the same value as `require(mId)`, and that is also how the function is implemented.\" } ,\n { \"unit\" : \"doc\" ,\n \"name\" : \"Program.NodeModule\" ,\n \"header\" : \"The conversions\" ,\n \"info\" : \"Node module to standard module conversion can be done with the additional statement\\n\\n for (var k in module.exports) { window[k] = module.exports[k]; }\\n\\nfor the browser or more general\\n\\n for (var k in module.exports) { Global.setValue (k) (module.exports[k]); }\" } ]\n"