diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/binops.js | 33 | ||||
-rw-r--r-- | lib/doml.js | 220 | ||||
-rw-r--r-- | lib/readability.js | 38 | ||||
-rw-r--r-- | lib/run.js | 20 | ||||
-rw-r--r-- | lib/statements.js | 74 | ||||
-rw-r--r-- | lib/types.js | 22 | ||||
-rw-r--r-- | lib/util.js | 13 |
7 files changed, 220 insertions, 200 deletions
diff --git a/lib/binops.js b/lib/binops.js deleted file mode 100644 index a709097..0000000 --- a/lib/binops.js +++ /dev/null @@ -1,33 +0,0 @@ -var binaryOperators = { - '!=': function(a, b) { - return a != b; - }, - - '<': function(a, b) { - return a < b; - }, - - '>': function(a, b) { - return a > b; - }, - - '-': function(a, b) { - return a - b; - }, - - '+': function(a, b) { - return a + b; - }, - - '==': function(a, b) { - return a == b; - }, - - '<=': function(a, b) { - return a <= b; - }, - - '>=': function(a, b) { - return a >= b; - } -}; diff --git a/lib/doml.js b/lib/doml.js new file mode 100644 index 0000000..332a17e --- /dev/null +++ b/lib/doml.js @@ -0,0 +1,220 @@ +(function() { + var listFromHtmlCollection = function(collection) { + var lst = []; + for (var idx = 0; idx < collection.length; idx++) { + lst.push(collection[idx]); + } + return lst; + }; + + var DomlEvaluator = function() { + var me = this; + + // members of the Types object are functions that take a string and return + // an appropriate value as a native type + me.Types = { + 'number': function(val) { + if (val.indexOf('.')) { + return parseFloat(val); + } else { + return parseInt(val, 10); + } + }, + + 'string': function(val) { + return val; + }, + + 'boolean': function(val) { + if (val === 'true') { + return true; + } + if (val === 'false') { + return false; + } + throw new Error('Invalid boolean value ' + val); + } + }; + + // members of the BinaryOperators object are functions that take two arguments + // and return the result of that operation + me.BinaryOperators = { + '!=': function(a, b) { + return a != b; + }, + + '<': function(a, b) { + return a < b; + }, + + '>': function(a, b) { + return a > b; + }, + + '-': function(a, b) { + return a - b; + }, + + '+': function(a, b) { + return a + b; + }, + + '==': function(a, b) { + return a == b; + }, + + '<=': function(a, b) { + return a <= b; + }, + + '>=': function(a, b) { + return a >= b; + } + }; + + // members of the Statements object are functions that take a dataset, children, and context + // and return the result of the statement + me.Statements = { + 'statement-sequence': function(dataset, children, context) { + var retval = null; + children.forEach(function(child) { + retval = me.evaluate(child, context); + }); + return retval; + }, + + 'while': function(dataset, children, context) { + var condition = children[0]; + var body = children[1]; + while (me.evaluate(condition, context)) { + me.evaluate(body, context); + } + }, + + 'compare': function(dataset, children, context) { + var operator = me.BinaryOperators[dataset.op]; + var lhs = me.evaluate(children[0], context); + var rhs = me.evaluate(children[1], context); + var result = operator(lhs, rhs); + return result; + }, + + 'variable': function(dataset, children, context) { + return context[dataset.name]; + }, + + 'constant': function(dataset, children, context) { + return me.Types[dataset.type](dataset.val); + }, + + 'branch': function(dataset, children, context) { + if (me.evaluate(children[0], context)) { + return me.evaluate(children[1], context); + } else if (children.length > 2) { + return me.evaluate(children[2], context); + } + }, + + 'assign': function(dataset, children, context) { + context[dataset.name] = me.evaluate(children[0], context); + return context[dataset.name]; + }, + + 'bin-op': function(dataset, children, context) { + var operator = me.BinaryOperators[dataset.op]; + var lhs = me.evaluate(children[0], context); + var rhs = me.evaluate(children[1], context); + return operator(lhs, rhs); + }, + + 'return': function(dataset, children, context) { + return me.evaluate(children[0], context); + }, + + 'print': function(dataset, children, context) { + var args = children.map(function(child) { + return me.evaluate(child, context); + }); + console.log.apply(this, args); + } + }; + + // members of the Readability object are functions which take an element + // and return an array of additional text nodes which should be added + // to enhance readability + me.Decorators = { + 'assign': function(e) { + return [ e.dataset.name ]; + }, + + 'variable': function(e) { + return [ e.dataset.name ]; + }, + + 'constant': function(e) { + return [ e.dataset.type + '(' + e.dataset.val + ')' ]; + }, + + 'compare': function(e) { + return [ e.dataset.op ]; + }, + + 'bin-op': function(e) { + return [ e.dataset.op ]; + } + }; + + me.evaluate = function(node, context) { + if (typeof context === 'undefined') { + context = {}; + } + var value = me.Statements[node.className](node.dataset, listFromHtmlCollection(node.children), context); + return value; + }; + + me.appendText = function(node, text) { + var n = document.createElement('var'); + n.innerText = text; + node.appendChild(n); + }; + + me.decorate = function(root) { + var classes = Object.keys(me.Decorators); + for (var idx = 0; idx < classes.length; idx++) { + var klass = classes[idx]; + var els = listFromHtmlCollection(root.getElementsByClassName(klass)); + els.forEach(function(el) { + me.Decorators[klass](el).forEach(function(text) { + me.appendText(el, text); + }); + }); + } + }; + + me.run = function(root) { + var t0 = performance.now(); + me.evaluate(root); + var t1 = performance.now(); + me.decorate(root); + console.debug('Evaluated DOML program in ' + (t1 - t0) + 'ms'); + } + }; + + var Doml = { + Evaluator: DomlEvaluator, + runOnLoad: function(root) { + document.addEventListener('DOMContentLoaded', function() { + (new DomlEvaluator()).run(document.body.children[0]); + }); + } + }; + + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = Doml; + } else if (typeof window !== 'undefined') { + window.Doml = Doml; + } else { + throw new Error('Unable to register Doml'); + } +})(); + diff --git a/lib/readability.js b/lib/readability.js deleted file mode 100644 index 06eb4ad..0000000 --- a/lib/readability.js +++ /dev/null @@ -1,38 +0,0 @@ -var appendText = function(node, text) { - var n = document.createElement('var'); - n.innerText = text; - node.appendChild(n); -}; - -var readability = { - 'assign': function(e) { - return e.dataset.name; - }, - - 'variable': function(e) { - return e.dataset.name; - }, - - 'constant': function(e) { - return e.dataset.type + '(' + e.dataset.val + ')'; - }, - - 'compare': function(e) { - return e.dataset.op; - }, - - 'bin-op': function(e) { - return e.dataset.op; - } -}; - -var makeReadable = function(root) { - var classes = Object.keys(readability); - for (var idx = 0; idx < classes.length; idx++) { - var klass = classes[idx]; - var els = root.getElementsByClassName(klass); - els.forEach(function(el) { - appendText(el, readability[klass](el)); - }); - } -}; diff --git a/lib/run.js b/lib/run.js deleted file mode 100644 index 92441a2..0000000 --- a/lib/run.js +++ /dev/null @@ -1,20 +0,0 @@ -(function() { - var evaluate = function(node, context) { - if (typeof context === 'undefined') { - context = {}; - } - return statementEvaluators[node.className](node.dataset, node.children, context); - }; - - var statementEvaluators = getStatementEvaluators(evaluate); - - document.addEventListener('DOMContentLoaded', function() { - var t0 = performance.now(); - evaluate(document.body.children[0]); - var t1 = performance.now(); - makeReadable(document.body); - var t2 = performance.now(); - console.debug('Evaluated in ' + (t1 - t0) + 'ms'); - console.debug('Rendered in ' + (t2 - t1) + 'ms'); - }); -})(); diff --git a/lib/statements.js b/lib/statements.js deleted file mode 100644 index b59c08f..0000000 --- a/lib/statements.js +++ /dev/null @@ -1,74 +0,0 @@ -var getStatementEvaluators = function(evaluate) { - return { - 'statement-sequence': function(dataset, children, context) { - var retval = null; - children.forEach(function(child) { - retval = evaluate(child, context); - }); - return retval; - }, - - 'while': function(dataset, children, context) { - var condition = children[0]; - var body = children[1]; - while (evaluate(condition, context)) { - evaluate(body, context); - } - }, - - 'compare': function(dataset, children, context) { - var operator = binaryOperators[dataset.op]; - var lhs = evaluate(children[0], context); - var rhs = evaluate(children[1], context); - var result = operator(lhs, rhs); - return result; - }, - - 'variable': function(dataset, children, context) { - return context[dataset.name]; - }, - - 'constant': function(dataset, children, context) { - return stringToType(dataset.val, dataset.type); - }, - - 'branch': function(dataset, children, context) { - var condition = children[0]; - var ifBody = children[1]; - - // else is optional - if (children.length > 2) { - var elseBody = children[2]; - } - - if (evaluate(condition, context)) { - return evaluate(ifBody, context); - } else if (elseBody) { - return evaluate(elseBody, context); - } - }, - - 'assign': function(dataset, children, context) { - context[dataset.name] = evaluate(children[0], context); - return context[dataset.name]; - }, - - 'bin-op': function(dataset, children, context) { - var operator = binaryOperators[dataset.op]; - var lhs = evaluate(children[0], context); - var rhs = evaluate(children[1], context); - return operator(lhs, rhs); - }, - - 'return': function(dataset, children, context) { - return evaluate(children[0], context); - }, - - 'print': function(dataset, children, context) { - var args = children.map(function(child) { - return evaluate(child, context); - }); - console.log.apply(this, args); - } - }; -}; diff --git a/lib/types.js b/lib/types.js deleted file mode 100644 index 38e2b60..0000000 --- a/lib/types.js +++ /dev/null @@ -1,22 +0,0 @@ -var stringToType = function(str, type) { - switch (type) { - case 'number': - if (str.indexOf('.')) { - return parseFloat(str); - } else { - return parseInt(str, 10); - } - case 'string': - return str; - case 'boolean': - if (str === 'true') { - return true; - } else if (str === 'false') { - return false; - } else { - throw new Error('Invalid boolean value ' + str); - } - default: - throw new Error('type', type, 'is not defined'); - } -}; diff --git a/lib/util.js b/lib/util.js deleted file mode 100644 index 3c6857c..0000000 --- a/lib/util.js +++ /dev/null @@ -1,13 +0,0 @@ -HTMLCollection.prototype.map = function(fn) { - var results = []; - for (var idx = 0; idx < this.length; idx++) { - results.push(fn(this.item(idx))); - } - return results; -}; - -HTMLCollection.prototype.forEach = function(fn) { - for (var idx = 0; idx < this.length; idx++) { - fn(this.item(idx)); - } -}; |