babelute
Version:
Internal Domain Specific (Multi)Modeling javascript framework
1 lines • 51.2 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../src/lexem.js","../../src/utils/extends.js","../../src/babelute.js","../../src/from-json.js","../../src/lexicon/first-level.js","../../src/lexicon/initializer.js","../../src/lexicon/lexicon.js","../../src/pragmatics/pragmatics-core.js","../../src/pragmatics/facade-pragmatics.js","../../src/index.js"],"sourcesContent":["/*\n* @Author: Gilles Coomans\n*/\n\nimport assert from 'assert'; // removed in production\n\n/**\n * Lexem class : a lexem is just an object containing 3 properties { lexicon:String, name:String, args:Arguments|Array }\n * You should never construct them directly (but if you do babelute's plugins). And it should never be extended.\n * @protected\n */\nexport default class Lexem {\n\n\t/**\n\t * construct a new lexem instance\n\t * @param {String} lexicon the lexicon's name of the lexem\n\t * @param {String} name the lexem's name\n\t * @param {Array|arguments} args the lexem's arguments (an array or the \"callee arguments\" object) \n\t */\n\tconstructor(lexicon, name, args) {\n\t\tassert(typeof lexicon === 'string' && lexicon.length, 'Lexicon\\'s name should be a valid string');\n\t\tassert(typeof name === 'string' && lexicon.length, 'Lexem\\'s name should be a valid string');\n\t\tassert(Array.isArray(args) || typeof args.length !== 'undefined', 'Lexem\\'s args should be an array (or iterable with bracket access)');\n\n\t\t/**\n\t\t * the lexicon name from where the lexem comes\n\t\t * @type {String}\n\t\t */\n\t\tthis.lexicon = lexicon;\n\n\t\t/**\n\t\t * the lexem's name\n\t\t * @type {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t/**\n\t\t * The lexem's arguments array (or arguments object)\n\t\t * @type {Array|arguments}\n\t\t */\n\t\tthis.args = args;\n\t}\n}","function extend(BaseClass, ...apis) {\n\tconst B = function(...args) {\n\t\tBaseClass.apply(this, args);\n\t};\n\tB.prototype = Object.create(BaseClass.prototype);\n\tB.prototype.constructor = B;\n\tapis.forEach((api) => {\n\t\tfor (var i in api) B.prototype[i] = api[i];\n\t});\n\treturn B;\n}\n\nexport default extend;\n\n","/**\n * Babelute core\n *\n * @author Gilles Coomans\n * @licence MIT\n * @copyright 2016-2017 Gilles Coomans\n */\n\nimport assert from 'assert'; // removed in production\nimport Lexem from './lexem';\nimport extend from './utils/extends';\n/**\n * Babelute subclass(es) instances : for holding array of lexems (i.e. a sentence) written through the DSL's API.\n *\n * Will be the base class for all DSLs handlers.\n *\n * Babelute API and lexems Naming Conventions : \n * \n * - any \"meta-language\" method (aka any method that handle the sentence it self - appending new lexem, changing current lexicon, sentences translations, ...) \n * must start with and underscore : e.g. _append, _lexicon, _if, _each, _eachLexem, _translate...\n * - any \"pragmatics output related\" method should start with a '$' and should be named with followed format : e.g. .$myLexiconToMyOutputType(...)\n * - any DSL lexems (so any other \"api\"'s method) should start with a simple alphabetic char : e.g. .myLexem(), .description(), .title(), ...\n * \t\t\n * @public\n */\nexport default class Babelute {\n\n\t/**\n\t * construct a babelute instance\n\t * @param {?Array} lexems array of lexems for init. (only for internal use)\n\t */\n\tconstructor(lexems = null) {\n\t\tassert(!lexems || Array.isArray(lexems), 'Babelute\\'s constructor accept only an array of lexems as argument (optionaly)');\n\n\t\t/**\n\t\t * the array where lexems are stored\n\t\t * @type {Array}\n\t\t */\n\t\tthis._lexems = lexems || [];\n\n\t\t/**\n\t\t * useful marker for fast instanceof replacement (frame/multiple-js-runtime friendly)\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.__babelute__ = true;\n\t}\n\n\t/**\n\t * The absolute Babelute atom method : add a lexem to babelute's array\n\t * @public\n\t * @param {String} lexiconName the current lexicon name\n\t * @param {String} name the lexem's name\n\t * @param {Array|arguments} args the lexem's arguments (either an array or maybe directly the arguments object from when lexem is called)\n\t * @return {Babelute} \tthe current Babelute instance\n\t */\n\t_append(lexiconName, name, args) {\n\n\t\tthis._lexems.push(new Lexem(lexiconName, name, args));\n\n\t\treturn this;\n\t}\n\n\n\t/**\n\t * conditional sentences concatenation.\n\t *\n\t * Apply modification at sentence writing time (aka the babelute does not contains the _if lexems. _if has immediatly been applied).\n\t * \n\t * @public\n\t * @param {*} condition any value that will be casted to Boolean (!!)\n\t * @param {Babelute} babelute which sentence to insert if !!condition === true\n\t * @param {?Babelute} elseBabelute which sentence to insert if !!condition === false\n\t * @return {Babelute} the current Babelute instance\n\t */\n\t_if(condition, babelute, elseBabelute = null) {\n\n\t\tassert(babelute instanceof Babelute, '._if meta-api need an babelute instance as second argument');\n\t\tassert(!elseBabelute || elseBabelute instanceof Babelute, '._if meta-api need an babelute instance as third argument (optional)');\n\n\t\tif (condition)\n\t\t\tthis._lexems = this._lexems.concat(babelute._lexems);\n\t\telse if (elseBabelute)\n\t\t\tthis._lexems = this._lexems.concat(elseBabelute._lexems);\n\t\treturn this;\n\t}\n\n\t/**\n\t * For each item from array : execute function and concatenate returned babelute sentence to current one. \n\t * Provided function must return a babelute.\n\t *\n\t * Apply modification at sentence writing time (aka the babelute does not contains the _each lexems. _each has immediatly been applied).\n\t * \n\t * @public\n\t * @param {Array} array the array to iterate on\n\t * @param {Function} func the function to handle each item. it must return a babelute.\n\t * @return {Babelute} the current Babelute instance\n\t */\n\t_each(array, func) {\n\n\t\tassert(!array || Array.isArray(array), '._each meta-api need an array (or iterable with bracket access) as first argument');\n\t\tassert(typeof func === 'function', '._each meta-api need a function as second argument');\n\n\t\tif (array)\n\t\t\tarray.forEach((item, index) => {\n\t\t\t\tconst b = func(item, index);\n\n\t\t\t\tassert(b instanceof Babelute, '._each need a function that return a babelute');\n\n\t\t\t\tthis._lexems.push.apply(this._lexems, b._lexems);\n\t\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Use a babelute (another sentence) at this point in the current sentence\n\t * @public\n\t * @param {string|Babelute} babelute Either a string formatted as 'mylexicon:myMethod' (which gives the lexem's method to call), or a Babelute instance (which will be inserted in current sentence)\n\t * @param {?...args} args the optional arguments to use when calling lexem (only if first argument is a string)\n\t * @return {Babelute} the current Babelute instance\n\t * @throws {Error} If lexicon not found (when first arg is string)\n\t * @throws {Error} If method not found in lexicon (when first arg is string)\n\t */\n\t/* istanbul ignore next */\n\t_use(babelute, ...args) { // eslint-disable-line no-unused-vars\n\t\t// will be implemented in lexicon\n\t}\n\n\n\t/**\n\t * Change current lexicon for next lexems\n\t * @public\n\t * @param {string} lexiconName the lexicon to use\n\t * @return {Babelute} a new Babelute from lexicon (i.e. with lexicon's API)\n\t * @throws {Error} If lexicon not found with lexiconName\n\t */\n\t/* istanbul ignore next */\n\t_lexicon(lexiconName) { // eslint-disable-line no-unused-vars\n\t\t// will be implemented in lexicon\n\t}\n\n\t/**\n\t * transform a sentence through a function. This function must return a new sentence.\n\t * @param {Function} handler a function that receive the current sentence as argument and that return a new sentence.\n\t * @return {Babelute} the new sentence\n\t */\n\t_transform(handler) {\n\t\treturn handler(this);\n\t}\n\n\t/**\n\t * translate each lexems\n\t * @param {[type]} handler [description]\n\t * @return {[type]} [description]\n\t */\n\t_translateLexems(handler) {\n\t\treturn this._transform((sentence) => {\n\t\t\tconst b = new Babelute();\n\t\t\tsentence._lexems.forEach((lexem) => b._use(handler(lexem)));\n\t\t\treturn b;\n\t\t});\n\t}\n\n\t/**\n\t * translate current sentence's lexems through a Lexicon or a map of Lexicon.\n\t * \n\t * @param {Lexicon|Object} lexicon the Lexicon (or a map of Lexicon) to get translation from\n\t * @param {Boolean} firstLevel true if should produce FirstLevel translation (i.e. targetLexicon.FirstLevel). False otherwise.\n\t * @return {Babelute} a new Babelute instance with translated lexems.\n\t */\n\t/* istanbul ignore next */\n\t_translateLexemsThrough(lexicon, firstLevel = false) { // eslint-disable-line no-unused-vars\n\t\t// will be implemented in Lexicon\n\t}\n\n\n\t// static extends(BaseClass, ...apis) {\n\t// \tassert(BaseClass === Babelute || (BaseClass.prototype instanceof Babelute), 'Babelute.extends accepts only a Babelute Class (or subclass) as first argument');\n\t// \tconst B = function(...args) {\n\t// \t\tBaseClass.apply(this, args);\n\t// \t};\n\t// \tB.prototype = Object.create(BaseClass.prototype);\n\t// \tB.prototype.constructor = B;\n\n\t// \tapis.forEach((api) => {\n\t// \t\tfor (var i in api) B.prototype[i] = api[i];\n\t// \t});\n\n\t// \t// Object.assign seems to bug when used on prototype (not investigate enough : so use plain old for-in syntax)\n\t// \t// investigation gives : babel make prototype not enumerable\n\n\t// \treturn B;\n\t// }\n}\n\n/**\n * Create Babelute subclass\n * @param {Babelute} BaseClass the class to be extended\n * @param {?Object} api an object containing methods to add to prototype\n * @return {Babelute} The subclass\n * @throws {AssertionError} (only in dev mode) If BaseClass is not a Babelute Subclass (or Babelute)\n */\nBabelute.extends = extend;\n\n","/*\n* @Author: Gilles Coomans\n*/\nimport assert from 'assert'; // removed in production\nimport Babelute from './babelute';\nimport Lexem from './lexem';\n/**\n * deserialize json to babelute\n * @param {String} json the json string\n * @return {Babelute} the deserialized babelute\n * @throws {Error} If json is badly formated\n */\nexport default function fromJSON(json) {\n\tassert(typeof json === 'string', 'babelute.fromJSON need a string as first argument');\n\treturn JSON.parse(json, (k, v) => {\n\t\tif (v && v.__babelute__)\n\t\t\treturn new Babelute(v._lexems.map((lexem) => {\n\t\t\t\treturn new Lexem(lexem.lexicon, lexem.name, lexem.args);\n\t\t\t}));\n\t\treturn v;\n\t});\n}\n","/**\n * @author Gilles Coomans\n * @licence MIT\n * @copyright 2017 Gilles Coomans\n */\n\nimport assert from 'assert'; // removed in production\nimport Lexem from '../lexem';\nimport Babelute from '../babelute';\n\n/**\n * A FirstLevel is a Babelute that has exactly same api than its corresponding Babelute (from a DSL) but where every compounds methods has been replaced by its \"atomic\" equivalent.\n * (Same concept than 'first-level of understanding', as if we where stupid by always understanding only first literal sens of words.)\n * \n * It provides sentences and lexems without any interpretation, and that could be really useful : e.g.\n * - to see sentence as \"editable document\" and/or for allowing meta-writing of sentences\n * - to obtain the full AST of babelute sentences \n * \n * @access protected\n */\nexport default class FirstLevel extends Babelute {\n\n\t/**\n\t * construct a firstlevel babelute instance\n\t * @param {?Array} lexems array of lexems for init. (only for internal use)\n\t */\n\tconstructor(lexems) {\n\t\tsuper(lexems);\n\t\tthis.__first_level_babelute__ = true;\n\t}\n\n\t/**\n\t * return a FirstLevelMethod aka a method that only append an atom (lexicon, name, args)\n\t * @param {String} lexiconName the lexicon name of the appended atom\n\t * @param {String} lexemName the lexem name of the appended atom\n\t * @return {Function} a function that append the atom\n\t */\n\tstatic getFirstLevelMethod(lexiconName, lexemName) {\n\t\tassert(typeof lexiconName === 'string', 'FirstLevel.getFirstLevelMethod(...) need a string (the lexicon name) as first argument');\n\t\tassert(typeof lexemName === 'string', 'FirstLevel.getFirstLevelMethod(...) need a string (the lexem name) as second argument');\n\t\treturn function (...args) {\n\t\t\tthis._lexems.push(new Lexem(lexiconName, lexemName, args));\n\t\t\treturn this;\n\t\t};\n\t}\n}","/*\n * @Author: Gilles Coomans\n * @Date: 2017-03-10 13:25:25\n * @Last Modified by: Gilles Coomans\n * @Last Modified time: 2017-05-10 11:03:28\n */\n\nimport assert from 'assert'; // removed in production\nimport Babelute from '../babelute';\nimport extend from '../utils/extends';\n\n/**\n * Initializer Class\n * @protected\n */\nclass Initializer {}\n\n/**\n * extends Initializer\n * @param {Class} BaseInitializer the Initializer to extends\n * @return {Class} the extended Initalizer class\n */\nInitializer.extends = extend;\n\n/**\n * create a Initializer (based on a Babelute subclass) and instanciate it\n * @param {Babelute} BabeluteClass a Babelute subclass from where create initializer\n * @param {?Initializer} BaseInitializer a parent initializer to be extended (optional)\n * @return {Initializer} the Initializer instance\n * @protected\n */\nfunction createInitializer(BabeluteClass, BaseInitializer = null) {\n\n\tassert(BabeluteClass === Babelute || (BabeluteClass.prototype instanceof Babelute), 'Lexicon createInitializer accepts only a Babelute Class (or subclass) as first argument');\n\tassert(!BaseInitializer || BaseInitializer === Initializer || (BaseInitializer.prototype instanceof Initializer), 'Lexicon createInitializer accepts only a Initializer Class (or subclass) as second argument');\n\n\tconst Init = BabeluteClass.Initializer = BaseInitializer ? Initializer.extends(BaseInitializer) : Initializer;\n\tBabeluteClass.initializer = new Init();\n\tBabeluteClass.initializer._empty = function() {\n\t\treturn new BabeluteClass();\n\t};\n\tBabeluteClass.initializer.Class = BabeluteClass;\n\tObject.keys(BabeluteClass).forEach((i) => addToInitializer(Init, i));\n\treturn BabeluteClass.initializer;\n}\n\n/**\n * add method to initializer\n * @protected\n * @param {Initializer} Initializer Initializer class where add methods in proto\n * @param {string} methodName the name of method to add\n */\nfunction addToInitializer(Initializer, methodName) {\n\tInitializer.prototype[methodName] = function() {\n\t\treturn new this.Class()[methodName](...arguments);\n\t};\n}\n\n// add base Babelute's api\n['_use', '_each', '_if', '_append', '_lexicon']\n.forEach((methodName) => {\n\taddToInitializer(Initializer, methodName);\n});\n\nexport {\n\tInitializer,\n\tcreateInitializer,\n\taddToInitializer\n};\n\n","/**\n * Babelute Lexicon class and helpers.\n * @author Gilles Coomans\n * @licence MIT\n * @copyright 2016-2017 Gilles Coomans\n */\n\nimport assert from 'assert'; // removed in production\nimport Lexem from '../lexem';\nimport Babelute from '../babelute';\nimport FirstLevel from './first-level';\nimport { addToInitializer, createInitializer } from './initializer';\n\n/**\n * Lexicons dico : where to store public (registered) lexicon\n * @type {Object}\n * @private\n */\nconst lexicons = {};\n\n/**\n * Lexicon class : helpers to store and manage DSL's API.\n * \n * A __Lexicon__ is just an object aimed to handle, store and construct easily a DSL (its lexicon - i.e. the bunch of words that compose it)\n * and its related Atomic/FirstLevel/SecondLevel Babelute subclasses, and their initializers.\n *\n * One DSL = One lexicon.\n *\n * A lexicon could extend another lexicon to manage dialects.\n *\n * You should never use frontaly the constructor (aka never use new Lexicon in your app). Use createLexicon or createDialect in place.\n * \n * @public\n */\nclass Lexicon {\n\n\t/**\n\t * @param {string} name the lexicon name\n\t * @param {?Lexicon} parent an optional parent lexicon to be extended here\n\t */\n\tconstructor(name, parent) {\n\n\t\tassert(typeof name === 'string' && name.length, 'Lexicon constructor need a valid name as first argument'); // all assertions will be removed in production\n\t\tassert(!parent || parent instanceof Lexicon, 'Lexicon constructor second (optional) argument should be another Lexicon that will be used as parent');\n\n\t\t/**\n\t\t * the parent lexicon (if any)\n\t\t * @type {Lexicon}\n\t\t * @public\n\t\t */\n\t\tthis.parent = parent;\n\t\tparent = parent || {};\n\n\t\t/**\n\t\t * the lexicon's name\n\t\t * @type {String}\n\t\t */\n\t\tthis.name = name;\n\n\t\t// the three APIs :\n\t\t/**\n\t\t * interpretable sentences API (finally always made from syntactic/semantic atoms (aka last level))\n\t\t * @type {Babelute}\n\t\t * @protected\n\t\t */\n\t\tthis.Atomic = initClass(parent.Atomic || Babelute);\n\t\t/**\n\t\t * \"document\" sentences API (first level : aka all methods has been replaced by fake atomic methods)\n\t\t * @type {Babelute}\n\t\t * @protected\n\t\t */\n\t\tthis.FirstLevel = initClass(parent.FirstLevel || FirstLevel);\n\t\t/**\n\t\t * AST-provider API aka the whole tree between first level and last level. Never use it directly : its used under the hood by {@link developOneLevel} method.\n\t\t * @type {Babelute}\n\t\t * @protected\n\t\t */\n\t\tthis.SecondLevel = Babelute.extends(parent.SecondLevel || Babelute);\n\n\t\t/**\n\t\t * the secondLevel instance\n\t\t * @type {Babelute}\n\t\t * @protected\n\t\t */\n\t\tthis.secondLevel = new this.SecondLevel();\n\n\t\tif (parent.Atomic)\n\t\t\tObject.keys(parent.Atomic.initializer)\n\t\t\t.forEach((key) => {\n\t\t\t\taddToInitializer(this.Atomic.Initializer, key);\n\t\t\t\taddToInitializer(this.FirstLevel.Initializer, key);\n\t\t\t});\n\t}\n\n\t/**\n\t * add atomic lexem (atoms) to lexicon\n\t * @param {string[]} atomsArray array of atoms name (as string)\n\t * @return {Lexicon} the lexicon itself\n\t */\n\taddAtoms(atomsArray) {\n\n\t\tassert(Array.isArray(atomsArray), 'lexicon.addAtoms(...) need an array as first argument');\n\n\t\tatomsArray.forEach((name) => addAtom(this, name));\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * add compounds lexems to lexicon\n\t * @param {Function} producer a function that take a babelute initializer as argument and that return an object containing methods (lexems) to add to lexicon\n\t * @return {Lexicon} the lexicon itself\n\t */\n\taddCompounds(producer) {\n\n\t\tassert(typeof producer === 'function', 'lexicon.addCompounds(...) need a function (that return an object containing dsl methods) as first argument');\n\n\t\t// Atomic API is produced with Atomic initializer\n\t\tconst atomicMethods = producer(this.Atomic.initializer, false);\n\n\t\tassert(atomicMethods && typeof atomicMethods === 'object', 'lexicon.addCompounds(function(){...}) need a function that return an object containing dsl methods to add');\n\n\t\tfor (let i in atomicMethods)\n\t\t\tthis.Atomic.prototype[i] = atomicMethods[i];\n\n\t\t// SecondLevel API is simply produced with the related FirstLevel initializer. \n\t\t// (so same producer method, same api, but different handler for inner composition)\n\t\t// is the only thing to do to gain capability to handle full AST. (see docs)\n\t\tconst secondLevelCompounds = producer(this.FirstLevel.initializer, true);\n\t\tfor (let j in secondLevelCompounds)\n\t\t\tthis.SecondLevel.prototype[j] = secondLevelCompounds[j];\n\n\t\tObject.keys(atomicMethods)\n\t\t\t.forEach((key) => {\n\t\t\t\tthis.FirstLevel.prototype[key] = FirstLevel.getFirstLevelMethod(this.name, key);\n\t\t\t\taddToInitializer(this.Atomic.Initializer, key);\n\t\t\t\taddToInitializer(this.FirstLevel.Initializer, key);\n\t\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * add aliases lexems to lexicon (aliases are like shortcuts : they are added as this to Atomic, FirstLevel and SecondLevel API)\n\t * @param {Object} methods an object containing methods (lexems) to add to lexicon\n\t * @return {Lexicon} the lexicon itself\n\t */\n\taddAliases(producer) {\n\t\t\n\t\tconst producerType = typeof producer;\n\n\t\tassert(producerType === 'function' || producerType === 'object', 'lexicon.addAliases(...) need a function (that return an object containing aliases methods) as first argument');\n\t\t\n\t\tconst methods = producerType === 'function' ? producer() : producer;\n\n\t\tassert(methods && typeof methods === 'object', 'lexicon.addAliases(function(){...}) need a function that return an object containing aliases methods to add');\n\t\t\n\t\tObject.keys(methods)\n\t\t\t.forEach((key) => {\n\t\t\t\tthis.Atomic.prototype[key] = this.FirstLevel.prototype[key] = this.SecondLevel.prototype[key] = methods[key];\n\t\t\t\taddToInitializer(this.Atomic.Initializer, key);\n\t\t\t\taddToInitializer(this.FirstLevel.Initializer, key);\n\t\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * @protected\n\t */\n\tuse(babelute, name, args, firstLevel) {\n\t\tassert(babelute && babelute.__babelute__, 'lexicon.use(...) need a babelute intance as first argument');\n\t\tassert(typeof name === 'string', 'lexicon.use(...) need a string (a method name) as second argument');\n\n\t\tconst instance = firstLevel ? this.FirstLevel.instance : this.Atomic.instance;\n\n\t\tif (!instance[name])\n\t\t\tthrow new Error(`Babelute (${ this.name }) : method not found : ${ name }`);\n\t\tinstance[name].apply(babelute, args);\n\t}\n\n\t/**\n\t * return lexicon's initializer instance. (atomic or firstlevel depending on argument)\n\t * @public\n\t * @param {Boolean} firstLevel true if you want firstLevel initializer, false overwise.\n\t * @return {Initializer} the needed initializer instance\n\t */\n\tinitializer(firstLevel) {\n\t\treturn firstLevel ? this.FirstLevel.initializer : this.Atomic.initializer;\n\t}\n\n\t/**\n\t * Create a dialect from this lexicon. a dialect is also a Lexicon.\n\t * @param {String} name the new lexicon name\n\t * @return {Lexicon} the new Lexicon that inherit from this one\n\t */\n\tcreateDialect(name) {\n\n\t\tassert(typeof name === 'string', 'lexicon.createDialect(...) need a string (the new lexicon name) as first argument');\n\t\t\n\t\treturn new Lexicon(name, this);\n\t}\n}\n\n/**\n * Add syntactical atom lexem to lexicon (actually to inner classes that reflect API). A syntactical Atom method is a function that only add one lexem.\n * @private\n */\nfunction addAtom(lexicon, name) {\n\tassert(lexicon instanceof Lexicon, 'Lexicon addAtom(...) first argument should be a Lexicon where add syntactical atom');\n\tassert(typeof name === 'string', 'Lexicon addAtom(...) need a string (a method name) as second argument');\n\n\tlexicon.Atomic.prototype[name] = lexicon.FirstLevel.prototype[name] = lexicon.SecondLevel.prototype[name] = FirstLevel.getFirstLevelMethod(lexicon.name, name);\n\taddToInitializer(lexicon.Atomic.Initializer, name);\n\taddToInitializer(lexicon.FirstLevel.Initializer, name);\n}\n\n/**\n * babelute lexicon's Classes initialisation\n * @private\n */\nfunction initClass(BaseClass) {\n\tconst Class = Babelute.extends(BaseClass);\n\tcreateInitializer(Class, BaseClass.Initializer);\n\tClass.instance = new Class();\n\treturn Class;\n}\n\n/**\n * Way to create lexicon instances\n * @public\n * @param {string} name the name of the lexicon\n * @param {Lexicon} parent a lexicon instance as parent for this one (optional)\n * @return {Lexicon} a lexicon instance\n */\nfunction createLexicon(name, parent = null) {\n\treturn new Lexicon(name, parent);\n}\n\n/**\n * getLexicon registred lexicon by name\n * \n * @param {string} lexiconName the lexicon's name\n * @return {Lexicon} the lexicon\n * @throws {Error} If lexicon not found with lexiconName\n */\nfunction getLexicon(lexiconName) {\n\tassert(typeof lexiconName === 'string', 'Lexicon.getLexicon(...) need a string (a lexicon name) as first argument');\n\n\tconst lexicon = lexicons[lexiconName];\n\tif (!lexicon)\n\t\tthrow new Error('lexicon not found : ' + lexiconName);\n\treturn lexicon;\n}\n\n/**\n * registerLexicon lexicon by name\n * @param {Lexicon} lexicon the lexicon instance to registerLexicon\n * @param {?string} name lexicon name (optional : if not provided : use the one from lexicon itself)\n */\nfunction registerLexicon(lexicon, name = null) {\n\tassert(lexicon instanceof Lexicon, 'Lexicon.registerLexicon(...) first argument should be a Lexicon');\n\tassert(!name || typeof name === 'string', 'Lexicon.registerLexicon(...) need a string (a lexicon name) as second argument');\n\n\tlexicons[name || lexicon.name] = lexicon;\n}\n\n/*\n * _lexicon handeling\n */\n\n// implementation of already declared method in Babelute's proto\nBabelute.prototype._lexicon = function(lexiconName) {\n\tassert(typeof lexiconName === 'string', '._lexicon(...) accept only a string (a Lexicon id) as argument');\n\treturn new(getLexicon(lexiconName).Atomic)(this._lexems);\n};\n\nFirstLevel.prototype._lexicon = function(lexiconName) {\n\tassert(typeof lexiconName === 'string', '._lexicon(...) accept only a string (a Lexicon id) as argument');\n\treturn new(getLexicon(lexiconName).FirstLevel)(this._lexems);\n};\n\n/*\n * translation through lexicon (already delcared in Babelute proto)\n * @TODO: translation and each and if\n * each :\n * \t.each(collec, handler)\n * \ttranslated to \n * \t.each(collec, wrap(handler, translationInfos))\n * \t\n * \t==> should translate automatically output from handler\n * if ==> same things : wrap handlers\n * ==> while translating : when lexem.name === \"each\" (or \"if\") (should always be present in target lexicon)\n * \t==> apply wrapping\n */\n\nBabelute.prototype._translateLexemsThrough = function(lexicon, firstLevel = false) {\n\tconst map = (lexicon instanceof Lexicon) ? null : lexicon;\n\treturn this._translateLexems((lexem) => {\n\t\tif (map)\n\t\t\tlexicon = map[lexem.lexicon];\n\t\tif (!lexicon)\n\t\t\treturn null;\n\t\tconst args = translateArgs(lexem.args, lexicon, firstLevel);\n\t\tconst b = new (firstLevel ? lexicon.FirstLevel : lexicon.Atomic)();\n\t\treturn b[lexem.name] && b[lexem.name](...args);\n\t});\n};\n\nfunction translateArgs(args, lexicon, firstLevel){\n\tconst result = [];\n\tfor(let i = 0, len = args.length; i < len; ++i)\n\t\tif(args[i] && args[i].__babelute__)\n\t\t\tresult.push(args[i]._translateLexemsThrough(lexicon, firstLevel));\n\t\telse\n\t\t\tresult.push(args[i]);\n\treturn result;\n}\n\n\n\n/**\n * _use handeling\n */\n\n// implementation of already declared method in Babelute's proto\nBabelute.prototype._use = function(babelute /* could be a string in \"lexiconName:methodName\" format */ , ...args) {\n\tassert(!babelute || typeof babelute === 'string' || babelute.__babelute__);\n\treturn babelute ? use(this, babelute, args, false) : this;\n};\n\n// implementation of already declared method in Babelute's proto\nFirstLevel.prototype._use = function(babelute /* could be a string in \"lexiconName:methodName\" format */ /*, ...args */ ) {\n\tassert(!babelute || typeof babelute === 'string' || babelute.__babelute__);\n\treturn babelute ? use(this, babelute, [].slice.call(arguments, 1), true) : this;\n};\n\nfunction use(self, babelute, args, firstLevel) {\n\tif (typeof babelute === 'string') {\n\t\tconst splitted = babelute.split(':');\n\t\tgetLexicon(splitted[0]).use(self, splitted[1], args, firstLevel);\n\t} else\n\t\tself._lexems = self._lexems.concat(babelute._lexems);\n\treturn self;\n}\n\n\n/**\n * return a new babelute from needed lexicon\n * @param {string} lexiconName the lexicon from where to take api\n * @param {Boolean} asFirstLevel True if it needs to return a FirstLevel instance. False or ommitted : returns an Atomic instance.\n * @return {[type]} the babelute instance (either an Atomic or a FirstLevel)\n * @throws {Error} If lexicon not found with lexiconName\n */\nfunction init(lexiconName, asFirstLevel) {\n\tif (lexiconName)\n\t\treturn new(getLexicon(lexiconName)[asFirstLevel ? 'FirstLevel' : 'Atomic'])();\n\telse if (asFirstLevel)\n\t\treturn new FirstLevel();\n\treturn new Babelute();\n}\n\n/**\n * develop a FirstLevel compounds-words-lexem through SecondLevel API. It returns the FirstLevel sentence corresponding to lexem's semantic developement.\n * @param {Lexem} lexem the lexem to develop\n * @param {?Lexicon} lexicon the optional lexicon to use\n * @return {FirstLevel} the developed sentence\n * @throws {Error} If lexicon not found with lexem.lexicon\n * @throws {Error} If method not found in lexicon\n */\nfunction developOneLevel(lexem, lexicon = null) {\n\tassert(lexem && lexem instanceof Lexem, 'lexicon.developOneLevel(...) need a lexem intance as first argument');\n\tassert(lexicon === null || lexicon instanceof Lexicon, 'lexicon.developOneLevel(...) second argument should be null or an instance of Lexicon');\n\n\tlexicon = lexicon || getLexicon(lexem.lexicon);\n\tassert(lexicon.secondLevel[lexem.name], `lexicon.developOneLevel(...) : lexem\\'s name (${lexem.name}) not found in its own referenced lexicon (${ lexem.lexicon })`);\n\n\treturn lexicon.secondLevel[lexem.name].apply(new lexicon.FirstLevel(), lexem.args);\n}\n\n/**\n * develop a FirstLevel lexem through Atomic API. Return the atomic representation of the lexem (in its own language).\n * @param {Lexem} lexem the lexem to develop\n * @param {?Lexicon} lexicon the optional lexicon to use\n * @return {Babelute} the developed sentence\n * @throws {Error} If lexicon not found with lexem.lexicon\n * @throws {Error} If method not found in lexicon\n */\nfunction developToAtoms(lexem, lexicon = null) {\n\tassert(lexem && lexem instanceof Lexem, 'lexicon.developToAtoms(...) need a lexem intance as first argument');\n\tassert(lexicon === null || lexicon instanceof Lexicon, 'lexicon.developToAtoms(...) second argument should be null or an instance of Lexicon');\n\n\tlexicon = lexicon || getLexicon(lexem.lexicon);\n\n\tassert(lexicon.Atomic.instance[lexem.name], 'lexicon.developToAtoms(...) : lexem\\'s name (${lexem.name}) not found in its own referenced lexicon (${ lexem.lexicon })');\n\n\treturn lexicon.Atomic.instance[lexem.name].apply(new lexicon.Atomic(), lexem.args);\n}\n\n/**\n * Provide Babelute Subclass \"initializer\" object (the one with all the flattened shortcut api for starting sentences easily)\n * @param {string} lexiconName The lexiconName where catch the Babelute Class from where getLexicon or create the initializer object.\n * @param {boolean} asFirstLevel true if should return a first-level instance. false to return an atomic instance.\n * @return {Object} An initializer object with shortcuted API from lexicon's Atomic prototype\n * @throws {Error} If lexicon not found with lexiconName\n */\nfunction initializer(lexiconName, asFirstLevel) {\n\tassert(typeof lexiconName === 'string', 'Babelute.initializer(...) accept only a string (a Lexicon id) as argument');\n\tif (!asFirstLevel)\n\t\treturn getLexicon(lexiconName).Atomic.initializer;\n\treturn getLexicon(lexiconName).FirstLevel.initializer;\n}\n\nexport {\n\tLexicon,\n\tcreateLexicon,\n\tgetLexicon,\n\tregisterLexicon,\n\tinit,\n\tinitializer,\n\tdevelopOneLevel,\n\tdevelopToAtoms,\n\tlexicons\n};\n\n","/**\n * Pragmatics Class : minimal abstract class for homogeneous pragmatics.\n *\n * This is the minimal contract that a pragmatics should satisfy.\n *\n * @author Gilles Coomans\n * @licence MIT\n * @copyright 2016-2017 Gilles Coomans\n */\n\nimport assert from 'assert'; // removed in production\n\n/**\n * Base class to provide homogeneous Pragmatics interface. You should never instanciate a Pragmatics directly with new. use {@link createPragmatics}.\n */\nexport class Pragmatics {\n\n\t/**\n\t * @param {Object} targets initial targets object\n\t * @param {Object} pragmas pragmatics methods to add\n\t */\n\tconstructor(targets, pragmas) {\n\n\t\tassert(typeof targets === 'object', 'Pragmatics constructor need an object (the lexicons targets) as first argument');\n\t\tassert(typeof pragmas === 'object', 'Pragmatics constructor need an object (the pragma\\'s base methods) as second argument');\n\n\t\t/**\n\t\t * targets holder object\n\t\t * @type {Object}\n\t\t * @public\n\t\t */\n\t\tthis._targets = targets;\n\n\t\tif(pragmas)\n\t\t\tthis.addPragmas(pragmas);\n\t}\n\n\t/**\n\t * add methods to pragmatics instance\n\t * @param {Object} pragmas an object containing methods to add\n\t */\n\taddPragmas(pragmas) {\n\n\t\tassert(pragmas && typeof pragmas === 'object', 'pragmatics.addPragmas(...) need a valid object (the methods map to add) as argument');\n\n\t\tfor (const i in pragmas)\n\t\t\t/**\n\t\t\t * @ignore\n\t\t\t */\n\t\t\tthis[i] = pragmas[i];\n\t}\n\n\t/* istanbul ignore next */\n\t/**\n\t * the method used to output a babelute through this pragmatics instance\n\t * @abstract\n\t */\n\t$output( /* ... */ ) {\n\t\t// to be overridden\n\t\tthrow new Error('pragmatics.$output should be implemented in subclasses');\n\t}\n}\n\n/**\n * return a new Pragmatics instance. Do not forget to implement $output before usage.\n * @param {Object} targets initial targets object\n * @param {Object} pragmas pragmatics methods to add\n * @return {Pragmatics} the Pragmatics instance\n */\nexport function createPragmatics(targets = {}, pragmas = {}) {\n\treturn new Pragmatics(targets, pragmas);\n}\n\n","/**\n * @author Gilles Coomans\n * @licence MIT\n * @copyright 2016-2017 Gilles Coomans\n */\n\nimport assert from 'assert'; // removed in production\nimport Babelute from '../babelute';\nimport { Pragmatics } from './pragmatics-core.js';\n\n/**\n * FacadePragmatics : a facade oriented Pragmatics subclass. You should never instanciate a FacadePragmatics directly with new. use {@link createFacadePragmatics}.\n * @example\n * // Remarque : any lexem's method will be of the following format : \n * function(subject, args, ?percolator){\n * \t// return nothing\n * }\n */\nexport class FacadePragmatics extends Pragmatics {\n\n\t/**\n\t * @param {Object} targets initial targets object\n\t * @param {?Object} pragmas pragmatics methods to add\n\t */\n\tconstructor(targets, pragmas) {\n\t\tsuper(targets, pragmas);\n\t}\n\n\t/**\n\t * \"each\" facade implementation\n\t * @param {Object} subject the handled subject\n\t * @param {Array|arguments} args the lexem's args : [ collection:Array, itemHandler:Function ]\n\t * @param {?Object} percolator the sentence's percolator instance\n\t * @return {void} nothing\n\t */\n\teach(subject, args /* collection, itemHandler */ , percolator) {\n\n\t\tassert(typeof subject === 'object', '.each facade pragma need an object as subject (first argument)');\n\t\tassert(!args[0] || Array.isArray(args[0]), '.each facade pragma need an array (or iterable with bracket access) as first args object (first argument passed to lexem)');\n\t\tassert(typeof args[1] === 'function', '.each facade pragma need a function as second args object (second argument passed to lexem)');\n\t\t\n\t\tconst collec = args[0],\n\t\t\titemHandler = args[1];\n\n\t\tif (collec && collec.length) // no supputation on collection kind : use \"for\"\n\t\t\tfor (let i = 0, len = collec.length, item, templ; i < len; ++i) {\n\t\t\t\titem = collec[i];\n\t\t\t\ttempl = itemHandler(item, i);\n\t\t\t\tif (!templ)\n\t\t\t\t\tthrow new Error('.each function should return a sentence.');\n\t\t\t\tthis.$output(subject, templ, percolator);\n\t\t\t}\n\t}\n\n\t/**\n\t * \"if\" facade implementation \n\t * @param {Object} subject the handled subject\n\t * @param {Array|arguments} args the lexem's args : [ conditionIsTrue:Babelute, conditionIsFalse:Babelute ]\n\t * @param {?Object} percolator the sentence's percolator instance\n\t * @return {void} nothing\n\t */\n\tif (subject, args /* trueBabelute, falseBabelute */ , percolator) {\n\n\t\tassert(typeof subject === 'object', '.if facade pragma need an object as subject (first argument)');\n\t\tassert(args[1] instanceof Babelute, '.if facade pragma need an babelute instance as second args object (second argument passed to lexem)');\n\t\tassert(!args[2] || args[2] instanceof Babelute, '.if facade pragma third args object (third argument passed to lexem) (optional) should be a babelute instance');\n\n\t\tif (args[0])\n\t\t\tthis.$output(subject, args[1], percolator);\n\t\telse if (args[2])\n\t\t\tthis.$output(subject, args[2], percolator);\n\t}\n\n\t/**\n\t *\n\t * @override\n\t * @param {Object} subject the subject handle through interpretation\n\t * @param {Babelute} babelute the babelute \"to interpret on\" subject\n\t * @param {Scope} percolator the sentence percolator instance (optional)\n\t * @return {Object} the subject\n\t */\n\t$output(subject, babelute, percolator = null) {\n\n\t\tassert(typeof subject === 'object', '.$output facade pragma need an object as subject (first argument)');\n\t\tassert(babelute instanceof Babelute, '.$output facade pragma need an babelute instance as second argument');\n\t\tassert(!percolator || typeof percolator === 'object', '.$output facade pragma need an (optional) scope instance as third argument');\n\n\t\tfor (let i = 0, lexem, len = babelute._lexems.length; i < len; ++i) {\n\t\t\tlexem = babelute._lexems[i];\n\t\t\tif (this._targets[lexem.lexicon] && this[lexem.name])\n\t\t\t\tthis[lexem.name](subject, lexem.args, percolator);\n\t\t}\n\t\treturn subject;\n\t}\n}\n\n/**\n * create a FacadePragmatics instance\n * @param {Object} targets the pragmatics targets DSL\n * @param {?Object} pragmas the methods to add\n * @return {FacadePragmatics} the facade pragmatics instance\n * @example\n * const myPragmas = babelute.createFacadePragmatics({\n * \t'my-lexicon':true\n * }, {\n * \tfoo(subject, args, percolator){\n * \t\t// do something\n * \t},\n * \tbar(subject, args, percolator){\n * \t\t// do something\n * \t}\n * });\n */\nexport function createFacadePragmatics(targets, pragmas = null) {\n\treturn new FacadePragmatics(targets, pragmas);\n}\n\n","/*\n * @author Gilles Coomans\n * @licence MIT\n * @copyright 2016 Gilles Coomans\n */\n\nimport Lexem from './lexem';\nimport Babelute from './babelute';\nimport fromJSON from './from-json';\n\nimport {\n\tLexicon,\n\tcreateLexicon,\n\tinit,\n\tgetLexicon,\n\tregisterLexicon,\n\tinitializer,\n\tdevelopOneLevel,\n\tdevelopToAtoms,\n\tlexicons\n} from './lexicon/lexicon';\n\nimport FirstLevel from './lexicon/first-level';\nimport { Pragmatics, createPragmatics } from './pragmatics/pragmatics-core';\nimport { FacadePragmatics, createFacadePragmatics } from './pragmatics/facade-pragmatics';\n\nexport default {\n\tcreateLexicon,\n\tcreatePragmatics,\n\tcreateFacadePragmatics,\n\tinit,\n\tinitializer,\n\tgetLexicon,\n\tregisterLexicon,\n\tdevelopOneLevel,\n\tdevelopToAtoms,\n\tfromJSON,\n\tBabelute,\n\tLexem,\n\tFirstLevel,\n\tPragmatics,\n\tFacadePragmatics,\n\tLexicon,\n\tlexicons\n};\n\n"],"names":["Lexem","lexicon","name","args","extend","BaseClass","B","apply","prototype","Object","create","constructor","apis","forEach","api","i","Babelute","lexems","_lexems","__babelute__","lexiconName","push","condition","babelute","elseBabelute","concat","array","func","item","index","b","handler","_transform","sentence","lexem","_use","firstLevel","extends","fromJSON","json","JSON","parse","k","v","map","FirstLevel","__first_level_babelute__","lexemName","Initializer","createInitializer","BabeluteClass","BaseInitializer","Init","initializer","_empty","Class","keys","addToInitializer","methodName","arguments","lexicons","Lexicon","parent","Atomic","initClass","SecondLevel","secondLevel","key","atomsArray","addAtom","producer","atomicMethods","secondLevelCompounds","j","getFirstLevelMethod","producerType","methods","instance","Error","createLexicon","getLexicon","registerLexicon","_lexicon","_translateLexemsThrough","_translateLexems","translateArgs","result","len","length","use","slice","call","self","splitted","split","init","asFirstLevel","developOneLevel","developToAtoms","Pragmatics","targets","pragmas","_targets","addPragmas","createPragmatics","FacadePragmatics","subject","percolator","collec","itemHandler","templ","$output","createFacadePragmatics"],"mappings":"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