From 9bc76cfc6df24f4b5621294e1496388a9f71612b Mon Sep 17 00:00:00 2001 From: Simeon Chaos Date: Thu, 6 Mar 2014 15:41:21 +0800 Subject: [PATCH] gulpfile.coffee is modified heavily. gulpfile.coffee is modified heavily, tested gulp-twoside.js is copied from twoside project --- coffee/deprecated/autopeasy.coffee | 519 ------ coffee/deprecated/logic.coffee | 327 ---- coffee/deprecated/modularpeasy.coffee | 372 ----- coffee/deprecated/nonmodularpeasy.coffee | 587 ------- coffee/index.coffee | 34 + coffee/lineparser.coffee | 16 + coffee/logicparser.coffee | 290 ++++ coffee/logicpeasy.coffee | 294 ---- coffee/parser.coffee | 240 +++ coffee/peasy.coffee | 271 --- coffee/samples/arithmatic.coffee | 427 +++-- coffee/samples/arithmatic2.coffee | 381 +++-- coffee/samples/dsl.coffee | 99 +- coffee/samples/latex.coffee | 73 +- coffee/samples/statemachine.coffee | 83 +- coffee/test/karma-conf.coffee | 17 +- .../karma/deprecated/testautopeasy.coffee | 79 - coffee/test/karma/deprecated/testlogic.coffee | 61 - .../karma/deprecated/testmodularpeasy.coffee | 139 -- .../deprecated/testnonmodularpeasy.coffee | 86 - coffee/test/karma/karma-bundle.coffee | 5 + .../test/karma/samples/testarithmatic.coffee | 115 +- .../test/karma/samples/testarithmatic2.coffee | 119 +- coffee/test/karma/samples/testdsl.coffee | 125 +- coffee/test/karma/testlogicparser.coffee | 72 + coffee/test/karma/testlogicpeasy.coffee | 75 - coffee/test/karma/testparser.coffee | 134 ++ coffee/test/karma/testpeasy.coffee | 137 -- .../{testpeasy.coffee => testparser.coffee} | 4 +- coffee/twoside.coffee | 39 +- gruntfile.coffee | 61 - gulp-twoside.js | 25 + gulpfile.coffee | 131 ++ gulpfile.js | 2 + js/deprecated/autopeasy.js | 797 --------- js/deprecated/logic.js | 649 -------- js/deprecated/modularpeasy.js | 620 ------- js/deprecated/nonmodularpeasy.js | 710 -------- js/index.js | 66 + js/lineparser.js | 45 + js/logicparser.js | 636 +++++++ js/logicpeasy.js | 619 ------- js/logicpeasy.min.js | 1 - js/parser.js | 474 ++++++ js/peasy-min.js | 31 + js/peasy.js | 1475 ++++++++++++----- js/peasy.min.js | 1 - js/samples/arithmatic.js | 671 ++++---- js/samples/arithmatic2.js | 710 ++++---- js/samples/dsl.js | 110 +- js/samples/latex.js | 130 +- js/samples/statemachine.js | 157 +- js/test/karma-conf.js | 2 +- js/test/karma/deprecated/testautopeasy.js | 104 -- js/test/karma/deprecated/testlogic.js | 111 -- js/test/karma/deprecated/testmodularpeasy.js | 205 --- .../karma/deprecated/testnonmodularpeasy.js | 108 -- js/test/karma/karma-bundle.js | 14 + js/test/karma/samples/testarithmatic.js | 164 +- js/test/karma/samples/testarithmatic2.js | 174 +- js/test/karma/samples/testdsl.js | 205 +-- js/test/karma/testlogicparser.js | 131 ++ js/test/karma/testlogicpeasy.js | 132 -- js/test/karma/testparser.js | 247 +++ js/test/karma/testpeasy.js | 236 --- js/test/mocha/{testpeasy.js => testparser.js} | 101 +- js/twoside.js | 50 +- js/twoside.min.js | 1 - package.json | 9 +- 69 files changed, 5661 insertions(+), 9674 deletions(-) delete mode 100644 coffee/deprecated/autopeasy.coffee delete mode 100644 coffee/deprecated/logic.coffee delete mode 100644 coffee/deprecated/modularpeasy.coffee delete mode 100644 coffee/deprecated/nonmodularpeasy.coffee create mode 100644 coffee/index.coffee create mode 100644 coffee/lineparser.coffee create mode 100644 coffee/logicparser.coffee delete mode 100644 coffee/logicpeasy.coffee create mode 100644 coffee/parser.coffee delete mode 100644 coffee/peasy.coffee delete mode 100644 coffee/test/karma/deprecated/testautopeasy.coffee delete mode 100644 coffee/test/karma/deprecated/testlogic.coffee delete mode 100644 coffee/test/karma/deprecated/testmodularpeasy.coffee delete mode 100644 coffee/test/karma/deprecated/testnonmodularpeasy.coffee create mode 100644 coffee/test/karma/karma-bundle.coffee create mode 100644 coffee/test/karma/testlogicparser.coffee delete mode 100644 coffee/test/karma/testlogicpeasy.coffee create mode 100644 coffee/test/karma/testparser.coffee delete mode 100644 coffee/test/karma/testpeasy.coffee rename coffee/test/mocha/{testpeasy.coffee => testparser.coffee} (98%) delete mode 100644 gruntfile.coffee create mode 100644 gulp-twoside.js create mode 100644 gulpfile.coffee create mode 100644 gulpfile.js delete mode 100644 js/deprecated/autopeasy.js delete mode 100644 js/deprecated/logic.js delete mode 100644 js/deprecated/modularpeasy.js delete mode 100644 js/deprecated/nonmodularpeasy.js create mode 100644 js/index.js create mode 100644 js/lineparser.js create mode 100644 js/logicparser.js delete mode 100644 js/logicpeasy.js delete mode 100644 js/logicpeasy.min.js create mode 100644 js/parser.js create mode 100644 js/peasy-min.js delete mode 100644 js/peasy.min.js delete mode 100644 js/test/karma/deprecated/testautopeasy.js delete mode 100644 js/test/karma/deprecated/testlogic.js delete mode 100644 js/test/karma/deprecated/testmodularpeasy.js delete mode 100644 js/test/karma/deprecated/testnonmodularpeasy.js create mode 100644 js/test/karma/karma-bundle.js create mode 100644 js/test/karma/testlogicparser.js delete mode 100644 js/test/karma/testlogicpeasy.js create mode 100644 js/test/karma/testparser.js delete mode 100644 js/test/karma/testpeasy.js rename js/test/mocha/{testpeasy.js => testparser.js} (77%) delete mode 100644 js/twoside.min.js diff --git a/coffee/deprecated/autopeasy.coffee b/coffee/deprecated/autopeasy.coffee deleted file mode 100644 index c6c20ed..0000000 --- a/coffee/deprecated/autopeasy.coffee +++ /dev/null @@ -1,519 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/deprecated/autopeasy') -do (require=require, exports=exports, module=module) -> -# The two lines above make this module can be used both in browser(with twoside.js) and on node.js - - # # Peasy - # ## Peasy means parsing is easy - # ### an easy but powerful parser - # With Peasy, you write the parser by hand, just like to write any other kind of program. - # You need not play ![many balls like that any more.](https://raw.github.com/chaosim/peasy/master/doc/ballacrobatics.jpg) - # You just play ![one ball like so!](https://raw.github.com/chaosim/peasy/master/doc/dolphinball.jpg), - - # Peasy provided two method to tell which symbol is left recursive. - # here is the automiatic method: - # You just write your rules normally at first. before parsing, you first call intialize() and autoComputeLeftRecursives(grammar), - # and then everything about left recursive symbols is automatic computed. - - # ### global variables - # It is for the performace that I use global variables, and I provided another version which have Parser class for - # people who prefer more modular to speed. - - # some global variable used while parsing - - text = '' # the text which is being parsed, this could be any sequence, not only strincs. - textLength = 0 # the length of text - cursor = 0 # the current position of parsing, use text[cursor] to get current character in parsed stream - - grammar = undefined # the grammar object which contains all of rules defined for the symbol in grammar. - originalRules = {} # saved the original rules of the grammar. - - # store the wrapped function to rule of the left recursive symbol, and before entering them, store it in grammar too. - # when entering them, grammar[symbol] is unwrapped to originalRules[symbol] or memorizeRecursives[symbol] - recursiveRules = {} - memorizedRecursivs = {} - memoRules = {} - symbolDescedentsMap = {} - - symbolToTagMap = {} # {symbol: tag}, from rule symbol map to a shorter memo tag, for memory efficeny - tags = {} # {tag: true}, record tags that has been used to avoid conflict - parseCache = {} # {tag+start: [result, cursor]}, memorized parser result - functionCache = {} # memorized normal function result - - hasOwnProperty = Object.hasOwnProperty - - # call intialize() at first - exports.initialize = () -> - parseCache = {} - functionCache = {} - originalRules = {} - recursiveRules = {} - memorizedRecursivs = {} - memoRules = {} - symbolDescedentsMap = {} - symbolToTagMap = {} - tags = {} - parseCache = {} - - # parse @data from @root with @aGrammar function @root - exports.parse = (data, aGrammar, root) -> - text = data - textLength = text.length - cursor = 0 - root = root or aGrammar.rootSymbol - grammar = aGrammar - grammar[root](0) - - # Peasy provided two method to tell which symbol is left recursive. - # - - # check whether property = @grammar[@name] is a grammar rule? - # if property is not function, or property(undefined) does not change cursor to a nonzero, then it is not rule. - # the property is a combinator like andp, any and so on, property('') will not touch cursor, - # so cursor should keep its value unchanged. - isRule = (grammar, name) -> - if hasOwnProperty.call(functionCache, name) then return functionCache[name] - if not hasOwnProperty.call(grammar, name) then result = false - else - property = grammar[name] - if typeof(property)!= "function" then result = false - else - try if typeof(property(spaces))=="function" then result = false - catch e then result = true - functionCache[name] = result - result - - # automatic compute left recursive rules - exports.autoComputeLeftRecursives = computeLeftRecursives = (grammar) -> - originalRules = {} - for symbol of grammar - if not isRule(grammar, symbol) then break - originalRules[symbol] = grammar[symbol] - parentToChildren = {} - currentLeftHand = null # declare a closure variable for probe function - # replace every grammar symbol's rule with a probe function - # by running this probe function, the parent-children left call relation will be built up automaticlly. - for symbol of grammar - if not isRule(grammar, symbol) then break - do (symbol = symbol) -> - grammar[symbol] = (start) -> - if start!=0 then return - else - cursor++ - children = parentToChildren[currentLeftHand] ?= [] - if symbol not in children then children.push symbol - for symbol of grammar - if not isRule(grammar, symbol) then break - currentLeftHand = symbol - originalRules[symbol](0) - # find all left recursives circles in grammar. - appendToPaths = (symbol, meetTable, paths) -> - if not (chidlren = parentToChildren[symbol]) then return - for child in chidlren - for path in paths - length = path.length - if length>1 and path[length-1]==path[0] then continue - else if child in path - if child==path[0] then path.push child - else continue - else path.push child - if not meetTable[child] then appendToPaths(child, meetTable, paths) - symbolPathsMap = {} - for symbol of grammar - if not isRule(grammar, symbol) then break - meetTable = {}; meetTable[symbol] = true - paths = symbolPathsMap[symbol] ?= [[symbol]] - appendToPaths(symbol, meetTable, paths) - i = 0 - pathsCount = paths.length - circles = [] - while i - (start) -> - for child in symbolDescedentsMap[symbol] - memoRule = memorizedRecursivs[child] - if memoRule then grammar[child] = memoRule - else grammar[child] = originalRules[child] - hash = symbol+start - m = parseCache[hash] ?= [undefined, -1] - if m[1]>=0 then cursor = m[1]; return m[0] - rule = grammar[symbol] - while 1 - result = rule(start) - if m[1]<0 - m[0] = result - if result then m[1] = cursor - else m[1] = start - continue - else - if m[1]==cursor then m[0] = result; return result - else if cursor - rule = originalRules[symbol] - (start) -> - descendents = symbolDescedentsMap[symbol] - for child in descendents - grammar[child] = memoRules[child] - result = rule(start) - for child in descendents - memoRecursive = memorizedRecursivs[child] - if memoRecursive then grammar[child] = memoRecursive - else grammar[child] = originalRules[child] - result - - # some utilities used by the parser - # on succeed any matcher should not return a value which is not null or undefined, except the root symbol. - - # set a shorter start part of symbol as the tag used in parseCache - setMemoTag = (symbol) -> - i = 1 - while 1 - if hasOwnProperty.call(tags, symbol.slice(0, i)) in tags then i++ - else break - tag = symbol.slice(0, i) - symbolToTagMap[symbol] = tag - tags[tag] = true - - # set the symbols in grammar which memorize their rule's result. - setMemorizeRules = (grammar, symbols) -> - for symbol in symbols - originalRules[symbol] = grammar[symbol] - grammar[symbol] = memorize(symbol) - - # memorize result and cursor for @symbol which is not left recursive. - # left recursive should be wrapped by recursive(symbol)!!! - memorize = (symbol) -> - tag = symbolToTagMap[symbol] - rule = originalRules[symbol] - (start) -> - hash = tag+start - m = parseCache[hash] - if m then cursor = m[1]; m[0] - else - result = rule(start) - parseCache[hash] = [result, cursor] - result - - # lookup the memorized result and reached cursor for @symbol at the position of @start - exports.memo = memo = (symbol) -> - (start) -> - hash = symbol+start - m = parseCache[hash] - if m then m[0] - - # compute exps in sequence, return the result of the last one. - # andp and orp are used to compose the matchers - # the effect is the same as by using the Short-circuit evaluation, like below: - # exps[0](start) and exps[2](cursor] ... and exps[exps.length-1](cursor) - exports.andp = (exps) -> - exps = for exp in exps - if isString(exp) then literal(exp) else exp - (start) -> - cursor = start - for exp in exps - if not(result = exp(cursor)) then return - return result - - # compute exps in parallel, return the result of the first which is not evaluated to false. - # the effect is the same as by using the Short-circuit evaluation, like below: - # exps[0](start) or exps[2](cursor] ... or exps[exps.length-1](cursor) - exports.orp = (exps...) -> - exps = for exp in exps - if isString(exp) then literal(exp) else exp - (start) -> - for exp in exps - if result = exp(start) then return result - return result - - # applicaton of not operation - # notp is not useful except to compose the matchers. - # It's not unnessary, low effecient and ugly to write "notp(exp)(start)", - # so don't write "notp(exp)(start)", instead "not exp(start)". - exports.notp = (exp) -> - if isString(exp) then exp = literal(exp) - (start) -> not exp(start) - - # any: zero or more times of @exp(start) - exports.any = (exp) -> - if isString(exp) then exp = literal(exp) - (start) -> - result = []; cursor = start - while ( x = exp(cursor)) then result.push(x) - result - - # any: one or more times of @exp(start) - exports.some = (exp) -> - if isString(exp) then exp = literal(exp) - (start) -> - result = []; cursor = start - - if not (x = exp(cursor)) then return x - while 1 - result.push(x) - x = exp(cursor) - if not x then break - result - - # maybe exp(start) - exports.may = exports.optional = (exp) -> - if isString(exp) then exp = literal(exp) - (start) -> - cursor = start - if x = exp(cursor) then x - else cursor = start; true - - # follow exp(start)? - # whether succeed or not, cursor is reset to start - exports.follow = (exp) -> - if isString(exp) then exp = literal(exp) - (start) -> - cursor = start - if x = exp(cursor) then cursor = start; x - - # given @n times @exp, n>=1 - exports.times = (exp, n) -> - if isString(exp) then exp = literal(exp) - (start) -> - cursor = start; i = 0 - while i++ - if isString(exp) then exp = literal(exp) - if isString(separator) then separator = literal(separator) - (start) -> - cursor = start - result = [] - x = exp(cursor) - if not x then return - while 1 - result.push(x) - if not(x = exp(cursor)) then break - result - - # given @n times @exp separated by @separator, n>=1 - exports.timesSeperatedList = (exp, n, separator=spaces) -> - if isString(exp) then exp = literal(exp) - if isString(separator) then separator = literal(separator) - (start) -> - cursor = start - result = [] - x = exp(cursor) - if not x then return - i = 1 - while i++ (start) -> - if text[start]==c then cursor = start+1; return c - - exports.char_ = (c) -> () -> - if text[cursor]==c then cursor++; return c - - # match a literal string. - exports.literal = literal = (string) -> (start) -> - len = string.length - if text.slice(start, stop = start+len)==string then cursor = stop; true - - exports.literal_ = literal_ = (string) -> (start) -> - len = string.length - if text.slice(cursor, stop = cursor+len)==string then cursor = stop; true - - # In spaces, spaces_, spaces1, spaces1_, a tat('\t') is seen as tabWidth spaces, - # which is used in indent style language, such as coffeescript, python, haskell, etc. - # If you don't need this feature, you can rewrite these utilities to remove the code about tab width by yourself easily. - - # zero or more whitespaces, ie. space or tab. - exports.spaces = (start) -> - len = 0 - cursor = start - text = text - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - return len - - # faster version, do not pass @start as parameter - # zero or more whitespaces, ie. space or tab. - exports.spaces_ = () -> - len = 0 - text = text - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - len - - # one or more whitespaces, ie. space or tab. - exports.spaces1 = (start) -> - len = 0 - cursor = start - text = text - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - if len then return cursor = cursor; len - - # faster version, do not pass @start as parameter - # one or more whitespaces, ie. space or tab. - exports.spaces1_ = () -> - len = 0 - cursor = start - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - if len then return cursor = cursor; len - - exports.wrap = (item, left=spaces, right=spaces) -> - if isString(item) then item = literal(item) - (start) -> - if left(start) and result = item(cursor) and right(cursor) then result - - exports.getcursor = exports.cur = () -> cursor - - exports.setcursor = exports.setcur = (pos) -> cursor = pos - - # is a letter used in identifer? - # follow word such as return, break, etc. - # javascript style, '$' is a identifierLetter_ - identifierLetter = (start) -> - start = cursor - c = text[cursor] - if c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - cursor++; true - - # is a letter used in identifer? - # javascript style, '$' is a identifierLetter_ - identifierLetter_ = () -> - c = text[cursor] - if c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - cursor++; true - - # lookahead whether the following character is a letter used in identifer, don't change cursor? - # javascript style, '$' is a identifierLetter_ - followIdentifierLetter_ = () -> - c = text[cursor] - c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - - isIdentifierLetter = (c) -> 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='$' or 'c'=='_' - - ObjecttoString = Object.prototype.toString - exports.isString = isString = (x) -> ObjecttoString.call(x) is '[object String]' - - exports.isdigit = (c) -> '0'<=c<='9' - exports.digit = (start) -> - c = text[start]; if '0'<=c<='9' then cursor = start+1 - #faster version, do not pass @start as parameter - exports.digit_ = () -> - c = text[cursor]; if '0'<=c<='9' then cursor++ - - exports.isletter = exports.isalpha = (c) -> 'a'<=c<='z' or 'A'<=c<='Z' - exports.letter = exports.alpha = (start) -> - c = text[start]; if 'a'<=c<='z' or 'A'<=c<='Z' then cursor = start+1 - #faster version, do not pass @start as parameter - exports.letter_ = exports.alpha_ = () -> - c = text[cursor]; if 'a'<=c<='z' or 'A'<=c<='Z' then cursor++ - - exports.islower = (c) -> 'a'<=c<='z' - exports.lower = (start) -> - c = text[start]; if 'a'<=c<='z' then cursor = start+1 - #faster version, do not pass @start as parameter - exports.lower_ = () -> - c = text[cursor]; if 'a'<=c<='z' then cursor++ - - exports.isupper = (c) ->'A'<=c<='Z' - exports.upper = (start) -> - c = text[start]; if 'A'<=c<='Z' then cursor = start+1 - #faster version, do not pass @start as parameter - exports.upper_ = (start) -> - c = text[cursor]; if 'A'<=c<='Z' then cursor++ - - exports.identifier = (start) -> - cursor = start - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or 'c'=='$' or 'c'=='_' then cursor++ - else return - while 1 - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='$' or 'c'=='_' then cursor++ - else break - true - - # faster version, do not pass @start as parameter - exports.identifier = (start) -> - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or 'c'=='$' or 'c'=='_' then cursor++ - else return - while 1 - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='$' or 'c'=='_' then cursor++ - else break - true - - # The untilites above is just for providing some examples on how to write matchers for Peasy. - # In fact, It's realy easy peasy to write any matchers for your grammar. - # http://en.wiktionary.org/wiki/easy_peasy - # you can embedde your grammar rules with other features seamless, - # such as lexer, rewriter, semantic action, error process( error reporting, error recovering) - # you can dynamicly modify your parser's grammar rules, dynamic update the parsed text, if you wish. - - # With the method provided by Peasy, you can parse stream which is not text or stream, - # including list, binary stream, or other data structure, like tree, graph, and so on. diff --git a/coffee/deprecated/logic.coffee b/coffee/deprecated/logic.coffee deleted file mode 100644 index 4d75e3e..0000000 --- a/coffee/deprecated/logic.coffee +++ /dev/null @@ -1,327 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/deprecated/logic') -do (require=require, exports=exports, module=module) -> -# The two lines above make this module can be used both in browser(with twoside.js) and on node.js - - # logic dependency for peasy - - exports.Error = class Error - constructor: (@exp, @message='', @stack = @) -> # @stack: to make webstorm nodeunit happy. - toString: () -> "#{@constructor.name}: #{@exp} >>> #{@message}" - - exports.BindingError = class BindingError extends Error - - # record the trail for variable binding
- # when multiple choices exist, a new Trail for current branch is constructored,
- # when backtracking, undo the trail to restore the previous variable binding - # todo: when variable is new constrctored in current branch, it should not be recorded. - exports.Trail = class Trail - constructor: (@data={}) -> - copy: () -> new Trail(_.extend({},@data)) - set: (vari, value) -> - data = @data - if not data.hasOwnProperty(vari.name) - data[vari.name] = [vari, value] - - undo: () -> for nam, pair of @data then pair[0].binding = pair[1] - - deref: (x) -> x?.deref?(@) or x - getvalue: (x, memo={}) -> - getvalue = x?.getvalue - if getvalue then getvalue.call(x, @, memo) - else x - unify: (x, y, compare) -> - x = @deref(x); y = @deref(y) - if x instanceof Var then @set(x, x.binding); x.binding = y; true; - else if y instanceof Var then @set(y, y.binding); y.binding = x; true; - else x?.unify?(y, @) or y?.unify?(x, @) or compare(x, y) - - # ####class Var - # Var for logic bindings, used in unify, lisp.assign, inc/dec, parser operation, etc. - exports.Var = class Var - constructor: (@name='', @binding = @) -> - deref: (trail) -> - v = @ - next = @binding - if next is @ or next not instanceof Var then next - else - chains = [v] - length = 1 - while 1 - chains.push(next) - v = next; next = v.binding - length++ - if next is v - for i in [0...chains.length-2] - x = chains[i] - x.binding = next - trail.set(x, chains[i+1]) - return next - else if next not instanceof Var - for i in [0...chains.length-1] - x = chains[i] - x.binding = next - trail.set(x, chains[i+1]) - return next - - bind: (value, trail) -> - trail.set(@, @binding) - @binding = trail.deref(value) - - getvalue: (trail, memo={}) -> - name = @name - if memo.hasOwnProperty(name) then return memo[name] - result = @deref(trail) - if result instanceof Var - memo[name] = result - result - else - result = trail.getvalue(result, memo) - memo[name] = result - result - - toString:() -> "vari(#{@name})" - - reElements = /\s*,\s*|\s+/ - - # utilities for new variables - # sometiems, say in macro, we need unique var to avoid name conflict - nameToIndexMap = {} - exports.vari = (name='') -> - index = nameToIndexMap[name] or 1 - nameToIndexMap[name] = index+1 - new Var(name+index) - - exports.vars = (names) -> vari(name) for name in split names, reElements - - # DummyVar never fail when it unify. see tests on any/some/times in test_parser for examples - exports.DummyVar = class DummyVar extends Var - constructor: (name) -> @name = '_$'+name - deref: (trail) -> @ - getvalue: (trail, memo={}) -> - name = @name - if memo.hasOwnProperty(name) then return memo[name] - result = @binding - if result is @ - memo[name] = result - result - else - result = trail.getvalue(result, memo) - memo[name] = result - result - - # nottodo: variable's applyCont:: canceled. lisp1 should be good. - exports.dummy = dummy = (name) -> - index = nameToIndexMap[name] or 1 - nameToIndexMap[name] = index+1 - new exports.DummyVar(name+index) - exports.dummies = (names) -> new dummy(name) for name in split names, reElements - - exports.UObject = class UObject - constructor: (@data) -> - - getvalue: (trail, memo) -> - result = {} - changed = false - for key, value of @data - v = trail.getvalue(value, memo) - if v isnt value then changed = true - result[key] = v - if changed then new UObject(result) - else @ - - unify: (y, trail, compare=(x, y) -> x==y) -> - xdata = @data - ydata = if y instanceof UObject then y.data else y - ykeys = Object.keys(y) - for key of xdata - index = ykeys.indexOf(key) - if index==-1 then return false - if not trail.unify(xdata[key], ydata[key], compare) then return false - ykeys.splice(index, 1); - if ykeys.length isnt 0 then return false - true - - # make unifable object - exports.uobject = (x) -> new UObject(x) - - exports.UArray = class UArray - constructor: (@data) -> - - getvalue: (trail, memo={}) -> - result = [] - changed = false - for x in @data - v = trail.getvalue(x, memo) - if v isnt x then changed = true - result.push(v) - if changed then new UArray(result) - else @ - - unify: (y, trail, compare=(x, y) -> x==y) -> - xdata = @data; ydata = y.data or y - length = @data.length - if length!=y.length then return false - for i in [0...length] - if not trail.unify(xdata[i], ydata[i], compare) then return false - true - - toString: () -> @data.toString() - - # make unifable array - exports.uarray = uarray = (x) -> new UArray(x) - - exports.Cons = class Cons - constructor: (@head, @tail) -> - - getvalue: (trail, memo={}) -> - head = @head; tail = @tail - head1 = trail.getvalue(head, memo) - tail1 = trail.getvalue(tail, memo) - if head1 is head and tail1 is tail then @ - else new Cons(head1, tail1) - - unify: (y, trail, compare=(x, y) -> x==y) -> - if y not instanceof Cons then false - else if not trail.unify(@head, y.head, compare) then false - else trail.unify(@tail, y.tail, compare) - - flatString: () -> - result = "#{@head}" - tail = @tail - if tail is null then null - else if tail instanceof Cons - result += ',' - result += tail.flatString() - else result += tail.toString() - result - - toString: () -> "cons(#{@head}, #{@tail})" - - # cons, like pair in lisp - exports.cons = (x, y) -> new Cons(x, y) - - # conslist, like list in lisp - exports.conslist = (args...) -> - result = null - for i in [args.length-1..0] by -1 - result = new Cons([args[i], result]) - result - - # make unifiable array or unifiable object - exports.unifiable = (x) -> - if _.isArray(x) then new UArray(x) - else if _.isObject(x) then new UObject(x) - else x - - exports.bind = (info) -> (vari, term) -> - vari.bind(info.trail.deref(term)) - true - - exports.unify = unify = (info) -> (x, y, compare=(x, y) -> x==y) -> - info.trail.unify(x, y, compare) - - exports.unifyList = unifyList = (info) -> (xs, ys, compare=(x, y) -> x==y) -> - xlen = xs.length - if ys.length isnt xlen then return false - else - _unify = info.trail.unify - for i in [0...xlen] - if not _unify(xs[i], ys[i], compare) then return false - true - - {identifier} = require "./../peasy" - - # combinator *orp*
- exports.orp = orp = (info) -> (items...) -> - items = for item in items - if (typeof item)=='string' then literal(info)(item) else item - -> - start = info.cursor - length = items.length - for i in [0...length] - info.cursor = start - info.trail = new Trail - if result = items[i]() then return result - if i!= length-1 then info.trail.undo() - result - - # matcher *char*: match one character
- exports.char = char = (info) -> (x) -> -> - x = info.trail.deref(x) - if x instanceof Var - c = info.data[info.cursor++] - x.bind(c) - c - else - if info.data[info.cursor]==x then info.cursor++; return x - - exports.digit = (info) -> (x) -> -> - c = info.data[info.cursor] - if '0'<=c<='9' - x = info.trail.deref(x) - if x instanceof Var - info.cursor++ - x.bind(c) - c - else if x==c - info.cursor++ - c - - exports.letter = (info) -> (x) -> -> - c = info.data[info.cursor] - if 'a'<=x<='z' or 'A'<=x<='Z' - x = info.trail.deref(x) - if x instanceof Var - info.cursor++ - x.bind(c) - c - else if x==c - info.cursor++ - c - - exports.lower = (info) -> (x) -> -> - c = info.data[info.cursor]; - if 'a'<=x<='z' - x = info.trail.deref(x) - if x instanceof Var - info.cursor++ - x.bind(c) - c - else if x==c - info.cursor++ - c - - exports.upper = (info) -> (x) -> -> - c = info.data[info.cursor] - if 'A'<=x<='Z' - x = info.trail.deref(x) - if x instanceof Var - info.cursor++ - x.bind(c) - c - else if x==c - info.cursor++ - c - - exports.identifier = (info) -> - id = identifier(info) - uni = unify(info) - (x) -> -> - if n = id() and uni(x, n) then return n - - exports.combinators = (info) -> - bind: exports.bind(info) - unify: unify(info) - unifyList: exports.unifyList(info) - char: exports.char(info) - digit: exports.digit(info), letter: exports.letter(info) - lower: exports.lower(info), upper: exports.upper(info), - identifier: exports.identifier(info) - - exports.makeInfo = makeInfo = (data, options={cursor:0, tabWidth:2}) -> - data:data, - cursor:options.cursor or 0, - tabWidth: options.tabWidth or 2, - parsingLeftRecursives: {}, - parseCache: {}, - trail: new Trail \ No newline at end of file diff --git a/coffee/deprecated/modularpeasy.coffee b/coffee/deprecated/modularpeasy.coffee deleted file mode 100644 index d17e526..0000000 --- a/coffee/deprecated/modularpeasy.coffee +++ /dev/null @@ -1,372 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/deprecated/modularpeasy') -do (require=require, exports=exports, module=module) -> -# The two lines above make this module can be used both in browser(with twoside.js) and on node.js - - # # Peasy - # ###### Peasy means parsing is easy - # ###### an easy but powerful parser - - # To use Peasy, just require or copy this file to your project, read it, modify it, write the grammar rules,, and - # remove any unnecessary stuffs in it, and parse with the data.@
- # See [here](#peasysample) for a sample grammar in Peasy.
- - # With Peasy, you write the parser by hand, just like to write any other kind of program.
- # You need not play many balls like that any more:

- # ![ballacrobatics.jpg](https://raw.github.com/chaosim/peasy/master/doc/ballacrobatics.jpg)
- # You just play one ball like so:

- # ![dolphinball.jpg](https://raw.github.com/chaosim/peasy/master/doc/dolphinball.jpg)
, - - # You can embeded other features in the grammar rules seamless, such as lexer, rewriter, semantic action, error - # process or any other tasks; you can dynamicly modify the grammar rules, even the parsed object, if you wish.
- - # Instead of a tool or a library, Peasy is rather a new method to write parser. As a demonstration, Peasy presents - # itself as a module of single file, which includes some functions to process left recursives symbols, some matchers - # which parse text, and some matchers and cominators.

- - # With the method provided by Peasy, you can parse any object which is not only text, but also array, embedded list, - # binary stream, or other data structures, like tree, graph, and so on.
- - # ###### Nothing but the method in Peasy is indispensable:
- - # * If there is no left recursive symbol, you can remove the code about that(mainly refer to the function `recursive` and 20 lines).
- # * If you don't need memorize the parsed result, you can remove the stuffs about - # memorization(mainly refer to the function `memorize`).
- # * The matchers(e.g. spaces, literal, identifier, etc.) and combinators(e.g. andp, orp, etc) in this module exists just - # for demostrating the method initiated by Peasy. You will see they are all very simple, after seeing them, I bet - # that you would rather to remove them and write them by hand yourself when you write the grammar rules.

- - # The notation *@name* below means a parameter.
- # all occurences of *@info* refer to the parsed object and the cursor, e.g. it's initial value can be {data: text, cursor:0} - - exports.makeInfo = makeInfo = (data, options={cursor:0, tabWidth:2}) -> - data:data - cursor:options.cursor or 0 - tabWidth: options.tabWidth or 2 - parsingLeftRecursives: {} - parseCache: {} - - # A *matcher* is a function which matches the data being parsed and move cursor directly.
- exports.isMatcher = isMatcher = (item) -> typeof(item)=="function" - - memoSymbolIndex = 0 - - # *recursive*: this is the key function to left recursive.
- # Make *@symbol* a left recursive symbol, which means to wrap `@originalRules[symbol]` with recursive. - # when recursiv(info, rules, symbol)() is executed, loop computing rule() until no changes happened - exports.recursive = recursive = (info) -> (rule) -> - index = memoSymbolIndex - tag = index+':' - memoSymbolIndex++ - parsingLeftRecursives = info.parsingLeftRecursives - parseCache = info.parseCache[tag] = {} - -> - start = info.cursor - callPath = parsingLeftRecursives[start] ?= [] - if tag not in callPath - callPath.push(tag) - m = parseCache[start] ?= [undefined, start] - while 1 - info.cursor = start - result = rule() - if not result then result = m[0]; info.cursor = m[1]; break - if m[1]==info.cursor then m[0] = result; break - else m[0] = result; m[1] = info.cursor - callPath.pop() - result - else - m = parseCache[start] - info.cursor = m[1] - m[0] - - # *memorize*: memorize result and @cursor for *@symbol* which is not left recursive.
- # *The symbols which is left recursive should be wrapped by `recursive(symbol)`, not `memorize(symbol)`!!!* - exports.memorize = memorize = (info) -> (rule) -> - index = memoSymbolIndex - tag = index+':' - memoSymbolIndex++ - parseCache = info.parseCache[tag] = {} - -> - start = info.cursor - m = parseCache[start] - if m then info.cursor = m[1]; m[0] - else - result = rule() - parseCache[start] = [result, info.cursor] - result - - # #### matchers and combinators
- - # A *matcher* is a function which matches the data being parsed and move cursor directly.
- # All matcher should return truth value on succeed, and return falsic value on fail.
- # A *combinator* is a function which receive zero or more matchers as parameter(maybe plus some other parameters - # which are not matchers), and generate a new matchers.
- # there are other matcher generator besides the standard combinators described as above, like `recursive`, `memorize`, - # which we have met above. - - # combinator *andp*
- # execute item() in sequence, return the result of the last one.
- # when `andp` is used to combined of the matchers, the effect is the same as by using the Short-circuit evaluation, like below:
- # `item1() and item2() ... and itemn().`
- # In fact, you maybe would rather like to use `item1() and item2(info.cursor) ..` when you write the grammar rule in the - # manner of Peasy. That would be simpler, faster and more elegant.
- # And in that manner, you would have more control on your grammar rule, say like below:
- # `if (x=item1() and (x>100) and item2() and not item3() and (y = item()) then doSomething()` - exports.andp = andp = (info) -> (items...) -> - items = for item in items - if not isMatcher(item) then literal(info)(item) else item - -> - for item in items - if not (result = item()) then return - result - - # combinator *orp*
- exports.orp = orp = (info) -> (items...) -> - items = for item in items - if not isMatcher(item) then literal(info)(item) else item - -> - start = info.cursor - length = items.length - for i in [0...length] - info.cursor = start - if result = items[i]() then return result - result - - # combinator *notp*
- # `notp` is not useful except being used in other combinators, just like this = `andp(item1, notp(item2))`.
- # *It's unnessary, low effecient and ugly to write `notp(item)()`, just write `not item()`.* - exports.notp = notp = (info) -> (item) -> - if not isMatcher(item) then item = literal(info)(item) - -> not item() - - # combinator *may*: a.k.a optional
- # try to match `item()`, wether `item()` succeed or not, `maybe(item)()` succeed. - exports.may = may = (info) -> (item) -> - if not isMatcher(item) then item = literal(info)(item) - -> - start = info.cursor - if x = item() then x - else info.cursor = start; true - - # combinator *any*: zero or more times of `item()` - exports.any = any = (info) -> (item) -> - if not isMatcher(item) then item = literal(info)(item) - -> - result = [] - while (x = item()) then result.push(x) - result - - # combinator *some*: one or more times of `item()` - exports.some = some = (info) -> (item) -> - if not isMatcher(item) then item = literal(info)(item) - -> - if not (x = item()) then return - result = [x] - while (x = item()) then result.push(x) - result - - # combinator *times*: match *@n* times item(), n>=1 - exports.times = times = (info) -> (item, n) -> - if not isMatcher(item) then item = literal(info)(item) - -> - i = 0 - while i++ (item, separator=spaces(info)) -> - if not isMatcher(item) then item = literal(info)(item) - if not isMatcher(separator) then separator = literal(info)(separator) - -> - if not (x = item()) then return - result = [x] - while separator() and (x=item()) then result.push(x) - result - - # combinator *timesSeperatedList*: given info.n times @item separated by info.separator, n>=1 - exports.timesSeperatedList = timesSeperatedList = (info) -> (item, n, separator=spaces(info)) -> - if not isMatcher(item) then item = literal(info)(item) - if not isMatcher(separator) then separator = literal(info)(separator) - -> - if not (x = item()) then return - result = [x] - i = 1 - while i++ - exports.follow = follow = (info) -> (item) -> - if not isMatcher(item) then item = literal(info)(item) - -> - start = info.cursor - if x = item() then info.cursor = start; x - else info.cursor = start; return - - exports.combinators = combinators = (info) -> - rec: recursive(info), memo: memorize(info), - andp: andp(info), orp: orp(info), notp: notp(info) - may: may(info), any: any(info), some: some(info), times: times(info) - seperatedList: seperatedList(info), timesSeperatedList: timesSeperatedList(info) - follow: follow(info) - - # As the same as andp, orp, in the manner of Peasy, you would rather to write youself a loop to do the things, instead - # of useing the combinators like any, some, times, seperatedList,etc. and that would be simpler, faster and more elegant.
- # And in that manner, you would have more control on your grammar rule so that we can do other things include lexer, - # error report, errer recovery, semantic operatons, and any other things you would like to do.
- - # It is for three motives to put all of the stuffs abve here: - # * 1. to demonstrate how to write matcher and grammar rules in the method brought by Peasy - # * 2. to demonstrate that Peasy can also implement any component that other combinational parser libaries like pyparsing, - # parsec, but in a simpler, faster manner. - # * 3. to show that it is how easy to write the combinators in the manner of Peasy.

- - # As you have seen above, all of these utilities is so simple that you can write them at home by hand easily. In fact, - # you can write yourself all of the grammar rules in the same manner as above. - - # If you like, you can add a faster version for every matcher, which do not pass *@start* as parameter around.
- # Some of the matchers below have two version, to demonstrate how to do that. - # *Don't use the faster version in orp, any, some, times, separatedList, timesSeparatedList.*

- - # #### other predicates, matchers, and combinators
- # below is some little utilities which may be useful.
- # just remove them if you don't need them, except *literal*, which is depended by the combinators above. - - # predicate - # A *predicate* is a function which return true or false. - exports.isdigit = (c) -> '0'<=c<='9' - exports.isletter = (c) -> 'a'<=c<='z' or 'A'<=c<='Z' - exports.islower = (c) -> 'a'<=c<='z' - exports.isupper = (c) ->'A'<=c<='Z' - exports.isIdentifierLetter = (c) -> 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='@' or 'c'=='_' - - # matcher *literal*
- # match a text string.
- # `notice = some combinators like andp, orp, notp, any, some, etc. use literal to wrap a object which is not a matcher. - exports.literal = literal = (info) -> (string) -> -> - len = string.length - start = info.cursor - if info.data.slice(start, stop = start+len)==string then info.cursor = stop; true - - # matcher *char*: match one character
- exports.char = char = (info) -> (c) -> -> if info.data[info.cursor]==c then info.cursor++; return c - - # In spaces, spaces1, a tab('\t') is computed as info.tabWidth spaces,
- # which is used in indent style language, such as coffeescript, python, haskell, etc.
- # If you don't need this feature, you can easily rewrite these utilities to remove the code about tab width yourself.

- - # matcher *spaces*: zero or more whitespaces, ie. space or tab.
- exports.spaces = spaces = (info) -> -> - data = info.data - len = 0 - cursor = info.cursor - tabWidth = info.tabWidth - while 1 - switch data[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - info.cursor = cursor - len+1 - - # matcher *spaces1*
- # one or more whitespaces, ie. space or tab.
- exports.spaces1 = spaces1 = (info) -> -> - data = info.data - cursor = info.cursor - len = 0 - tabWidth = info.tabWidth - while 1 - switch data[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - info.cursor = cursor - len - - # matcher *wrap*
- # match left, then match item, match right at last - exports.wrap = wrap = (info) -> (item, left=spaces(info), right=spaces(info)) -> - if not isMatcher(item) then item = literal(info)(item) - -> - if left() and result = item() and right() then result - - # matcher *identifierLetter* = normal version
- # is a letter than can be used in identifer?
- # javascript style, '@' is a identifierLetter_
- exports.identifierLetter = identifierLetter = (info) -> -> - c = info.data[info.cursor] - if c is '@' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - info.cursor++; true - - # matcher *followIdentifierLetter_*, faster version
- # lookahead whether the following character is a letter used in identifer. don't change info.cursor.
- # javascript style, '@' is a identifierLetter_ - exports.followIdentifierLetter_ = followIdentifierLetter_ = (info) -> -> - c = info.data[info.cursor] - (c is '@' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9') and c - - exports.digit = digit = (info) -> -> c = info.data[info.cursor]; if '0'<=c<='9' then info.cursor++; c - exports.letter = letter = (info) -> -> c = info.data[info.cursor]; if 'a'<=c<='z' or 'A'<=c<='Z' then info.cursor++; c - exports.lower = lower = (info) -> -> c = info.data[info.cursor]; if 'a'<=c<='z' then info.cursor++; c - exports.upper = upper = (info) -> -> c = info.data[info.cursor]; if 'A'<=c<='Z' then info.cursor++; c - - # matcher identifier - exports.identifier = identifier = (info) -> -> - data = info.data - cursor = info.cursor - c = data[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or 'c'=='$' or 'c'=='_' then cursor++ - else return - while 1 - c = data[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='@' or 'c'=='_' then cursor++ - else break - info.cursor = cursor - true - - exports.matchers = matchers = (info) -> - literal: literal(info), char: char(info), spaces: spaces(info), spaces1: spaces1(info), wrap: wrap(info), - identifierLetter: identifierLetter(info), followIdentifierLetter: followIdentifierLetter(info) - digit: digit(info), letter: letter(info), lower: lower(info), upper: upper(info), - identifier: identifier(info) - - exports.digits = digits = (info) -> - ch = char(info) - $0: ch('0'), $1: ch('1'), $2: ch('2'), $3: ch('3'), $4: ch('4'), - $5: ch('6'), $1: ch('7'), $2: ch('7'), $8: ch('8'), $9: ch('9') - - exports.letters = letters = (info) -> - ch = char(info) - a: ch('a'), b: ch('b'), c: ch('c'), d: ch('d'), e: ch('e'), f: ch('f'), g: ch('g') - h: ch('h'), i: ch('i'), j: ch('j'), k: ch('k'), l: ch('l'), m: ch('m'), n: ch('n') - o: ch('o'), p: ch('p'), q: ch('q'), r: ch('r'), s: ch('s'), t: ch('t') - u: ch('u'), v: ch('v'), w: ch('w'), x: ch('x'), y: ch('y'), z: ch('z') - A: ch('A'), B: ch('B'), C: ch('C'), D: ch('D'), E: ch('E'), F: ch('F'), G: ch('G') - H: ch('H'), I: ch('I'), J: ch('J'), K: ch('K'), L: ch('L'), M: ch('M'), N: ch('N') - O: ch('O'), P: ch('P'), Q: ch('Q'), R: ch('R'), S: ch('S'), T: ch('T') - U: ch('U'), V: ch('V'), W: ch('W'), X: ch('X'), Y: ch('Y'), Z: ch('Z') - - # The utilites above is just for providing some examples on how to write matchers for Peasy.
- # In fact, It's realy easy peasy to write the matchers for your grammar rule yourself.
- # see [easy peasy]( http://en.wiktionary.org/wiki/easy_peasy )
- - # - # *parse*: this is a sample parse function to demonstrate on how to write your own grammar rules yourself.
- # notice that there exists indirect left recursion in the rules - parse = (text) -> - makeGrammar = (info) -> - # generate the matchers by the combinators in advance for better performance.
- # if you don't mind performance, you can write them in the rule directly. - {a, b, x, y} = letters(info) - {rec, orp} = combinators(info) - # the grammar rules object. - rules = - Root: -> (m = rules.A()) and z() and m+'z' - A: rec orp((-> (m = rules.B()) and x() and m+'x' or m), a) - B: rec orp((-> (m = rules.A()) and y() and m+'y'), -> rules.C()) - C: rec orp((-> rules.A()), b) - grammar = makeGrammar(makeInfo(text)) - grammar.Root(0) diff --git a/coffee/deprecated/nonmodularpeasy.coffee b/coffee/deprecated/nonmodularpeasy.coffee deleted file mode 100644 index cd8a6a7..0000000 --- a/coffee/deprecated/nonmodularpeasy.coffee +++ /dev/null @@ -1,587 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/deprecated/nonmodularpeasy') -do (require=require, exports=exports, module=module) -> -# The two lines above make this module can be used both in browser(with twoside.js) and on node.js - - # # Peasy - # ###### Peasy means parsing is easy - # ###### an easy but powerful parser - - # To use Peasy, just copy this file to your project, read it, modify it, write the grammar rules,, and - # remove any unnecessary stuffs in Peasy, and parse with the grammar.
- # See [here](#peasysample) for a sample grammar in Peasy.
- - # With Peasy, you write the parser by hand, just like to write any other kind of program.
- # You need not play many balls like that any more:

- # ![ballacrobatics.jpg](https://raw.github.com/chaosim/peasy/master/doc/ballacrobatics.jpg)
- # You just play one ball like so:

- # ![dolphinball.jpg](https://raw.github.com/chaosim/peasy/master/doc/dolphinball.jpg)
, - - # You can embeded other features in the grammar rules seamless, such as lexer, rewriter, semantic action, error - # process( error reporting, error recovering) or any other tasks; you can dynamicly modify the grammar rules, even - # the parsed object, if you wish.
- - # Instead of a tool or a library, Peasy is rather a new method to write parser. As a demonstration, Peasy presents - # itself as a module of single file, which includes some global variables used while parsing, some functions to - # process left recursives symbols, some matchers which parse the text, and some cominators of matchers.

- - # With the method provided by Peasy, you can parse any object which is not only text, but also array, embedded list, - # binary stream, or other data structures, like tree, graph, and so on.
- - # ###### Nothing but the method in Peasy is indispensable:
- - # * If there is no left recursive symbol, you can remove the code about that(mainly three functions and 80 lines).
- # * If you don't need memorize the parsed result, you can remove the stuffs about - # memorization(mainly refer to the function `memorize`).
- # * The matchers(e.g. spaces, literal, identifier, etc.) and combinators(e.g. andp, orp, etc) in this module exists just - # for demostrating the method initiated by Peasy. You will see they are all very simple, after seeing them, I bet - # that you would rather to remove them and write them by hand yourself when you write the grammar rules.

- - # Peasy provided two method to tell which symbols are left recursive.
- # This module presents the semiautomatic method:
- # At first you write grammar rules in this manner: replace one and only one of - # grmmar.symbol in the grammar rule with memo(symbol) for every left recursive circles. Before parsing, you first call - # intialize(), and tell which symbol are left call or left recursive by calling addParentChildrens(grammar, parentChildren) - # and/or addRecursiveCircles(grammar, recursiveCircles...), and then call computeLeftRecursives(grammar), now - # everything about left recursive symbols is computed and you can call parse(data, grammar, root) to do the work. - - # The notation **@name** in the comment below means a global variable, and **$name** means a parameter.
- - # #### global variables
- # It is for the performace reason that I use global variables, and at some time I will provide another version which - # have the class Parser for people who prefer modularization to speed. Of course you can modify the code to have the - # class Parser yourself if you like. It's just a snap to do that. - - # some global variable used while parsing
- - # the text which is being parsed
- # *Don't be confused by the variable name, it could be not only text strings but also array, sequence, tree, graph,etc.* - text = '' - # the length of @text - textLength = 0 - # the current position of parsing, use text[cursor] to get current character in parsed stream - cursor = 0 - - # the grammar object which contains all of rules defined for the symbol in grammar. - grammar = undefined - # saved the original rules of the grammar. - originalRules = {} - - # store the wrapped function to rule of the left recursive symbol with `recursive`, and before entering them, store it in grammar too. - # when entering them, `grammar[symbol]` is unwrapped to `originalRules[symbol]` or `memorizeRecursives[symbol]` - recursiveRules = {} - symbolDescedentsMap = {} - - # if you would like to use just symbol itself as the hash head, remove these four lines below and other correlative stuffs.
- # {symbol: tag}, from rule symbol map to a shorter memo tag, for memory efficeny - symbolToTagMap = {} - # {tag: true}, record tags that has been used to avoid conflict - tags = {} - - parseCache = {} # {tag+start: [result, cursor]}, memorized parser result - functionCache = {} # memorized normal function result - - hasOwnProperty = Object.hasOwnProperty - - # #### helper functions - # some functions is helpful to make the parser. - - # **intialize**: clear global varialbes. you should call `intialize()` at first. - exports.initialize = () -> - parseCache = {} - functionCache = {} - originalRules = {} - recursiveRules = {} - symbolDescedentsMap = {} - symbolToTagMap = {} - tags = {} - parseCache = {} - - # **_parse**: parse **$data** from **$root** with **$aGrammar**.
- # before parsing, you should tell the informations about left recursion in grammar. - exports.parse = _parse = (data, aGrammar, root) -> - text = data - textLength = text.length - cursor = 0 - root = root or aGrammar.rootSymbol - grammar = aGrammar - grammar[root](0) - - # - # **parse**: this is a sample parse function to demonstrate on how to write your own grammar rules yourself.
- # notice that there exists indirect left recursion in the grammar. - parse = (text) -> - # generate the matchers by the combinators in advance for better performance.
- # if you don't mind performance, you can write them in the rule directly. - a = char('a'); b = char('b'); x = char('x') - memoA = memo('A') - # the grammar rules object. - rules = - A: (start) -> - # *add `or memoResult` to prevent executing nonrecursive part more than once.* - (memoResult = m = rules.B(start)) and x(p.cur()) and m+'x' or memoResult\ - or a(start) - B: (start) -> rules.C(start) - C: (start) -> memoA(start) or b(start) - rootSymbol: 'A' - initialize() - addRecursiveCircles(rules, ['A', 'B', 'C']) - computeLeftRecursives(rules) - _parse(text, rules) - - # ##### stuffs for left recursives - # use `addParentChildren(grammar, parentChildrens)` or `addRecursiveCircles(grammar, recursiveCircles...)` to tell - # the left calling relations between symbols in the grammar
- - # **addParentChildrens**: add direct left call parent->children relation for **$parentChildrens** to **@symbolToParentsMap**
- # e.g. `addRecursiveCircles(grammar, {A:['B'], B:['A', 'B']})` - exports.addParentChildrens = (grammar, parentChildren) -> - map = grammar.parentToChildren ?= {} - for parent, children of parentChildren - list = map[parent] ?= [] - for name in children - if name not in list then list.push name - null - - # **addRecursiveCircles**: add left recursive parent->children relation to `grammar.parentToChildren` for symbols in **@recursiveCircles**
- # e.g. `addRecursiveCircles(grammar, ['A', 'B'], ['B'])` tell the same left recursive relations as above sample. - exports.addRecursiveCircles = (grammar, recursiveCircles...) -> - map = grammar.parentToChildren ?= {} - for circle in recursiveCircles - i = 0 - length = circle.length - while i - exports.computeLeftRecursives = (grammar) -> - parentToChildren = grammar.parentToChildren - addDescendents = (symbol, meetTable, descedents) -> - children = parentToChildren[symbol] - for child in children - if child not in descedents then descedents.push child - if not meetTable[child] then addDescendents(child, meetTable, descedents) - symbolDescedentsMap = {} - for symbol of parentToChildren - meetTable = {}; meetTable[symbol] = true - descendents = symbolDescedentsMap[symbol] = [] - addDescendents(symbol, meetTable, descendents) - if symbol in descendents - originalRules[symbol] = grammar[symbol] - grammar[symbol] = recursive(symbol) - symbolDescedentsMap - - # **recursive**: this is the key function to left recursive.
- # Make **$symbol** a left recursive symbol, which means to wrap `originalRules[symbol]` with recursive. - # when recursiv(symbol)(start) is executed, first let `rule = grammar[symbol]`, `grammar[symbol] = originalRules[child]` for - # all symbols in left recursive circles and loop computing rule(start) until no changes happened, and - # restore all symbols in left recursive cirle to `recursiveRules[symbol]` at last., - exports.recursive = recursive = (symbol) -> - rule = originalRules[symbol] - (start) -> - for child in symbolDescedentsMap[symbol] - grammar[child] = originalRules[child] - hash = symbol+start - m = parseCache[hash] ?= [undefined, -1] - if m[1]>=0 then cursor = m[1]; return m[0] - while 1 - result = rule(start) - if m[1]<0 - m[0] = result - if result then m[1] = cursor - else m[1] = start - else - if m[1]==cursor then m[0] = result; return result - else if cursor - # It is set up automaticly by `computeLeftRecursives(grammar)` for the symbols which is left recursive.
- # For other symbol, you should be able to call this in rule mannually. - exports.memo = memo = (symbol) -> - (start) -> - hash = symbol+start - m = parseCache[hash] - if m then m[0] - - # **setMemorizeRules**: set the symbols in grammar which memorize their rule's result.
- # this function should be used only for the symbols which is not left recursives.
- # you can do this after `initialize()` and before `parse(...)`. - setMemorizeRules = (grammar, symbols) -> - for symbol in symbols - originalRules[symbol] = grammar[symbol] - grammar[symbol] = memorize(symbol) - - # **memorize**: memorize result and cursor for **$symbol** which is not left recursive.
- # *The symbols which is left recursive should be wrapped by `recursive(symbol)`, not `memorize(symbol)`!!!* - memorize = (symbol) -> - tag = symbolToTagMap[symbol] - rule = originalRules[symbol] - (start) -> - hash = tag+start - m = parseCache[hash] - if m then cursor = m[1]; m[0] - else - result = rule(start) - parseCache[hash] = [result, cursor] - result - - # **setMemoTag**: find a shorter part of symbol as the head of hash tag to index **@parseCache**
- # It exists just for performance reason. If you don't like this idea, you can remove the stuffs about memo tag yourself and - # just use symbol itself as the head of hash tag. - setMemoTag = (symbol) -> - i = 1 - while 1 - if hasOwnProperty.call(tags, symbol.slice(0, i)) then i++ - else break - tag = symbol.slice(0, i) - symbolToTagMap[symbol] = tag - tags[tag] = true - - # #### matchers and matcher combinators
- - # A **matcher** is a function which read the text being parsed and move cursor directly.
- # All matcher should return truth value on succeed, and return falsic value on fail.
- # A **combinator** is a function which receive zero or more matchers as parameter(maybe plus some other parameters - # which are not matchers), and generate a new matchers.
- # there are other matcher generator besides the standard combinators described as above, like `recursive`, `memo`, `memorize`, - # which we have met above. - - isMatcher = (item) -> typeof(item)=="function" - - # combinator **andp**
- # execute item(cursor) in sequence, return the result of the last one.
- # when `andp` is used to combined of the matchers, the effect is the same as by using the Short-circuit evaluation, like below:
- # `item1(start) and item2(cursor] ... and itemn(cursor).`
- # In fact, you maybe would rather like to use `item1(start) and item2(cursor) ..` when you write the grammar rule in the - # manner of Peasy. That would be simpler, faster and more elegant.
- # And in that manner, you would have more control on your grammar rule, say like below:
- # `if (x=item1(start) and (x>100) and item2(cursor) and not item3(cursor) and (y = item(cursor)) then doSomething()` - exports.andp = (items) -> - items = for item in items - if not isMatcher(item) then literal(item) else item - (start) -> - cursor = start - for item in items - if not(result = item(cursor)) then return - return result - - # combinator **orp**
- # execute `item(start)` one by one, until the first item which is evaluated to truth value and return the value.
- # when orp is used to combined of the matchers, the effect is the same as by using the Short-circuit evaluation, like below:
- # item1(start) or item2(cursor] ... or itemn(cursor)
- # In fact, you maybe would rather like to use `item1(start) or item2(cursor) ..` when you write the grammar rule in the - # manner of Peasy. That would be simpler, faster and more elegant.
- # And in that manner, you would have more control on your grammar rule, say like below:
- # `if ((x=item1(start) and (x>100)) or (item2(cursor) and not item3(cursor)) or (y = item(cursor)) then doSomething()` - exports.orp = (items...) -> - items = for item in items - if not isMatcher(item) then literal(item) else item - (start) -> - for item in items - if result = item(start) then return result - result - - # combinator **notp**
- # `notp` is not useful except being used in other combinators, just like this: `andp(item1, notp(item2))`.
- # *It's unnessary, low effecient and ugly to write `notp(item)(start)`, just write `not item(start)`.* - exports.notp = (item) -> - if not isMatcher(item) then item = literal(item) - (start) -> not item(start) - - # combinator **any**: zero or more times of `item(cursor)` - exports.any = (item) -> - if not isMatcher(item) then item = literal(item) - (start) -> - result = []; cursor = start - while ( x = item(cursor)) then result.push(x) - result - - # combinator **some**: one or more times of `item(cursor)` - exports.some = (item) -> - if not isMatcher(item) then item = literal(item) - (start) -> - result = []; cursor = start - if not (x = item(cursor)) then return x - while 1 - result.push(x) - x = item(cursor) - if not x then break - result - - # combinator **may**: a.k.a optional
- # try to match `item(cursor)`, wether `item(cursor)` succeed or not, `maybe(item)(start)` succeed. - exports.may = exports.optional = (item) -> - if not isMatcher(item) then item = literal(item) - (start) -> - cursor = start - if x = item(cursor) then x - else cursor = start; true - - # combinator **follow**
- # try to match `item(start)`, if succeed, reset cursor and return the value of item(start)
- # whether succeed or not, cursor is reset to start - exports.follow = (item) -> - if not isMatcher(item) then item = literal(item) - (start) -> - cursor = start - if x = item(cursor) then cursor = start; x - - # combinator **times**: match **$n** times item(cursor), n>=1 - exports.times = (item, n) -> - if not isMatcher(item) then item = literal(item) - (start) -> - cursor = start; i = 0 - while i++ - if not isMatcher(item) then item = literal(item) - if not isMatcher(separator) then separator = literal(separator) - (start) -> - cursor = start - result = [] - x = item(cursor) - if not x then return - while 1 - result.push(x) - if not(x = item(cursor)) then break - result - - # combinator **timesSeperatedList**: given @n times $item separated by @separator, n>=1 - exports.timesSeperatedList = (item, n, separator=spaces) -> - if not isMatcher(item) then item = literal(item) - if not isMatcher(separator) then separator = literal(separator) - (start) -> - cursor = start - result = [] - x = item(cursor) - if not x then return - i = 1 - while i++ - # And in that manner, you would have more control on your grammar rule so that we can do other things include lexer, - # error report, errer recovery, semantic operatons, and any other things you would like to do.
- - # It is for three motives to put all of the stuffs abve here: - # * 1. to demonstrate how to write matcher and grammar rules in the method brought by Peasy - # * 2. to demonstrate that Peasy can implement any component that other combinational parser libaries like pyparsing, - # parsec too, but in a simpler, faster manner. - # * 3. to show that it is how easy to write the matchers in the manner of Peasy.

- - # As you have seen above, all of these utilities is so simple that you can write them at home by hand easily. In fact, - # you can write yourself all of the grammar rules in the same manner as above. - - # If you like, you can add a faster version for every matcher, which do not pass $start as parameter around.
- # Some of the matchers below have two version, to demonstrate how to do that. - # *Don't use the faster version in orp, any, some, times, separatedList, timesSeparatedList.*

- - # #### some other matchers, combinators and predicate
- # A **predicate** is a function which return true or false, usually according to its parameter, but not look at parsed object. - # below is some little utilities may be useful. Three version of some of them is provided.
- # just remove them if you don't need them, except **literal**, which is depended by the matchers above. - - # matcher **literal**, normal version
- # match a text string.
- # `notice: some combinators like andp, orp, notp, any, some, etc. use literal to wrap a object which is not a matcher. - - exports.literal = literal = (string) -> (start) -> - len = string.length - if text.slice(start, stop = start+len)==string then cursor = stop; true - - # matcher **literal_**, faster version
- # match a text string. - exports.literal_ = literal_ = (string) -> (start) -> - len = string.length - if text.slice(cursor, stop = cursor+len)==string then cursor = stop; true - - # matcher **char**, normal version
- # match one character - exports.char = (c) -> (start) -> - if text[start]==c then cursor = start+1; return c - - # matcher **char_**, normal version
- # match one character - exports.char_ = (c) -> () -> - if text[cursor]==c then cursor++; return c - - # In spaces, spaces_, spaces1, spaces1_, a tat('\t') is seen as tabWidth spaces,
- # which is used in indent style language, such as coffeescript, python, haskell, etc.
- # If you don't need this feature, you can easily rewrite these utilities to remove the code about tab width yourself.

- - # matcher **spaces**, normal version
- # zero or more whitespaces, ie. space or tab.
- exports.spaces = (start) -> - len = 0 - cursor = start - text = text - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - return len - - # matcher **spaces_**, faster version
- # zero or more whitespaces, ie. space or tab. - exports.spaces_ = () -> - len = 0 - text = text - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - len - - # matcher **spaces1**, normal version
- # one or more whitespaces, ie. space or tab.
- exports.spaces1 = (start) -> - len = 0 - cursor = start - text = text - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - if len then return cursor = cursor; len - - # matcher **spaces1_**, faster version
- # one or more whitespaces, ie. space or tab. - exports.spaces1_ = () -> - len = 0 - cursor = start - while 1 - switch text[cursor++] - when ' ' then len++ - when '\t' then len += tabWidth - else break - if len then return cursor = cursor; len - - # matcher **wrap**, normal version
- # match left, then match item, match right at last - exports.wrap = (item, left=spaces, right=spaces) -> - if not isMatcher(item) then item = literal(item) - (start) -> - if left(start) and result = item(cursor) and right(cursor) then result - - # matcher **identifierLetter**: normal version
- # is a letter than can be used in identifer?
- # javascript style, '$' is a identifierLetter_
- identifierLetter = (start) -> - start = cursor - c = text[cursor] - if c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - cursor++; true - - # matcher **identifierLetter_**, version
- # is a letter that can be used in identifer?
- # javascript style, '$' is a identifierLetter_ - identifierLetter_ = () -> - c = text[cursor] - if c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - cursor++; true - - # matcher **followIdentifierLetter_**, faster version
- # lookahead whether the following character is a letter used in identifer. don't change cursor.
- # javascript style, '$' is a identifierLetter_ - followIdentifierLetter_ = () -> - c = text[cursor] - c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - - isIdentifierLetter = (c) -> 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='$' or 'c'=='_' - - # predicate isdigit
- exports.isdigit = (c) -> '0'<=c<='9' - # matcher digit, normal version
- exports.digit = (start) -> - c = text[start]; if '0'<=c<='9' then cursor = start+1 - # matcher digit_, faster version
- exports.digit_ = () -> - c = text[cursor]; if '0'<=c<='9' then cursor++ - - # predicate isletter
- exports.isletter = exports.isalpha = (c) -> 'a'<=c<='z' or 'A'<=c<='Z' - # matcher letter, normal version
- exports.letter = exports.alpha = (start) -> - c = text[start]; if 'a'<=c<='z' or 'A'<=c<='Z' then cursor = start+1 - # matcher letter, faster version
- exports.letter_ = exports.alpha_ = () -> - c = text[cursor]; if 'a'<=c<='z' or 'A'<=c<='Z' then cursor++ - - # predicate: islower - exports.islower = (c) -> 'a'<=c<='z' - # matcher lower, normal version - exports.lower = (start) -> - c = text[start]; if 'a'<=c<='z' then cursor = start+1 - #matcher lower_, faster version - exports.lower_ = () -> - c = text[cursor]; if 'a'<=c<='z' then cursor++ - - exports.isupper = (c) ->'A'<=c<='Z' - # matcher upper, normal version - exports.upper = (start) -> c = text[start]; if 'A'<=c<='Z' then cursor = start+1 - #matcher upper_, faster version - exports.upper_ = (start) -> c = text[cursor]; if 'A'<=c<='Z' then cursor++ - - # matcher identifier, normal version - exports.identifier = (start) -> - cursor = start - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or 'c'=='$' or 'c'=='_' then cursor++ - else return - while 1 - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='$' or 'c'=='_' then cursor++ - else break - true - - # matcher identifier_, faster version - exports.identifier_ = (start) -> - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or 'c'=='$' or 'c'=='_' then cursor++ - else return - while 1 - c = text[cursor] - if 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or 'c'=='$' or 'c'=='_' then cursor++ - else break - true - - # The utilites above is just for providing some examples on how to write matchers for Peasy.
- # In fact, It's realy easy peasy to write the matchers for your grammar rule yourself.
- # see [easy peasy]( http://en.wiktionary.org/wiki/easy_peasy )
- - # These utilities below exists for people who want to use these file a independent module, and put the grammar rule in - # another separated file.
- - # gettext: get the being pased text
- # If you use this file to contain the grammar rules, just directly use `text`
- # and use `text[cursor]` to get current character, `text.slice(cursor, cursor+n)` to get substring of the text, if - # text is a string object. - exports.gettext = () -> text - - # If you use this file to contain the grammar rules, just directly use `cursor` or `cursor = n` or `cursor++` or `cursor--` - exports.getcursor = exports.cur = () -> cursor - exports.setcursor = exports.setcur = (pos) -> cursor = pos - - diff --git a/coffee/index.coffee b/coffee/index.coffee new file mode 100644 index 0000000..d7de5cd --- /dev/null +++ b/coffee/index.coffee @@ -0,0 +1,34 @@ +exports = module.exports = + Parser: require './parser' + LogicParser: require './logicparser' + LineParser: require './lineparser' + + debugging: false + testing: false + debug: (message) -> if exports.debugging then console.log message + warn: (message) -> if exports.debugging or exports.testing then console.log message + + ### some utilities for parsing ### + Charset: (string) -> + for x in string then @[x] = true + this + charset: (string) -> new exports.Charset(string) + + inCharset: (ch, chars) -> + exports.warn 'peasy.inCharset(char, set) is deprecated, use set.contain(char) instead.' + chars.hasOwnProperty(ch) + in_: exports.inCharset + + isdigit: (c) -> '0'<=c<='9' + isletter: (c) -> 'a'<=c<='z' or 'A'<=c<='Z' + islower: (c) -> 'a'<=c<='z' + isupper: (c) ->'A'<=c<='Z' + isIdentifierLetter: (c) -> c=='$' or c=='_' or 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' + + digits: '0123456789' + lowers: 'abcdefghijklmnopqrstuvwxyz' + uppers: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + letters: exports.lowers+exports.uppers + letterDigits: exports.letterDigits + +exports.Charset::contain = (ch) -> @hasOwnProperty(ch) diff --git a/coffee/lineparser.coffee b/coffee/lineparser.coffee new file mode 100644 index 0000000..cf01ee8 --- /dev/null +++ b/coffee/lineparser.coffee @@ -0,0 +1,16 @@ +### an extended parser with lineno and row support ### + +BaseParser = require "./parser" + +exports = module.exports = class Parser extends BaseParser + constructor: -> + super + self = @ + + @parse = (data, root=self.root, cur=0, lineno=0, row=0) -> + self.data = data + self.cur = cur + self.trail = new Trail + self.ruleStack = {} + self.cache = {} + root() diff --git a/coffee/logicparser.coffee b/coffee/logicparser.coffee new file mode 100644 index 0000000..f7ff454 --- /dev/null +++ b/coffee/logicparser.coffee @@ -0,0 +1,290 @@ +### an extended parser with logic features ### + +BaseParser = require "./parser" + +exports = module.exports = class Parser extends BaseParser + constructor: -> + super + self = @ + + @parse = (data, root=self.root, cur=0) -> + self.data = data + self.cur = cur + self.trail = new Trail + self.ruleStack = {} + self.cache = {} + root() + + @bind = (vari, term) -> + vari.bind(self.trail.deref(term)) + true + + @unify = (x, y, equal=((x, y) -> x==y)) -> + self.trail.unify(x, y, equal) + + @unifyList = (xs, ys, equal=((x, y) -> x==y)) -> + xlen = xs.length + if ys.length isnt xlen then return false + else + _unify = self.trail.unify + for i in [0...xlen] + if not _unify(xs[i], ys[i], equal) then return false + true + + # combinator *orp*
+ @orp = (items...) -> + items = for item in items then (if (typeof item)=='string' then self.literal(item) else item) + -> + start = self.cur + length = items.length + for i in [0...length] + self.cur = start + self.trail = new Trail + if result = items[i]() then return result + if i!= length-1 then self.trail.undo() + result + + # matcher *char*: match one character
+ @unifyChar = (x) -> -> + x = self.trail.deref(x) + if x instanceof Var then c = self.data[self.cur++]; x.bind(c); c + else if self.data[self.cur]==x then self.cur++; x + + @unifyDigit = (x) -> -> + c = self.data[self.cur] + if '0'<=c<='9' + x = self.trail.deref(x) + if x instanceof Var then self.cur++; x.bind(c); c + else if x==c then self.cur++; c + + @unifyLetter = (x) -> -> + c = self.data[self.cur] + if 'a'<=x<='z' or 'A'<=x<='Z' + x = self.trail.deref(x) + if x instanceof Va then x.bind(c); self.cur++; c + else if x==c then self.cur++; c + + @unifyLower = (x) -> -> + c = self.data[self.cur]; + if 'a'<=x<='z' + x = self.trail.deref(x) + if x instanceof Var then x.bind(c); self.cur++; c + else if x==c then self.cur++; c + + @unifyUpper = (x) -> -> + c = self.data[self.cur] + if 'A'<=x<='Z' + x = self.trail.deref(x) + if x instanceof Var then x.bind(c); self.cur++; c + else if x==c then self.cur++; c + + @unifyIdentifier = (x) -> -> + if n = self.identifier() and self.unify(x, n) then n + +exports.Error = class Error + constructor: (@exp, @message='', @stack = @) -> # @stack: to make webstorm nodeunit happy. + toString: () -> "#{@constructor.name}: #{@exp} >>> #{@message}" + +exports.BindingError = class BindingError extends Error + +# record the trail for variable binding
+# when multiple choices exist, a new Trail for current branch is constructored,
+# when backtracking, undo the trail to restore the previous variable binding +exports.Trail = class Trail + constructor: (@data={}) -> + copy: () -> new Trail(_.extend({},@data)) + set: (vari, value) -> + data = @data + if not data.hasOwnProperty(vari.name) + data[vari.name] = [vari, value] + + undo: () -> for nam, pair of @data then pair[0].binding = pair[1] + + deref: (x) -> x?.deref?(@) or x + getvalue: (x, memo={}) -> + getvalue = x?.getvalue + if getvalue then getvalue.call(x, @, memo) + else x + unify: (x, y, equal) -> + x = @deref(x); y = @deref(y) + if x instanceof Var then @set(x, x.binding); x.binding = y; true; + else if y instanceof Var then @set(y, y.binding); y.binding = x; true; + else x?.unify?(y, @) or y?.unify?(x, @) or equal(x, y) + +# ####class Var +# Var for logic bindings, used in unify, lisp.assign, inc/dec, parser operation, etc. +exports.Var = class Var + constructor: (@name='', @binding = @) -> + deref: (trail) -> + v = @ + next = @binding + if next is @ or next not instanceof Var then next + else + chains = [v] + length = 1 + while 1 + chains.push(next) + v = next; next = v.binding + length++ + if next is v + for i in [0...chains.length-2] + x = chains[i] + x.binding = next + trail.set(x, chains[i+1]) + return next + else if next not instanceof Var + for i in [0...chains.length-1] + x = chains[i] + x.binding = next + trail.set(x, chains[i+1]) + return next + + bind: (value, trail) -> + trail.set(@, @binding) + @binding = trail.deref(value) + + getvalue: (trail, memo={}) -> + name = @name + if memo.hasOwnProperty(name) then return memo[name] + result = @deref(trail) + if result instanceof Var + memo[name] = result + result + else + result = trail.getvalue(result, memo) + memo[name] = result + result + + toString:() -> "vari(#{@name})" + +reElements = /\s*,\s*|\s+/ + +# utilities for new variables +# sometiems, say in macro, we need unique var to avoid name conflict +nameToIndexMap = {} +exports.vari = (name='') -> + index = nameToIndexMap[name] or 1 + nameToIndexMap[name] = index+1 + new Var(name+index) + +exports.vars = (names) -> vari(name) for name in split names, reElements + +# DummyVar never fail when it unify. see tests on any/some/times in test_parser for examples +exports.DummyVar = class DummyVar extends Var + constructor: (name) -> @name = '_$'+name + deref: (trail) -> @ + getvalue: (trail, memo={}) -> + name = @name + if memo.hasOwnProperty(name) then return memo[name] + result = @binding + if result is @ + memo[name] = result + result + else + result = trail.getvalue(result, memo) + memo[name] = result + result + +# nottodo: variable's applyCont:: canceled. lisp1 should be good. +exports.dummy = dummy = (name) -> + index = nameToIndexMap[name] or 1 + nameToIndexMap[name] = index+1 + new exports.DummyVar(name+index) +exports.dummies = (names) -> new dummy(name) for name in split names, reElements + +exports.UObject = class UObject + constructor: (@data) -> + + getvalue: (trail, memo) -> + result = {} + changed = false + for key, value of @data + v = trail.getvalue(value, memo) + if v isnt value then changed = true + result[key] = v + if changed then new UObject(result) + else @ + + unify: (y, trail, equal=(x, y) -> x==y) -> + xdata = @data + ydata = if y instanceof UObject then y.data else y + ykeys = Object.keys(y) + for key of xdata + index = ykeys.indexOf(key) + if index==-1 then return false + if not trail.unify(xdata[key], ydata[key], equal) then return false + ykeys.splice(index, 1); + if ykeys.length isnt 0 then return false + true + +# make unifable object +exports.uobject = (x) -> new UObject(x) + +exports.UArray = class UArray + constructor: (@data) -> + + getvalue: (trail, memo={}) -> + result = [] + changed = false + for x in @data + v = trail.getvalue(x, memo) + if v isnt x then changed = true + result.push(v) + if changed then new UArray(result) + else @ + + unify: (y, trail, equal=(x, y) -> x==y) -> + xdata = @data; ydata = y.data or y + length = @data.length + if length!=y.length then return false + for i in [0...length] + if not trail.unify(xdata[i], ydata[i], equal) then return false + true + + toString: () -> @data.toString() + +# make unifable array +exports.uarray = uarray = (x) -> new UArray(x) + +exports.Cons = class Cons + constructor: (@head, @tail) -> + + getvalue: (trail, memo={}) -> + head = @head; tail = @tail + head1 = trail.getvalue(head, memo) + tail1 = trail.getvalue(tail, memo) + if head1 is head and tail1 is tail then @ + else new Cons(head1, tail1) + + unify: (y, trail, equal=(x, y) -> x==y) -> + if y not instanceof Cons then false + else if not trail.unify(@head, y.head, equal) then false + else trail.unify(@tail, y.tail, equal) + + flatString: () -> + result = "#{@head}" + tail = @tail + if tail is null then result += '' + else if tail instanceof Cons + result += ',' + result += tail.flatString() + else result += tail.toString() + result + + toString: () -> "cons(#{@head}, #{@tail})" + +# cons, like pair in lisp +exports.cons = (x, y) -> new Cons(x, y) + +# conslist, like list in lisp +exports.conslist = (args...) -> + result = null + for i in [args.length-1..0] by -1 + result = new Cons([args[i], result]) + result + +# make unifiable array or unifiable object +exports.unifiable = (x) -> + if _.isArray(x) then new UArray(x) + else if _.isObject(x) then new UObject(x) + else x \ No newline at end of file diff --git a/coffee/logicpeasy.coffee b/coffee/logicpeasy.coffee deleted file mode 100644 index 444d397..0000000 --- a/coffee/logicpeasy.coffee +++ /dev/null @@ -1,294 +0,0 @@ -### an extended parser with logic features ### - -if typeof window=='object' then {require, exports, module} = twoside('/logicpeasy') -do (require=require, exports=exports, module=module) -> -# The two lines above make this module can be used both in browser(with twoside.js) and on node.js - - peasy = require "./peasy" - - exports.Parser = class Parser extends peasy.Parser - constructor: -> - super - self = @ - - @parse = (data, root=self.root, cur=0) -> - self.data = data - self.cur = cur - self.trail = new Trail - self.ruleStack = {} - self.cache = {} - root() - - @bind = (vari, term) -> - vari.bind(self.trail.deref(term)) - true - - @unify = (x, y, equal=((x, y) -> x==y)) -> - self.trail.unify(x, y, equal) - - @unifyList = (xs, ys, equal=((x, y) -> x==y)) -> - xlen = xs.length - if ys.length isnt xlen then return false - else - _unify = self.trail.unify - for i in [0...xlen] - if not _unify(xs[i], ys[i], equal) then return false - true - - # combinator *orp*
- @orp = (items...) -> - items = for item in items then (if (typeof item)=='string' then self.literal(item) else item) - -> - start = self.cur - length = items.length - for i in [0...length] - self.cur = start - self.trail = new Trail - if result = items[i]() then return result - if i!= length-1 then self.trail.undo() - result - - # matcher *char*: match one character
- @unifyChar = (x) -> -> - x = self.trail.deref(x) - if x instanceof Var then c = self.data[self.cur++]; x.bind(c); c - else if self.data[self.cur]==x then self.cur++; x - - @unifyDigit = (x) -> -> - c = self.data[self.cur] - if '0'<=c<='9' - x = self.trail.deref(x) - if x instanceof Var then self.cur++; x.bind(c); c - else if x==c then self.cur++; c - - @unifyLetter = (x) -> -> - c = self.data[self.cur] - if 'a'<=x<='z' or 'A'<=x<='Z' - x = self.trail.deref(x) - if x instanceof Va then x.bind(c); self.cur++; c - else if x==c then self.cur++; c - - @unifyLower = (x) -> -> - c = self.data[self.cur]; - if 'a'<=x<='z' - x = self.trail.deref(x) - if x instanceof Var then x.bind(c); self.cur++; c - else if x==c then self.cur++; c - - @unifyUpper = (x) -> -> - c = self.data[self.cur] - if 'A'<=x<='Z' - x = self.trail.deref(x) - if x instanceof Var then x.bind(c); self.cur++; c - else if x==c then self.cur++; c - - @unifyIdentifier = (x) -> -> - if n = self.identifier() and self.unify(x, n) then n - - exports.Error = class Error - constructor: (@exp, @message='', @stack = @) -> # @stack: to make webstorm nodeunit happy. - toString: () -> "#{@constructor.name}: #{@exp} >>> #{@message}" - - exports.BindingError = class BindingError extends Error - - # record the trail for variable binding
- # when multiple choices exist, a new Trail for current branch is constructored,
- # when backtracking, undo the trail to restore the previous variable binding - exports.Trail = class Trail - constructor: (@data={}) -> - copy: () -> new Trail(_.extend({},@data)) - set: (vari, value) -> - data = @data - if not data.hasOwnProperty(vari.name) - data[vari.name] = [vari, value] - - undo: () -> for nam, pair of @data then pair[0].binding = pair[1] - - deref: (x) -> x?.deref?(@) or x - getvalue: (x, memo={}) -> - getvalue = x?.getvalue - if getvalue then getvalue.call(x, @, memo) - else x - unify: (x, y, equal) -> - x = @deref(x); y = @deref(y) - if x instanceof Var then @set(x, x.binding); x.binding = y; true; - else if y instanceof Var then @set(y, y.binding); y.binding = x; true; - else x?.unify?(y, @) or y?.unify?(x, @) or equal(x, y) - - # ####class Var - # Var for logic bindings, used in unify, lisp.assign, inc/dec, parser operation, etc. - exports.Var = class Var - constructor: (@name='', @binding = @) -> - deref: (trail) -> - v = @ - next = @binding - if next is @ or next not instanceof Var then next - else - chains = [v] - length = 1 - while 1 - chains.push(next) - v = next; next = v.binding - length++ - if next is v - for i in [0...chains.length-2] - x = chains[i] - x.binding = next - trail.set(x, chains[i+1]) - return next - else if next not instanceof Var - for i in [0...chains.length-1] - x = chains[i] - x.binding = next - trail.set(x, chains[i+1]) - return next - - bind: (value, trail) -> - trail.set(@, @binding) - @binding = trail.deref(value) - - getvalue: (trail, memo={}) -> - name = @name - if memo.hasOwnProperty(name) then return memo[name] - result = @deref(trail) - if result instanceof Var - memo[name] = result - result - else - result = trail.getvalue(result, memo) - memo[name] = result - result - - toString:() -> "vari(#{@name})" - - reElements = /\s*,\s*|\s+/ - - # utilities for new variables - # sometiems, say in macro, we need unique var to avoid name conflict - nameToIndexMap = {} - exports.vari = (name='') -> - index = nameToIndexMap[name] or 1 - nameToIndexMap[name] = index+1 - new Var(name+index) - - exports.vars = (names) -> vari(name) for name in split names, reElements - - # DummyVar never fail when it unify. see tests on any/some/times in test_parser for examples - exports.DummyVar = class DummyVar extends Var - constructor: (name) -> @name = '_$'+name - deref: (trail) -> @ - getvalue: (trail, memo={}) -> - name = @name - if memo.hasOwnProperty(name) then return memo[name] - result = @binding - if result is @ - memo[name] = result - result - else - result = trail.getvalue(result, memo) - memo[name] = result - result - - # nottodo: variable's applyCont:: canceled. lisp1 should be good. - exports.dummy = dummy = (name) -> - index = nameToIndexMap[name] or 1 - nameToIndexMap[name] = index+1 - new exports.DummyVar(name+index) - exports.dummies = (names) -> new dummy(name) for name in split names, reElements - - exports.UObject = class UObject - constructor: (@data) -> - - getvalue: (trail, memo) -> - result = {} - changed = false - for key, value of @data - v = trail.getvalue(value, memo) - if v isnt value then changed = true - result[key] = v - if changed then new UObject(result) - else @ - - unify: (y, trail, equal=(x, y) -> x==y) -> - xdata = @data - ydata = if y instanceof UObject then y.data else y - ykeys = Object.keys(y) - for key of xdata - index = ykeys.indexOf(key) - if index==-1 then return false - if not trail.unify(xdata[key], ydata[key], equal) then return false - ykeys.splice(index, 1); - if ykeys.length isnt 0 then return false - true - - # make unifable object - exports.uobject = (x) -> new UObject(x) - - exports.UArray = class UArray - constructor: (@data) -> - - getvalue: (trail, memo={}) -> - result = [] - changed = false - for x in @data - v = trail.getvalue(x, memo) - if v isnt x then changed = true - result.push(v) - if changed then new UArray(result) - else @ - - unify: (y, trail, equal=(x, y) -> x==y) -> - xdata = @data; ydata = y.data or y - length = @data.length - if length!=y.length then return false - for i in [0...length] - if not trail.unify(xdata[i], ydata[i], equal) then return false - true - - toString: () -> @data.toString() - - # make unifable array - exports.uarray = uarray = (x) -> new UArray(x) - - exports.Cons = class Cons - constructor: (@head, @tail) -> - - getvalue: (trail, memo={}) -> - head = @head; tail = @tail - head1 = trail.getvalue(head, memo) - tail1 = trail.getvalue(tail, memo) - if head1 is head and tail1 is tail then @ - else new Cons(head1, tail1) - - unify: (y, trail, equal=(x, y) -> x==y) -> - if y not instanceof Cons then false - else if not trail.unify(@head, y.head, equal) then false - else trail.unify(@tail, y.tail, equal) - - flatString: () -> - result = "#{@head}" - tail = @tail - if tail is null then null - else if tail instanceof Cons - result += ',' - result += tail.flatString() - else result += tail.toString() - result - - toString: () -> "cons(#{@head}, #{@tail})" - - # cons, like pair in lisp - exports.cons = (x, y) -> new Cons(x, y) - - # conslist, like list in lisp - exports.conslist = (args...) -> - result = null - for i in [args.length-1..0] by -1 - result = new Cons([args[i], result]) - result - - # make unifiable array or unifiable object - exports.unifiable = (x) -> - if _.isArray(x) then new UArray(x) - else if _.isObject(x) then new UObject(x) - else x \ No newline at end of file diff --git a/coffee/parser.coffee b/coffee/parser.coffee new file mode 100644 index 0000000..8438124 --- /dev/null +++ b/coffee/parser.coffee @@ -0,0 +1,240 @@ +exports = module.exports = class Parser + constructor: -> + self = @ + # base collects all members of peasy.Parser, so that the derived parser can be modularized. + base = @base = {} + @ruleIndex = 0 + + base.parse = @parse = (data, root=self.root, cur=0) -> + self.data = data + self.cur = cur + self.ruleStack = {}; + self.cache = {}; + root() + + # make rule left recursive + base.rec = @rec = (rule) -> + tag = self.ruleIndex++ + -> + ruleStack = self.ruleStack + cache = self.cache[tag] ?= {} + start = self.cur + callStack = ruleStack[start] ?= [] + if tag not in callStack + callStack.push(tag) + m = cache[start] ?= [undefined, start] + while 1 + self.cur = start + result = rule() + if not result then result = m[0]; self.cur = m[1]; break + if m[1]==self.cur then m[0] = result; break + m[0] = result; m[1] = self.cur + callStack.pop() + result + else + m = cache[start] + self.cur = m[1] + m[0] + + base.memo = @memo = (rule) -> + tag = self.ruleIndex++ + => + cache = self.cache[tag] ?= {} + start = self.cur + m = cache[start] + if m then self.cur = m[1]; m[0] + else + result = rule() + self.cache[tag][start] = [result, self.cur] + result + + # combinator *orp*
+ base.orp = @orp = (items...) -> + items = for item in items + if (typeof item)=='string' then self.literal(item) else item + => + start = self.cur + length = items.length + for item in items + self.cur = start + if result = item() then return result + + # #### matchers and combinators
+ base.andp = @andp = (items...) -> + items = for item in items + if (typeof item)=='string' then self.literal(item) else item + -> + for item in items + if not (result = item()) then return + result + + base.notp = @notp = (item) -> + if (typeof item)=='string' then item = self.literal(item) + -> not item() + + base.may = @may = (item) -> + if (typeof item)=='string' then item = self.literal(item) + => + start = self.cur + if x = item() then x + else self.cur = start; true + + # combinator *any*: zero or more times of `item()` + base.any = @any = (item) -> + if (typeof item)=='string' then item = self.literal(item) + => + result = [] + while (x = item()) then result.push(x) + result + + # combinator *some*: one or more times of `item()` + base.some = @some = (item) -> + if (typeof item)=='string' then item = self.literal(item) + -> + if not (x = item()) then return + result = [x] + while (x = item()) then result.push(x) + result + + # combinator *times*: match *self.n* times item(), n>=1 + base.times = @times = (item, n) -> + if (typeof item)=='string' then item = self.literal(item) + -> + i = 0 + while i++ + if (typeof item)=='string' then item = self.literal(item) + if (typeof separator)=='string' then separator = self.literal(separator) + -> + if not (x = item()) then return + result = [x] + while separator() and (x=item()) then result.push(x) + result + + # combinator *listn*: given self.n times self.item separated by self.separator, n>=1 + base.listn = @listn = (item, n, separator=self.spaces) -> + if (typeof item)=='string' then item = self.literal(item) + if (typeof separator)=='string' then separator = self.literal(separator) + -> + if not (x = item()) then return + result = [x] + i = 1 + while i++ + base.follow = @follow = (item) -> + if (typeof item)=='string' then item = self.literal(item) + => + start = self.cur + x = item(); self.cur = start; x + + # matcher *literal*
+ # match a text string.
+ # `notice = some combinators like andp, orp, notp, any, some, etc. use literal to wrap a object which is not a matcher. + base.literal = @literal = (string) -> -> + len = string.length + start = self.cur + if self.data.slice(start, stop = start+len)==string then self.cur = stop; true + + # matcher *char*: match one character
+ base['char'] = @['char'] = (c) -> -> if self.data[self.cur]==c then self.cur++; c + + # matcher *wrap*
+ # match left, then match item, match right at last + base.wrap = @wrap = (item, left=self.spaces, right=self.spaces) -> + if (typeof item)=='string' then item = self.literal(item) + -> if left() and result = item() and right() then result + + # matcher *spaces*: zero or more whitespaces, ie. space or tab.
+ base.spaces = @spaces = -> + data = self.data + len = 0 + cur = self.cur + while 1 + if ((c=data[cur++]) and (c==' ' or c=='\t')) then len++ else break + self.cur += len + len+1 + + # matcher *spaces1*
+ # one or more whitespaces, ie. space or tab.
+ base.spaces1 = @spaces1 = -> + data = self.data + cur = self.cur + len = 0 + while 1 + if ((c=data[cur++]) and (c==' ' or c=='\t')) then lent++ else break + self.cur += len + len + + base.eoi = @eoi = -> self.cur==self.data.length + + # matcher *identifierLetter* = normal version
+ base.identifierLetter = @identifierLetter = -> + c = self.data[self.cur] + if c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' + self.cur++; true + + base.followIdentifierLetter = @followIdentifierLetter = -> + c = self.data[self.cur] + (c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9') and c + + base.digit = @digit = -> c = self.data[self.cur]; if '0'<=c<='9' then self.cur++; c + base.letter = @letter = -> c = self.data[self.cur]; if 'a'<=c<='z' or 'A'<=c<='Z' then self.cur++; c + base.lower = @lower = -> c = self.data[self.cur]; if 'a'<=c<='z' then self.cur++; c + base.upper = @upper = -> c = self.data[self.cur]; if 'A'<=c<='Z' then self.cur++; c + + base.identifier = @identifier = -> + data = self.data + start = cur = self.cur + c = data[cur] + if 'a'<=c<='z' or 'A'<=c<='Z' or c=='$' or c=='_' then cur++ + else return + while 1 + c = data[cur] + if 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or c=='$' or c=='_' then cur++ + else break + self.cur = cur + data[start...cur] + + base.number = @number = -> + data = self.data + cur = self.cur + c = data[cur] + if '0'<=c<='9' then cur++ + else return + while 1 + c = data[cur] + if '0'<=c<='9' then cur++ + else break + self.cur = cur + data[start...cur] + + base.string = @string = -> + text = self.data + start = cur = self.cur + c = text[cur] + if c=='"' or c=="'" then quote = c + else return + cur++ + while 1 + c = text[cur] + if c=='\\' then cur += 2 + else if c==quote + self.cur = cur+1 + return text[start..cur] + else if not c then return + + base.select = @select = (item, actions) -> + console.log 'select' + action = actions[item] + if action then return action() + defaultAction = actions['default'] or actions[''] + if defaultAction then defaultAction() \ No newline at end of file diff --git a/coffee/peasy.coffee b/coffee/peasy.coffee deleted file mode 100644 index 0c1cdd7..0000000 --- a/coffee/peasy.coffee +++ /dev/null @@ -1,271 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/peasy') -do (require=require, exports=exports, module=module) -> -# The two lines above make this module can be used both in browser(with twoside.js) and on node.js - - exports.Parser = class Parser - constructor: -> - self = @ - # base collects all members of peasy.Parser, so that the derived parser can be modularized. - base = @base = {} - @ruleIndex = 0 - - base.parse = @parse = (data, root=self.root, cur=0) -> - self.data = data - self.cur = cur - self.ruleStack = {}; - self.cache = {}; - root() - - # make rule left recursive - base.rec = @rec = (rule) -> - tag = self.ruleIndex++ - -> - ruleStack = self.ruleStack - cache = self.cache[tag] ?= {} - start = self.cur - callStack = ruleStack[start] ?= [] - if tag not in callStack - callStack.push(tag) - m = cache[start] ?= [undefined, start] - while 1 - self.cur = start - result = rule() - if not result then result = m[0]; self.cur = m[1]; break - if m[1]==self.cur then m[0] = result; break - m[0] = result; m[1] = self.cur - callStack.pop() - result - else - m = cache[start] - self.cur = m[1] - m[0] - - base.memo = @memo = (rule) -> - tag = self.ruleIndex++ - => - cache = self.cache[tag] ?= {} - start = self.cur - m = cache[start] - if m then self.cur = m[1]; m[0] - else - result = rule() - self.cache[tag][start] = [result, self.cur] - result - - # combinator *orp*
- base.orp = @orp = (items...) -> - items = for item in items - if (typeof item)=='string' then self.literal(item) else item - => - start = self.cur - length = items.length - for item in items - self.cur = start - if result = item() then return result - - # #### matchers and combinators
- base.andp = @andp = (items...) -> - items = for item in items - if (typeof item)=='string' then self.literal(item) else item - -> - for item in items - if not (result = item()) then return - result - - base.notp = @notp = (item) -> - if (typeof item)=='string' then item = self.literal(item) - -> not item() - - base.may = @may = (item) -> - if (typeof item)=='string' then item = self.literal(item) - => - start = self.cur - if x = item() then x - else self.cur = start; true - - # combinator *any*: zero or more times of `item()` - base.any = @any = (item) -> - if (typeof item)=='string' then item = self.literal(item) - => - result = [] - while (x = item()) then result.push(x) - result - - # combinator *some*: one or more times of `item()` - base.some = @some = (item) -> - if (typeof item)=='string' then item = self.literal(item) - -> - if not (x = item()) then return - result = [x] - while (x = item()) then result.push(x) - result - - # combinator *times*: match *self.n* times item(), n>=1 - base.times = @times = (item, n) -> - if (typeof item)=='string' then item = self.literal(item) - -> - i = 0 - while i++ - if (typeof item)=='string' then item = self.literal(item) - if (typeof separator)=='string' then separator = self.literal(separator) - -> - if not (x = item()) then return - result = [x] - while separator() and (x=item()) then result.push(x) - result - - # combinator *listn*: given self.n times self.item separated by self.separator, n>=1 - base.listn = @listn = (item, n, separator=self.spaces) -> - if (typeof item)=='string' then item = self.literal(item) - if (typeof separator)=='string' then separator = self.literal(separator) - -> - if not (x = item()) then return - result = [x] - i = 1 - while i++ - base.follow = @follow = (item) -> - if (typeof item)=='string' then item = self.literal(item) - => - start = self.cur - x = item(); self.cur = start; x - - # matcher *literal*
- # match a text string.
- # `notice = some combinators like andp, orp, notp, any, some, etc. use literal to wrap a object which is not a matcher. - base.literal = @literal = (string) -> -> - len = string.length - start = self.cur - if self.data.slice(start, stop = start+len)==string then self.cur = stop; true - - # matcher *char*: match one character
- base.char = @char = (c) -> -> if self.data[self.cur]==c then self.cur++; c - - # matcher *wrap*
- # match left, then match item, match right at last - base.wrap = @wrap = (item, left=self.spaces, right=self.spaces) -> - if (typeof item)=='string' then item = self.literal(item) - -> if left() and result = item() and right() then result - - # matcher *spaces*: zero or more whitespaces, ie. space or tab.
- base.spaces = @spaces = -> - data = self.data - len = 0 - cur = self.cur - while 1 - if ((c=data[cur++]) and (c==' ' or c=='\t')) then len++ else break - self.cur += len - len+1 - - # matcher *spaces1*
- # one or more whitespaces, ie. space or tab.
- base.spaces1 = @spaces1 = -> - data = self.data - cur = self.cur - len = 0 - while 1 - if ((c=data[cur++]) and (c==' ' or c=='\t')) then lent++ else break - self.cur += len - len - - base.eoi = @eoi = -> self.cur==self.data.length - - # matcher *identifierLetter* = normal version
- base.identifierLetter = @identifierLetter = -> - c = self.data[self.cur] - if c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9' - self.cur++; true - - base.followIdentifierLetter = @followIdentifierLetter = -> - c = self.data[self.cur] - (c is '$' or c is '_' or 'a'<=c<'z' or 'A'<=c<='Z' or '0'<=c<='9') and c - - base.digit = @digit = -> c = self.data[self.cur]; if '0'<=c<='9' then self.cur++; c - base.letter = @letter = -> c = self.data[self.cur]; if 'a'<=c<='z' or 'A'<=c<='Z' then self.cur++; c - base.lower = @lower = -> c = self.data[self.cur]; if 'a'<=c<='z' then self.cur++; c - base.upper = @upper = -> c = self.data[self.cur]; if 'A'<=c<='Z' then self.cur++; c - - base.identifier = @identifier = -> - data = self.data - start = cur = self.cur - c = data[cur] - if 'a'<=c<='z' or 'A'<=c<='Z' or c=='$' or c=='_' then cur++ - else return - while 1 - c = data[cur] - if 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' or c=='$' or c=='_' then cur++ - else break - self.cur = cur - data[start...cur] - - base.number = @number = -> - data = self.data - cur = self.cur - c = data[cur] - if '0'<=c<='9' then cur++ - else return - while 1 - c = data[cur] - if '0'<=c<='9' then cur++ - else break - self.cur = cur - data[start...cur] - - base.string = @string = -> - text = self.data - start = cur = self.cur - c = text[cur] - if c=='"' or c=="'" then quote = c - else return - cur++ - while 1 - c = text[cur] - if c=='\\' then cur += 2 - else if c==quote - self.cur = cur+1 - return text[start..cur] - else if not c then return - - base.select = @select = (item, actions) -> - console.log 'select' - action = actions[item] - if action then return action() - defaultAction = actions['default'] or actions[''] - if defaultAction then defaultAction() - - exports.debugging = false - exports.testing = false - exports.debug = (message) -> if exports.debugging then console.log message - exports.warn = (message) -> if exports.debugging or exports.testing then console.log message - - ### some utilities for parsing ### - Charset = (string) -> @[x] = true for x in string; this - Charset::contain = (char) -> @hasOwnProperty(char) - exports.charset = charset = (string) -> new Charset(string) - - exports.inCharset = exports.in_ = (char, set) -> - exports.warn 'peasy.inCharset(char, set) is deprecated, use set.contain(char) instead.' - set.hasOwnProperty(char) - - exports.isdigit = (c) -> '0'<=c<='9' - exports.isletter = (c) -> 'a'<=c<='z' or 'A'<=c<='Z' - exports.islower = (c) -> 'a'<=c<='z' - exports.isupper = (c) ->'A'<=c<='Z' - exports.isIdentifierLetter = (c) -> c=='$' or c=='_' or 'a'<=c<='z' or 'A'<=c<='Z' or '0'<=c<='9' - - exports.digits = digits = '0123456789' - exports.lowers = lowers = 'abcdefghijklmnopqrstuvwxyz' - exports.uppers = uppers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - exports.letters = letters = lowers+uppers - exports.letterDigits = letterDigits = letterDigits - diff --git a/coffee/samples/arithmatic.coffee b/coffee/samples/arithmatic.coffee index 627379c..6f9c156 100644 --- a/coffee/samples/arithmatic.coffee +++ b/coffee/samples/arithmatic.coffee @@ -1,220 +1,217 @@ -if typeof window=='object' then {require, exports, module} = twoside('/samples/arithmatic') -do (require=require, exports=exports, module=module) -> - - peasy = require "../peasy" - - {in_, charset, letterDigits} = peasy - _in_ = in_ - identifierChars = '$_'+letterDigits - identifierCharSet = charset(identifierChars) - - exports.Parser = class Parser extends peasy.Parser - constructor: -> - super - self = @ - - number = -> - text = self.data - start = cur = self.cur - base = 10 - c = text[cur] - if c=='+' or c=='-' then cur++ - if text[cur]=='0' - c = text[++cur] - if c=='x' or c=='X' then base = 16; cur++ - if base==16 - while c = text[cur] - if not ('0'<=c<='9' or 'a'<=c<='f' or 'A'<=c<='F') - self.cur = cur - return text[start...cur] - cur++ +peasy = require "../index" + +{in_, charset, letterDigits} = peasy +_in_ = in_ +identifierChars = '$_'+letterDigits +identifierCharSet = charset(identifierChars) + +exports.Parser = class Parser extends peasy.Parser + constructor: -> + super + self = @ + + number = -> + text = self.data + start = cur = self.cur + base = 10 + c = text[cur] + if c=='+' or c=='-' then cur++ + if text[cur]=='0' + c = text[++cur] + if c=='x' or c=='X' then base = 16; cur++ + if base==16 while c = text[cur] - if not ('0'<=c<='9') then break + if not ('0'<=c<='9' or 'a'<=c<='f' or 'A'<=c<='F') + self.cur = cur + return text[start...cur] cur++ - if text[cur]=='.' + while c = text[cur] + if not ('0'<=c<='9') then break + cur++ + if text[cur]=='.' + cur++ + while c = text[cur] + if not ('0'<=c<='9') then break cur++ - while c = text[cur] - if not ('0'<=c<='9') then break - cur++ - if text[cur-1]=='.' and (c = text[cur-2]) and not ('0'<=c<='9') then return - c = text[cur] - if c=='E' or c=='e' + if text[cur-1]=='.' and (c = text[cur-2]) and not ('0'<=c<='9') then return + c = text[cur] + if c=='E' or c=='e' + cur++ + while c = text[cur] + if not ('0'<=c<='9') then break cur++ - while c = text[cur] - if not ('0'<=c<='9') then break - cur++ - if (c =text[cur-1]) and (c=='E' or c=='e') then return - self.cur = cur - text[start...cur] - - string = -> - text = self.data - cur = self.cur + if (c =text[cur-1]) and (c=='E' or c=='e') then return + self.cur = cur + text[start...cur] + + string = -> + text = self.data + cur = self.cur + c = text[cur] + if c=='"' or c=="'" then quote = c + else return + result = '' + cur++ + while 1 c = text[cur] - if c=='"' or c=="'" then quote = c - else return - result = '' - cur++ - while 1 - c = text[cur] - if c=='\\' then result += text[cur+1]; cur += 2; - else if c==quote - self.cur = cur+1 - return quote+result+quote - else if not c then error('expect '+quote) - else result += c; cur++ - - {orp, rec, memo, wrap, char, literal, spaces, eoi, identifier} = self = @ - - question = char('?'); colon = char(':'); comma = char(','); dot = char('.') - lpar = char('('); rpar = char(')') - lbracket = char('['); rbracket = char(']') - - myop = (op) -> - if op.length==1 then opFn = char(op) else opFn = literal(op) - if _in_(op[0], identifierCharSet) - -> spaces() and (op=opFn()) and spaces() and not _in_(data[self.cur], identifierCharSet) and ' '+op+' ' - else -> spaces() and (op=opFn()) and spaces() and op - - posNeg = (op) -> - opFn = char(op) - -> spaces() and (op=opFn()) and (c = self.data[self.cur]) and c!='.' and not('0'<=c<='9') and spaces() and op - positive = posNeg('+'); negative = posNeg('-') - new_ = myop('new') - inc = myop('++'); dec = myop('--') - not1 = orp(myop('!'), myop('not')) - not_ = -> not1() and '!' - bitnot = myop('~') - typeof_ = myop('typeof'); void_ = myop('void'); delete_ = myop('delete') - unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_) - plus = myop('+'); minus = myop('-') - mul = myop('*'); div = myop('/'); idiv = myop('//'); mod = myop('%') - lshift = myop('<<'); rshift = myop('>>'); zrshift = myop('>>>') - lt = myop('<'); le = myop('<='); gt = myop('>'); ge = myop('>=') - in_ = myop('in'); instanceof_ = myop('instanceof') - eq = myop('=='); ne = myop('!='); eq2 = myop('==='); ne2 = myop('!==') - bitand = myop('&'); bitxor = myop('^'); bitor = myop('|') - and1 = orp(myop('&&'), myop('and')) - and_ = -> and1() and '&&' - or1 = orp(myop('||'), myop('or')) - or_ = -> or1() and '||' - comma = myop(',') - assign = myop('='); - addassign = myop('+='); subassign = myop('-=') - mulassign = myop('*='); divassign = myop('/='); modassign = myop('%='); idivassign = myop('//=') - rshiftassign = myop('>>='); lshiftassign = myop('<<='); zrshiftassign = myop('>>>=') - bitandassign = myop('&='); bitxorassign = myop('^='); bitorassign = myop('|=') - - error = (msg) -> throw self.data[self.cur-20..self.cur+20]+' '+self.cur+': '+msg - expect = (fn, msg) -> fn() or error(msg) - - incDec = orp(inc, dec) - prefixOperation = -> (op=incDec()) and (x=headExpr()) and op+x - suffixOperation = -> (x=headExpr()) and (op=incDec()) and x+op - - paren = (item, left=lpar, right=rpar, msg='expect ) to match (') -> - if (typeof item)=='string' then left = self.literal(item) - if (typeof left)=='string' then left = self.literal(left) - if (typeof right)=='string' then right = self.literal(right) - -> start=self.cur; left() and (x=item()) and expect(right, msg+' at: '+start) and x - - paren1 = paren(-> (spaces() and (x=expr()) and spaces() and x)) - parenExpr = memo -> (x=paren1()) and '('+x+')' - literalExpr = orp(number, string, identifier) - atom = memo orp(parenExpr, literalExpr) - unaryTail = orp(prefixSuffixExpr, atom) - unary_ = -> (op=unaryOp()) and (x=unaryTail()) and op+x - - bracketExpr1 = wrap(paren(wrap(-> commaExpr()), lbracket, rbracket, 'expect ) to match (')) - bracketExpr = -> (x=bracketExpr1()) and '['+x+']' - wrapDot = wrap(dot) - dotIdentifier = -> wrapDot() and (id=expect(identifier, 'expect identifier')) and '.'+id - attr = orp(bracketExpr, dotIdentifier) - param = paren -> (spaces() and (x=expr()) and spaces() and expect(rpar,'expect )')) or ' ' - paramExpr = memo -> (x=param()) and '('+x+')' - callPropTail = orp(paramExpr, attr) - callProp = rec -> (h=headExpr()) and (((e=callPropTail()) and h+e) or h) - property = rec -> (h=headExpr()) and (((e=attr()) and h+e) or h) - headAtom = memo orp(parenExpr, identifier) - headExpr = memo orp(callProp, headAtom) - - wrapQuestion = wrap(question) - wrapColon = wrap(colon) - condition_ = -> (x=logicOrExpr()) and wrapQuestion() and (y=assignExpr()) and expect(wrapColon, 'expect :') and (z=assignExpr()) and x+'? '+y+': '+z - assignLeft = property - assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign,\ - rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign) - assignExpr_ = -> (v=assignLeft()) and (op=assignOperator()) and (e=assignExpr()) and v+op+e - - #https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence - ''' - Precedence Operator type Associativity Individual operators - 1 new right-to-left new - 2 function call left-to-right () - property access left-to-right . - left-to-right [] - 3 ++ n/a -- - 4 right-to-left ! ~ + - typeof void delete - 5 * / % // - 6 + - - 7 << >> >>> - 8 < <= > >= in instanceof - 9 == != === !== - 10 bitwise-and left-to-right & - 11 bitwise-xor left-to-right ^ - 12 bitwise-or left-to-right | - 13 logical-and left-to-right && - 14 logical-or left-to-right || - 15 condition right-to-left ?: - 16 yield right-to-left yield - 17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |= - 18 comma left-to-right , - ''' - operations = - 0: atom - 1: -> new_() and (x=expr()) and 'new '+x - 2: callProp - 3: orp(prefixOperation, suffixOperation) - 4: unary_ - 5: [mul, div, idiv] - 6: [plus, minus] - 7: [lshift, rshift, zrshift] - 8: [lt, le, gt, ge, in_, instanceof_] - 9: [eq, ne, eq2, ne2] - 10: [bitand] - 11: [bitxor] - 12: [bitor] - 13: [and_] - 14: [or_] - 15: condition_ - 16: assignExpr_ - 17: [comma] - - operationFnList = [atom] - - getExpr = (n) -> - operation = operations[n] - lower = operationFnList[n-1] - if typeof operation == 'function' then orp(operation, lower) - else - operator = if operation.length==1 then operation[0] else orp(operation...) - binary = rec -> - n - start = self.cur; - if (x = binary()) - if (op=operator()) and (y=lower()) then x+op+y - else x - else self.cur=start; lower() - - for i in [1..17] then operationFnList[i] = getExpr(i) - - prefixSuffixExpr = operationFnList[3] - logicOrExpr = operationFnList[14] - assignExpr = operationFnList[16] - expr = operationFnList[16] - - @root = -> (x=expr()) and expect(eoi, 'expect end of input') and x - - exports.parser = parser = new Parser - - exports.parse = (text) -> parser.parse(text) \ No newline at end of file + if c=='\\' then result += text[cur+1]; cur += 2; + else if c==quote + self.cur = cur+1 + return quote+result+quote + else if not c then error('expect '+quote) + else result += c; cur++ + + {orp, rec, memo, wrap, char, literal, spaces, eoi, identifier} = self = @ + + question = char('?'); colon = char(':'); comma = char(','); dot = char('.') + lpar = char('('); rpar = char(')') + lbracket = char('['); rbracket = char(']') + + myop = (op) -> + if op.length==1 then opFn = char(op) else opFn = literal(op) + if _in_(op[0], identifierCharSet) + -> spaces() and (op=opFn()) and spaces() and not _in_(data[self.cur], identifierCharSet) and ' '+op+' ' + else -> spaces() and (op=opFn()) and spaces() and op + + posNeg = (op) -> + opFn = char(op) + -> spaces() and (op=opFn()) and (c = self.data[self.cur]) and c!='.' and not('0'<=c<='9') and spaces() and op + positive = posNeg('+'); negative = posNeg('-') + new_ = myop('new') + inc = myop('++'); dec = myop('--') + not1 = orp(myop('!'), myop('not')) + not_ = -> not1() and '!' + bitnot = myop('~') + typeof_ = myop('typeof'); void_ = myop('void'); delete_ = myop('delete') + unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_) + plus = myop('+'); minus = myop('-') + mul = myop('*'); div = myop('/'); idiv = myop('//'); mod = myop('%') + lshift = myop('<<'); rshift = myop('>>'); zrshift = myop('>>>') + lt = myop('<'); le = myop('<='); gt = myop('>'); ge = myop('>=') + in_ = myop('in'); instanceof_ = myop('instanceof') + eq = myop('=='); ne = myop('!='); eq2 = myop('==='); ne2 = myop('!==') + bitand = myop('&'); bitxor = myop('^'); bitor = myop('|') + and1 = orp(myop('&&'), myop('and')) + and_ = -> and1() and '&&' + or1 = orp(myop('||'), myop('or')) + or_ = -> or1() and '||' + comma = myop(',') + assign = myop('='); + addassign = myop('+='); subassign = myop('-=') + mulassign = myop('*='); divassign = myop('/='); modassign = myop('%='); idivassign = myop('//=') + rshiftassign = myop('>>='); lshiftassign = myop('<<='); zrshiftassign = myop('>>>=') + bitandassign = myop('&='); bitxorassign = myop('^='); bitorassign = myop('|=') + + error = (msg) -> throw self.data[self.cur-20..self.cur+20]+' '+self.cur+': '+msg + expect = (fn, msg) -> fn() or error(msg) + + incDec = orp(inc, dec) + prefixOperation = -> (op=incDec()) and (x=headExpr()) and op+x + suffixOperation = -> (x=headExpr()) and (op=incDec()) and x+op + + paren = (item, left=lpar, right=rpar, msg='expect ) to match (') -> + if (typeof item)=='string' then left = self.literal(item) + if (typeof left)=='string' then left = self.literal(left) + if (typeof right)=='string' then right = self.literal(right) + -> start=self.cur; left() and (x=item()) and expect(right, msg+' at: '+start) and x + + paren1 = paren(-> (spaces() and (x=expr()) and spaces() and x)) + parenExpr = memo -> (x=paren1()) and '('+x+')' + literalExpr = orp(number, string, identifier) + atom = memo orp(parenExpr, literalExpr) + unaryTail = orp(prefixSuffixExpr, atom) + unary_ = -> (op=unaryOp()) and (x=unaryTail()) and op+x + + bracketExpr1 = wrap(paren(wrap(-> commaExpr()), lbracket, rbracket, 'expect ) to match (')) + bracketExpr = -> (x=bracketExpr1()) and '['+x+']' + wrapDot = wrap(dot) + dotIdentifier = -> wrapDot() and (id=expect(identifier, 'expect identifier')) and '.'+id + attr = orp(bracketExpr, dotIdentifier) + param = paren -> (spaces() and (x=expr()) and spaces() and expect(rpar,'expect )')) or ' ' + paramExpr = memo -> (x=param()) and '('+x+')' + callPropTail = orp(paramExpr, attr) + callProp = rec -> (h=headExpr()) and (((e=callPropTail()) and h+e) or h) + property = rec -> (h=headExpr()) and (((e=attr()) and h+e) or h) + headAtom = memo orp(parenExpr, identifier) + headExpr = memo orp(callProp, headAtom) + + wrapQuestion = wrap(question) + wrapColon = wrap(colon) + condition_ = -> (x=logicOrExpr()) and wrapQuestion() and (y=assignExpr()) and expect(wrapColon, 'expect :') and (z=assignExpr()) and x+'? '+y+': '+z + assignLeft = property + assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign,\ + rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign) + assignExpr_ = -> (v=assignLeft()) and (op=assignOperator()) and (e=assignExpr()) and v+op+e + + #https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence + ''' + Precedence Operator type Associativity Individual operators + 1 new right-to-left new + 2 function call left-to-right () + property access left-to-right . + left-to-right [] + 3 ++ n/a -- + 4 right-to-left ! ~ + - typeof void delete + 5 * / % // + 6 + - + 7 << >> >>> + 8 < <= > >= in instanceof + 9 == != === !== + 10 bitwise-and left-to-right & + 11 bitwise-xor left-to-right ^ + 12 bitwise-or left-to-right | + 13 logical-and left-to-right && + 14 logical-or left-to-right || + 15 condition right-to-left ?: + 16 yield right-to-left yield + 17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |= + 18 comma left-to-right , + ''' + operations = + 0: atom + 1: -> new_() and (x=expr()) and 'new '+x + 2: callProp + 3: orp(prefixOperation, suffixOperation) + 4: unary_ + 5: [mul, div, idiv] + 6: [plus, minus] + 7: [lshift, rshift, zrshift] + 8: [lt, le, gt, ge, in_, instanceof_] + 9: [eq, ne, eq2, ne2] + 10: [bitand] + 11: [bitxor] + 12: [bitor] + 13: [and_] + 14: [or_] + 15: condition_ + 16: assignExpr_ + 17: [comma] + + operationFnList = [atom] + + getExpr = (n) -> + operation = operations[n] + lower = operationFnList[n-1] + if typeof operation == 'function' then orp(operation, lower) + else + operator = if operation.length==1 then operation[0] else orp(operation...) + binary = rec -> + n + start = self.cur; + if (x = binary()) + if (op=operator()) and (y=lower()) then x+op+y + else x + else self.cur=start; lower() + + for i in [1..17] then operationFnList[i] = getExpr(i) + + prefixSuffixExpr = operationFnList[3] + logicOrExpr = operationFnList[14] + assignExpr = operationFnList[16] + expr = operationFnList[16] + + @root = -> (x=expr()) and expect(eoi, 'expect end of input') and x + +exports.parser = parser = new Parser + +exports.parse = (text) -> parser.parse(text) \ No newline at end of file diff --git a/coffee/samples/arithmatic2.coffee b/coffee/samples/arithmatic2.coffee index ade05b5..6bf9dfd 100644 --- a/coffee/samples/arithmatic2.coffee +++ b/coffee/samples/arithmatic2.coffee @@ -1,197 +1,194 @@ -if typeof window=='object' then {require, exports, module} = twoside('/samples/arithmatic2') -do (require=require, exports=exports, module=module) -> - - ###https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence - Precedence Operator type Associativity Individual operators - 1 new right-to-left new - 2 function call left-to-right () - property access left-to-right . - left-to-right [] - 3 ++ n/a -- - 4 right-to-left ! ~ + - typeof void delete - 5 * / % // - 6 + - - 7 << >> >>> - 8 < <= > >= in instanceof - 9 == != === !== - 10 bitwise-and left-to-right & - 11 bitwise-xor left-to-right ^ - 12 bitwise-or left-to-right | - 13 logical-and left-to-right && - 14 logical-or left-to-right || - 15 condition right-to-left ?: - 16 yield right-to-left yield - 17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |= - 18 comma left-to-right , - ### - - peasy = require "../peasy" - {StateMachine} = require "./statemachine" - - {in_, charset, letterDigits} = peasy - _in_ = in_ - identifierChars = '$_'+letterDigits - identifierCharSet = charset(identifierChars) - - exports.Parser = class Parser extends peasy.Parser - constructor: -> - super - {orp, list, rec, memo, wrap, char, literal, spaces, eoi, identifier} = self = @ - - number = -> - text = self.data - start = cur = self.cur - base = 10 - c = text[cur] - if c=='+' or c=='-' then cur++ - if text[cur]=='0' - c = text[++cur] - if c=='x' or c=='X' then base = 16; cur++ - if base==16 - while c = text[cur] - if not ('0'<=c<='9' or 'a'<=c<='f' or 'A'<=c<='F') - self.cur = cur - return text[start...cur] - cur++ +###https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence +Precedence Operator type Associativity Individual operators +1 new right-to-left new +2 function call left-to-right () +property access left-to-right . +left-to-right [] +3 ++ n/a -- +4 right-to-left ! ~ + - typeof void delete +5 * / % // +6 + - +7 << >> >>> +8 < <= > >= in instanceof +9 == != === !== +10 bitwise-and left-to-right & +11 bitwise-xor left-to-right ^ +12 bitwise-or left-to-right | +13 logical-and left-to-right && +14 logical-or left-to-right || +15 condition right-to-left ?: +16 yield right-to-left yield +17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |= +18 comma left-to-right , +### + +peasy = require "../index" +{StateMachine} = require "./statemachine" + +{in_, charset, letterDigits} = peasy +_in_ = in_ +identifierChars = '$_'+letterDigits +identifierCharSet = charset(identifierChars) + +exports.Parser = class Parser extends peasy.Parser + constructor: -> + super + {orp, list, rec, memo, wrap, char, literal, spaces, eoi, identifier} = self = @ + + number = -> + text = self.data + start = cur = self.cur + base = 10 + c = text[cur] + if c=='+' or c=='-' then cur++ + if text[cur]=='0' + c = text[++cur] + if c=='x' or c=='X' then base = 16; cur++ + if base==16 while c = text[cur] - if not ('0'<=c<='9') then break + if not ('0'<=c<='9' or 'a'<=c<='f' or 'A'<=c<='F') + self.cur = cur + return text[start...cur] cur++ - if text[cur]=='.' + while c = text[cur] + if not ('0'<=c<='9') then break + cur++ + if text[cur]=='.' + cur++ + while c = text[cur] + if not ('0'<=c<='9') then break cur++ - while c = text[cur] - if not ('0'<=c<='9') then break - cur++ - if text[cur-1]=='.' and (c = text[cur-2]) and not ('0'<=c<='9') then return - c = text[cur] - if c=='E' or c=='e' + if text[cur-1]=='.' and (c = text[cur-2]) and not ('0'<=c<='9') then return + c = text[cur] + if c=='E' or c=='e' + cur++ + while c = text[cur] + if not ('0'<=c<='9') then break cur++ - while c = text[cur] - if not ('0'<=c<='9') then break - cur++ - if (c =text[cur-1]) and (c=='E' or c=='e') then return - self.cur = cur - text[start...cur] - - string = -> - text = self.data - cur = self.cur + if (c =text[cur-1]) and (c=='E' or c=='e') then return + self.cur = cur + text[start...cur] + + string = -> + text = self.data + cur = self.cur + c = text[cur] + if c=='"' or c=="'" then quote = c + else return + result = '' + cur++ + while 1 c = text[cur] - if c=='"' or c=="'" then quote = c - else return - result = '' - cur++ - while 1 - c = text[cur] - if c=='\\' then result += text[cur+1]; cur += 2; - else if c==quote - self.cur = cur+1 - return quote+result+quote - else if not c then error('expect '+quote) - else result += c; cur++ - - question = char('?'); colon = char(':'); comma = char(','); dot = char('.') - lpar = char('('); rpar = char(')') - lbracket = char('['); rbracket = char(']') - - myop = (op) -> - if op.length==1 then opFn = char(op) else opFn = literal(op) - if _in_(op[0], identifierCharSet) - -> spaces() and (op=opFn()) and spaces() and not _in_(data[self.cur], identifierCharSet) and ' '+op+' ' - else -> spaces() and (op=opFn()) and spaces() and op - - posNeg = (op) -> - opFn = char(op) - -> spaces() and (op=opFn()) and (c = self.data[self.cur]) and c!='.' and not('0'<=c<='9') and spaces() and op - positive = posNeg('+'); negative = posNeg('-') - new_ = myop('new') - inc = myop('++'); dec = myop('--') - not1 = orp(myop('!'), myop('not')) - not_ = -> not1() - bitnot = myop('~') - typeof_ = myop('typeof'); void_ = myop('void'); delete_ = myop('delete') - unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_) - comma = myop(',') - assign = myop('='); - addassign = myop('+='); subassign = myop('-=') - mulassign = myop('*='); divassign = myop('/='); modassign = myop('%='); idivassign = myop('//=') - rshiftassign = myop('>>='); lshiftassign = myop('<<='); zrshiftassign = myop('>>>=') - bitandassign = myop('&='); bitxorassign = myop('^='); bitorassign = myop('|=') - - error = (msg) -> throw self.data[self.cur-20..self.cur+20]+' '+self.cur+': '+msg - expect = (fn, msg) -> fn() or error(msg) - - incDec = orp(inc, dec) - prefixExpr = -> (op=incDec()) and (x=headExpr()) and op+x - suffixExpr = -> (x=headExpr()) and (op=incDec()) and x+op - - paren = (item, left=lpar, right=rpar, msg='expect ) to match (') -> - if (typeof item)=='string' then left = self.literal(item) - if (typeof left)=='string' then left = self.literal(left) - if (typeof right)=='string' then right = self.literal(right) - -> start=self.cur; left() and (x=item()) and expect(right, msg+' at: '+start) and x - - paren1 = paren(-> (spaces() and (x=expression()) and spaces() and x)) - parenExpr = memo -> (x=paren1()) and '('+x+')' - atom = memo orp(parenExpr, number, string, identifier) - newExpr = -> new_() and (x=callProp()) and 'new '+x - unaryTail = orp(prefixExpr, suffixExpr, atom) - unaryExpr = -> (op=unaryOp()) and (x=unaryTail()) and op+x - - bracketExpr1 = wrap(paren(wrap(-> commaExpr()), lbracket, rbracket, 'expect ] to match [')) - bracketExpr = -> (x=bracketExpr1()) and '['+x+']' - wrapDot = wrap(dot) - dotIdentifier = -> wrapDot() and (id=expect(identifier, 'expect identifier')) and '.'+id - attr = orp(bracketExpr, dotIdentifier) - param = paren -> (spaces() and (x=expression()) and spaces() and expect(rpar,'expect )')) or ' ' - paramExpr = memo -> (x=param()) and '('+x+')' - callPropTail = orp(paramExpr, attr) - callPropExpr = rec -> (h=headExpr()) and (((e=callPropTail()) and h+e) or h) - property = rec -> (h=headExpr()) and (((e=attr()) and h+e) or h) - headAtom = memo orp(parenExpr, identifier) - headExpr = memo orp(callPropExpr, headAtom) - simpleExpr = memo orp(unaryExpr, prefixExpr, suffixExpr, callPropExpr, newExpr, atom) - - binaryOpPriorityMap = - 5: ['*', '/', '//', '%'] - 6: ['+', '-'] - 7: ['<<', '>>', '>>>'] - 8: ['<', '<=', '>', '>=', 'in ', 'in\t', 'instanceof ', 'instanceof\t'] - 9: ['==', '!=', '==', '==='] - 10: ['&'] - 11: ['|'] - 12: ['^'] - 13: ['&&'] - 14: ['||'] - 17: [','] - - binaryOpItems = [] - do -> for k, ops of binaryOpPriorityMap - for op in ops then binaryOpItems.push [op, {text:op, pri:parseInt(k)}] - - binarysm = new StateMachine(binaryOpItems) - - binaryOperator = memo -> - m = binarysm.match(self.data, self.cur) - if m[0] then self.cur = m[1]; m[0] - - expr = (n) -> - binary = rec -> - if x = binary() - beforeOp = self.cur - if (op=binaryOperator()) and (n>=op.pri>=x.pri) and (fn=expr(op.pri)) and y=fn() - {text: x.text+op.text+y.text, pri:op.pri} - else self.cur = beforeOp; x - else if x=simpleExpr() then {text:x, pri:4} - - orBinary = expr(15) - logicOrExpr = -> (x = orBinary()) and x.text - wrapQuestion = wrap(question); wrapColon = wrap(colon) - condition = -> (x=logicOrExpr()) and ((wrapQuestion() and (y=assignExpr()) and expect(wrapColon, 'expect :') and (z=assignExpr()) and x+'? '+y+': '+z) or x) - assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign, - rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign) - assignExpr_ = -> if (v=property()) and (op=assignOperator()) then (e = expect(assignExpr, 'expect the right hand side of assign.')) and v+op+e - assignExpr = orp(assignExpr_, condition) - expression_ = list(assignExpr, wrap(comma)) - expression = -> x = expression_(); if x then x.join(',') - - @root = -> (x=expression()) and expect(eoi, 'expect end of input') and x \ No newline at end of file + if c=='\\' then result += text[cur+1]; cur += 2; + else if c==quote + self.cur = cur+1 + return quote+result+quote + else if not c then error('expect '+quote) + else result += c; cur++ + + question = char('?'); colon = char(':'); comma = char(','); dot = char('.') + lpar = char('('); rpar = char(')') + lbracket = char('['); rbracket = char(']') + + myop = (op) -> + if op.length==1 then opFn = char(op) else opFn = literal(op) + if _in_(op[0], identifierCharSet) + -> spaces() and (op=opFn()) and spaces() and not _in_(data[self.cur], identifierCharSet) and ' '+op+' ' + else -> spaces() and (op=opFn()) and spaces() and op + + posNeg = (op) -> + opFn = char(op) + -> spaces() and (op=opFn()) and (c = self.data[self.cur]) and c!='.' and not('0'<=c<='9') and spaces() and op + positive = posNeg('+'); negative = posNeg('-') + new_ = myop('new') + inc = myop('++'); dec = myop('--') + not1 = orp(myop('!'), myop('not')) + not_ = -> not1() + bitnot = myop('~') + typeof_ = myop('typeof'); void_ = myop('void'); delete_ = myop('delete') + unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_) + comma = myop(',') + assign = myop('='); + addassign = myop('+='); subassign = myop('-=') + mulassign = myop('*='); divassign = myop('/='); modassign = myop('%='); idivassign = myop('//=') + rshiftassign = myop('>>='); lshiftassign = myop('<<='); zrshiftassign = myop('>>>=') + bitandassign = myop('&='); bitxorassign = myop('^='); bitorassign = myop('|=') + + error = (msg) -> throw self.data[self.cur-20..self.cur+20]+' '+self.cur+': '+msg + expect = (fn, msg) -> fn() or error(msg) + + incDec = orp(inc, dec) + prefixExpr = -> (op=incDec()) and (x=headExpr()) and op+x + suffixExpr = -> (x=headExpr()) and (op=incDec()) and x+op + + paren = (item, left=lpar, right=rpar, msg='expect ) to match (') -> + if (typeof item)=='string' then left = self.literal(item) + if (typeof left)=='string' then left = self.literal(left) + if (typeof right)=='string' then right = self.literal(right) + -> start=self.cur; left() and (x=item()) and expect(right, msg+' at: '+start) and x + + paren1 = paren(-> (spaces() and (x=expression()) and spaces() and x)) + parenExpr = memo -> (x=paren1()) and '('+x+')' + atom = memo orp(parenExpr, number, string, identifier) + newExpr = -> new_() and (x=callProp()) and 'new '+x + unaryTail = orp(prefixExpr, suffixExpr, atom) + unaryExpr = -> (op=unaryOp()) and (x=unaryTail()) and op+x + + bracketExpr1 = wrap(paren(wrap(-> commaExpr()), lbracket, rbracket, 'expect ] to match [')) + bracketExpr = -> (x=bracketExpr1()) and '['+x+']' + wrapDot = wrap(dot) + dotIdentifier = -> wrapDot() and (id=expect(identifier, 'expect identifier')) and '.'+id + attr = orp(bracketExpr, dotIdentifier) + param = paren -> (spaces() and (x=expression()) and spaces() and expect(rpar,'expect )')) or ' ' + paramExpr = memo -> (x=param()) and '('+x+')' + callPropTail = orp(paramExpr, attr) + callPropExpr = rec -> (h=headExpr()) and (((e=callPropTail()) and h+e) or h) + property = rec -> (h=headExpr()) and (((e=attr()) and h+e) or h) + headAtom = memo orp(parenExpr, identifier) + headExpr = memo orp(callPropExpr, headAtom) + simpleExpr = memo orp(unaryExpr, prefixExpr, suffixExpr, callPropExpr, newExpr, atom) + + binaryOpPriorityMap = + 5: ['*', '/', '//', '%'] + 6: ['+', '-'] + 7: ['<<', '>>', '>>>'] + 8: ['<', '<=', '>', '>=', 'in ', 'in\t', 'instanceof ', 'instanceof\t'] + 9: ['==', '!=', '==', '==='] + 10: ['&'] + 11: ['|'] + 12: ['^'] + 13: ['&&'] + 14: ['||'] + 17: [','] + + binaryOpItems = [] + do -> for k, ops of binaryOpPriorityMap + for op in ops then binaryOpItems.push [op, {text:op, pri:parseInt(k)}] + + binarysm = new StateMachine(binaryOpItems) + + binaryOperator = memo -> + m = binarysm.match(self.data, self.cur) + if m[0] then self.cur = m[1]; m[0] + + expr = (n) -> + binary = rec -> + if x = binary() + beforeOp = self.cur + if (op=binaryOperator()) and (n>=op.pri>=x.pri) and (fn=expr(op.pri)) and y=fn() + {text: x.text+op.text+y.text, pri:op.pri} + else self.cur = beforeOp; x + else if x=simpleExpr() then {text:x, pri:4} + + orBinary = expr(15) + logicOrExpr = -> (x = orBinary()) and x.text + wrapQuestion = wrap(question); wrapColon = wrap(colon) + condition = -> (x=logicOrExpr()) and ((wrapQuestion() and (y=assignExpr()) and expect(wrapColon, 'expect :') and (z=assignExpr()) and x+'? '+y+': '+z) or x) + assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign, + rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign) + assignExpr_ = -> if (v=property()) and (op=assignOperator()) then (e = expect(assignExpr, 'expect the right hand side of assign.')) and v+op+e + assignExpr = orp(assignExpr_, condition) + expression_ = list(assignExpr, wrap(comma)) + expression = -> x = expression_(); if x then x.join(',') + + @root = -> (x=expression()) and expect(eoi, 'expect end of input') and x \ No newline at end of file diff --git a/coffee/samples/dsl.coffee b/coffee/samples/dsl.coffee index 61764a5..3e7990b 100644 --- a/coffee/samples/dsl.coffee +++ b/coffee/samples/dsl.coffee @@ -1,62 +1,59 @@ -if typeof window=='object' then {require, exports, module} = twoside('/samples/dsl') -do (require=require, exports=exports, module=module) -> +{inCharset, letters, charset} = peasy = require '../index' - {inCharset, letters, charset} = peasy = require '../peasy' +identifierHeadChars = '$_'+letters +endTextCharset = charset(')@'+identifierHeadChars) +identifierHeadCharset = charset(identifierHeadChars) - identifierHeadChars = '$_'+letters - endTextCharset = charset(')@'+identifierHeadChars) - identifierHeadCharset = charset(identifierHeadChars) +exports.TemplateParser = class TemplateParser extends peasy.Parser + constructor: -> + super - exports.TemplateParser = class TemplateParser extends peasy.Parser - constructor: -> - super + [at, lpar, rpar, exclam] = for c in '@()!' then do(c=c) => @char(c) - [at, lpar, rpar, exclam] = for c in '@()!' then do(c=c) => @char(c) + mayExclam = @may(exclam) - mayExclam = @may(exclam) + error = (msg) => throw @data[@cur-20..@cur+20]+' '+@cur+': '+msg - error = (msg) => throw @data[@cur-20..@cur+20]+' '+@cur+': '+msg + tcall = => (f = tfield()) and lpar() and (args = template()) and ((rpar() and f+'('+args+')') or error('expect )')) - tcall = => (f = tfield()) and lpar() and (args = template()) and ((rpar() and f+'('+args+')') or error('expect )')) + tfield = @memo(=> at() and (((id=@identifier()) and mayExclam() and 't.'+id) or error('expect @identifier'))) - tfield = @memo(=> at() and (((id=@identifier()) and mayExclam() and 't.'+id) or error('expect @identifier'))) + field = => (id=@identifier()) and mayExclam() and "t.transform(e.#{id})" - field = => (id=@identifier()) and mayExclam() and "t.transform(e.#{id})" - - text = => - data = @data - start = cur = @cur - result = '' - while 1 + text = => + data = @data + start = cur = @cur + result = '' + while 1 + c = data[cur] + if (not c) then break + else if c=='!' + cur++ c = data[cur] - if (not c) then break - else if c=='!' + if inCharset(c, identifierHeadCharset) + @cur = cur + id = @identifier() + cur = @cur + result += id + else if c=='!' or c=='@' or c==')' + result += c + cur++ + else if c + result += '!'+c cur++ - c = data[cur] - if inCharset(c, identifierHeadCharset) - @cur = cur - id = @identifier() - cur = @cur - result += id - else if c=='!' or c=='@' or c==')' - result += c - cur++ - else if c - result += '!'+c - cur++ - else break - else if c=='\n' then cur++; result +='\\n' - else if inCharset(c, endTextCharset) then break - else result += c; cur++ - if cur==start then return - @cur = cur - if '"' in result then "'"+result+"'" - else '"'+result+'"' - - anySegment = @any(@orp(tcall, tfield, field, text)) - template = => (x = anySegment()) and x.join(',') - @root = => (t = template()) and ((@eoi() and t) or error('unexpected )')) - - templateParser = new TemplateParser - - exports.parseTemplate = parseTemplate = (text) -> templateParser.parse(text) \ No newline at end of file + else break + else if c=='\n' then cur++; result +='\\n' + else if inCharset(c, endTextCharset) then break + else result += c; cur++ + if cur==start then return + @cur = cur + if '"' in result then "'"+result+"'" + else '"'+result+'"' + + anySegment = @any(@orp(tcall, tfield, field, text)) + template = => (x = anySegment()) and x.join(',') + @root = => (t = template()) and ((@eoi() and t) or error('unexpected )')) + +templateParser = new TemplateParser + +exports.parseTemplate = parseTemplate = (text) -> templateParser.parse(text) \ No newline at end of file diff --git a/coffee/samples/latex.coffee b/coffee/samples/latex.coffee index 588251d..5551e7d 100644 --- a/coffee/samples/latex.coffee +++ b/coffee/samples/latex.coffee @@ -19,47 +19,44 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -} {- | - Module : Text.Pandoc.Readers.LaTeX - Copyright : Copyright (C) 2006-2012 John MacFarlane - License : GNU GPL, version 2 or above + Module : Text.Pandoc.Readers.LaTeX + Copyright : Copyright (C) 2006-2012 John MacFarlane + License : GNU GPL, version 2 or above - Maintainer : John MacFarlane - Stability : alpha - Portability : portable + Maintainer : John MacFarlane + Stability : alpha + Portability : portable Conversion of LaTeX to 'Pandoc' document. -} ### -if typeof window=='object' then {require, exports, module} = twoside('/samples/latex') -do (require=require, exports=exports, module=module) -> - - peasy = require "../peasy" - {StateMachine} = require "./statemachine" - - {in_, charset, letterDigits} = peasy - _in_ = in_ - identifierChars = '$_'+letterDigits - identifierCharSet = charset(identifierChars) - - exports.Parser = class Parser extends peasy.Parser - constructor: -> - super - {orp, list, rec, memo, wrap, char, literal, spaces, eoi, identifier} = self = @ - mayNewLine = may(newline) - anyControlSeq = -> slash() and orp(NewLine, anyChar)() - controlSeq = (name) -> slash() - dimenarg = (ch=orp("", literal('='))()) and (num=many1(digit)()) and (dim=oneOfStrings("pt","pc","in","bp","cm","mm","dd","cc","sp")()) and ch+num+dim - isLowerHex = (x) -> (x >= '0' && x <= '9' || x >= 'a' && x <= 'f') - anyCharUnless('\n') - skipLine = -> - text = self.data - cur = self.cur - while 1 - c = text[cur++] - if c=='\n' then return true - percent = char('%') - comment = percent() and skipLine() - block = orp(comment, emptyLines, environment, macro, blockCommand, groupedBlock, paragraph, charAt) - blocks = any(block) - @root = -> (x = blocks()) and x +peasy = require "../index" +{StateMachine} = require "./statemachine" + +{in_, charset, letterDigits} = peasy +_in_ = in_ +identifierChars = '$_'+letterDigits +identifierCharSet = charset(identifierChars) + +exports.Parser = class Parser extends peasy.Parser + constructor: -> + super + {orp, list, rec, memo, wrap, char, literal, spaces, eoi, identifier} = self = @ + mayNewLine = may(newline) + anyControlSeq = -> slash() and orp(NewLine, anyChar)() + controlSeq = (name) -> slash() + dimenarg = (ch=orp("", literal('='))()) and (num=many1(digit)()) and (dim=oneOfStrings("pt","pc","in","bp","cm","mm","dd","cc","sp")()) and ch+num+dim + isLowerHex = (x) -> (x >= '0' && x <= '9' || x >= 'a' && x <= 'f') + anyCharUnless('\n') + skipLine = -> + text = self.data + cur = self.cur + while 1 + c = text[cur++] + if c=='\n' then return true + percent = char('%') + comment = percent() and skipLine() + block = orp(comment, emptyLines, environment, macro, blockCommand, groupedBlock, paragraph, charAt) + blocks = any(block) + @root = -> (x = blocks()) and x diff --git a/coffee/samples/statemachine.coffee b/coffee/samples/statemachine.coffee index 6511567..0694ea2 100644 --- a/coffee/samples/statemachine.coffee +++ b/coffee/samples/statemachine.coffee @@ -1,50 +1,47 @@ -if typeof window=='object' then {require, exports, module} = twoside('/samples/statemachine') -do (require=require, exports=exports, module=module) -> +hasOwnProperty = Object.hasOwnProperty - hasOwnProperty = Object.hasOwnProperty +exports.StateMachine = class StateMachine + constructor: (items=[]) -> + @index = 1 + @stateMap = {} + @stateMap[0] = {} + @tagMap = {} + for item in items then @add(item[0], item[1] or item[0]) - exports.StateMachine = class StateMachine - constructor: (items=[]) -> - @index = 1 - @stateMap = {} - @stateMap[0] = {} - @tagMap = {} - for item in items then @add(item[0], item[1] or item[0]) - - add: (word, tag=word) -> - length = word.length - state = 0 - i = 0 - stateMap = @stateMap - while i + length = word.length + state = 0 + i = 0 + stateMap = @stateMap + while i0 - stateMap[state][c] = -s - @tagMap[s] = tag + state = stateMap[state][c] + if state < 0 then state = -state else newState = @index++ - stateMap[state][c] = -newState + stateMap[state][c] = newState stateMap[newState] = {} - @tagMap[newState] = tag + state = newState + c = word[i] + if hasOwnProperty.call(stateMap[state], c) + s = stateMap[state][c] + if s>0 + stateMap[state][c] = -s + @tagMap[s] = tag + else + newState = @index++ + stateMap[state][c] = -newState + stateMap[newState] = {} + @tagMap[newState] = tag - match: (text, i=0) -> - state = 0 - length = text.length - stateMap = @stateMap - while i + state = 0 + length = text.length + stateMap = @stateMap + while i 'twoside.js' 'peasy.js' 'logicpeasy.js' - 'deprecated/logic.js' - 'deprecated/autopeasy.js' - 'deprecated/modularpeasy.js' - 'deprecated/nonmodularpeasy.js' +# 'deprecated/logic.js' +# 'deprecated/autopeasy.js' +# 'deprecated/modularpeasy.js' +# 'deprecated/nonmodularpeasy.js' 'samples/dsl.js' 'samples/arithmatic.js' 'samples/statemachine.js' 'samples/arithmatic2.js' 'test/karma/testpeasy.js' 'test/karma/testlogicpeasy.js' - 'test/karma/deprecated/testlogic.js' - 'test/karma/deprecated/testautopeasy.js' - 'test/karma/deprecated/testmodularpeasy.js' - 'test/karma/deprecated/testnonmodularpeasy.js' +# 'test/karma/deprecated/testlogic.js' +# 'test/karma/deprecated/testautopeasy.js' +# 'test/karma/deprecated/testmodularpeasy.js' +# 'test/karma/deprecated/testnonmodularpeasy.js' 'test/karma/samples/testdsl.js' 'test/karma/samples/testarithmatic.js' 'test/karma/samples/testarithmatic2.js' +# 'test/karma/karma-bundle.js' ], exclude: [] #after switching from win7 64bit to win7 32bit, dsable many services, karma say chrome have not captured in 6000ms. use 9876 ok. diff --git a/coffee/test/karma/deprecated/testautopeasy.coffee b/coffee/test/karma/deprecated/testautopeasy.coffee deleted file mode 100644 index 5a9a451..0000000 --- a/coffee/test/karma/deprecated/testautopeasy.coffee +++ /dev/null @@ -1,79 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/karma/deprecated/testautopeasy') -do (require=require, exports=exports, module=module) -> - - {char, initialize, autoComputeLeftRecursives} = parser = p = require "../../../deprecated/autopeasy" - - hasOwnProperty = Object.hasOwnProperty - - a = char('a'); b = char('b'); x = char('x') - - parse1 = (text) -> - rules = - A: (start) -> - (m = rules.A(start)) and x(p.cur()) and m+'x' or m\ - or a(start) - rootSymbol: 'A' - initialize() - autoComputeLeftRecursives(rules) - parser.parse(text, rules) - - parse2 = (text) -> - rules = - A: (start) -> - (m = rules.B(start)) and x(p.cur()) and m+'x' or m\ - or a(start) - B: (start) -> rules.A(start) or b(start) - rootSymbol: 'A' - initialize() - autoComputeLeftRecursives(rules) - parser.parse(text, rules) - - parse3 = (text) -> - rules = - A: (start) -> - (m = rules.B(start)) and x(p.cur()) and m+'x' or m\ - or a(start) - B: (start) -> rules.C(start) - C: (start) -> rules.A(start) or b(start) - rootSymbol: 'A' - initialize() - autoComputeLeftRecursives(rules) - parser.parse(text, rules) - - describe 'auto peasy', -> - it "test A: Ax|a", -> - parse = parse1 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - - it "test A: Bx|a; B:A|b", -> - parse = parse2 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "test A: Bx|a; B:C; C:A|b", -> - parse = parse3 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined \ No newline at end of file diff --git a/coffee/test/karma/deprecated/testlogic.coffee b/coffee/test/karma/deprecated/testlogic.coffee deleted file mode 100644 index 544a7c4..0000000 --- a/coffee/test/karma/deprecated/testlogic.coffee +++ /dev/null @@ -1,61 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/karma/deprecated/testlogic') -do (require=require, exports=exports, module=module) -> - - {vari, cons, uarray, uobject, makeInfo} = logic = require "../../../deprecated/logic" - - makeCmd = -> - info = makeInfo('') - {unify: logic.unify(info), orp: logic.orp(info)} - - describe 'logic', -> - it "test unify 1 1, 1 2", -> - {unify, orp} = makeCmd() - expect( unify(1, 1)).toBe true - {unify, orp} = makeCmd() - expect( unify(1, 2)).toBe false - - it "test unify logicvar", -> - {unify, orp} = makeCmd() - expect( unify(vari(), 1)).toBe true - {unify, orp} = makeCmd() - expect( ($a=vari()) and unify($a, 1) and unify($a, 2)).toBe false - {unify, orp} = makeCmd() - expect( ($a = vari()) and orp((-> unify($a, 1) and unify($a, 2)), -> unify($a, 2))()).toBe true - - it "test unify cons", -> - {unify, orp} = makeCmd() - expect( unify(cons(1, null), cons(1, null))).toBe true - {unify, orp} = makeCmd() - expect( unify(cons(vari(), null), cons(1, null))).toBe true - {unify, orp} = makeCmd() - expect( ($a = vari()) and unify(cons($a, null), cons(1, null)) and unify($a, 2)).toBe false - {unify, orp} = makeCmd() - expect( ($a = vari()) and orp((-> unify(cons($a, null), cons(1, null)) and unify($a, 2)), -> unify($a, 2))()).toBe true - - it "test unify uobject", -> - {unify, orp} = makeCmd() - expect( unify(uobject({a: 1}), {a:1})).toBe true - {unify, orp} = makeCmd() - expect( unify(uobject({a: 1}), {a:2})).toBe false - {unify, orp} = makeCmd() - expect( unify(uobject({a: vari()}), {a:1})).toBe true - {unify, orp} = makeCmd() - expect( ($a = vari()) and unify(uobject({a: $a}), {a:1}) and unify($a, 2)).toBe false - {unify, orp} = makeCmd() - expect( ($a = vari()) and orp((-> unify(uobject({a: $a}), {a:1}) and unify($a, 2)), -> unify($a, 2))()).toBe true - - it "test unify array, uarray", -> - {unify, orp} = makeCmd() - expect( unify([], [])).toBe false - {unify, orp} = makeCmd() - expect( unify(uarray([]), [])).toBe true - {unify, orp} = makeCmd() - expect( unify(uarray([vari()]), [])).toBe false - {unify, orp} = makeCmd() - expect( unify(uarray([vari()]), [1])).toBe true - {unify, orp} = makeCmd() - expect( ($a = vari()) and unify(uarray([$a]), [1]) and unify($a, 2)).toBe false - {unify, orp} = makeCmd() - expect( ($a = vari()) and orp((-> unify(uarray([$a]), [1]) and unify($a, 2)), -> unify($a, 2))()).toBe true - - diff --git a/coffee/test/karma/deprecated/testmodularpeasy.coffee b/coffee/test/karma/deprecated/testmodularpeasy.coffee deleted file mode 100644 index 29fc586..0000000 --- a/coffee/test/karma/deprecated/testmodularpeasy.coffee +++ /dev/null @@ -1,139 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/karma/deprecated/testmodularpeasy') -do (require=require, exports=exports, module=module) -> - - {makeInfo, letters, combinators} = require "../../../deprecated/modularpeasy" - - parse1 = (text) -> - makeGrammar = (info) -> - {a, x} = letters(info) - {rec, orp} = combinators(info) - rules = A: rec orp(( -> (m = rules.A()) and x() and m+'x' or m), a) - grammar = makeGrammar(makeInfo(text)) - grammar.A(0) - - parse2 = (text) -> - makeGrammar = (info) -> - {a, b, x} = letters(info) - {rec, orp} = combinators(info) - rules = {} - rules.A = rec orp((-> (m = rules.B()) and x() and m+'x' or m), a) - rules.B = rec orp(rules.A, b) - rules - grammar = makeGrammar(makeInfo(text)) - grammar.A(0) - - parse3 = (text) -> - makeGrammar = (info) -> - {a, b, x} = letters(info) - {rec, orp} = combinators(info) - rules = {} - rules.A = rec orp((-> (m = rules.B()) and x() and m+'x' or m), a) - rules.B = rec -> rules.C() - rules.C = rec orp(rules.A, b) - rules - grammar = makeGrammar(makeInfo(text)) - grammar.A(0) - - parse4 = (text) -> - makeGrammar = (info) -> - {a, b, x, y} = letters(info) - {rec, orp} = combinators(info) - rules = - A: rec -> orp((-> (m = rules.B()) and x() and m+'x' or m), a)() - B: rec -> orp(( -> (m = rules.A()) and y() and m+'y'), rules.C)() - C: rec -> orp(rules.A, b)() - grammar = makeGrammar(makeInfo(text)) - grammar.A(0) - - parse5 = (text) -> - makeGrammar = (info) -> - {a, b, x, y, z} = letters(info) - {rec, orp} = combinators(info) - rules = - Root: -> (m = rules.A()) and z() and m+'z' - A: rec orp(( -> (m = rules.B()) and x() and m+'x' or m), a) - B: rec orp((-> (m = rules.A()) and y() and m+'y'), -> rules.C()) - C: rec orp((-> rules.A()), b) - grammar = makeGrammar(makeInfo(text)) - grammar.Root(0) - - describe 'modular peasy', -> - it "test A: Ax|a", -> - parse = parse1 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - - it "test A: Bx|a; B:A|b", -> - parse = parse2 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "test A: Bx|a; B:C; C:A|b", -> - parse = parse3 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "test A: Bx|a; B:C|Ay; C:A|b", -> - parse = parse4 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('ay')).toBe 'ay' - expect(parse('ayx')).toBe 'ayx' - expect(parse('ayxyx')).toBe 'ayxyx' - expect(parse('bxx')).toBe 'bxx' - expect(parse('ayxxx')).toBe 'ayxxx' - expect(parse('ayxmxx')).toBe 'ayx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "test Start: Az; A: Bx|a; B:C|Ay; C:A|b", -> - parse = parse5 - expect(parse('az')).toBe 'az' - expect(parse('axz')).toBe 'axz' - expect(parse('axxz')).toBe 'axxz' - expect(parse('axxxz')).toBe 'axxxz' - expect(parse('ayz')).toBe 'ayz' - expect(parse('ayxz')).toBe 'ayxz' - expect(parse('ayxyxz')).toBe 'ayxyxz' - expect(parse('bxxz')).toBe 'bxxz' - expect(parse('ayxxxz')).toBe 'ayxxxz' - expect(parse('ayxmxxz')).toBe undefined - expect(parse('bz')).toBe 'bz' - expect(parse('bxz')).toBe 'bxz' - expect(parse('bxxxz')).toBe 'bxxxz' - expect(parse('bxgz')).toBe undefined - expect(parse('bxxgz')).toBe undefined - expect(parse('bxxxgz')).toBe undefined - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - diff --git a/coffee/test/karma/deprecated/testnonmodularpeasy.coffee b/coffee/test/karma/deprecated/testnonmodularpeasy.coffee deleted file mode 100644 index 39c6740..0000000 --- a/coffee/test/karma/deprecated/testnonmodularpeasy.coffee +++ /dev/null @@ -1,86 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/karma/deprecated/testnonmodularpeasy') -do (require=require, exports=exports, module=module) -> - - {initialize, char, memo, setRules, addRecursiveCircles, computeLeftRecursives - } = parser = p = require "../../../deprecated/nonmodularpeasy" - - hasOwnProperty = Object.hasOwnProperty - - a = char('a'); b = char('b'); x = char('x') - - memoA = memo('A') - - parse1 = (text) -> - rules = - A: (start) -> - (m = memoA(start)) and x(p.cur()) and m+'x' or m\ - or a(start) - rootSymbol: 'A' - initialize() - addRecursiveCircles(rules, ['A']) - computeLeftRecursives(rules) - parser.parse(text, rules) - - parse2 = (text) -> - rules = - A: (start) -> - (m = rules.B(start)) and x(p.cur()) and m+'x' or m\ - or a(start) - B: (start) ->memoA(start) or b(start) - rootSymbol: 'A' - initialize() - addRecursiveCircles(rules, ['A', 'B']) - computeLeftRecursives(rules) - parser.parse(text, rules) - - parse3 = (text) -> - rules = - A: (start) -> - (m = rules.B(start)) and x(p.cur()) and m+'x' or m\ - or a(start) - B: (start) -> rules.C(start) - C: (start) -> memoA(start) or b(start) - rootSymbol: 'A' - initialize() - addRecursiveCircles(rules, ['A', 'B', 'C']) - computeLeftRecursives(rules) - parser.parse(text, rules) - - describe 'non modular peasy', -> - it "test A: Ax|a", -> - parse = parse1 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - - it "test A: Bx|a; B:A|b", -> - parse = parse2 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "test A: Bx|a; B:C; C:A|b", -> - parse = parse3 - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - diff --git a/coffee/test/karma/karma-bundle.coffee b/coffee/test/karma/karma-bundle.coffee new file mode 100644 index 0000000..bf706eb --- /dev/null +++ b/coffee/test/karma/karma-bundle.coffee @@ -0,0 +1,5 @@ +require './testparser.js' +require './testlogicparser' +require './samples/testdsl' +require './samples/testarithmatic' +require './samples/testarithmatic2' \ No newline at end of file diff --git a/coffee/test/karma/samples/testarithmatic.coffee b/coffee/test/karma/samples/testarithmatic.coffee index cbab0e7..3a90d71 100644 --- a/coffee/test/karma/samples/testarithmatic.coffee +++ b/coffee/test/karma/samples/testarithmatic.coffee @@ -1,61 +1,58 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/mocha/samples/testarithmatic') -do (require=require, exports=exports, module=module) -> +{parse} = arithmatic = require '../../../samples/arithmatic' - {parse} = arithmatic = require '../../../samples/arithmatic' +describe "run samples/testarithmatic:", -> + it '', -> - describe "run samples/testarithmatic:", -> - it '', -> - - describe "arithmatic", -> - it "parse number", -> - expect(parse('1')).toBe '1' - expect(parse('01')).toBe '01' - expect(parse('0x01')).toBe '0x01' - expect(parse('.1')).toBe '.1' - expect(parse('1.')).toBe '1.' - expect(parse('+1.')).toBe '+1.' - expect(parse('+1.e0')).toBe '+1.e0' - expect(parse('+1.e023')).toBe '+1.e023' - expect(parse('+1.e')).toBe undefined - expect(parse('+.e')).toBe undefined - expect(parse('+.')).toBe undefined - expect(parse('-.')).toBe undefined - expect(parse('-.1')).toBe '-.1' - it "parse identifier", -> - expect(parse('a')).toBe 'a' - expect(parse('$a')).toBe '$a' - expect(parse('$a_')).toBe '$a_' - expect(parse('$a_1')).toBe '$a_1' - expect(parse('_1')).toBe '_1' - it "parse string", -> - expect(parse('"a\\"b"')).toBe '"a\"b"' - expect(parse('"a"')).toBe '"a"' - expect(parse("'a'")).toBe "'a'" - it "parse a.b", -> - expect(parse('a.b')).toBe 'a.b' - it "parse 1+1", -> - expect(parse('1+1')).toBe '1+1' - it "parse 1+1*1", -> - expect(parse('1+1*1')).toBe '1+1*1' - it "parse 1*1+1", -> - expect(parse('1*1+1')).toBe '1*1+1' - it "parse 1*1", -> - expect(parse('1*1')).toBe '1*1' - it "parse 1*1*1", -> - expect(parse('1*1*1')).toBe '1*1*1' - it "parse (1*1)", -> - expect(parse('(1*1)')).toBe '(1*1)' - it "parse (1*1)", -> - expect(parse('(1*1)')).toBe '(1*1)' - it "parse (1*1)+(2*3)", -> - expect(parse('(1*1)+(2*3)')).toBe '(1*1)+(2*3)' - it "parse a=1", -> - expect(parse('a=1')).toBe 'a=1' - it "parse a = 1", -> - expect(parse('a = 1')).toBe 'a=1' - it "parse a = b = 1", -> - expect(parse('a = b = 1')).toBe 'a=b=1' - it "parse 1? a = 3: b = 4", -> - expect(parse('1? a = 3: b = 4')).toBe '1? a=3: b=4' - it "parse 1?a=3:b=4", -> - expect(parse('1?a=3:b=4')).toBe '1? a=3: b=4' \ No newline at end of file +describe "arithmatic", -> + it "parse number", -> + expect(parse('1')).toBe '1' + expect(parse('01')).toBe '01' + expect(parse('0x01')).toBe '0x01' + expect(parse('.1')).toBe '.1' + expect(parse('1.')).toBe '1.' + expect(parse('+1.')).toBe '+1.' + expect(parse('+1.e0')).toBe '+1.e0' + expect(parse('+1.e023')).toBe '+1.e023' + expect(parse('+1.e')).toBe undefined + expect(parse('+.e')).toBe undefined + expect(parse('+.')).toBe undefined + expect(parse('-.')).toBe undefined + expect(parse('-.1')).toBe '-.1' + it "parse identifier", -> + expect(parse('a')).toBe 'a' + expect(parse('$a')).toBe '$a' + expect(parse('$a_')).toBe '$a_' + expect(parse('$a_1')).toBe '$a_1' + expect(parse('_1')).toBe '_1' + it "parse string", -> + expect(parse('"a\\"b"')).toBe '"a\"b"' + expect(parse('"a"')).toBe '"a"' + expect(parse("'a'")).toBe "'a'" + it "parse a.b", -> + expect(parse('a.b')).toBe 'a.b' + it "parse 1+1", -> + expect(parse('1+1')).toBe '1+1' + it "parse 1+1*1", -> + expect(parse('1+1*1')).toBe '1+1*1' + it "parse 1*1+1", -> + expect(parse('1*1+1')).toBe '1*1+1' + it "parse 1*1", -> + expect(parse('1*1')).toBe '1*1' + it "parse 1*1*1", -> + expect(parse('1*1*1')).toBe '1*1*1' + it "parse (1*1)", -> + expect(parse('(1*1)')).toBe '(1*1)' + it "parse (1*1)", -> + expect(parse('(1*1)')).toBe '(1*1)' + it "parse (1*1)+(2*3)", -> + expect(parse('(1*1)+(2*3)')).toBe '(1*1)+(2*3)' + it "parse a=1", -> + expect(parse('a=1')).toBe 'a=1' + it "parse a = 1", -> + expect(parse('a = 1')).toBe 'a=1' + it "parse a = b = 1", -> + expect(parse('a = b = 1')).toBe 'a=b=1' + it "parse 1? a = 3: b = 4", -> + expect(parse('1? a = 3: b = 4')).toBe '1? a=3: b=4' + it "parse 1?a=3:b=4", -> + expect(parse('1?a=3:b=4')).toBe '1? a=3: b=4' \ No newline at end of file diff --git a/coffee/test/karma/samples/testarithmatic2.coffee b/coffee/test/karma/samples/testarithmatic2.coffee index 87ab1fd..c18e01a 100644 --- a/coffee/test/karma/samples/testarithmatic2.coffee +++ b/coffee/test/karma/samples/testarithmatic2.coffee @@ -1,65 +1,62 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/mocha/samples/testarithmatic2') -do (require=require, exports=exports, module=module) -> +{Parser} = require '../../../samples/arithmatic2' - {Parser} = require '../../../samples/arithmatic2' +parser = new Parser - parser = new Parser +parse = (text) -> parser.parse(text) - parse = (text) -> parser.parse(text) +describe "run samples/testarithmatic2:", -> + it '', -> - describe "run samples/testarithmatic2:", -> - it '', -> - - describe "testarithmatic2", -> - it "testaritmatic2: parse number", -> - expect(parse('1')).toBe '1' - expect(parse('01')).toBe '01' - expect(parse('0x01')).toBe '0x01' - expect(parse('.1')).toBe '.1' - expect(parse('1.')).toBe '1.' - expect(parse('+1.')).toBe '+1.' - expect(parse('+1.e0')).toBe '+1.e0' - expect(parse('+1.e023')).toBe '+1.e023' - expect(parse('+1.e')).toBe undefined - expect(parse('+.e')).toBe undefined - expect(parse('+.')).toBe undefined - expect(parse('-.')).toBe undefined - expect(parse('-.1')).toBe '-.1' - it "testaritmatic2: parse identifier", -> - expect(parse('a')).toBe 'a' - expect(parse('$a')).toBe '$a' - expect(parse('$a_')).toBe '$a_' - expect(parse('$a_1')).toBe '$a_1' - expect(parse('_1')).toBe '_1' - it "testaritmatic2: parse string", -> - expect(parse('"a\\"b"')).toBe '"a\"b"' - expect(parse('"a"')).toBe '"a"' - expect(parse("'a'")).toBe "'a'" - it "testaritmatic2: parse a.b", -> - expect(parse('a.b')).toBe 'a.b' - it "testaritmatic2: parse 1+1", -> - expect(parse('1+1')).toBe '1+1' - it "testaritmatic2: parse 1+1*1", -> - expect(parse('1+1*1')).toBe '1+1*1' - it "testaritmatic2: parse 1*1+1", -> - expect(parse('1*1+1')).toBe '1*1+1' - it "testaritmatic2: parse 1*1", -> - expect(parse('1*1')).toBe '1*1' - it "testaritmatic2: parse 1*1*1 ", -> - expect(parse('1*1*1')).toBe '1*1*1' - it "testaritmatic2: parse (1*1) ", -> - expect(parse('(1*1)')).toBe '(1*1)' - it "testaritmatic2: parse (1*1)", -> - expect(parse('(1*1)')).toBe '(1*1)' - it "testaritmatic2: parse (1*1)+(2*3)", -> - expect(parse('(1*1)+(2*3)')).toBe '(1*1)+(2*3)' - it "testaritmatic2: parse a=1", -> - expect(parse('a=1')).toBe 'a=1' - it "testaritmatic2: parse a = 1", -> - expect(parse('a = 1')).toBe 'a=1' - it "testaritmatic2: parse a = b = 1", -> - expect(parse('a = b = 1')).toBe 'a=b=1' - it "testaritmatic2: parse 1? a = 3: b = 4", -> - expect(parse('1? a = 3: b = 4')).toBe '1? a=3: b=4' - it "testaritmatic2: parse 1?a=3:b=4", -> - expect(parse('1?a=3:b=4')).toBe '1? a=3: b=4' \ No newline at end of file +describe "testarithmatic2", -> + it "testaritmatic2: parse number", -> + expect(parse('1')).toBe '1' + expect(parse('01')).toBe '01' + expect(parse('0x01')).toBe '0x01' + expect(parse('.1')).toBe '.1' + expect(parse('1.')).toBe '1.' + expect(parse('+1.')).toBe '+1.' + expect(parse('+1.e0')).toBe '+1.e0' + expect(parse('+1.e023')).toBe '+1.e023' + expect(parse('+1.e')).toBe undefined + expect(parse('+.e')).toBe undefined + expect(parse('+.')).toBe undefined + expect(parse('-.')).toBe undefined + expect(parse('-.1')).toBe '-.1' + it "testaritmatic2: parse identifier", -> + expect(parse('a')).toBe 'a' + expect(parse('$a')).toBe '$a' + expect(parse('$a_')).toBe '$a_' + expect(parse('$a_1')).toBe '$a_1' + expect(parse('_1')).toBe '_1' + it "testaritmatic2: parse string", -> + expect(parse('"a\\"b"')).toBe '"a\"b"' + expect(parse('"a"')).toBe '"a"' + expect(parse("'a'")).toBe "'a'" + it "testaritmatic2: parse a.b", -> + expect(parse('a.b')).toBe 'a.b' + it "testaritmatic2: parse 1+1", -> + expect(parse('1+1')).toBe '1+1' + it "testaritmatic2: parse 1+1*1", -> + expect(parse('1+1*1')).toBe '1+1*1' + it "testaritmatic2: parse 1*1+1", -> + expect(parse('1*1+1')).toBe '1*1+1' + it "testaritmatic2: parse 1*1", -> + expect(parse('1*1')).toBe '1*1' + it "testaritmatic2: parse 1*1*1 ", -> + expect(parse('1*1*1')).toBe '1*1*1' + it "testaritmatic2: parse (1*1) ", -> + expect(parse('(1*1)')).toBe '(1*1)' + it "testaritmatic2: parse (1*1)", -> + expect(parse('(1*1)')).toBe '(1*1)' + it "testaritmatic2: parse (1*1)+(2*3)", -> + expect(parse('(1*1)+(2*3)')).toBe '(1*1)+(2*3)' + it "testaritmatic2: parse a=1", -> + expect(parse('a=1')).toBe 'a=1' + it "testaritmatic2: parse a = 1", -> + expect(parse('a = 1')).toBe 'a=1' + it "testaritmatic2: parse a = b = 1", -> + expect(parse('a = b = 1')).toBe 'a=b=1' + it "testaritmatic2: parse 1? a = 3: b = 4", -> + expect(parse('1? a = 3: b = 4')).toBe '1? a=3: b=4' + it "testaritmatic2: parse 1?a=3:b=4", -> + expect(parse('1?a=3:b=4')).toBe '1? a=3: b=4' \ No newline at end of file diff --git a/coffee/test/karma/samples/testdsl.coffee b/coffee/test/karma/samples/testdsl.coffee index 79f4730..8f2046f 100644 --- a/coffee/test/karma/samples/testdsl.coffee +++ b/coffee/test/karma/samples/testdsl.coffee @@ -1,66 +1,63 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/karma//testdsl') -do (require=require, exports=exports, module=module) -> +peasy = require '../../../index' +console.log 'peasy is required:', peasy +peasy.testing = true +{parseTemplate} = require '../../../samples/dsl' - peasy = require '../../../peasy' - console.log 'peasy is required:', peasy - peasy.testing = true - {parseTemplate} = require '../../../samples/dsl' +describe "run samples/testdsl:", -> + it '', -> - describe "run samples/testdsl:", -> - it '', -> - - describe "parse template", -> - it "parse @) shold throw error", -> - expect(-> parseTemplate('@)')).toThrow() - it "parse @x()) shold throw error", -> - expect(-> parseTemplate('@x())')).toThrow() - it "should parse 'x'", -> - expect(parseTemplate('x')).toBe 't.transform(e.x)' - it "should parse 'x!y'", -> - expect(parseTemplate('x!y')).toBe 't.transform(e.x),t.transform(e.y)' - it "should parse '@if_(x!y)'", -> - expect(parseTemplate('@if_(x!y)')).toBe 't.if_(t.transform(e.x),t.transform(e.y))' - it "should parse '@if_(x!!!y)'", -> - expect(parseTemplate('@if_(x!!!y)')).toBe 't.if_(t.transform(e.x),"!",t.transform(e.y))' - it "should parse '@x", -> - expect(parseTemplate('@x')).toBe 't.x' - it "should parse '@x@y", -> - expect(parseTemplate('@x@y')).toBe 't.x,t.y' - it "should parsen !)", -> - expect(parseTemplate('!)')).toBe '")"' - it "should parsen ;23445", -> - expect(parseTemplate(';23445')).toBe '";23445"' - it "should parsen ;23445qwe", -> - expect(parseTemplate(';23445qwe')).toBe '";23445",t.transform(e.qwe)' - it "should parsen ;23445!qwe", -> - expect(parseTemplate(';23445!qwe')).toBe '";23445qwe"' - it "should parsen ;23445!!qwe", -> - expect(parseTemplate(';23445!!qwe')).toBe '";23445!",t.transform(e.qwe)' - it "should parsen @whileLoop(!while @paren(item)\n@block(body))", -> - expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe "t.whileLoop(\"while \",t.paren(t.transform(e.item)),\"\\n\",t.block(t.transform(e.body)))" - it 'should parse "value"', -> - expect(parseTemplate('"value"')).toBe '\'"\',t.transform(e.value),\'"\'' - it "should parse @array(items)", -> - expect(parseTemplate('@array(items)')).toBe 't.array(t.transform(e.items))' - it "should parse @if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))", -> - expect(parseTemplate('@if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))')).toBe 't.if_("if ",t.paren(t.transform(e.test)),"\\n",t.block(t.transform(e.then_)),t.may("\\nelse ",t.block(t.transform(e.else_))))' - it "should parse '@forInLoop(!for @paren(item !in range)\n@block(body))'", -> - expect(parseTemplate('@forInLoop(!for @paren(item !in range)\n@block(body))')).toBe 't.forInLoop("for ",t.paren(t.transform(e.item)," in ",t.transform(e.range)),"\\n",t.block(t.transform(e.body)))' - it "should parse @whileLoop(!while @paren(item)\n@block(body))", -> - expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe 't.whileLoop("while ",t.paren(t.transform(e.item)),"\\n",t.block(t.transform(e.body)))' - it "should parse @tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))", -> - expect(parseTemplate('@tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))')).toBe 't.tryCatch("try ",t.block(t.transform(e.test)),"\\n",t.transform(e.catcher),t.may("\\nfinally ",t.block(t.transform(e.final))))' - it "should parsen !catch @paren(variable@may(!if test))@block(\nbody)", -> - expect(parseTemplate('!catch @paren(variable@may(!if test))@block(\nbody)')).toBe '"catch ",t.paren(t.transform(e.variable),t.may("if ",t.transform(e.test))),t.block("\\n",t.transform(e.body))' - it "should parsen !throw value", -> - expect(parseTemplate('!throw value')).toBe '"throw ",t.transform(e.value)' - it "should parsen caller@paren(@list(args))", -> - expect(parseTemplate('caller@paren(@list(args))')).toBe 't.transform(e.caller),t.paren(t.list(t.transform(e.args)))' - it "should parsen !var @list(vars)", -> - expect(parseTemplate('left = right')).toBe 't.transform(e.left)," = ",t.transform(e.right)' - it "left @op(operator) = right", -> - expect(parseTemplate('left @op(operator) = right')).toBe 't.transform(e.left)," ",t.op(t.transform(e.operator))," = ",t.transform(e.right)' - it "should parsen @switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))", -> - expect(parseTemplate('@switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))')).toBe 't.switch_("switch ",t.paren(t.transform(e.expression))," \\n",t.block(t.list(t.transform(e.cases)," ",t.empty))," ",t.may("\\ndefault: ",t.block(t.transform(e.else))))' - it "!case test: \n@block(body)", -> - expect(parseTemplate('!case test: \n@block(body)')).toBe '"case ",t.transform(e.test),": \\n",t.block(t.transform(e.body))' \ No newline at end of file +describe "parse template", -> + it "parse @) shold throw error", -> + expect(-> parseTemplate('@)')).toThrow() + it "parse @x()) shold throw error", -> + expect(-> parseTemplate('@x())')).toThrow() + it "should parse 'x'", -> + expect(parseTemplate('x')).toBe 't.transform(e.x)' + it "should parse 'x!y'", -> + expect(parseTemplate('x!y')).toBe 't.transform(e.x),t.transform(e.y)' + it "should parse '@if_(x!y)'", -> + expect(parseTemplate('@if_(x!y)')).toBe 't.if_(t.transform(e.x),t.transform(e.y))' + it "should parse '@if_(x!!!y)'", -> + expect(parseTemplate('@if_(x!!!y)')).toBe 't.if_(t.transform(e.x),"!",t.transform(e.y))' + it "should parse '@x", -> + expect(parseTemplate('@x')).toBe 't.x' + it "should parse '@x@y", -> + expect(parseTemplate('@x@y')).toBe 't.x,t.y' + it "should parsen !)", -> + expect(parseTemplate('!)')).toBe '")"' + it "should parsen ;23445", -> + expect(parseTemplate(';23445')).toBe '";23445"' + it "should parsen ;23445qwe", -> + expect(parseTemplate(';23445qwe')).toBe '";23445",t.transform(e.qwe)' + it "should parsen ;23445!qwe", -> + expect(parseTemplate(';23445!qwe')).toBe '";23445qwe"' + it "should parsen ;23445!!qwe", -> + expect(parseTemplate(';23445!!qwe')).toBe '";23445!",t.transform(e.qwe)' + it "should parsen @whileLoop(!while @paren(item)\n@block(body))", -> + expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe "t.whileLoop(\"while \",t.paren(t.transform(e.item)),\"\\n\",t.block(t.transform(e.body)))" + it 'should parse "value"', -> + expect(parseTemplate('"value"')).toBe '\'"\',t.transform(e.value),\'"\'' + it "should parse @array(items)", -> + expect(parseTemplate('@array(items)')).toBe 't.array(t.transform(e.items))' + it "should parse @if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))", -> + expect(parseTemplate('@if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))')).toBe 't.if_("if ",t.paren(t.transform(e.test)),"\\n",t.block(t.transform(e.then_)),t.may("\\nelse ",t.block(t.transform(e.else_))))' + it "should parse '@forInLoop(!for @paren(item !in range)\n@block(body))'", -> + expect(parseTemplate('@forInLoop(!for @paren(item !in range)\n@block(body))')).toBe 't.forInLoop("for ",t.paren(t.transform(e.item)," in ",t.transform(e.range)),"\\n",t.block(t.transform(e.body)))' + it "should parse @whileLoop(!while @paren(item)\n@block(body))", -> + expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe 't.whileLoop("while ",t.paren(t.transform(e.item)),"\\n",t.block(t.transform(e.body)))' + it "should parse @tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))", -> + expect(parseTemplate('@tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))')).toBe 't.tryCatch("try ",t.block(t.transform(e.test)),"\\n",t.transform(e.catcher),t.may("\\nfinally ",t.block(t.transform(e.final))))' + it "should parsen !catch @paren(variable@may(!if test))@block(\nbody)", -> + expect(parseTemplate('!catch @paren(variable@may(!if test))@block(\nbody)')).toBe '"catch ",t.paren(t.transform(e.variable),t.may("if ",t.transform(e.test))),t.block("\\n",t.transform(e.body))' + it "should parsen !throw value", -> + expect(parseTemplate('!throw value')).toBe '"throw ",t.transform(e.value)' + it "should parsen caller@paren(@list(args))", -> + expect(parseTemplate('caller@paren(@list(args))')).toBe 't.transform(e.caller),t.paren(t.list(t.transform(e.args)))' + it "should parsen !var @list(vars)", -> + expect(parseTemplate('left = right')).toBe 't.transform(e.left)," = ",t.transform(e.right)' + it "left @op(operator) = right", -> + expect(parseTemplate('left @op(operator) = right')).toBe 't.transform(e.left)," ",t.op(t.transform(e.operator))," = ",t.transform(e.right)' + it "should parsen @switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))", -> + expect(parseTemplate('@switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))')).toBe 't.switch_("switch ",t.paren(t.transform(e.expression))," \\n",t.block(t.list(t.transform(e.cases)," ",t.empty))," ",t.may("\\ndefault: ",t.block(t.transform(e.else))))' + it "!case test: \n@block(body)", -> + expect(parseTemplate('!case test: \n@block(body)')).toBe '"case ",t.transform(e.test),": \\n",t.block(t.transform(e.body))' \ No newline at end of file diff --git a/coffee/test/karma/testlogicparser.coffee b/coffee/test/karma/testlogicparser.coffee new file mode 100644 index 0000000..1440134 --- /dev/null +++ b/coffee/test/karma/testlogicparser.coffee @@ -0,0 +1,72 @@ +{vari, cons, uobject, uarray, Trail, Parser} = require '../../logicparser' + +describe 'logicparser', -> + orp = unify = null + + beforeEach -> + parser = new Parser + parser.trail = new Trail + unify = (x, y) -> parser.unify(x,y) + orp = (items...) -> parser.orp(items...)() + + it "should unify 1 1", -> + expect( unify(1, 1)).toBe true + + it "should unify 1 2", -> + expect( unify(1, 2)).toBe false + + it "should unify logicvar", -> + expect( unify(vari(), 1)).toBe true + + it "should sequential unify logicvar", -> + expect( ($a=vari()) and unify($a, 1) and unify($a, 2)).toBe false + + it "should unify logicvar with backtracking", -> + expect( ($a = vari()) and orp((-> unify($a, 1) and unify($a, 2)), -> unify($a, 2))).toBe true + + it "should unify cons 1", -> + expect( unify(cons(1, null), cons(1, null))).toBe true + + it "should unify cons 2", -> + expect( unify(cons(vari(), null), cons(1, null))).toBe true + + it "should unify cons 3", -> + expect( ($a = vari()) and unify(cons($a, null), cons(1, null)) and unify($a, 2)).toBe false + + it "should unify cons 4", -> + expect( ($a = vari()) and orp((-> unify(cons($a, null), cons(1, null)) and unify($a, 2)), -> unify($a, 2))).toBe true + + it "should unify uobject 1", -> + expect( unify(uobject({a: 1}), {a:1})).toBe true + + it "should unify uobject 2", -> + expect( unify(uobject({a: 1}), {a:2})).toBe false + + it "should unify uobject 3", -> + expect( unify(uobject({a: vari()}), {a:1})).toBe true + + it "should unify uobject 4", -> + expect( ($a = vari()) and unify(uobject({a: $a}), {a:1}) and unify($a, 2)).toBe false + + it "should unify uobject 5", -> + expect( ($a = vari()) and orp((-> unify(uobject({a: $a}), {a:1}) and unify($a, 2)), -> unify($a, 2))).toBe true + + it "should unify array, uarray 1", -> + expect( unify([], [])).toBe false + + it "should unify array, uarray 2", -> + expect( unify(uarray([]), [])).toBe true + + it "should unify array, uarray 3", -> + expect( unify(uarray([vari()]), [])).toBe false + + it "should unify array, uarray 4", -> + expect( unify(uarray([vari()]), [1])).toBe true + + it "should unify array, uarray 5", -> + expect( ($a = vari()) and unify(uarray([$a]), [1]) and unify($a, 2)).toBe false + + it "should unify array, uarray 6", -> + expect( ($a = vari()) and orp((-> unify(uarray([$a]), [1]) and unify($a, 2)), -> unify($a, 2))).toBe true + + diff --git a/coffee/test/karma/testlogicpeasy.coffee b/coffee/test/karma/testlogicpeasy.coffee deleted file mode 100644 index 836d87e..0000000 --- a/coffee/test/karma/testlogicpeasy.coffee +++ /dev/null @@ -1,75 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/karma/testlogicpeasy') -do (require=require, exports=exports, module=module) -> - - {vari, cons, uobject, uarray, Trail, Parser} = require '../../logicpeasy' - - describe 'logicpeasy', -> - orp = unify = null - - beforeEach -> - parser = new Parser - parser.trail = new Trail - unify = (x, y) -> parser.unify(x,y) - orp = (items...) -> parser.orp(items...)() - - it "should unify 1 1", -> - expect( unify(1, 1)).toBe true - - it "should unify 1 2", -> - expect( unify(1, 2)).toBe false - - it "should unify logicvar", -> - expect( unify(vari(), 1)).toBe true - - it "should sequential unify logicvar", -> - expect( ($a=vari()) and unify($a, 1) and unify($a, 2)).toBe false - - it "should unify logicvar with backtracking", -> - expect( ($a = vari()) and orp((-> unify($a, 1) and unify($a, 2)), -> unify($a, 2))).toBe true - - it "should unify cons 1", -> - expect( unify(cons(1, null), cons(1, null))).toBe true - - it "should unify cons 2", -> - expect( unify(cons(vari(), null), cons(1, null))).toBe true - - it "should unify cons 3", -> - expect( ($a = vari()) and unify(cons($a, null), cons(1, null)) and unify($a, 2)).toBe false - - it "should unify cons 4", -> - expect( ($a = vari()) and orp((-> unify(cons($a, null), cons(1, null)) and unify($a, 2)), -> unify($a, 2))).toBe true - - it "should unify uobject 1", -> - expect( unify(uobject({a: 1}), {a:1})).toBe true - - it "should unify uobject 2", -> - expect( unify(uobject({a: 1}), {a:2})).toBe false - - it "should unify uobject 3", -> - expect( unify(uobject({a: vari()}), {a:1})).toBe true - - it "should unify uobject 4", -> - expect( ($a = vari()) and unify(uobject({a: $a}), {a:1}) and unify($a, 2)).toBe false - - it "should unify uobject 5", -> - expect( ($a = vari()) and orp((-> unify(uobject({a: $a}), {a:1}) and unify($a, 2)), -> unify($a, 2))).toBe true - - it "should unify array, uarray 1", -> - expect( unify([], [])).toBe false - - it "should unify array, uarray 2", -> - expect( unify(uarray([]), [])).toBe true - - it "should unify array, uarray 3", -> - expect( unify(uarray([vari()]), [])).toBe false - - it "should unify array, uarray 4", -> - expect( unify(uarray([vari()]), [1])).toBe true - - it "should unify array, uarray 5", -> - expect( ($a = vari()) and unify(uarray([$a]), [1]) and unify($a, 2)).toBe false - - it "should unify array, uarray 6", -> - expect( ($a = vari()) and orp((-> unify(uarray([$a]), [1]) and unify($a, 2)), -> unify($a, 2))).toBe true - - diff --git a/coffee/test/karma/testparser.coffee b/coffee/test/karma/testparser.coffee new file mode 100644 index 0000000..0ae6624 --- /dev/null +++ b/coffee/test/karma/testparser.coffee @@ -0,0 +1,134 @@ +peasy = require '../../index.js' + +describe "run testparser:", -> + it '', -> + +describe "peasy", -> + it "should parse with A: Ax|a", -> + class Parser extends peasy.Parser + constructor: -> + super + a = @char('a') + x = @char('x') + @A = @rec @orp(( => (m = @A()) and x() and m+'x' or m), a) + parser = new Parser() + parse = (text) -> parser.parse(text, parser.A) + expect(parse('a')).toBe 'a' + expect(parse('ax')).toBe 'ax' + expect(parse('axx')).toBe 'axx' + expect(parse('axxx')).toBe 'axxx' + + it "should parse with A: Bx|a; B:A|b", -> + class Parser extends peasy.Parser + constructor: -> + super + a = @char('a') + b = @char('b') + x = @char('x') + @A = @rec @orp((=> (m = B()) and x() and m+'x' or m), a) + B = @rec @orp(@A, b) + parser = new Parser() + parse = (text) -> parser.parse(text, parser.A) + expect(parse('a')).toBe 'a' + expect(parse('ax')).toBe 'ax' + expect(parse('axx')).toBe 'axx' + expect(parse('axxx')).toBe 'axxx' + expect(parse('b')).toBe 'b' + expect(parse('bx')).toBe 'bx' + expect(parse('bxxx')).toBe 'bxxx' + expect(parse('bxg')).toBe 'bx' + expect(parse('bxxg')).toBe 'bxx' + expect(parse('bxxxg')).toBe 'bxxx' + expect(parse('fg')).toBe undefined + expect(parse('')).toBe undefined + + it "should parse with A: Bx|a; B:C; C:A|b", -> + class Parser extends peasy.Parser + constructor: -> + super + a = @char('a') + b = @char('b') + x = @char('x') + @A = @rec @orp((=> (m = B()) and x() and m+'x' or m), a) + B = @rec -> C() + C = @rec @orp(@A, b) + parser = new Parser() + parse = (text) -> parser.parse(text, parser.A) + expect(parse('a')).toBe 'a' + expect(parse('ax')).toBe 'ax' + expect(parse('axx')).toBe 'axx' + expect(parse('axxx')).toBe 'axxx' + expect(parse('b')).toBe 'b' + expect(parse('bx')).toBe 'bx' + expect(parse('bxxx')).toBe 'bxxx' + expect(parse('bxg')).toBe 'bx' + expect(parse('bxxg')).toBe 'bxx' + expect(parse('bxxxg')).toBe 'bxxx' + expect(parse('fg')).toBe undefined + expect(parse('')).toBe undefined + + it "should parse with A: Bx|a; B:C|Ay; C:A|b", -> + class Parser extends peasy.Parser + constructor: -> + super + a = @char('a') + b = @char('b') + x = @char('x') + y = @char('y') + @A = @rec @orp((=> (m = B()) and x() and m+'x' or m), a) + B = @rec @orp(( => (m = @A()) and y() and m+'y'), -> C()) + C = @rec @orp(@A, b) + parser = new Parser() + parse = (text) -> parser.parse(text, parser.A) + expect(parse('a')).toBe 'a' + expect(parse('ax')).toBe 'ax' + expect(parse('axx')).toBe 'axx' + expect(parse('axxx')).toBe 'axxx' + expect(parse('ay')).toBe 'ay' + expect(parse('ayx')).toBe 'ayx' + expect(parse('ayxyx')).toBe 'ayxyx' + expect(parse('bxx')).toBe 'bxx'# Bx Cx Ax Bxx Cxx bxx + expect(parse('ayxxx')).toBe 'ayxxx'# Bx Cx Ax Bxx Cxx Axx Bxxx Ayxxx ayxxx + expect(parse('ayxmxx')).toBe 'ayx' + expect(parse('b')).toBe 'b' + expect(parse('bx')).toBe 'bx' + expect(parse('bxxx')).toBe 'bxxx' + expect(parse('bxg')).toBe 'bx' + expect(parse('bxxg')).toBe 'bxx' + expect(parse('bxxxg')).toBe 'bxxx' + expect(parse('fg')).toBe undefined + expect(parse('')).toBe undefined + + it "should parse with Root: Az; A: Bx|a; B:C|Ay; C:A|b", -> + class Parser extends peasy.Parser + constructor: -> + super + a = @char('a') + b = @char('b') + x = @char('x') + y = @char('y') + z = @char('z') + @root = => (m = @A()) and z() and m+'z' + @A = @rec @orp(( => (m = B()) and x() and m+'x' or m), a) + B = @rec @orp((=> (m = @A()) and y() and m+'y'), -> C()) + C = @rec @orp(@A, b) + parser = new Parser() + parse = (text) -> parser.parse(text) + expect(parse('az')).toBe 'az' + expect(parse('axz')).toBe 'axz' + expect(parse('axxz')).toBe 'axxz' + expect(parse('axxxz')).toBe 'axxxz' + expect(parse('ayz')).toBe 'ayz' + expect(parse('ayxz')).toBe 'ayxz' + expect(parse('ayxyxz')).toBe 'ayxyxz' + expect(parse('bxxz')).toBe 'bxxz' + expect(parse('ayxxxz')).toBe 'ayxxxz' + expect(parse('ayxmxxz')).toBe undefined + expect(parse('bz')).toBe 'bz' + expect(parse('bxz')).toBe 'bxz' + expect(parse('bxxxz')).toBe 'bxxxz' + expect(parse('bxgz')).toBe undefined + expect(parse('bxxgz')).toBe undefined + expect(parse('bxxxgz')).toBe undefined + expect(parse('fg')).toBe undefined + expect(parse('')).toBe undefined diff --git a/coffee/test/karma/testpeasy.coffee b/coffee/test/karma/testpeasy.coffee deleted file mode 100644 index a7af1a4..0000000 --- a/coffee/test/karma/testpeasy.coffee +++ /dev/null @@ -1,137 +0,0 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/karma/testpeasy') -do (require=require, exports=exports, module=module) -> - - peasy = require '../../peasy' - - describe "run testpeasy:", -> - it '', -> - - describe "peasy", -> - it "should parse with A: Ax|a", -> - class Parser extends peasy.Parser - constructor: -> - super - a = @char('a') - x = @char('x') - @A = @rec @orp(( => (m = @A()) and x() and m+'x' or m), a) - parser = new Parser() - parse = (text) -> parser.parse(text, parser.A) - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - - it "should parse with A: Bx|a; B:A|b", -> - class Parser extends peasy.Parser - constructor: -> - super - a = @char('a') - b = @char('b') - x = @char('x') - @A = @rec @orp((=> (m = B()) and x() and m+'x' or m), a) - B = @rec @orp(@A, b) - parser = new Parser() - parse = (text) -> parser.parse(text, parser.A) - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "should parse with A: Bx|a; B:C; C:A|b", -> - class Parser extends peasy.Parser - constructor: -> - super - a = @char('a') - b = @char('b') - x = @char('x') - @A = @rec @orp((=> (m = B()) and x() and m+'x' or m), a) - B = @rec -> C() - C = @rec @orp(@A, b) - parser = new Parser() - parse = (text) -> parser.parse(text, parser.A) - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "should parse with A: Bx|a; B:C|Ay; C:A|b", -> - class Parser extends peasy.Parser - constructor: -> - super - a = @char('a') - b = @char('b') - x = @char('x') - y = @char('y') - @A = @rec @orp((=> (m = B()) and x() and m+'x' or m), a) - B = @rec @orp(( => (m = @A()) and y() and m+'y'), -> C()) - C = @rec @orp(@A, b) - parser = new Parser() - parse = (text) -> parser.parse(text, parser.A) - expect(parse('a')).toBe 'a' - expect(parse('ax')).toBe 'ax' - expect(parse('axx')).toBe 'axx' - expect(parse('axxx')).toBe 'axxx' - expect(parse('ay')).toBe 'ay' - expect(parse('ayx')).toBe 'ayx' - expect(parse('ayxyx')).toBe 'ayxyx' - expect(parse('bxx')).toBe 'bxx'# Bx Cx Ax Bxx Cxx bxx - expect(parse('ayxxx')).toBe 'ayxxx'# Bx Cx Ax Bxx Cxx Axx Bxxx Ayxxx ayxxx - expect(parse('ayxmxx')).toBe 'ayx' - expect(parse('b')).toBe 'b' - expect(parse('bx')).toBe 'bx' - expect(parse('bxxx')).toBe 'bxxx' - expect(parse('bxg')).toBe 'bx' - expect(parse('bxxg')).toBe 'bxx' - expect(parse('bxxxg')).toBe 'bxxx' - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined - - it "should parse with Root: Az; A: Bx|a; B:C|Ay; C:A|b", -> - class Parser extends peasy.Parser - constructor: -> - super - a = @char('a') - b = @char('b') - x = @char('x') - y = @char('y') - z = @char('z') - @root = => (m = @A()) and z() and m+'z' - @A = @rec @orp(( => (m = B()) and x() and m+'x' or m), a) - B = @rec @orp((=> (m = @A()) and y() and m+'y'), -> C()) - C = @rec @orp(@A, b) - parser = new Parser() - parse = (text) -> parser.parse(text) - expect(parse('az')).toBe 'az' - expect(parse('axz')).toBe 'axz' - expect(parse('axxz')).toBe 'axxz' - expect(parse('axxxz')).toBe 'axxxz' - expect(parse('ayz')).toBe 'ayz' - expect(parse('ayxz')).toBe 'ayxz' - expect(parse('ayxyxz')).toBe 'ayxyxz' - expect(parse('bxxz')).toBe 'bxxz' - expect(parse('ayxxxz')).toBe 'ayxxxz' - expect(parse('ayxmxxz')).toBe undefined - expect(parse('bz')).toBe 'bz' - expect(parse('bxz')).toBe 'bxz' - expect(parse('bxxxz')).toBe 'bxxxz' - expect(parse('bxgz')).toBe undefined - expect(parse('bxxgz')).toBe undefined - expect(parse('bxxxgz')).toBe undefined - expect(parse('fg')).toBe undefined - expect(parse('')).toBe undefined diff --git a/coffee/test/mocha/testpeasy.coffee b/coffee/test/mocha/testparser.coffee similarity index 98% rename from coffee/test/mocha/testpeasy.coffee rename to coffee/test/mocha/testparser.coffee index 2c9b2e7..e1f2f4b 100644 --- a/coffee/test/mocha/testpeasy.coffee +++ b/coffee/test/mocha/testparser.coffee @@ -1,10 +1,10 @@ -if typeof window=='object' then {require, exports, module} = twoside('/test/mocha/testpeasy') +if typeof window=='object' then {require, exports, module} = twoside('/test/mocha/testparser') do (require=require, exports=exports, module=module) -> chai = require 'chai' expect = chai.expect - {charset, inCharset} = peasy = require '../../peasy' + {charset, inCharset} = peasy = require '../../index' describe "run testpeasy:", -> it '', -> diff --git a/coffee/twoside.coffee b/coffee/twoside.coffee index 350e15e..3012505 100644 --- a/coffee/twoside.coffee +++ b/coffee/twoside.coffee @@ -1,8 +1,5 @@ ### modules/twoside # make modules can be used on both server side and client side. -github.com/chaosim/twoside -npmjs.org/package/twoside -npm install twoside ### do -> oldrequire = window.require @@ -16,25 +13,29 @@ do -> window.require = oldrequire window.exports = oldexports window.module = oldmodule - path = normalize(path) + # extension name will be removed, so don't make different modules with same path and different extension name. + path = normalize(path).slice(0, path.lastIndexOf(".")) + modulePath = path.slice(0, path.lastIndexOf("/")) + filename = path.slice(path.lastIndexOf("/")+1) exports = {} module = twoside._modules[path] = {exports:exports} - modulePath = path.slice(0, path.lastIndexOf("/")+1) + # support folder as module that is similar to nodejs + if filename=='index' then twoside._modules[modulePath] = module require = (path) -> - module = twoside._modules[path] - if module then return module - path = normalize(modulePath+path) - module = twoside._modules[path] - if !module + requiredModule = twoside._modules[path] + if requiredModule then return requiredModule + path = path.slice(0, path.lastIndexOf(".")) # remove .js, .coffee, .json extension name + path = normalize(modulePath+'/'+path) + requiredModule = twoside._modules[path] + if !requiredModule console.log(getStackTrace()) throw path+' is a wrong twoside module path.' - module.exports + requiredModule.exports {require:require, exports:exports, module:module} twoside._modules = {} ### we can alias some external modules.### twoside.alias = (path, object) -> twoside._modules[path] = object - ### e.g. n browser, if underscore have been imported before, we can alias it like below: ### - # twoside.alias('underscore', _) + twoside.alias('lodash', _) normalize = (path) -> if !path || path == '/' then return '/' @@ -45,15 +46,3 @@ do -> ### for IE 6 & 7 - use path.charAt(i), not path[i] ### head = if path.charAt(0)=='/' or path.charAt(0)=='.' then '/' else '' head + target.join('/').replace(/[\/]{2,}/g, '/') - -# coffee-script sample -# if typeof window=='object' then {require, exports, module} = twoside('/module1') -# do (require=require, exports=exports, module=module) -> -# indent module definition - -### javascript sample -if (typeof window==='object'){ var m = twoside('/module1'), exports= m.exports, module = m.module, require = m.module; } -(function(require, exports, module){ - // wrapped module definition -})(require, exports, module); -### \ No newline at end of file diff --git a/gruntfile.coffee b/gruntfile.coffee deleted file mode 100644 index 83de038..0000000 --- a/gruntfile.coffee +++ /dev/null @@ -1,61 +0,0 @@ -coffeeFolders = ['**/'] -coffeePatterns = ('coffee/'+folder+'*.coffee' for folder in coffeeFolders) - -module.exports = (grunt) -> - grunt.initConfig - pkg: grunt.file.readJSON 'package.json' - clean: {js: 'js'} - coffee: - options: {sourceRoot: '', bare: true} # sourceMap: true - dev: files: for folder in coffeeFolders - {expand: true, cwd: 'coffee', src: folder+'*.coffee', dest:'js', ext:'.js'} - uglify: - options: {mangle: false} - target: - files: - 'js/twoside.min.js': ['js/twoside.js'] - 'js/peasy.min.js': ['js/peasy.js'] - 'js/logicpeasy.min.js': ['js/logicpeasy.js'] - karma: - auto: {configFile: 'js/test/karma-conf', autoWatch: true, singleRun: false} - once: {configFile: 'js/test/karma-conf', autoWatch: false, singleRun: true} - mochaTest: - test: - options: {reporter: 'spec', clearRequireCache: true} - src: ['js/test/mocha/**/*.js'] - concurrent: - options: logConcurrentOutput: true - dev: tasks: ['look:dev', 'karma:auto'] - - watchConfig = - dev: - options:{spawn: false, debounceDelay: 100} - coffee:{files: coffeePatterns, tasks: ['coffee:dev']} - - grunt.option 'force', true - for task in ['grunt-contrib-clean', 'grunt-contrib-coffee', 'grunt-karma', 'grunt-contrib-watch',\ - 'grunt-mocha-test', 'grunt-concurrent', 'grunt-contrib-uglify'] - grunt.loadNpmTasks(task) - - defaultMochaSrc = grunt.config('mochaTest.test.src') - - grunt.registerTask 'look', 'dynamic watch', -> - target = grunt.task.current.args[0] or 'dev' - grunt.config.set('watch', watchConfig[target]) - grunt.task.run 'watch' - if target=='dev' - grunt.event.on 'watch', (action, filepath) -> - grunt.config('mochaTest.test.src', defaultMochaSrc) - if filepath.match('js/test/mocha/') then grunt.config('mochaTest.test.src', filepath); return - if action=='deleted' then return - if grunt.file.isMatch coffeePatterns, [filepath] - grunt.config.set 'coffee', - options: {sourceRoot: '', bare: true} # , sourceMap: true - dev: {expand: true, cwd: 'coffee', dest: 'js', src: filepath.slice(7), ext: '.js'} - - grunt.registerTask('build', ['clean:js', 'coffee', 'uglify']) - grunt.registerTask('karm1', ['karma:once']) - grunt.registerTask('karm', ['karma:auto']) - grunt.registerTask('test', ['build', 'karm1']) - grunt.registerTask('dev', ['build','mochaTest', 'concurrent']) - grunt.registerTask 'default', ['dev'] diff --git a/gulp-twoside.js b/gulp-twoside.js new file mode 100644 index 0000000..7e13fbf --- /dev/null +++ b/gulp-twoside.js @@ -0,0 +1,25 @@ +/* jshint node: true */ +'use strict'; +var path = require('path'); +var es = require('event-stream'); +var gutil = require('gulp-util'); + +module.exports = function(basepath, moduleName) { + return es.through(function(file){ + if (file.isStream()) return this.emit('error', new Error("gulp-twoside: Streaming not supported")); + var padpath = path.join(moduleName, file.path.slice(basepath.length)).replace(/\\/g, '/'); + var filename = padpath.slice(padpath.lastIndexOf("/")+1); + if (filename==='twoside.js') { this.emit('data', file); return;} +// console.log(filename); + var head = "// wrap lines by gulp-twoside for providing twoside module\nvar exports, module, require;\n(function(require, exports, module) {var ts;\nif (typeof window === 'object') { ts = twoside('"+padpath+"'), require = ts.require, exports = ts.exports, module = ts.module;} \n"; + var foot = "\n// wrap line by gulp-twoside\n})(require, exports, module);" + //console.log(file); + file.contents = Buffer.concat([ + new Buffer(head), + file.contents, + new Buffer(foot) + ]); + //console.log(file.path); + this.emit('data', file); + }); +}; diff --git a/gulpfile.coffee b/gulpfile.coffee new file mode 100644 index 0000000..9a73fcd --- /dev/null +++ b/gulpfile.coffee @@ -0,0 +1,131 @@ +_ = require 'lodash' +gulp = require('gulp') +gutil = require 'gulp-util' +changed = require('gulp-changed') +cache = require('gulp-cached') +plumber = require('gulp-plumber') +clean = require('gulp-clean') +shell = require 'gulp-shell' +rename = require("gulp-rename") +coffee = require ('gulp-coffee') +browserify = require('gulp-browserify') +concat = require('gulp-concat') +closureCompiler = require('gulp-closure-compiler') +size = require('gulp-size') +mocha = require('gulp-mocha') +karma = require('gulp-karma') +twoside = require './gulp-twoside' + + +#pluginwatch = require('gulp-watch') +#styl = require('gulp-styl') + +express = require('express') + +#http://rhumaric.com/2014/01/livereload-magic-gulp-style/ +livereload = require('gulp-livereload') +tinylr = require('tiny-lr') + +task = gulp.task.bind(gulp) +watch = gulp.watch.bind(gulp) +src = gulp.src.bind(gulp) +dest = gulp.dest.bind(gulp) +from = (source, options={dest:folders.destjs, cache:'cache'}) -> + options.dest ?= folders.destjs + options.cache ?= 'cache' + src(source).pipe(changed(options.dest)).pipe(cache(options.cache)).pipe(plumber()) +GulpStream = src('').constructor +GulpStream::to = (dst) -> @pipe(dest(dst))#.pipe(livereload(tinylrServer)) +GulpStream::pipelog = (obj, log=gutil.log) -> @pipe(obj).on('error', log) + +rootOf = (path) -> path.slice(0, path.indexOf('/')) +midOf = (path) -> path.slice(path.indexOf('/')+1, path.indexOf('/*')) +patterns = (args...) -> + for arg in args + if typeof arg =='string' then pattern(arg) + else arg +gulpto = (destbase, args...) -> + for arg in args + if typeof arg =='string' then pattern(arg, destbase) + else arg +pattern = (src, destbase, options) -> new Pattern(src, destbase, options) +class Pattern + constructor: (@src, @destbase, options={}) -> + if typeof destbase=='object' then options = destbase; @destbase = undefined + srcRoot = rootOf(@src) + if not @destbase then @destbase = rootOf(@src) + if not options.desttail? then @desttail = midOf(@src) + if @desttail then @dest = @destbase+'/'+@desttail + else @dest = @destbase + +# below will put output js files in wrong directory structure!!! +# coffee: [coffeeroot+'/*.coffee', coffeeroot+'/samples/**/*.coffee', coffeeroot+'/test/**/*.coffee'] + +folders = + dest: 'dist' + dist: 'dist' + dev: 'dev' + src: 'coffee' + coffee: 'coffee' + destjs: 'js' + pulic: 'public' + static: 'static' + +files = + copy: (folders.src+'/'+name for name in ['**/*.js', '**/*.json', '**/*.jade', '**/*.html', '**/*.css', '**/*.tjv']) + coffee: [folders.coffee+'/**/*.coffee'] + mocha: folders.destjs+'/test/mocha/**/*.js' + karma: folders.destjs+'/test/karma/**/*.js' + modulejs: folders.destjs+'/lib/modules/**/*.js' + serverjs: folders.destjs+'/lib/server/**/*.js' + reload: ['*.html', folders.destjs+'/client/**/*.js', folders.destjs+'/modules/**/*.js', 'public/**/*.js', 'public/**/*.css'] + +task 'clean', -> src([folders.destjs], {read:false}) .pipe(clean()) +task 'runapp', shell.task ['node dist/examples/sockio/app.js'] +task 'express', -> + app = express() + app.use(require('connect-livereload')()) # play with tiny-lr to livereload stuffs + console.log __dirname + app.use(express.static(__dirname)) + app.listen(4000) +task 'copy', -> from(files.copy, {cache:'copy'}).to(folders.destjs) +task 'coffee', -> from(files.coffee, {cache:'coffee'}).pipelog(coffee({bare: true})).to(folders.destjs) +task 'twoside', ['coffee'], (cb) -> + for pattern in patterns(folders.destjs+'/*.js', folders.destjs+'/samples/**/*.js', folders.destjs+'/test/karma/**/*.js') + stream = src(pattern.src).pipelog(twoside('f:/peasy/js', 'peasy')).to(pattern.dest) + stream +gulp.task 'browserify', ['coffee'], -> + src(folders.destjs+'/test/karma/karma-bundle.js').pipe(browserify({ + insertGlobals : true, + #debug : !gulp.env.production + })) + .to(folders.destjs+'/test/karma') +gulp.task 'concat', ['twoside'], -> + src([folders.destjs+'/parser.js', folders.destjs+'/lineparser.js', folders.destjs+'/logicparser.js', folders.destjs+'/index.js']).pipe(concat("peasy.js")).to(folders.destjs) +gulp.task 'min', ['concat'], -> src(folders.destjs+'/peasy.js').pipe(closureCompiler()).pipe(rename(suffix: "-min")).pipe(size(showFiles:true)).to(folders.destjs) + +onErrorContinue = (err) -> console.log(err.stack); @emit 'end' +#onErrorContinue = (err) -> @emit 'end' +task 'mocha', -> + src(files.mocha) +# .pipelog(plumber()) + .pipe(mocha({reporter: 'dot'})).on("error", onErrorContinue) +task 'karma', -> src(files.karma).pipe(karma({configFile: folders.destjs+'/test/karma-conf', action: 'run'})) # run: once, watch: autoWatch=true +task 'stylus', -> from(['css/**/*.css']).pipe(styl({compress: true})).to(folders.destjs) +task 'tinylr', -> server.listen 35729, (err) -> if err then console.log(err) +task 'watch/copy', -> watch files.copy, ['copy'] +task 'watch/coffee', -> watch files.coffee, ['coffee'] +task 'watch/mocha', -> watch [files.modulejs, files.serverjs, files.mocha], ['mocha'] +#task 'watch:mocha', -> +# src([files.modulejs, files.serverjs, files.mocha]) +# .pipe(plumber()) +# .pipe pluginwatch emit: 'all', (files) -> +# files.pipe(mocha(reporter: 'dot' )) +# .on 'error', onErrorContinue +onWatchReload = (event) -> src(event.path, {read: false}).pipe(livereload(tinylrServer)) +task 'watch/reload', -> tinylrServer = tinylr(); tinylrServer.listen(35729); watch files.reload,onWatchReload +task 'watch/all', -> ['watch/copy', 'watch/coffee', 'watch/mocha', 'watch/reload'] # +task 'build', ['copy', 'coffee'] +task 'mocha/auto', ['watch/copy', 'watch/coffee', 'watch/mocha'] +task 'default',['build', 'watch:all'] + diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..d32eb53 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,2 @@ +require('coffee-script/register'); +require('./gulpfile.coffee'); \ No newline at end of file diff --git a/js/deprecated/autopeasy.js b/js/deprecated/autopeasy.js deleted file mode 100644 index a3a5717..0000000 --- a/js/deprecated/autopeasy.js +++ /dev/null @@ -1,797 +0,0 @@ -var exports, module, require, _ref, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = [].slice; - -if (typeof window === 'object') { - _ref = twoside('/deprecated/autopeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var ObjecttoString, autoRecursive, computeLeftRecursives, cursor, followIdentifierLetter_, functionCache, grammar, hasOwnProperty, identifierLetter, identifierLetter_, isIdentifierLetter, isRule, isString, literal, literal_, memo, memoAutoRecursive, memoRules, memorize, memorizedRecursivs, originalRules, parseCache, recursiveRules, setMemoTag, setMemorizeRules, symbolDescedentsMap, symbolToTagMap, tags, text, textLength; - text = ''; - textLength = 0; - cursor = 0; - grammar = void 0; - originalRules = {}; - recursiveRules = {}; - memorizedRecursivs = {}; - memoRules = {}; - symbolDescedentsMap = {}; - symbolToTagMap = {}; - tags = {}; - parseCache = {}; - functionCache = {}; - hasOwnProperty = Object.hasOwnProperty; - exports.initialize = function() { - parseCache = {}; - functionCache = {}; - originalRules = {}; - recursiveRules = {}; - memorizedRecursivs = {}; - memoRules = {}; - symbolDescedentsMap = {}; - symbolToTagMap = {}; - tags = {}; - return parseCache = {}; - }; - exports.parse = function(data, aGrammar, root) { - text = data; - textLength = text.length; - cursor = 0; - root = root || aGrammar.rootSymbol; - grammar = aGrammar; - return grammar[root](0); - }; - isRule = function(grammar, name) { - var e, property, result; - if (hasOwnProperty.call(functionCache, name)) { - return functionCache[name]; - } - if (!hasOwnProperty.call(grammar, name)) { - result = false; - } else { - property = grammar[name]; - if (typeof property !== "function") { - result = false; - } else { - try { - if (typeof (property(spaces)) === "function") { - result = false; - } - } catch (_error) { - e = _error; - result = true; - } - } - } - functionCache[name] = result; - return result; - }; - exports.autoComputeLeftRecursives = computeLeftRecursives = function(grammar) { - var appendToPaths, circle, circles, currentLeftHand, descendents, i, length, meetTable, memorized, parentToChildren, path, paths, pathsCount, sym, symbol, symbolPathsMap, _fn, _i, _j, _len; - originalRules = {}; - for (symbol in grammar) { - if (!isRule(grammar, symbol)) { - break; - } - originalRules[symbol] = grammar[symbol]; - } - parentToChildren = {}; - currentLeftHand = null; - _fn = function(symbol) { - return grammar[symbol] = function(start) { - var children; - if (start !== 0) { - - } else { - cursor++; - children = parentToChildren[currentLeftHand] != null ? parentToChildren[currentLeftHand] : parentToChildren[currentLeftHand] = []; - if (__indexOf.call(children, symbol) < 0) { - return children.push(symbol); - } - } - }; - }; - for (symbol in grammar) { - if (!isRule(grammar, symbol)) { - break; - } - _fn(symbol); - } - for (symbol in grammar) { - if (!isRule(grammar, symbol)) { - break; - } - currentLeftHand = symbol; - originalRules[symbol](0); - } - appendToPaths = function(symbol, meetTable, paths) { - var chidlren, child, length, path, _i, _j, _len, _len1, _results; - if (!(chidlren = parentToChildren[symbol])) { - return; - } - _results = []; - for (_i = 0, _len = chidlren.length; _i < _len; _i++) { - child = chidlren[_i]; - for (_j = 0, _len1 = paths.length; _j < _len1; _j++) { - path = paths[_j]; - length = path.length; - if (length > 1 && path[length - 1] === path[0]) { - continue; - } else if (__indexOf.call(path, child) >= 0) { - if (child === path[0]) { - path.push(child); - } else { - continue; - } - } else { - path.push(child); - } - } - if (!meetTable[child]) { - _results.push(appendToPaths(child, meetTable, paths)); - } else { - _results.push(void 0); - } - } - return _results; - }; - symbolPathsMap = {}; - for (symbol in grammar) { - if (!isRule(grammar, symbol)) { - break; - } - meetTable = {}; - meetTable[symbol] = true; - paths = symbolPathsMap[symbol] != null ? symbolPathsMap[symbol] : symbolPathsMap[symbol] = [[symbol]]; - appendToPaths(symbol, meetTable, paths); - i = 0; - pathsCount = paths.length; - circles = []; - while (i < pathsCount) { - path = paths[i++]; - length = path.length; - if (path[length - 1] === symbol) { - path.pop(); - circles.push(path); - } - } - if (circles.length) { - symbolPathsMap[symbol] = circles; - } else { - delete symbolPathsMap[symbol]; - } - } - for (symbol in grammar) { - if (!isRule(grammar, symbol)) { - continue; - } - if (!hasOwnProperty.call(symbolPathsMap, symbol)) { - grammar[symbol] = originalRules[symbol]; - delete originalRules[symbol]; - continue; - } - descendents = symbolDescedentsMap[symbol] = []; - grammar[symbol] = recursiveRules[symbol] = autoRecursive(symbol); - memoRules[symbol] = memo(symbol); - circles = symbolPathsMap[symbol]; - for (_i = 0, _len = circles.length; _i < _len; _i++) { - circle = circles[_i]; - length = circle.length; - memorized = false; - for (i = _j = 0; 0 <= length ? _j < length : _j > length; i = 0 <= length ? ++_j : --_j) { - sym = circle[i]; - if (__indexOf.call(descendents, sym) < 0) { - descendents.push(sym); - } - if (memorizedRecursivs[sym]) { - memorized = true; - } - if (i === length - 1 && !memorized) { - memorizedRecursivs[sym] = memoAutoRecursive(sym); - } - } - } - } - symbolPathsMap = void 0; - return functionCache = void 0; - }; - autoRecursive = function(symbol) { - return function(start) { - var child, hash, m, memoRule, result, rule, _i, _j, _len, _len1, _ref1, _ref2; - _ref1 = symbolDescedentsMap[symbol]; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - child = _ref1[_i]; - memoRule = memorizedRecursivs[child]; - if (memoRule) { - grammar[child] = memoRule; - } else { - grammar[child] = originalRules[child]; - } - } - hash = symbol + start; - m = parseCache[hash] != null ? parseCache[hash] : parseCache[hash] = [void 0, -1]; - if (m[1] >= 0) { - cursor = m[1]; - return m[0]; - } - rule = grammar[symbol]; - while (1) { - result = rule(start); - if (m[1] < 0) { - m[0] = result; - if (result) { - m[1] = cursor; - } else { - m[1] = start; - } - continue; - } else { - if (m[1] === cursor) { - m[0] = result; - return result; - } else if (cursor < m[1]) { - m[0] = result; - cursor = m[1]; - return result; - } else { - m[0] = result; - m[1] = cursor; - } - } - } - _ref2 = symbolDescedentsMap[symbol]; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - child = _ref2[_j]; - grammar[child] = recursiveRules[child]; - } - return result; - }; - }; - memoAutoRecursive = function(symbol) { - var rule; - rule = originalRules[symbol]; - return function(start) { - var child, descendents, memoRecursive, result, _i, _j, _len, _len1; - descendents = symbolDescedentsMap[symbol]; - for (_i = 0, _len = descendents.length; _i < _len; _i++) { - child = descendents[_i]; - grammar[child] = memoRules[child]; - } - result = rule(start); - for (_j = 0, _len1 = descendents.length; _j < _len1; _j++) { - child = descendents[_j]; - memoRecursive = memorizedRecursivs[child]; - if (memoRecursive) { - grammar[child] = memoRecursive; - } else { - grammar[child] = originalRules[child]; - } - } - return result; - }; - }; - setMemoTag = function(symbol) { - var i, tag, _ref1; - i = 1; - while (1) { - if (_ref1 = hasOwnProperty.call(tags, symbol.slice(0, i)), __indexOf.call(tags, _ref1) >= 0) { - i++; - } else { - break; - } - } - tag = symbol.slice(0, i); - symbolToTagMap[symbol] = tag; - return tags[tag] = true; - }; - setMemorizeRules = function(grammar, symbols) { - var symbol, _i, _len, _results; - _results = []; - for (_i = 0, _len = symbols.length; _i < _len; _i++) { - symbol = symbols[_i]; - originalRules[symbol] = grammar[symbol]; - _results.push(grammar[symbol] = memorize(symbol)); - } - return _results; - }; - memorize = function(symbol) { - var rule, tag; - tag = symbolToTagMap[symbol]; - rule = originalRules[symbol]; - return function(start) { - var hash, m, result; - hash = tag + start; - m = parseCache[hash]; - if (m) { - cursor = m[1]; - return m[0]; - } else { - result = rule(start); - parseCache[hash] = [result, cursor]; - return result; - } - }; - }; - exports.memo = memo = function(symbol) { - return function(start) { - var hash, m; - hash = symbol + start; - m = parseCache[hash]; - if (m) { - return m[0]; - } - }; - }; - exports.andp = function(exps) { - var exp; - exps = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = exps.length; _i < _len; _i++) { - exp = exps[_i]; - if (isString(exp)) { - _results.push(literal(exp)); - } else { - _results.push(exp); - } - } - return _results; - })(); - return function(start) { - var result, _i, _len; - cursor = start; - for (_i = 0, _len = exps.length; _i < _len; _i++) { - exp = exps[_i]; - if (!(result = exp(cursor))) { - return; - } - } - return result; - }; - }; - exports.orp = function() { - var exp, exps; - exps = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - exps = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = exps.length; _i < _len; _i++) { - exp = exps[_i]; - if (isString(exp)) { - _results.push(literal(exp)); - } else { - _results.push(exp); - } - } - return _results; - })(); - return function(start) { - var result, _i, _len; - for (_i = 0, _len = exps.length; _i < _len; _i++) { - exp = exps[_i]; - if (result = exp(start)) { - return result; - } - return result; - } - }; - }; - exports.notp = function(exp) { - if (isString(exp)) { - exp = literal(exp); - } - return function(start) { - return !exp(start); - }; - }; - exports.any = function(exp) { - if (isString(exp)) { - exp = literal(exp); - } - return function(start) { - var result, x; - result = []; - cursor = start; - while ((x = exp(cursor))) { - result.push(x); - } - return result; - }; - }; - exports.some = function(exp) { - if (isString(exp)) { - exp = literal(exp); - } - return function(start) { - var result, x; - result = []; - cursor = start; - if (!(x = exp(cursor))) { - return x; - } - while (1) { - result.push(x); - x = exp(cursor); - if (!x) { - break; - } - } - return result; - }; - }; - exports.may = exports.optional = function(exp) { - if (isString(exp)) { - exp = literal(exp); - } - return function(start) { - var x; - cursor = start; - if (x = exp(cursor)) { - return x; - } else { - cursor = start; - return true; - } - }; - }; - exports.follow = function(exp) { - if (isString(exp)) { - exp = literal(exp); - } - return function(start) { - var x; - cursor = start; - if (x = exp(cursor)) { - cursor = start; - return x; - } - }; - }; - exports.times = function(exp, n) { - if (isString(exp)) { - exp = literal(exp); - } - return function(start) { - var i, x; - cursor = start; - i = 0; - while (i++ < n) { - if (x = exp(cursor)) { - result.push(x); - } else { - return; - } - } - return result; - }; - }; - exports.seperatedList = function(exp, separator) { - if (separator == null) { - separator = spaces; - } - if (isString(exp)) { - exp = literal(exp); - } - if (isString(separator)) { - separator = literal(separator); - } - return function(start) { - var result, x; - cursor = start; - result = []; - x = exp(cursor); - if (!x) { - return; - } - while (1) { - result.push(x); - if (!(x = exp(cursor))) { - break; - } - } - return result; - }; - }; - exports.timesSeperatedList = function(exp, n, separator) { - if (separator == null) { - separator = spaces; - } - if (isString(exp)) { - exp = literal(exp); - } - if (isString(separator)) { - separator = literal(separator); - } - return function(start) { - var i, result, x; - cursor = start; - result = []; - x = exp(cursor); - if (!x) { - return; - } - i = 1; - while (i++ < n) { - result.push(x); - if (!(x = exp(cursor))) { - break; - } - } - return result; - }; - }; - exports.char = function(c) { - return function(start) { - if (text[start] === c) { - cursor = start + 1; - return c; - } - }; - }; - exports.char_ = function(c) { - return function() { - if (text[cursor] === c) { - cursor++; - return c; - } - }; - }; - exports.literal = literal = function(string) { - return function(start) { - var len, stop; - len = string.length; - if (text.slice(start, stop = start + len) === string) { - cursor = stop; - return true; - } - }; - }; - exports.literal_ = literal_ = function(string) { - return function(start) { - var len, stop; - len = string.length; - if (text.slice(cursor, stop = cursor + len) === string) { - cursor = stop; - return true; - } - }; - }; - exports.spaces = function(start) { - var len; - len = 0; - cursor = start; - text = text; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - return len; - }; - exports.spaces_ = function() { - var len; - len = 0; - text = text; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - return len; - }; - exports.spaces1 = function(start) { - var len; - len = 0; - cursor = start; - text = text; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - if (len) { - return cursor = cursor; - return len; - } - }; - exports.spaces1_ = function() { - var len; - len = 0; - cursor = start; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - if (len) { - return cursor = cursor; - return len; - } - }; - exports.wrap = function(item, left, right) { - if (left == null) { - left = spaces; - } - if (right == null) { - right = spaces; - } - if (isString(item)) { - item = literal(item); - } - return function(start) { - var result; - if (left(start) && (result = item(cursor) && right(cursor))) { - return result; - } - }; - }; - exports.getcursor = exports.cur = function() { - return cursor; - }; - exports.setcursor = exports.setcur = function(pos) { - return cursor = pos; - }; - identifierLetter = function(start) { - var c; - start = cursor; - c = text[cursor]; - if (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { - cursor++; - return true; - } - }; - identifierLetter_ = function() { - var c; - c = text[cursor]; - if (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { - cursor++; - return true; - } - }; - followIdentifierLetter_ = function() { - var c; - c = text[cursor]; - return c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9'); - }; - isIdentifierLetter = function(c) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '$' || 'c' === '_'; - }; - ObjecttoString = Object.prototype.toString; - exports.isString = isString = function(x) { - return ObjecttoString.call(x) === '[object String]'; - }; - exports.isdigit = function(c) { - return ('0' <= c && c <= '9'); - }; - exports.digit = function(start) { - var c; - c = text[start]; - if (('0' <= c && c <= '9')) { - return cursor = start + 1; - } - }; - exports.digit_ = function() { - var c; - c = text[cursor]; - if (('0' <= c && c <= '9')) { - return cursor++; - } - }; - exports.isletter = exports.isalpha = function(c) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); - }; - exports.letter = exports.alpha = function(start) { - var c; - c = text[start]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { - return cursor = start + 1; - } - }; - exports.letter_ = exports.alpha_ = function() { - var c; - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { - return cursor++; - } - }; - exports.islower = function(c) { - return ('a' <= c && c <= 'z'); - }; - exports.lower = function(start) { - var c; - c = text[start]; - if (('a' <= c && c <= 'z')) { - return cursor = start + 1; - } - }; - exports.lower_ = function() { - var c; - c = text[cursor]; - if (('a' <= c && c <= 'z')) { - return cursor++; - } - }; - exports.isupper = function(c) { - return ('A' <= c && c <= 'Z'); - }; - exports.upper = function(start) { - var c; - c = text[start]; - if (('A' <= c && c <= 'Z')) { - return cursor = start + 1; - } - }; - exports.upper_ = function(start) { - var c; - c = text[cursor]; - if (('A' <= c && c <= 'Z')) { - return cursor++; - } - }; - exports.identifier = function(start) { - var c; - cursor = start; - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - return; - } - while (1) { - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - break; - } - } - return true; - }; - return exports.identifier = function(start) { - var c; - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - return; - } - while (1) { - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - break; - } - } - return true; - }; -})(require, exports, module); diff --git a/js/deprecated/logic.js b/js/deprecated/logic.js deleted file mode 100644 index b612ed5..0000000 --- a/js/deprecated/logic.js +++ /dev/null @@ -1,649 +0,0 @@ -var exports, module, require, _ref, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - __slice = [].slice; - -if (typeof window === 'object') { - _ref = twoside('/deprecated/logic'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var BindingError, Cons, DummyVar, Error, Trail, UArray, UObject, Var, char, dummy, identifier, makeInfo, nameToIndexMap, orp, reElements, uarray, unify, unifyList, _ref1; - exports.Error = Error = (function() { - function Error(exp, message, stack) { - this.exp = exp; - this.message = message != null ? message : ''; - this.stack = stack != null ? stack : this; - } - - Error.prototype.toString = function() { - return "" + this.constructor.name + ": " + this.exp + " >>> " + this.message; - }; - - return Error; - - })(); - exports.BindingError = BindingError = (function(_super) { - __extends(BindingError, _super); - - function BindingError() { - _ref1 = BindingError.__super__.constructor.apply(this, arguments); - return _ref1; - } - - return BindingError; - - })(Error); - exports.Trail = Trail = (function() { - function Trail(data) { - this.data = data != null ? data : {}; - } - - Trail.prototype.copy = function() { - return new Trail(_.extend({}, this.data)); - }; - - Trail.prototype.set = function(vari, value) { - var data; - data = this.data; - if (!data.hasOwnProperty(vari.name)) { - return data[vari.name] = [vari, value]; - } - }; - - Trail.prototype.undo = function() { - var nam, pair, _ref2, _results; - _ref2 = this.data; - _results = []; - for (nam in _ref2) { - pair = _ref2[nam]; - _results.push(pair[0].binding = pair[1]); - } - return _results; - }; - - Trail.prototype.deref = function(x) { - return (x != null ? typeof x.deref === "function" ? x.deref(this) : void 0 : void 0) || x; - }; - - Trail.prototype.getvalue = function(x, memo) { - var getvalue; - if (memo == null) { - memo = {}; - } - getvalue = x != null ? x.getvalue : void 0; - if (getvalue) { - return getvalue.call(x, this, memo); - } else { - return x; - } - }; - - Trail.prototype.unify = function(x, y, compare) { - x = this.deref(x); - y = this.deref(y); - if (x instanceof Var) { - this.set(x, x.binding); - x.binding = y; - return true; - } else if (y instanceof Var) { - this.set(y, y.binding); - y.binding = x; - return true; - } else { - return (x != null ? typeof x.unify === "function" ? x.unify(y, this) : void 0 : void 0) || (y != null ? typeof y.unify === "function" ? y.unify(x, this) : void 0 : void 0) || compare(x, y); - } - }; - - return Trail; - - })(); - exports.Var = Var = (function() { - function Var(name, binding) { - this.name = name != null ? name : ''; - this.binding = binding != null ? binding : this; - } - - Var.prototype.deref = function(trail) { - var chains, i, length, next, v, x, _i, _j, _ref2, _ref3; - v = this; - next = this.binding; - if (next === this || !(next instanceof Var)) { - return next; - } else { - chains = [v]; - length = 1; - while (1) { - chains.push(next); - v = next; - next = v.binding; - length++; - if (next === v) { - for (i = _i = 0, _ref2 = chains.length - 2; 0 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 0 <= _ref2 ? ++_i : --_i) { - x = chains[i]; - x.binding = next; - trail.set(x, chains[i + 1]); - } - return next; - } else if (!(next instanceof Var)) { - for (i = _j = 0, _ref3 = chains.length - 1; 0 <= _ref3 ? _j < _ref3 : _j > _ref3; i = 0 <= _ref3 ? ++_j : --_j) { - x = chains[i]; - x.binding = next; - trail.set(x, chains[i + 1]); - } - return next; - } - } - } - }; - - Var.prototype.bind = function(value, trail) { - trail.set(this, this.binding); - return this.binding = trail.deref(value); - }; - - Var.prototype.getvalue = function(trail, memo) { - var name, result; - if (memo == null) { - memo = {}; - } - name = this.name; - if (memo.hasOwnProperty(name)) { - return memo[name]; - } - result = this.deref(trail); - if (result instanceof Var) { - memo[name] = result; - return result; - } else { - result = trail.getvalue(result, memo); - memo[name] = result; - return result; - } - }; - - Var.prototype.toString = function() { - return "vari(" + this.name + ")"; - }; - - return Var; - - })(); - reElements = /\s*,\s*|\s+/; - nameToIndexMap = {}; - exports.vari = function(name) { - var index; - if (name == null) { - name = ''; - } - index = nameToIndexMap[name] || 1; - nameToIndexMap[name] = index + 1; - return new Var(name + index); - }; - exports.vars = function(names) { - var name, _i, _len, _ref2, _results; - _ref2 = split(names, reElements); - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - name = _ref2[_i]; - _results.push(vari(name)); - } - return _results; - }; - exports.DummyVar = DummyVar = (function(_super) { - __extends(DummyVar, _super); - - function DummyVar(name) { - this.name = '_$' + name; - } - - DummyVar.prototype.deref = function(trail) { - return this; - }; - - DummyVar.prototype.getvalue = function(trail, memo) { - var name, result; - if (memo == null) { - memo = {}; - } - name = this.name; - if (memo.hasOwnProperty(name)) { - return memo[name]; - } - result = this.binding; - if (result === this) { - memo[name] = result; - return result; - } else { - result = trail.getvalue(result, memo); - memo[name] = result; - return result; - } - }; - - return DummyVar; - - })(Var); - exports.dummy = dummy = function(name) { - var index; - index = nameToIndexMap[name] || 1; - nameToIndexMap[name] = index + 1; - return new exports.DummyVar(name + index); - }; - exports.dummies = function(names) { - var name, _i, _len, _ref2, _results; - _ref2 = split(names, reElements); - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - name = _ref2[_i]; - _results.push(new dummy(name)); - } - return _results; - }; - exports.UObject = UObject = (function() { - function UObject(data) { - this.data = data; - } - - UObject.prototype.getvalue = function(trail, memo) { - var changed, key, result, v, value, _ref2; - result = {}; - changed = false; - _ref2 = this.data; - for (key in _ref2) { - value = _ref2[key]; - v = trail.getvalue(value, memo); - if (v !== value) { - changed = true; - } - result[key] = v; - } - if (changed) { - return new UObject(result); - } else { - return this; - } - }; - - UObject.prototype.unify = function(y, trail, compare) { - var index, key, xdata, ydata, ykeys; - if (compare == null) { - compare = function(x, y) { - return x === y; - }; - } - xdata = this.data; - ydata = y instanceof UObject ? y.data : y; - ykeys = Object.keys(y); - for (key in xdata) { - index = ykeys.indexOf(key); - if (index === -1) { - return false; - } - if (!trail.unify(xdata[key], ydata[key], compare)) { - return false; - } - ykeys.splice(index, 1); - } - if (ykeys.length !== 0) { - return false; - } - return true; - }; - - return UObject; - - })(); - exports.uobject = function(x) { - return new UObject(x); - }; - exports.UArray = UArray = (function() { - function UArray(data) { - this.data = data; - } - - UArray.prototype.getvalue = function(trail, memo) { - var changed, result, v, x, _i, _len, _ref2; - if (memo == null) { - memo = {}; - } - result = []; - changed = false; - _ref2 = this.data; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - x = _ref2[_i]; - v = trail.getvalue(x, memo); - if (v !== x) { - changed = true; - } - result.push(v); - } - if (changed) { - return new UArray(result); - } else { - return this; - } - }; - - UArray.prototype.unify = function(y, trail, compare) { - var i, length, xdata, ydata, _i; - if (compare == null) { - compare = function(x, y) { - return x === y; - }; - } - xdata = this.data; - ydata = y.data || y; - length = this.data.length; - if (length !== y.length) { - return false; - } - for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { - if (!trail.unify(xdata[i], ydata[i], compare)) { - return false; - } - } - return true; - }; - - UArray.prototype.toString = function() { - return this.data.toString(); - }; - - return UArray; - - })(); - exports.uarray = uarray = function(x) { - return new UArray(x); - }; - exports.Cons = Cons = (function() { - function Cons(head, tail) { - this.head = head; - this.tail = tail; - } - - Cons.prototype.getvalue = function(trail, memo) { - var head, head1, tail, tail1; - if (memo == null) { - memo = {}; - } - head = this.head; - tail = this.tail; - head1 = trail.getvalue(head, memo); - tail1 = trail.getvalue(tail, memo); - if (head1 === head && tail1 === tail) { - return this; - } else { - return new Cons(head1, tail1); - } - }; - - Cons.prototype.unify = function(y, trail, compare) { - if (compare == null) { - compare = function(x, y) { - return x === y; - }; - } - if (!(y instanceof Cons)) { - return false; - } else if (!trail.unify(this.head, y.head, compare)) { - return false; - } else { - return trail.unify(this.tail, y.tail, compare); - } - }; - - Cons.prototype.flatString = function() { - var result, tail; - result = "" + this.head; - tail = this.tail; - if (tail === null) { - null; - } else if (tail instanceof Cons) { - result += ','; - result += tail.flatString(); - } else { - result += tail.toString(); - } - return result; - }; - - Cons.prototype.toString = function() { - return "cons(" + this.head + ", " + this.tail + ")"; - }; - - return Cons; - - })(); - exports.cons = function(x, y) { - return new Cons(x, y); - }; - exports.conslist = function() { - var args, i, result, _i, _ref2; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - result = null; - for (i = _i = _ref2 = args.length - 1; _i >= 0; i = _i += -1) { - result = new Cons([args[i], result]); - } - return result; - }; - exports.unifiable = function(x) { - if (_.isArray(x)) { - return new UArray(x); - } else if (_.isObject(x)) { - return new UObject(x); - } else { - return x; - } - }; - exports.bind = function(info) { - return function(vari, term) { - vari.bind(info.trail.deref(term)); - return true; - }; - }; - exports.unify = unify = function(info) { - return function(x, y, compare) { - if (compare == null) { - compare = function(x, y) { - return x === y; - }; - } - return info.trail.unify(x, y, compare); - }; - }; - exports.unifyList = unifyList = function(info) { - return function(xs, ys, compare) { - var i, xlen, _i, _unify; - if (compare == null) { - compare = function(x, y) { - return x === y; - }; - } - xlen = xs.length; - if (ys.length !== xlen) { - return false; - } else { - _unify = info.trail.unify; - for (i = _i = 0; 0 <= xlen ? _i < xlen : _i > xlen; i = 0 <= xlen ? ++_i : --_i) { - if (!_unify(xs[i], ys[i], compare)) { - return false; - } - } - } - return true; - }; - }; - identifier = require("./../peasy").identifier; - exports.orp = orp = function(info) { - return function() { - var item, items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if ((typeof item) === 'string') { - _results.push(literal(info)(item)); - } else { - _results.push(item); - } - } - return _results; - })(); - return function() { - var i, length, result, start, _i; - start = info.cursor; - length = items.length; - for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { - info.cursor = start; - info.trail = new Trail; - if (result = items[i]()) { - return result; - } - if (i !== length - 1) { - info.trail.undo(); - } - } - return result; - }; - }; - }; - exports.char = char = function(info) { - return function(x) { - return function() { - var c; - x = info.trail.deref(x); - if (x instanceof Var) { - c = info.data[info.cursor++]; - x.bind(c); - return c; - } else { - if (info.data[info.cursor] === x) { - info.cursor++; - return x; - } - } - }; - }; - }; - exports.digit = function(info) { - return function(x) { - return function() { - var c; - c = info.data[info.cursor]; - if (('0' <= c && c <= '9')) { - x = info.trail.deref(x); - if (x instanceof Var) { - info.cursor++; - x.bind(c); - return c; - } else if (x === c) { - info.cursor++; - return c; - } - } - }; - }; - }; - exports.letter = function(info) { - return function(x) { - return function() { - var c; - c = info.data[info.cursor]; - if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { - x = info.trail.deref(x); - if (x instanceof Var) { - info.cursor++; - x.bind(c); - return c; - } else if (x === c) { - info.cursor++; - return c; - } - } - }; - }; - }; - exports.lower = function(info) { - return function(x) { - return function() { - var c; - c = info.data[info.cursor]; - if (('a' <= x && x <= 'z')) { - x = info.trail.deref(x); - if (x instanceof Var) { - info.cursor++; - x.bind(c); - return c; - } else if (x === c) { - info.cursor++; - return c; - } - } - }; - }; - }; - exports.upper = function(info) { - return function(x) { - return function() { - var c; - c = info.data[info.cursor]; - if (('A' <= x && x <= 'Z')) { - x = info.trail.deref(x); - if (x instanceof Var) { - info.cursor++; - x.bind(c); - return c; - } else if (x === c) { - info.cursor++; - return c; - } - } - }; - }; - }; - exports.identifier = function(info) { - var id, uni; - id = identifier(info); - uni = unify(info); - return function(x) { - return function() { - var n; - if (n = id() && uni(x, n)) { - return n; - } - }; - }; - }; - exports.combinators = function(info) { - return { - bind: exports.bind(info), - unify: unify(info), - unifyList: exports.unifyList(info), - char: exports.char(info), - digit: exports.digit(info), - letter: exports.letter(info), - lower: exports.lower(info), - upper: exports.upper(info), - identifier: exports.identifier(info) - }; - }; - return exports.makeInfo = makeInfo = function(data, options) { - if (options == null) { - options = { - cursor: 0, - tabWidth: 2 - }; - } - return { - data: data, - cursor: options.cursor || 0, - tabWidth: options.tabWidth || 2, - parsingLeftRecursives: {}, - parseCache: {}, - trail: new Trail - }; - }; -})(require, exports, module); diff --git a/js/deprecated/modularpeasy.js b/js/deprecated/modularpeasy.js deleted file mode 100644 index bafdec5..0000000 --- a/js/deprecated/modularpeasy.js +++ /dev/null @@ -1,620 +0,0 @@ -var exports, module, require, _ref, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = [].slice; - -if (typeof window === 'object') { - _ref = twoside('/deprecated/modularpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var andp, any, char, combinators, digit, digits, follow, followIdentifierLetter_, identifier, identifierLetter, isMatcher, letter, letters, literal, lower, makeInfo, matchers, may, memoSymbolIndex, memorize, notp, orp, parse, recursive, seperatedList, some, spaces, spaces1, times, timesSeperatedList, upper, wrap; - exports.makeInfo = makeInfo = function(data, options) { - if (options == null) { - options = { - cursor: 0, - tabWidth: 2 - }; - } - return { - data: data, - cursor: options.cursor || 0, - tabWidth: options.tabWidth || 2, - parsingLeftRecursives: {}, - parseCache: {} - }; - }; - exports.isMatcher = isMatcher = function(item) { - return typeof item === "function"; - }; - memoSymbolIndex = 0; - exports.recursive = recursive = function(info) { - return function(rule) { - var index, parseCache, parsingLeftRecursives, tag; - index = memoSymbolIndex; - tag = index + ':'; - memoSymbolIndex++; - parsingLeftRecursives = info.parsingLeftRecursives; - parseCache = info.parseCache[tag] = {}; - return function() { - var callPath, m, result, start; - start = info.cursor; - callPath = parsingLeftRecursives[start] != null ? parsingLeftRecursives[start] : parsingLeftRecursives[start] = []; - if (__indexOf.call(callPath, tag) < 0) { - callPath.push(tag); - m = parseCache[start] != null ? parseCache[start] : parseCache[start] = [void 0, start]; - while (1) { - info.cursor = start; - result = rule(); - if (!result) { - result = m[0]; - info.cursor = m[1]; - break; - } - if (m[1] === info.cursor) { - m[0] = result; - break; - } else { - m[0] = result; - m[1] = info.cursor; - } - } - callPath.pop(); - return result; - } else { - m = parseCache[start]; - info.cursor = m[1]; - return m[0]; - } - }; - }; - }; - exports.memorize = memorize = function(info) { - return function(rule) { - var index, parseCache, tag; - index = memoSymbolIndex; - tag = index + ':'; - memoSymbolIndex++; - parseCache = info.parseCache[tag] = {}; - return function() { - var m, result, start; - start = info.cursor; - m = parseCache[start]; - if (m) { - info.cursor = m[1]; - return m[0]; - } else { - result = rule(); - parseCache[start] = [result, info.cursor]; - return result; - } - }; - }; - }; - exports.andp = andp = function(info) { - return function() { - var item, items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!isMatcher(item)) { - _results.push(literal(info)(item)); - } else { - _results.push(item); - } - } - return _results; - })(); - return function() { - var result, _i, _len; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!(result = item())) { - return; - } - } - return result; - }; - }; - }; - exports.orp = orp = function(info) { - return function() { - var item, items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!isMatcher(item)) { - _results.push(literal(info)(item)); - } else { - _results.push(item); - } - } - return _results; - })(); - return function() { - var i, length, result, start, _i; - start = info.cursor; - length = items.length; - for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { - info.cursor = start; - if (result = items[i]()) { - return result; - } - } - return result; - }; - }; - }; - exports.notp = notp = function(info) { - return function(item) { - if (!isMatcher(item)) { - item = literal(info)(item); - } - return function() { - return !item(); - }; - }; - }; - exports.may = may = function(info) { - return function(item) { - if (!isMatcher(item)) { - item = literal(info)(item); - } - return function() { - var start, x; - start = info.cursor; - if (x = item()) { - return x; - } else { - info.cursor = start; - return true; - } - }; - }; - }; - exports.any = any = function(info) { - return function(item) { - if (!isMatcher(item)) { - item = literal(info)(item); - } - return function() { - var result, x; - result = []; - while ((x = item())) { - result.push(x); - } - return result; - }; - }; - }; - exports.some = some = function(info) { - return function(item) { - if (!isMatcher(item)) { - item = literal(info)(item); - } - return function() { - var result, x; - if (!(x = item())) { - return; - } - result = [x]; - while ((x = item())) { - result.push(x); - } - return result; - }; - }; - }; - exports.times = times = function(info) { - return function(item, n) { - if (!isMatcher(item)) { - item = literal(info)(item); - } - return function() { - var i, x; - i = 0; - while (i++ < n) { - if (x = item()) { - result.push(x); - } else { - return; - } - } - return result; - }; - }; - }; - exports.seperatedList = seperatedList = function(info) { - return function(item, separator) { - if (separator == null) { - separator = spaces(info); - } - if (!isMatcher(item)) { - item = literal(info)(item); - } - if (!isMatcher(separator)) { - separator = literal(info)(separator); - } - return function() { - var result, x; - if (!(x = item())) { - return; - } - result = [x]; - while (separator() && (x = item())) { - result.push(x); - } - return result; - }; - }; - }; - exports.timesSeperatedList = timesSeperatedList = function(info) { - return function(item, n, separator) { - if (separator == null) { - separator = spaces(info); - } - if (!isMatcher(item)) { - item = literal(info)(item); - } - if (!isMatcher(separator)) { - separator = literal(info)(separator); - } - return function() { - var i, result, x; - if (!(x = item())) { - return; - } - result = [x]; - i = 1; - while (i++ < n) { - if (separator() && (x = item())) { - result.push(x); - } else { - return; - } - } - return result; - }; - }; - }; - exports.follow = follow = function(info) { - return function(item) { - if (!isMatcher(item)) { - item = literal(info)(item); - } - return function() { - var start, x; - start = info.cursor; - if (x = item()) { - info.cursor = start; - return x; - } else { - info.cursor = start; - } - }; - }; - }; - exports.combinators = combinators = function(info) { - return { - rec: recursive(info), - memo: memorize(info), - andp: andp(info), - orp: orp(info), - notp: notp(info), - may: may(info), - any: any(info), - some: some(info), - times: times(info), - seperatedList: seperatedList(info), - timesSeperatedList: timesSeperatedList(info), - follow: follow(info) - }; - }; - exports.isdigit = function(c) { - return ('0' <= c && c <= '9'); - }; - exports.isletter = function(c) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); - }; - exports.islower = function(c) { - return ('a' <= c && c <= 'z'); - }; - exports.isupper = function(c) { - return ('A' <= c && c <= 'Z'); - }; - exports.isIdentifierLetter = function(c) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '@' || 'c' === '_'; - }; - exports.literal = literal = function(info) { - return function(string) { - return function() { - var len, start, stop; - len = string.length; - start = info.cursor; - if (info.data.slice(start, stop = start + len) === string) { - info.cursor = stop; - return true; - } - }; - }; - }; - exports.char = char = function(info) { - return function(c) { - return function() { - if (info.data[info.cursor] === c) { - info.cursor++; - return c; - } - }; - }; - }; - exports.spaces = spaces = function(info) { - return function() { - var cursor, data, len, tabWidth; - data = info.data; - len = 0; - cursor = info.cursor; - tabWidth = info.tabWidth; - while (1) { - switch (data[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - info.cursor = cursor; - return len + 1; - }; - }; - exports.spaces1 = spaces1 = function(info) { - return function() { - var cursor, data, len, tabWidth; - data = info.data; - cursor = info.cursor; - len = 0; - tabWidth = info.tabWidth; - while (1) { - switch (data[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - info.cursor = cursor; - return len; - }; - }; - exports.wrap = wrap = function(info) { - return function(item, left, right) { - if (left == null) { - left = spaces(info); - } - if (right == null) { - right = spaces(info); - } - if (!isMatcher(item)) { - item = literal(info)(item); - } - return function() { - var result; - if (left() && (result = item() && right())) { - return result; - } - }; - }; - }; - exports.identifierLetter = identifierLetter = function(info) { - return function() { - var c; - c = info.data[info.cursor]; - if (c === '@' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { - info.cursor++; - return true; - } - }; - }; - exports.followIdentifierLetter_ = followIdentifierLetter_ = function(info) { - return function() { - var c; - c = info.data[info.cursor]; - return (c === '@' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) && c; - }; - }; - exports.digit = digit = function(info) { - return function() { - var c; - c = info.data[info.cursor]; - if (('0' <= c && c <= '9')) { - info.cursor++; - return c; - } - }; - }; - exports.letter = letter = function(info) { - return function() { - var c; - c = info.data[info.cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { - info.cursor++; - return c; - } - }; - }; - exports.lower = lower = function(info) { - return function() { - var c; - c = info.data[info.cursor]; - if (('a' <= c && c <= 'z')) { - info.cursor++; - return c; - } - }; - }; - exports.upper = upper = function(info) { - return function() { - var c; - c = info.data[info.cursor]; - if (('A' <= c && c <= 'Z')) { - info.cursor++; - return c; - } - }; - }; - exports.identifier = identifier = function(info) { - return function() { - var c, cursor, data; - data = info.data; - cursor = info.cursor; - c = data[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - return; - } - while (1) { - c = data[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '@' || 'c' === '_') { - cursor++; - } else { - break; - } - } - info.cursor = cursor; - return true; - }; - }; - exports.matchers = matchers = function(info) { - return { - literal: literal(info), - char: char(info), - spaces: spaces(info), - spaces1: spaces1(info), - wrap: wrap(info), - identifierLetter: identifierLetter(info), - followIdentifierLetter: followIdentifierLetter(info), - digit: digit(info), - letter: letter(info), - lower: lower(info), - upper: upper(info), - identifier: identifier(info) - }; - }; - exports.digits = digits = function(info) { - var ch; - ch = char(info); - return { - $0: ch('0'), - $1: ch('1'), - $2: ch('2'), - $3: ch('3'), - $4: ch('4'), - $5: ch('6'), - $1: ch('7'), - $2: ch('7'), - $8: ch('8'), - $9: ch('9') - }; - }; - exports.letters = letters = function(info) { - var ch; - ch = char(info); - return { - a: ch('a'), - b: ch('b'), - c: ch('c'), - d: ch('d'), - e: ch('e'), - f: ch('f'), - g: ch('g'), - h: ch('h'), - i: ch('i'), - j: ch('j'), - k: ch('k'), - l: ch('l'), - m: ch('m'), - n: ch('n'), - o: ch('o'), - p: ch('p'), - q: ch('q'), - r: ch('r'), - s: ch('s'), - t: ch('t'), - u: ch('u'), - v: ch('v'), - w: ch('w'), - x: ch('x'), - y: ch('y'), - z: ch('z'), - A: ch('A'), - B: ch('B'), - C: ch('C'), - D: ch('D'), - E: ch('E'), - F: ch('F'), - G: ch('G'), - H: ch('H'), - I: ch('I'), - J: ch('J'), - K: ch('K'), - L: ch('L'), - M: ch('M'), - N: ch('N'), - O: ch('O'), - P: ch('P'), - Q: ch('Q'), - R: ch('R'), - S: ch('S'), - T: ch('T'), - U: ch('U'), - V: ch('V'), - W: ch('W'), - X: ch('X'), - Y: ch('Y'), - Z: ch('Z') - }; - }; - return parse = function(text) { - var grammar, makeGrammar; - makeGrammar = function(info) { - var a, b, rec, rules, x, y, _ref1, _ref2; - _ref1 = letters(info), a = _ref1.a, b = _ref1.b, x = _ref1.x, y = _ref1.y; - _ref2 = combinators(info), rec = _ref2.rec, orp = _ref2.orp; - return rules = { - Root: function() { - var m; - return (m = rules.A()) && z() && m + 'z'; - }, - A: rec(orp((function() { - var m; - return (m = rules.B()) && x() && m + 'x' || m; - }), a)), - B: rec(orp((function() { - var m; - return (m = rules.A()) && y() && m + 'y'; - }), function() { - return rules.C(); - })), - C: rec(orp((function() { - return rules.A(); - }), b)) - }; - }; - grammar = makeGrammar(makeInfo(text)); - return grammar.Root(0); - }; -})(require, exports, module); diff --git a/js/deprecated/nonmodularpeasy.js b/js/deprecated/nonmodularpeasy.js deleted file mode 100644 index 151108e..0000000 --- a/js/deprecated/nonmodularpeasy.js +++ /dev/null @@ -1,710 +0,0 @@ -var exports, module, require, _ref, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = [].slice; - -if (typeof window === 'object') { - _ref = twoside('/deprecated/nonmodularpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var cursor, followIdentifierLetter_, functionCache, grammar, hasOwnProperty, identifierLetter, identifierLetter_, isIdentifierLetter, isMatcher, literal, literal_, memo, memorize, originalRules, parse, parseCache, recursive, recursiveRules, setMemoTag, setMemorizeRules, symbolDescedentsMap, symbolToTagMap, tags, text, textLength, _parse; - text = ''; - textLength = 0; - cursor = 0; - grammar = void 0; - originalRules = {}; - recursiveRules = {}; - symbolDescedentsMap = {}; - symbolToTagMap = {}; - tags = {}; - parseCache = {}; - functionCache = {}; - hasOwnProperty = Object.hasOwnProperty; - exports.initialize = function() { - parseCache = {}; - functionCache = {}; - originalRules = {}; - recursiveRules = {}; - symbolDescedentsMap = {}; - symbolToTagMap = {}; - tags = {}; - return parseCache = {}; - }; - exports.parse = _parse = function(data, aGrammar, root) { - text = data; - textLength = text.length; - cursor = 0; - root = root || aGrammar.rootSymbol; - grammar = aGrammar; - return grammar[root](0); - }; - parse = function(text) { - var a, b, memoA, rules, x; - a = char('a'); - b = char('b'); - x = char('x'); - memoA = memo('A'); - rules = { - A: function(start) { - var m, memoResult; - return (memoResult = m = rules.B(start)) && x(p.cur()) && m + 'x' || memoResult || a(start); - }, - B: function(start) { - return rules.C(start); - }, - C: function(start) { - return memoA(start) || b(start); - }, - rootSymbol: 'A' - }; - initialize(); - addRecursiveCircles(rules, ['A', 'B', 'C']); - computeLeftRecursives(rules); - return _parse(text, rules); - }; - exports.addParentChildrens = function(grammar, parentChildren) { - var children, list, map, name, parent, _i, _len; - map = grammar.parentToChildren != null ? grammar.parentToChildren : grammar.parentToChildren = {}; - for (parent in parentChildren) { - children = parentChildren[parent]; - list = map[parent] != null ? map[parent] : map[parent] = []; - for (_i = 0, _len = children.length; _i < _len; _i++) { - name = children[_i]; - if (__indexOf.call(list, name) < 0) { - list.push(name); - } - } - } - return null; - }; - exports.addRecursiveCircles = function() { - var circle, grammar, i, j, length, list, map, name, parent, recursiveCircles, _i, _len; - grammar = arguments[0], recursiveCircles = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - map = grammar.parentToChildren != null ? grammar.parentToChildren : grammar.parentToChildren = {}; - for (_i = 0, _len = recursiveCircles.length; _i < _len; _i++) { - circle = recursiveCircles[_i]; - i = 0; - length = circle.length; - while (i < length) { - if (i === length - 1) { - j = 0; - } else { - j = i + 1; - } - name = circle[i]; - parent = circle[j]; - list = map[parent] != null ? map[parent] : map[parent] = []; - if (__indexOf.call(list, name) < 0) { - list.push(name); - } - i++; - } - } - return null; - }; - exports.computeLeftRecursives = function(grammar) { - var addDescendents, descendents, meetTable, parentToChildren, symbol; - parentToChildren = grammar.parentToChildren; - addDescendents = function(symbol, meetTable, descedents) { - var child, children, _i, _len, _results; - children = parentToChildren[symbol]; - _results = []; - for (_i = 0, _len = children.length; _i < _len; _i++) { - child = children[_i]; - if (__indexOf.call(descedents, child) < 0) { - descedents.push(child); - } - if (!meetTable[child]) { - _results.push(addDescendents(child, meetTable, descedents)); - } else { - _results.push(void 0); - } - } - return _results; - }; - symbolDescedentsMap = {}; - for (symbol in parentToChildren) { - meetTable = {}; - meetTable[symbol] = true; - descendents = symbolDescedentsMap[symbol] = []; - addDescendents(symbol, meetTable, descendents); - if (__indexOf.call(descendents, symbol) >= 0) { - originalRules[symbol] = grammar[symbol]; - grammar[symbol] = recursive(symbol); - } - } - return symbolDescedentsMap; - }; - exports.recursive = recursive = function(symbol) { - var rule; - rule = originalRules[symbol]; - return function(start) { - var child, hash, m, result, _i, _j, _len, _len1, _ref1, _ref2; - _ref1 = symbolDescedentsMap[symbol]; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - child = _ref1[_i]; - grammar[child] = originalRules[child]; - } - hash = symbol + start; - m = parseCache[hash] != null ? parseCache[hash] : parseCache[hash] = [void 0, -1]; - if (m[1] >= 0) { - cursor = m[1]; - return m[0]; - } - while (1) { - result = rule(start); - if (m[1] < 0) { - m[0] = result; - if (result) { - m[1] = cursor; - } else { - m[1] = start; - } - } else { - if (m[1] === cursor) { - m[0] = result; - return result; - } else if (cursor < m[1]) { - m[0] = result; - cursor = m[1]; - return result; - } else { - m[0] = result; - m[1] = cursor; - } - } - } - _ref2 = symbolDescedentsMap[symbol]; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - child = _ref2[_j]; - grammar[child] = recursiveRules[child]; - } - return result; - }; - }; - exports.memo = memo = function(symbol) { - return function(start) { - var hash, m; - hash = symbol + start; - m = parseCache[hash]; - if (m) { - return m[0]; - } - }; - }; - setMemorizeRules = function(grammar, symbols) { - var symbol, _i, _len, _results; - _results = []; - for (_i = 0, _len = symbols.length; _i < _len; _i++) { - symbol = symbols[_i]; - originalRules[symbol] = grammar[symbol]; - _results.push(grammar[symbol] = memorize(symbol)); - } - return _results; - }; - memorize = function(symbol) { - var rule, tag; - tag = symbolToTagMap[symbol]; - rule = originalRules[symbol]; - return function(start) { - var hash, m, result; - hash = tag + start; - m = parseCache[hash]; - if (m) { - cursor = m[1]; - return m[0]; - } else { - result = rule(start); - parseCache[hash] = [result, cursor]; - return result; - } - }; - }; - setMemoTag = function(symbol) { - var i, tag; - i = 1; - while (1) { - if (hasOwnProperty.call(tags, symbol.slice(0, i))) { - i++; - } else { - break; - } - } - tag = symbol.slice(0, i); - symbolToTagMap[symbol] = tag; - return tags[tag] = true; - }; - isMatcher = function(item) { - return typeof item === "function"; - }; - exports.andp = function(items) { - var item; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!isMatcher(item)) { - _results.push(literal(item)); - } else { - _results.push(item); - } - } - return _results; - })(); - return function(start) { - var result, _i, _len; - cursor = start; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!(result = item(cursor))) { - return; - } - } - return result; - }; - }; - exports.orp = function() { - var item, items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!isMatcher(item)) { - _results.push(literal(item)); - } else { - _results.push(item); - } - } - return _results; - })(); - return function(start) { - var result, _i, _len; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (result = item(start)) { - return result; - } - } - return result; - }; - }; - exports.notp = function(item) { - if (!isMatcher(item)) { - item = literal(item); - } - return function(start) { - return !item(start); - }; - }; - exports.any = function(item) { - if (!isMatcher(item)) { - item = literal(item); - } - return function(start) { - var result, x; - result = []; - cursor = start; - while ((x = item(cursor))) { - result.push(x); - } - return result; - }; - }; - exports.some = function(item) { - if (!isMatcher(item)) { - item = literal(item); - } - return function(start) { - var result, x; - result = []; - cursor = start; - if (!(x = item(cursor))) { - return x; - } - while (1) { - result.push(x); - x = item(cursor); - if (!x) { - break; - } - } - return result; - }; - }; - exports.may = exports.optional = function(item) { - if (!isMatcher(item)) { - item = literal(item); - } - return function(start) { - var x; - cursor = start; - if (x = item(cursor)) { - return x; - } else { - cursor = start; - return true; - } - }; - }; - exports.follow = function(item) { - if (!isMatcher(item)) { - item = literal(item); - } - return function(start) { - var x; - cursor = start; - if (x = item(cursor)) { - cursor = start; - return x; - } - }; - }; - exports.times = function(item, n) { - if (!isMatcher(item)) { - item = literal(item); - } - return function(start) { - var i, x; - cursor = start; - i = 0; - while (i++ < n) { - if (x = item(cursor)) { - result.push(x); - } else { - return; - } - } - return result; - }; - }; - exports.seperatedList = function(item, separator) { - if (separator == null) { - separator = spaces; - } - if (!isMatcher(item)) { - item = literal(item); - } - if (!isMatcher(separator)) { - separator = literal(separator); - } - return function(start) { - var result, x; - cursor = start; - result = []; - x = item(cursor); - if (!x) { - return; - } - while (1) { - result.push(x); - if (!(x = item(cursor))) { - break; - } - } - return result; - }; - }; - exports.timesSeperatedList = function(item, n, separator) { - if (separator == null) { - separator = spaces; - } - if (!isMatcher(item)) { - item = literal(item); - } - if (!isMatcher(separator)) { - separator = literal(separator); - } - return function(start) { - var i, result, x; - cursor = start; - result = []; - x = item(cursor); - if (!x) { - return; - } - i = 1; - while (i++ < n) { - result.push(x); - if (!(x = item(cursor))) { - break; - } - } - return result; - }; - }; - exports.literal = literal = function(string) { - return function(start) { - var len, stop; - len = string.length; - if (text.slice(start, stop = start + len) === string) { - cursor = stop; - return true; - } - }; - }; - exports.literal_ = literal_ = function(string) { - return function(start) { - var len, stop; - len = string.length; - if (text.slice(cursor, stop = cursor + len) === string) { - cursor = stop; - return true; - } - }; - }; - exports.char = function(c) { - return function(start) { - if (text[start] === c) { - cursor = start + 1; - return c; - } - }; - }; - exports.char_ = function(c) { - return function() { - if (text[cursor] === c) { - cursor++; - return c; - } - }; - }; - exports.spaces = function(start) { - var len; - len = 0; - cursor = start; - text = text; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - return len; - }; - exports.spaces_ = function() { - var len; - len = 0; - text = text; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - return len; - }; - exports.spaces1 = function(start) { - var len; - len = 0; - cursor = start; - text = text; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - if (len) { - return cursor = cursor; - return len; - } - }; - exports.spaces1_ = function() { - var len; - len = 0; - cursor = start; - while (1) { - switch (text[cursor++]) { - case ' ': - len++; - break; - case '\t': - len += tabWidth; - break; - default: - break; - } - } - if (len) { - return cursor = cursor; - return len; - } - }; - exports.wrap = function(item, left, right) { - if (left == null) { - left = spaces; - } - if (right == null) { - right = spaces; - } - if (!isMatcher(item)) { - item = literal(item); - } - return function(start) { - var result; - if (left(start) && (result = item(cursor) && right(cursor))) { - return result; - } - }; - }; - identifierLetter = function(start) { - var c; - start = cursor; - c = text[cursor]; - if (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { - cursor++; - return true; - } - }; - identifierLetter_ = function() { - var c; - c = text[cursor]; - if (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { - cursor++; - return true; - } - }; - followIdentifierLetter_ = function() { - var c; - c = text[cursor]; - return c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9'); - }; - isIdentifierLetter = function(c) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '$' || 'c' === '_'; - }; - exports.isdigit = function(c) { - return ('0' <= c && c <= '9'); - }; - exports.digit = function(start) { - var c; - c = text[start]; - if (('0' <= c && c <= '9')) { - return cursor = start + 1; - } - }; - exports.digit_ = function() { - var c; - c = text[cursor]; - if (('0' <= c && c <= '9')) { - return cursor++; - } - }; - exports.isletter = exports.isalpha = function(c) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); - }; - exports.letter = exports.alpha = function(start) { - var c; - c = text[start]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { - return cursor = start + 1; - } - }; - exports.letter_ = exports.alpha_ = function() { - var c; - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { - return cursor++; - } - }; - exports.islower = function(c) { - return ('a' <= c && c <= 'z'); - }; - exports.lower = function(start) { - var c; - c = text[start]; - if (('a' <= c && c <= 'z')) { - return cursor = start + 1; - } - }; - exports.lower_ = function() { - var c; - c = text[cursor]; - if (('a' <= c && c <= 'z')) { - return cursor++; - } - }; - exports.isupper = function(c) { - return ('A' <= c && c <= 'Z'); - }; - exports.upper = function(start) { - var c; - c = text[start]; - if (('A' <= c && c <= 'Z')) { - return cursor = start + 1; - } - }; - exports.upper_ = function(start) { - var c; - c = text[cursor]; - if (('A' <= c && c <= 'Z')) { - return cursor++; - } - }; - exports.identifier = function(start) { - var c; - cursor = start; - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - return; - } - while (1) { - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - break; - } - } - return true; - }; - exports.identifier_ = function(start) { - var c; - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - return; - } - while (1) { - c = text[cursor]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || 'c' === '$' || 'c' === '_') { - cursor++; - } else { - break; - } - } - return true; - }; - exports.gettext = function() { - return text; - }; - exports.getcursor = exports.cur = function() { - return cursor; - }; - return exports.setcursor = exports.setcur = function(pos) { - return cursor = pos; - }; -})(require, exports, module); diff --git a/js/index.js b/js/index.js new file mode 100644 index 0000000..486c3b9 --- /dev/null +++ b/js/index.js @@ -0,0 +1,66 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/index.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var exports; + +exports = module.exports = { + Parser: require('./parser'), + LogicParser: require('./logicparser'), + LineParser: require('./lineparser'), + debugging: false, + testing: false, + debug: function(message) { + if (exports.debugging) { + return console.log(message); + } + }, + warn: function(message) { + if (exports.debugging || exports.testing) { + return console.log(message); + } + }, + + /* some utilities for parsing */ + Charset: function(string) { + var x, _i, _len; + for (_i = 0, _len = string.length; _i < _len; _i++) { + x = string[_i]; + this[x] = true; + } + return this; + }, + charset: function(string) { + return new exports.Charset(string); + }, + inCharset: function(ch, chars) { + exports.warn('peasy.inCharset(char, set) is deprecated, use set.contain(char) instead.'); + return chars.hasOwnProperty(ch); + }, + in_: exports.inCharset, + isdigit: function(c) { + return ('0' <= c && c <= '9'); + }, + isletter: function(c) { + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); + }, + islower: function(c) { + return ('a' <= c && c <= 'z'); + }, + isupper: function(c) { + return ('A' <= c && c <= 'Z'); + }, + isIdentifierLetter: function(c) { + return c === '$' || c === '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9'); + }, + digits: '0123456789', + lowers: 'abcdefghijklmnopqrstuvwxyz', + uppers: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + letters: exports.lowers + exports.uppers, + letterDigits: exports.letterDigits +}; + +exports.Charset.prototype.contain = function(ch) { + return this.hasOwnProperty(ch); +}; +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/lineparser.js b/js/lineparser.js new file mode 100644 index 0000000..9aa8cc4 --- /dev/null +++ b/js/lineparser.js @@ -0,0 +1,45 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/lineparser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { + +/* an extended parser with lineno and row support */ +var BaseParser, Parser, exports, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +BaseParser = require("./parser"); + +exports = module.exports = Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var self; + Parser.__super__.constructor.apply(this, arguments); + self = this; + this.parse = function(data, root, cur, lineno, row) { + if (root == null) { + root = self.root; + } + if (cur == null) { + cur = 0; + } + if (lineno == null) { + lineno = 0; + } + if (row == null) { + row = 0; + } + self.data = data; + self.cur = cur; + self.trail = new Trail; + self.ruleStack = {}; + self.cache = {}; + return root(); + }; + } + + return Parser; + +})(BaseParser); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/logicparser.js b/js/logicparser.js new file mode 100644 index 0000000..2290fa4 --- /dev/null +++ b/js/logicparser.js @@ -0,0 +1,636 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/logicparser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { + +/* an extended parser with logic features */ +var BaseParser, BindingError, Cons, DummyVar, Error, Parser, Trail, UArray, UObject, Var, dummy, exports, nameToIndexMap, reElements, uarray, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + +BaseParser = require("./parser"); + +exports = module.exports = Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var self; + Parser.__super__.constructor.apply(this, arguments); + self = this; + this.parse = function(data, root, cur) { + if (root == null) { + root = self.root; + } + if (cur == null) { + cur = 0; + } + self.data = data; + self.cur = cur; + self.trail = new Trail; + self.ruleStack = {}; + self.cache = {}; + return root(); + }; + this.bind = function(vari, term) { + vari.bind(self.trail.deref(term)); + return true; + }; + this.unify = function(x, y, equal) { + if (equal == null) { + equal = (function(x, y) { + return x === y; + }); + } + return self.trail.unify(x, y, equal); + }; + this.unifyList = function(xs, ys, equal) { + var i, xlen, _i, _unify; + if (equal == null) { + equal = (function(x, y) { + return x === y; + }); + } + xlen = xs.length; + if (ys.length !== xlen) { + return false; + } else { + _unify = self.trail.unify; + for (i = _i = 0; 0 <= xlen ? _i < xlen : _i > xlen; i = 0 <= xlen ? ++_i : --_i) { + if (!_unify(xs[i], ys[i], equal)) { + return false; + } + } + } + return true; + }; + this.orp = function() { + var item, items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + items = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push((typeof item) === 'string' ? self.literal(item) : item); + } + return _results; + })(); + return function() { + var i, length, result, start, _i; + start = self.cur; + length = items.length; + for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { + self.cur = start; + self.trail = new Trail; + if (result = items[i]()) { + return result; + } + if (i !== length - 1) { + self.trail.undo(); + } + } + return result; + }; + }; + this.unifyChar = function(x) { + return function() { + var c; + x = self.trail.deref(x); + if (x instanceof Var) { + c = self.data[self.cur++]; + x.bind(c); + return c; + } else if (self.data[self.cur] === x) { + self.cur++; + return x; + } + }; + }; + this.unifyDigit = function(x) { + return function() { + var c; + c = self.data[self.cur]; + if (('0' <= c && c <= '9')) { + x = self.trail.deref(x); + if (x instanceof Var) { + self.cur++; + x.bind(c); + return c; + } else if (x === c) { + self.cur++; + return c; + } + } + }; + }; + this.unifyLetter = function(x) { + return function() { + var c; + c = self.data[self.cur]; + if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { + x = self.trail.deref(x); + if (x instanceof Va) { + x.bind(c); + self.cur++; + return c; + } else if (x === c) { + self.cur++; + return c; + } + } + }; + }; + this.unifyLower = function(x) { + return function() { + var c; + c = self.data[self.cur]; + if (('a' <= x && x <= 'z')) { + x = self.trail.deref(x); + if (x instanceof Var) { + x.bind(c); + self.cur++; + return c; + } else if (x === c) { + self.cur++; + return c; + } + } + }; + }; + this.unifyUpper = function(x) { + return function() { + var c; + c = self.data[self.cur]; + if (('A' <= x && x <= 'Z')) { + x = self.trail.deref(x); + if (x instanceof Var) { + x.bind(c); + self.cur++; + return c; + } else if (x === c) { + self.cur++; + return c; + } + } + }; + }; + this.unifyIdentifier = function(x) { + return function() { + var n; + if (n = self.identifier() && self.unify(x, n)) { + return n; + } + }; + }; + } + + return Parser; + +})(BaseParser); + +exports.Error = Error = (function() { + function Error(exp, message, stack) { + this.exp = exp; + this.message = message != null ? message : ''; + this.stack = stack != null ? stack : this; + } + + Error.prototype.toString = function() { + return "" + this.constructor.name + ": " + this.exp + " >>> " + this.message; + }; + + return Error; + +})(); + +exports.BindingError = BindingError = (function(_super) { + __extends(BindingError, _super); + + function BindingError() { + return BindingError.__super__.constructor.apply(this, arguments); + } + + return BindingError; + +})(Error); + +exports.Trail = Trail = (function() { + function Trail(data) { + this.data = data != null ? data : {}; + } + + Trail.prototype.copy = function() { + return new Trail(_.extend({}, this.data)); + }; + + Trail.prototype.set = function(vari, value) { + var data; + data = this.data; + if (!data.hasOwnProperty(vari.name)) { + return data[vari.name] = [vari, value]; + } + }; + + Trail.prototype.undo = function() { + var nam, pair, _ref, _results; + _ref = this.data; + _results = []; + for (nam in _ref) { + pair = _ref[nam]; + _results.push(pair[0].binding = pair[1]); + } + return _results; + }; + + Trail.prototype.deref = function(x) { + return (x != null ? typeof x.deref === "function" ? x.deref(this) : void 0 : void 0) || x; + }; + + Trail.prototype.getvalue = function(x, memo) { + var getvalue; + if (memo == null) { + memo = {}; + } + getvalue = x != null ? x.getvalue : void 0; + if (getvalue) { + return getvalue.call(x, this, memo); + } else { + return x; + } + }; + + Trail.prototype.unify = function(x, y, equal) { + x = this.deref(x); + y = this.deref(y); + if (x instanceof Var) { + this.set(x, x.binding); + x.binding = y; + return true; + } else if (y instanceof Var) { + this.set(y, y.binding); + y.binding = x; + return true; + } else { + return (x != null ? typeof x.unify === "function" ? x.unify(y, this) : void 0 : void 0) || (y != null ? typeof y.unify === "function" ? y.unify(x, this) : void 0 : void 0) || equal(x, y); + } + }; + + return Trail; + +})(); + +exports.Var = Var = (function() { + function Var(name, binding) { + this.name = name != null ? name : ''; + this.binding = binding != null ? binding : this; + } + + Var.prototype.deref = function(trail) { + var chains, i, length, next, v, x, _i, _j, _ref, _ref1; + v = this; + next = this.binding; + if (next === this || !(next instanceof Var)) { + return next; + } else { + chains = [v]; + length = 1; + while (1) { + chains.push(next); + v = next; + next = v.binding; + length++; + if (next === v) { + for (i = _i = 0, _ref = chains.length - 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + x = chains[i]; + x.binding = next; + trail.set(x, chains[i + 1]); + } + return next; + } else if (!(next instanceof Var)) { + for (i = _j = 0, _ref1 = chains.length - 1; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) { + x = chains[i]; + x.binding = next; + trail.set(x, chains[i + 1]); + } + return next; + } + } + } + }; + + Var.prototype.bind = function(value, trail) { + trail.set(this, this.binding); + return this.binding = trail.deref(value); + }; + + Var.prototype.getvalue = function(trail, memo) { + var name, result; + if (memo == null) { + memo = {}; + } + name = this.name; + if (memo.hasOwnProperty(name)) { + return memo[name]; + } + result = this.deref(trail); + if (result instanceof Var) { + memo[name] = result; + return result; + } else { + result = trail.getvalue(result, memo); + memo[name] = result; + return result; + } + }; + + Var.prototype.toString = function() { + return "vari(" + this.name + ")"; + }; + + return Var; + +})(); + +reElements = /\s*,\s*|\s+/; + +nameToIndexMap = {}; + +exports.vari = function(name) { + var index; + if (name == null) { + name = ''; + } + index = nameToIndexMap[name] || 1; + nameToIndexMap[name] = index + 1; + return new Var(name + index); +}; + +exports.vars = function(names) { + var name, _i, _len, _ref, _results; + _ref = split(names, reElements); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + _results.push(vari(name)); + } + return _results; +}; + +exports.DummyVar = DummyVar = (function(_super) { + __extends(DummyVar, _super); + + function DummyVar(name) { + this.name = '_$' + name; + } + + DummyVar.prototype.deref = function(trail) { + return this; + }; + + DummyVar.prototype.getvalue = function(trail, memo) { + var name, result; + if (memo == null) { + memo = {}; + } + name = this.name; + if (memo.hasOwnProperty(name)) { + return memo[name]; + } + result = this.binding; + if (result === this) { + memo[name] = result; + return result; + } else { + result = trail.getvalue(result, memo); + memo[name] = result; + return result; + } + }; + + return DummyVar; + +})(Var); + +exports.dummy = dummy = function(name) { + var index; + index = nameToIndexMap[name] || 1; + nameToIndexMap[name] = index + 1; + return new exports.DummyVar(name + index); +}; + +exports.dummies = function(names) { + var name, _i, _len, _ref, _results; + _ref = split(names, reElements); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + _results.push(new dummy(name)); + } + return _results; +}; + +exports.UObject = UObject = (function() { + function UObject(data) { + this.data = data; + } + + UObject.prototype.getvalue = function(trail, memo) { + var changed, key, result, v, value, _ref; + result = {}; + changed = false; + _ref = this.data; + for (key in _ref) { + value = _ref[key]; + v = trail.getvalue(value, memo); + if (v !== value) { + changed = true; + } + result[key] = v; + } + if (changed) { + return new UObject(result); + } else { + return this; + } + }; + + UObject.prototype.unify = function(y, trail, equal) { + var index, key, xdata, ydata, ykeys; + if (equal == null) { + equal = function(x, y) { + return x === y; + }; + } + xdata = this.data; + ydata = y instanceof UObject ? y.data : y; + ykeys = Object.keys(y); + for (key in xdata) { + index = ykeys.indexOf(key); + if (index === -1) { + return false; + } + if (!trail.unify(xdata[key], ydata[key], equal)) { + return false; + } + ykeys.splice(index, 1); + } + if (ykeys.length !== 0) { + return false; + } + return true; + }; + + return UObject; + +})(); + +exports.uobject = function(x) { + return new UObject(x); +}; + +exports.UArray = UArray = (function() { + function UArray(data) { + this.data = data; + } + + UArray.prototype.getvalue = function(trail, memo) { + var changed, result, v, x, _i, _len, _ref; + if (memo == null) { + memo = {}; + } + result = []; + changed = false; + _ref = this.data; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + x = _ref[_i]; + v = trail.getvalue(x, memo); + if (v !== x) { + changed = true; + } + result.push(v); + } + if (changed) { + return new UArray(result); + } else { + return this; + } + }; + + UArray.prototype.unify = function(y, trail, equal) { + var i, length, xdata, ydata, _i; + if (equal == null) { + equal = function(x, y) { + return x === y; + }; + } + xdata = this.data; + ydata = y.data || y; + length = this.data.length; + if (length !== y.length) { + return false; + } + for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { + if (!trail.unify(xdata[i], ydata[i], equal)) { + return false; + } + } + return true; + }; + + UArray.prototype.toString = function() { + return this.data.toString(); + }; + + return UArray; + +})(); + +exports.uarray = uarray = function(x) { + return new UArray(x); +}; + +exports.Cons = Cons = (function() { + function Cons(head, tail) { + this.head = head; + this.tail = tail; + } + + Cons.prototype.getvalue = function(trail, memo) { + var head, head1, tail, tail1; + if (memo == null) { + memo = {}; + } + head = this.head; + tail = this.tail; + head1 = trail.getvalue(head, memo); + tail1 = trail.getvalue(tail, memo); + if (head1 === head && tail1 === tail) { + return this; + } else { + return new Cons(head1, tail1); + } + }; + + Cons.prototype.unify = function(y, trail, equal) { + if (equal == null) { + equal = function(x, y) { + return x === y; + }; + } + if (!(y instanceof Cons)) { + return false; + } else if (!trail.unify(this.head, y.head, equal)) { + return false; + } else { + return trail.unify(this.tail, y.tail, equal); + } + }; + + Cons.prototype.flatString = function() { + var result, tail; + result = "" + this.head; + tail = this.tail; + if (tail === null) { + result += ''; + } else if (tail instanceof Cons) { + result += ','; + result += tail.flatString(); + } else { + result += tail.toString(); + } + return result; + }; + + Cons.prototype.toString = function() { + return "cons(" + this.head + ", " + this.tail + ")"; + }; + + return Cons; + +})(); + +exports.cons = function(x, y) { + return new Cons(x, y); +}; + +exports.conslist = function() { + var args, i, result, _i, _ref; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + result = null; + for (i = _i = _ref = args.length - 1; _i >= 0; i = _i += -1) { + result = new Cons([args[i], result]); + } + return result; +}; + +exports.unifiable = function(x) { + if (_.isArray(x)) { + return new UArray(x); + } else if (_.isObject(x)) { + return new UObject(x); + } else { + return x; + } +}; +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/logicpeasy.js b/js/logicpeasy.js deleted file mode 100644 index c0d5d58..0000000 --- a/js/logicpeasy.js +++ /dev/null @@ -1,619 +0,0 @@ -/* an extended parser with logic features*/ - -var exports, module, require, _ref, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - __slice = [].slice; - -if (typeof window === 'object') { - _ref = twoside('/logicpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var BindingError, Cons, DummyVar, Error, Parser, Trail, UArray, UObject, Var, dummy, nameToIndexMap, peasy, reElements, uarray, _ref1; - peasy = require("./peasy"); - exports.Parser = Parser = (function(_super) { - __extends(Parser, _super); - - function Parser() { - var self; - Parser.__super__.constructor.apply(this, arguments); - self = this; - this.parse = function(data, root, cur) { - if (root == null) { - root = self.root; - } - if (cur == null) { - cur = 0; - } - self.data = data; - self.cur = cur; - self.trail = new Trail; - self.ruleStack = {}; - self.cache = {}; - return root(); - }; - this.bind = function(vari, term) { - vari.bind(self.trail.deref(term)); - return true; - }; - this.unify = function(x, y, equal) { - if (equal == null) { - equal = (function(x, y) { - return x === y; - }); - } - return self.trail.unify(x, y, equal); - }; - this.unifyList = function(xs, ys, equal) { - var i, xlen, _i, _unify; - if (equal == null) { - equal = (function(x, y) { - return x === y; - }); - } - xlen = xs.length; - if (ys.length !== xlen) { - return false; - } else { - _unify = self.trail.unify; - for (i = _i = 0; 0 <= xlen ? _i < xlen : _i > xlen; i = 0 <= xlen ? ++_i : --_i) { - if (!_unify(xs[i], ys[i], equal)) { - return false; - } - } - } - return true; - }; - this.orp = function() { - var item, items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - _results.push((typeof item) === 'string' ? self.literal(item) : item); - } - return _results; - })(); - return function() { - var i, length, result, start, _i; - start = self.cur; - length = items.length; - for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { - self.cur = start; - self.trail = new Trail; - if (result = items[i]()) { - return result; - } - if (i !== length - 1) { - self.trail.undo(); - } - } - return result; - }; - }; - this.unifyChar = function(x) { - return function() { - var c; - x = self.trail.deref(x); - if (x instanceof Var) { - c = self.data[self.cur++]; - x.bind(c); - return c; - } else if (self.data[self.cur] === x) { - self.cur++; - return x; - } - }; - }; - this.unifyDigit = function(x) { - return function() { - var c; - c = self.data[self.cur]; - if (('0' <= c && c <= '9')) { - x = self.trail.deref(x); - if (x instanceof Var) { - self.cur++; - x.bind(c); - return c; - } else if (x === c) { - self.cur++; - return c; - } - } - }; - }; - this.unifyLetter = function(x) { - return function() { - var c; - c = self.data[self.cur]; - if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { - x = self.trail.deref(x); - if (x instanceof Va) { - x.bind(c); - self.cur++; - return c; - } else if (x === c) { - self.cur++; - return c; - } - } - }; - }; - this.unifyLower = function(x) { - return function() { - var c; - c = self.data[self.cur]; - if (('a' <= x && x <= 'z')) { - x = self.trail.deref(x); - if (x instanceof Var) { - x.bind(c); - self.cur++; - return c; - } else if (x === c) { - self.cur++; - return c; - } - } - }; - }; - this.unifyUpper = function(x) { - return function() { - var c; - c = self.data[self.cur]; - if (('A' <= x && x <= 'Z')) { - x = self.trail.deref(x); - if (x instanceof Var) { - x.bind(c); - self.cur++; - return c; - } else if (x === c) { - self.cur++; - return c; - } - } - }; - }; - this.unifyIdentifier = function(x) { - return function() { - var n; - if (n = self.identifier() && self.unify(x, n)) { - return n; - } - }; - }; - } - - return Parser; - - })(peasy.Parser); - exports.Error = Error = (function() { - function Error(exp, message, stack) { - this.exp = exp; - this.message = message != null ? message : ''; - this.stack = stack != null ? stack : this; - } - - Error.prototype.toString = function() { - return "" + this.constructor.name + ": " + this.exp + " >>> " + this.message; - }; - - return Error; - - })(); - exports.BindingError = BindingError = (function(_super) { - __extends(BindingError, _super); - - function BindingError() { - _ref1 = BindingError.__super__.constructor.apply(this, arguments); - return _ref1; - } - - return BindingError; - - })(Error); - exports.Trail = Trail = (function() { - function Trail(data) { - this.data = data != null ? data : {}; - } - - Trail.prototype.copy = function() { - return new Trail(_.extend({}, this.data)); - }; - - Trail.prototype.set = function(vari, value) { - var data; - data = this.data; - if (!data.hasOwnProperty(vari.name)) { - return data[vari.name] = [vari, value]; - } - }; - - Trail.prototype.undo = function() { - var nam, pair, _ref2, _results; - _ref2 = this.data; - _results = []; - for (nam in _ref2) { - pair = _ref2[nam]; - _results.push(pair[0].binding = pair[1]); - } - return _results; - }; - - Trail.prototype.deref = function(x) { - return (x != null ? typeof x.deref === "function" ? x.deref(this) : void 0 : void 0) || x; - }; - - Trail.prototype.getvalue = function(x, memo) { - var getvalue; - if (memo == null) { - memo = {}; - } - getvalue = x != null ? x.getvalue : void 0; - if (getvalue) { - return getvalue.call(x, this, memo); - } else { - return x; - } - }; - - Trail.prototype.unify = function(x, y, equal) { - x = this.deref(x); - y = this.deref(y); - if (x instanceof Var) { - this.set(x, x.binding); - x.binding = y; - return true; - } else if (y instanceof Var) { - this.set(y, y.binding); - y.binding = x; - return true; - } else { - return (x != null ? typeof x.unify === "function" ? x.unify(y, this) : void 0 : void 0) || (y != null ? typeof y.unify === "function" ? y.unify(x, this) : void 0 : void 0) || equal(x, y); - } - }; - - return Trail; - - })(); - exports.Var = Var = (function() { - function Var(name, binding) { - this.name = name != null ? name : ''; - this.binding = binding != null ? binding : this; - } - - Var.prototype.deref = function(trail) { - var chains, i, length, next, v, x, _i, _j, _ref2, _ref3; - v = this; - next = this.binding; - if (next === this || !(next instanceof Var)) { - return next; - } else { - chains = [v]; - length = 1; - while (1) { - chains.push(next); - v = next; - next = v.binding; - length++; - if (next === v) { - for (i = _i = 0, _ref2 = chains.length - 2; 0 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 0 <= _ref2 ? ++_i : --_i) { - x = chains[i]; - x.binding = next; - trail.set(x, chains[i + 1]); - } - return next; - } else if (!(next instanceof Var)) { - for (i = _j = 0, _ref3 = chains.length - 1; 0 <= _ref3 ? _j < _ref3 : _j > _ref3; i = 0 <= _ref3 ? ++_j : --_j) { - x = chains[i]; - x.binding = next; - trail.set(x, chains[i + 1]); - } - return next; - } - } - } - }; - - Var.prototype.bind = function(value, trail) { - trail.set(this, this.binding); - return this.binding = trail.deref(value); - }; - - Var.prototype.getvalue = function(trail, memo) { - var name, result; - if (memo == null) { - memo = {}; - } - name = this.name; - if (memo.hasOwnProperty(name)) { - return memo[name]; - } - result = this.deref(trail); - if (result instanceof Var) { - memo[name] = result; - return result; - } else { - result = trail.getvalue(result, memo); - memo[name] = result; - return result; - } - }; - - Var.prototype.toString = function() { - return "vari(" + this.name + ")"; - }; - - return Var; - - })(); - reElements = /\s*,\s*|\s+/; - nameToIndexMap = {}; - exports.vari = function(name) { - var index; - if (name == null) { - name = ''; - } - index = nameToIndexMap[name] || 1; - nameToIndexMap[name] = index + 1; - return new Var(name + index); - }; - exports.vars = function(names) { - var name, _i, _len, _ref2, _results; - _ref2 = split(names, reElements); - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - name = _ref2[_i]; - _results.push(vari(name)); - } - return _results; - }; - exports.DummyVar = DummyVar = (function(_super) { - __extends(DummyVar, _super); - - function DummyVar(name) { - this.name = '_$' + name; - } - - DummyVar.prototype.deref = function(trail) { - return this; - }; - - DummyVar.prototype.getvalue = function(trail, memo) { - var name, result; - if (memo == null) { - memo = {}; - } - name = this.name; - if (memo.hasOwnProperty(name)) { - return memo[name]; - } - result = this.binding; - if (result === this) { - memo[name] = result; - return result; - } else { - result = trail.getvalue(result, memo); - memo[name] = result; - return result; - } - }; - - return DummyVar; - - })(Var); - exports.dummy = dummy = function(name) { - var index; - index = nameToIndexMap[name] || 1; - nameToIndexMap[name] = index + 1; - return new exports.DummyVar(name + index); - }; - exports.dummies = function(names) { - var name, _i, _len, _ref2, _results; - _ref2 = split(names, reElements); - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - name = _ref2[_i]; - _results.push(new dummy(name)); - } - return _results; - }; - exports.UObject = UObject = (function() { - function UObject(data) { - this.data = data; - } - - UObject.prototype.getvalue = function(trail, memo) { - var changed, key, result, v, value, _ref2; - result = {}; - changed = false; - _ref2 = this.data; - for (key in _ref2) { - value = _ref2[key]; - v = trail.getvalue(value, memo); - if (v !== value) { - changed = true; - } - result[key] = v; - } - if (changed) { - return new UObject(result); - } else { - return this; - } - }; - - UObject.prototype.unify = function(y, trail, equal) { - var index, key, xdata, ydata, ykeys; - if (equal == null) { - equal = function(x, y) { - return x === y; - }; - } - xdata = this.data; - ydata = y instanceof UObject ? y.data : y; - ykeys = Object.keys(y); - for (key in xdata) { - index = ykeys.indexOf(key); - if (index === -1) { - return false; - } - if (!trail.unify(xdata[key], ydata[key], equal)) { - return false; - } - ykeys.splice(index, 1); - } - if (ykeys.length !== 0) { - return false; - } - return true; - }; - - return UObject; - - })(); - exports.uobject = function(x) { - return new UObject(x); - }; - exports.UArray = UArray = (function() { - function UArray(data) { - this.data = data; - } - - UArray.prototype.getvalue = function(trail, memo) { - var changed, result, v, x, _i, _len, _ref2; - if (memo == null) { - memo = {}; - } - result = []; - changed = false; - _ref2 = this.data; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - x = _ref2[_i]; - v = trail.getvalue(x, memo); - if (v !== x) { - changed = true; - } - result.push(v); - } - if (changed) { - return new UArray(result); - } else { - return this; - } - }; - - UArray.prototype.unify = function(y, trail, equal) { - var i, length, xdata, ydata, _i; - if (equal == null) { - equal = function(x, y) { - return x === y; - }; - } - xdata = this.data; - ydata = y.data || y; - length = this.data.length; - if (length !== y.length) { - return false; - } - for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { - if (!trail.unify(xdata[i], ydata[i], equal)) { - return false; - } - } - return true; - }; - - UArray.prototype.toString = function() { - return this.data.toString(); - }; - - return UArray; - - })(); - exports.uarray = uarray = function(x) { - return new UArray(x); - }; - exports.Cons = Cons = (function() { - function Cons(head, tail) { - this.head = head; - this.tail = tail; - } - - Cons.prototype.getvalue = function(trail, memo) { - var head, head1, tail, tail1; - if (memo == null) { - memo = {}; - } - head = this.head; - tail = this.tail; - head1 = trail.getvalue(head, memo); - tail1 = trail.getvalue(tail, memo); - if (head1 === head && tail1 === tail) { - return this; - } else { - return new Cons(head1, tail1); - } - }; - - Cons.prototype.unify = function(y, trail, equal) { - if (equal == null) { - equal = function(x, y) { - return x === y; - }; - } - if (!(y instanceof Cons)) { - return false; - } else if (!trail.unify(this.head, y.head, equal)) { - return false; - } else { - return trail.unify(this.tail, y.tail, equal); - } - }; - - Cons.prototype.flatString = function() { - var result, tail; - result = "" + this.head; - tail = this.tail; - if (tail === null) { - null; - } else if (tail instanceof Cons) { - result += ','; - result += tail.flatString(); - } else { - result += tail.toString(); - } - return result; - }; - - Cons.prototype.toString = function() { - return "cons(" + this.head + ", " + this.tail + ")"; - }; - - return Cons; - - })(); - exports.cons = function(x, y) { - return new Cons(x, y); - }; - exports.conslist = function() { - var args, i, result, _i, _ref2; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - result = null; - for (i = _i = _ref2 = args.length - 1; _i >= 0; i = _i += -1) { - result = new Cons([args[i], result]); - } - return result; - }; - return exports.unifiable = function(x) { - if (_.isArray(x)) { - return new UArray(x); - } else if (_.isObject(x)) { - return new UObject(x); - } else { - return x; - } - }; -})(require, exports, module); diff --git a/js/logicpeasy.min.js b/js/logicpeasy.min.js deleted file mode 100644 index 210619e..0000000 --- a/js/logicpeasy.min.js +++ /dev/null @@ -1 +0,0 @@ -var exports,module,require,_ref,__hasProp={}.hasOwnProperty,__extends=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)__hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},__slice=[].slice;"object"==typeof window&&(_ref=twoside("/logicpeasy"),require=_ref.require,exports=_ref.exports,module=_ref.module),function(require,exports){var BindingError,Cons,DummyVar,Error,Parser,Trail,UArray,UObject,Var,dummy,nameToIndexMap,peasy,reElements,uarray,_ref1;return peasy=require("./peasy"),exports.Parser=Parser=function(_super){function Parser(){var self;Parser.__super__.constructor.apply(this,arguments),self=this,this.parse=function(data,root,cur){return null==root&&(root=self.root),null==cur&&(cur=0),self.data=data,self.cur=cur,self.trail=new Trail,self.ruleStack={},self.cache={},root()},this.bind=function(vari,term){return vari.bind(self.trail.deref(term)),!0},this.unify=function(x,y,equal){return null==equal&&(equal=function(x,y){return x===y}),self.trail.unify(x,y,equal)},this.unifyList=function(xs,ys,equal){var i,xlen,_i,_unify;if(null==equal&&(equal=function(x,y){return x===y}),xlen=xs.length,ys.length!==xlen)return!1;for(_unify=self.trail.unify,i=_i=0;xlen>=0?xlen>_i:_i>xlen;i=xlen>=0?++_i:--_i)if(!_unify(xs[i],ys[i],equal))return!1;return!0},this.orp=function(){var item,items;return items=1<=arguments.length?__slice.call(arguments,0):[],items=function(){var _i,_len,_results;for(_results=[],_i=0,_len=items.length;_len>_i;_i++)item=items[_i],_results.push("string"==typeof item?self.literal(item):item);return _results}(),function(){var i,length,result,start,_i;for(start=self.cur,length=items.length,i=_i=0;length>=0?length>_i:_i>length;i=length>=0?++_i:--_i){if(self.cur=start,self.trail=new Trail,result=items[i]())return result;i!==length-1&&self.trail.undo()}return result}},this.unifyChar=function(x){return function(){var c;return x=self.trail.deref(x),x instanceof Var?(c=self.data[self.cur++],x.bind(c),c):self.data[self.cur]===x?(self.cur++,x):void 0}},this.unifyDigit=function(x){return function(){var c;if(c=self.data[self.cur],c>="0"&&"9">=c){if(x=self.trail.deref(x),x instanceof Var)return self.cur++,x.bind(c),c;if(x===c)return self.cur++,c}}},this.unifyLetter=function(x){return function(){var c;if(c=self.data[self.cur],x>="a"&&"z">=x||x>="A"&&"Z">=x){if(x=self.trail.deref(x),x instanceof Va)return x.bind(c),self.cur++,c;if(x===c)return self.cur++,c}}},this.unifyLower=function(x){return function(){var c;if(c=self.data[self.cur],x>="a"&&"z">=x){if(x=self.trail.deref(x),x instanceof Var)return x.bind(c),self.cur++,c;if(x===c)return self.cur++,c}}},this.unifyUpper=function(x){return function(){var c;if(c=self.data[self.cur],x>="A"&&"Z">=x){if(x=self.trail.deref(x),x instanceof Var)return x.bind(c),self.cur++,c;if(x===c)return self.cur++,c}}},this.unifyIdentifier=function(x){return function(){var n;return(n=self.identifier()&&self.unify(x,n))?n:void 0}}}return __extends(Parser,_super),Parser}(peasy.Parser),exports.Error=Error=function(){function Error(exp,message,stack){this.exp=exp,this.message=null!=message?message:"",this.stack=null!=stack?stack:this}return Error.prototype.toString=function(){return""+this.constructor.name+": "+this.exp+" >>> "+this.message},Error}(),exports.BindingError=BindingError=function(_super){function BindingError(){return _ref1=BindingError.__super__.constructor.apply(this,arguments)}return __extends(BindingError,_super),BindingError}(Error),exports.Trail=Trail=function(){function Trail(data){this.data=null!=data?data:{}}return Trail.prototype.copy=function(){return new Trail(_.extend({},this.data))},Trail.prototype.set=function(vari,value){var data;return data=this.data,data.hasOwnProperty(vari.name)?void 0:data[vari.name]=[vari,value]},Trail.prototype.undo=function(){var nam,pair,_ref2,_results;_ref2=this.data,_results=[];for(nam in _ref2)pair=_ref2[nam],_results.push(pair[0].binding=pair[1]);return _results},Trail.prototype.deref=function(x){return(null!=x?"function"==typeof x.deref?x.deref(this):void 0:void 0)||x},Trail.prototype.getvalue=function(x,memo){var getvalue;return null==memo&&(memo={}),getvalue=null!=x?x.getvalue:void 0,getvalue?getvalue.call(x,this,memo):x},Trail.prototype.unify=function(x,y,equal){return x=this.deref(x),y=this.deref(y),x instanceof Var?(this.set(x,x.binding),x.binding=y,!0):y instanceof Var?(this.set(y,y.binding),y.binding=x,!0):(null!=x?"function"==typeof x.unify?x.unify(y,this):void 0:void 0)||(null!=y?"function"==typeof y.unify?y.unify(x,this):void 0:void 0)||equal(x,y)},Trail}(),exports.Var=Var=function(){function Var(name,binding){this.name=null!=name?name:"",this.binding=null!=binding?binding:this}return Var.prototype.deref=function(trail){var chains,i,length,next,v,x,_i,_j,_ref2,_ref3;if(v=this,next=this.binding,!(next!==this&&next instanceof Var))return next;for(chains=[v],length=1;;){if(chains.push(next),v=next,next=v.binding,length++,next===v){for(i=_i=0,_ref2=chains.length-2;_ref2>=0?_ref2>_i:_i>_ref2;i=_ref2>=0?++_i:--_i)x=chains[i],x.binding=next,trail.set(x,chains[i+1]);return next}if(!(next instanceof Var)){for(i=_j=0,_ref3=chains.length-1;_ref3>=0?_ref3>_j:_j>_ref3;i=_ref3>=0?++_j:--_j)x=chains[i],x.binding=next,trail.set(x,chains[i+1]);return next}}},Var.prototype.bind=function(value,trail){return trail.set(this,this.binding),this.binding=trail.deref(value)},Var.prototype.getvalue=function(trail,memo){var name,result;return null==memo&&(memo={}),name=this.name,memo.hasOwnProperty(name)?memo[name]:(result=this.deref(trail),result instanceof Var?(memo[name]=result,result):(result=trail.getvalue(result,memo),memo[name]=result,result))},Var.prototype.toString=function(){return"vari("+this.name+")"},Var}(),reElements=/\s*,\s*|\s+/,nameToIndexMap={},exports.vari=function(name){var index;return null==name&&(name=""),index=nameToIndexMap[name]||1,nameToIndexMap[name]=index+1,new Var(name+index)},exports.vars=function(names){var name,_i,_len,_ref2,_results;for(_ref2=split(names,reElements),_results=[],_i=0,_len=_ref2.length;_len>_i;_i++)name=_ref2[_i],_results.push(vari(name));return _results},exports.DummyVar=DummyVar=function(_super){function DummyVar(name){this.name="_$"+name}return __extends(DummyVar,_super),DummyVar.prototype.deref=function(){return this},DummyVar.prototype.getvalue=function(trail,memo){var name,result;return null==memo&&(memo={}),name=this.name,memo.hasOwnProperty(name)?memo[name]:(result=this.binding,result===this?(memo[name]=result,result):(result=trail.getvalue(result,memo),memo[name]=result,result))},DummyVar}(Var),exports.dummy=dummy=function(name){var index;return index=nameToIndexMap[name]||1,nameToIndexMap[name]=index+1,new exports.DummyVar(name+index)},exports.dummies=function(names){var name,_i,_len,_ref2,_results;for(_ref2=split(names,reElements),_results=[],_i=0,_len=_ref2.length;_len>_i;_i++)name=_ref2[_i],_results.push(new dummy(name));return _results},exports.UObject=UObject=function(){function UObject(data){this.data=data}return UObject.prototype.getvalue=function(trail,memo){var changed,key,result,v,value,_ref2;result={},changed=!1,_ref2=this.data;for(key in _ref2)value=_ref2[key],v=trail.getvalue(value,memo),v!==value&&(changed=!0),result[key]=v;return changed?new UObject(result):this},UObject.prototype.unify=function(y,trail,equal){var index,key,xdata,ydata,ykeys;null==equal&&(equal=function(x,y){return x===y}),xdata=this.data,ydata=y instanceof UObject?y.data:y,ykeys=Object.keys(y);for(key in xdata){if(index=ykeys.indexOf(key),-1===index)return!1;if(!trail.unify(xdata[key],ydata[key],equal))return!1;ykeys.splice(index,1)}return 0!==ykeys.length?!1:!0},UObject}(),exports.uobject=function(x){return new UObject(x)},exports.UArray=UArray=function(){function UArray(data){this.data=data}return UArray.prototype.getvalue=function(trail,memo){var changed,result,v,x,_i,_len,_ref2;for(null==memo&&(memo={}),result=[],changed=!1,_ref2=this.data,_i=0,_len=_ref2.length;_len>_i;_i++)x=_ref2[_i],v=trail.getvalue(x,memo),v!==x&&(changed=!0),result.push(v);return changed?new UArray(result):this},UArray.prototype.unify=function(y,trail,equal){var i,length,xdata,ydata,_i;if(null==equal&&(equal=function(x,y){return x===y}),xdata=this.data,ydata=y.data||y,length=this.data.length,length!==y.length)return!1;for(i=_i=0;length>=0?length>_i:_i>length;i=length>=0?++_i:--_i)if(!trail.unify(xdata[i],ydata[i],equal))return!1;return!0},UArray.prototype.toString=function(){return this.data.toString()},UArray}(),exports.uarray=uarray=function(x){return new UArray(x)},exports.Cons=Cons=function(){function Cons(head,tail){this.head=head,this.tail=tail}return Cons.prototype.getvalue=function(trail,memo){var head,head1,tail,tail1;return null==memo&&(memo={}),head=this.head,tail=this.tail,head1=trail.getvalue(head,memo),tail1=trail.getvalue(tail,memo),head1===head&&tail1===tail?this:new Cons(head1,tail1)},Cons.prototype.unify=function(y,trail,equal){return null==equal&&(equal=function(x,y){return x===y}),y instanceof Cons?trail.unify(this.head,y.head,equal)?trail.unify(this.tail,y.tail,equal):!1:!1},Cons.prototype.flatString=function(){var result,tail;return result=""+this.head,tail=this.tail,null===tail||(tail instanceof Cons?(result+=",",result+=tail.flatString()):result+=tail.toString()),result},Cons.prototype.toString=function(){return"cons("+this.head+", "+this.tail+")"},Cons}(),exports.cons=function(x,y){return new Cons(x,y)},exports.conslist=function(){var args,i,result,_i,_ref2;for(args=1<=arguments.length?__slice.call(arguments,0):[],result=null,i=_i=_ref2=args.length-1;_i>=0;i=_i+=-1)result=new Cons([args[i],result]);return result},exports.unifiable=function(x){return _.isArray(x)?new UArray(x):_.isObject(x)?new UObject(x):x}}(require,exports,module); \ No newline at end of file diff --git a/js/parser.js b/js/parser.js new file mode 100644 index 0000000..196c493 --- /dev/null +++ b/js/parser.js @@ -0,0 +1,474 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/parser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var Parser, exports, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + __slice = [].slice; + +exports = module.exports = Parser = (function() { + function Parser() { + var base, self; + self = this; + base = this.base = {}; + this.ruleIndex = 0; + base.parse = this.parse = function(data, root, cur) { + if (root == null) { + root = self.root; + } + if (cur == null) { + cur = 0; + } + self.data = data; + self.cur = cur; + self.ruleStack = {}; + self.cache = {}; + return root(); + }; + base.rec = this.rec = function(rule) { + var tag; + tag = self.ruleIndex++; + return function() { + var cache, callStack, m, result, ruleStack, start, _base; + ruleStack = self.ruleStack; + cache = (_base = self.cache)[tag] != null ? _base[tag] : _base[tag] = {}; + start = self.cur; + callStack = ruleStack[start] != null ? ruleStack[start] : ruleStack[start] = []; + if (__indexOf.call(callStack, tag) < 0) { + callStack.push(tag); + m = cache[start] != null ? cache[start] : cache[start] = [void 0, start]; + while (1) { + self.cur = start; + result = rule(); + if (!result) { + result = m[0]; + self.cur = m[1]; + break; + } + if (m[1] === self.cur) { + m[0] = result; + break; + } + m[0] = result; + m[1] = self.cur; + } + callStack.pop(); + return result; + } else { + m = cache[start]; + self.cur = m[1]; + return m[0]; + } + }; + }; + base.memo = this.memo = function(rule) { + var tag; + tag = self.ruleIndex++; + return (function(_this) { + return function() { + var cache, m, result, start, _base; + cache = (_base = self.cache)[tag] != null ? _base[tag] : _base[tag] = {}; + start = self.cur; + m = cache[start]; + if (m) { + self.cur = m[1]; + return m[0]; + } else { + result = rule(); + self.cache[tag][start] = [result, self.cur]; + return result; + } + }; + })(this); + }; + base.orp = this.orp = function() { + var item, items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + items = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if ((typeof item) === 'string') { + _results.push(self.literal(item)); + } else { + _results.push(item); + } + } + return _results; + })(); + return (function(_this) { + return function() { + var length, result, start, _i, _len; + start = self.cur; + length = items.length; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + self.cur = start; + if (result = item()) { + return result; + } + } + }; + })(this); + }; + base.andp = this.andp = function() { + var item, items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + items = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if ((typeof item) === 'string') { + _results.push(self.literal(item)); + } else { + _results.push(item); + } + } + return _results; + })(); + return function() { + var result, _i, _len; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (!(result = item())) { + return; + } + } + return result; + }; + }; + base.notp = this.notp = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + return !item(); + }; + }; + base.may = this.may = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return (function(_this) { + return function() { + var start, x; + start = self.cur; + if (x = item()) { + return x; + } else { + self.cur = start; + return true; + } + }; + })(this); + }; + base.any = this.any = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return (function(_this) { + return function() { + var result, x; + result = []; + while ((x = item())) { + result.push(x); + } + return result; + }; + })(this); + }; + base.some = this.some = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + var result, x; + if (!(x = item())) { + return; + } + result = [x]; + while ((x = item())) { + result.push(x); + } + return result; + }; + }; + base.times = this.times = function(item, n) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + var i, x; + i = 0; + while (i++ < n) { + if (x = item()) { + result.push(x); + } else { + return; + } + } + return result; + }; + }; + base.list = this.list = function(item, separator) { + if (separator == null) { + separator = self.spaces; + } + if ((typeof item) === 'string') { + item = self.literal(item); + } + if ((typeof separator) === 'string') { + separator = self.literal(separator); + } + return function() { + var result, x; + if (!(x = item())) { + return; + } + result = [x]; + while (separator() && (x = item())) { + result.push(x); + } + return result; + }; + }; + base.listn = this.listn = function(item, n, separator) { + if (separator == null) { + separator = self.spaces; + } + if ((typeof item) === 'string') { + item = self.literal(item); + } + if ((typeof separator) === 'string') { + separator = self.literal(separator); + } + return function() { + var i, result, x; + if (!(x = item())) { + return; + } + result = [x]; + i = 1; + while (i++ < n) { + if (separator() && (x = item())) { + result.push(x); + } else { + return; + } + } + return result; + }; + }; + base.follow = this.follow = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return (function(_this) { + return function() { + var start, x; + start = self.cur; + x = item(); + self.cur = start; + return x; + }; + })(this); + }; + base.literal = this.literal = function(string) { + return function() { + var len, start, stop; + len = string.length; + start = self.cur; + if (self.data.slice(start, stop = start + len) === string) { + self.cur = stop; + return true; + } + }; + }; + base['char'] = this['char'] = function(c) { + return function() { + if (self.data[self.cur] === c) { + self.cur++; + return c; + } + }; + }; + base.wrap = this.wrap = function(item, left, right) { + if (left == null) { + left = self.spaces; + } + if (right == null) { + right = self.spaces; + } + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + var result; + if (left() && (result = item() && right())) { + return result; + } + }; + }; + base.spaces = this.spaces = function() { + var c, cur, data, len; + data = self.data; + len = 0; + cur = self.cur; + while (1) { + if ((c = data[cur++]) && (c === ' ' || c === '\t')) { + len++; + } else { + break; + } + } + self.cur += len; + return len + 1; + }; + base.spaces1 = this.spaces1 = function() { + var c, cur, data, len; + data = self.data; + cur = self.cur; + len = 0; + while (1) { + if ((c = data[cur++]) && (c === ' ' || c === '\t')) { + lent++; + } else { + break; + } + } + self.cur += len; + return len; + }; + base.eoi = this.eoi = function() { + return self.cur === self.data.length; + }; + base.identifierLetter = this.identifierLetter = function() { + var c; + c = self.data[self.cur]; + if (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { + self.cur++; + return true; + } + }; + base.followIdentifierLetter = this.followIdentifierLetter = function() { + var c; + c = self.data[self.cur]; + return (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) && c; + }; + base.digit = this.digit = function() { + var c; + c = self.data[self.cur]; + if (('0' <= c && c <= '9')) { + self.cur++; + return c; + } + }; + base.letter = this.letter = function() { + var c; + c = self.data[self.cur]; + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { + self.cur++; + return c; + } + }; + base.lower = this.lower = function() { + var c; + c = self.data[self.cur]; + if (('a' <= c && c <= 'z')) { + self.cur++; + return c; + } + }; + base.upper = this.upper = function() { + var c; + c = self.data[self.cur]; + if (('A' <= c && c <= 'Z')) { + self.cur++; + return c; + } + }; + base.identifier = this.identifier = function() { + var c, cur, data, start; + data = self.data; + start = cur = self.cur; + c = data[cur]; + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c === '$' || c === '_') { + cur++; + } else { + return; + } + while (1) { + c = data[cur]; + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c === '$' || c === '_') { + cur++; + } else { + break; + } + } + self.cur = cur; + return data.slice(start, cur); + }; + base.number = this.number = function() { + var c, cur, data; + data = self.data; + cur = self.cur; + c = data[cur]; + if (('0' <= c && c <= '9')) { + cur++; + } else { + return; + } + while (1) { + c = data[cur]; + if (('0' <= c && c <= '9')) { + cur++; + } else { + break; + } + } + self.cur = cur; + return data.slice(start, cur); + }; + base.string = this.string = function() { + var c, cur, quote, start, text; + text = self.data; + start = cur = self.cur; + c = text[cur]; + if (c === '"' || c === "'") { + quote = c; + } else { + return; + } + cur++; + while (1) { + c = text[cur]; + if (c === '\\') { + cur += 2; + } else if (c === quote) { + self.cur = cur + 1; + return text.slice(start, +cur + 1 || 9e9); + } else if (!c) { + return; + } + } + }; + base.select = this.select = function(item, actions) { + var action, defaultAction; + console.log('select'); + action = actions[item]; + if (action) { + return action(); + } + defaultAction = actions['default'] || actions['']; + if (defaultAction) { + return defaultAction(); + } + }; + } + + return Parser; + +})(); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/peasy-min.js b/js/peasy-min.js new file mode 100644 index 0000000..74592a4 --- /dev/null +++ b/js/peasy-min.js @@ -0,0 +1,31 @@ +var exports,module,require,ts;"object"===typeof window&&(ts=twoside("peasy/parser.js"),require=ts.require,exports=ts.exports,module=ts.module); +(function(n,f,p){var h=[].indexOf||function(d){for(var a=0,b=this.length;ah.call(l,e)){l.push(e);for(c=null!=c[f]?c[f]:c[f]=[void 0,f];;){a.cur=f;d=b();if(!d){d=c[0];a.cur=c[1];break}if(c[1]===a.cur){c[0]=d;break}c[0]=d;c[1]=a.cur}l.pop();return d}c=c[f];a.cur=c[1];return c[0]}};d.memo=this.memo=function(b){var e;e=a.ruleIndex++;return function(c){return function(){var c,d;c=null!=(d=a.cache)[e]?d[e]:d[e]={};d=a.cur;if(c=c[d])return a.cur=c[1],c[0];c=b();a.cache[e][d]=[c,a.cur];return c}}(this)};d.orp=this.orp=function(){var b,e;e=1<=arguments.length?m.call(arguments, +0):[];e=function(){var c,l,d;d=[];c=0;for(l=e.length;cb||"A"<=b&&"Z">=b||"0"<=b&&"9">=b)return a.cur++,!0};d.followIdentifierLetter=this.followIdentifierLetter=function(){var b;b=a.data[a.cur];return("$"===b||"_"===b||"a"<=b&&"z">b||"A"<=b&&"Z">=b||"0"<=b&&"9">=b)&&b};d.digit=this.digit=function(){var b;b=a.data[a.cur];if("0"<=b&&"9">=b)return a.cur++,b};d.letter=this.letter=function(){var b; +b=a.data[a.cur];if("a"<=b&&"z">=b||"A"<=b&&"Z">=b)return a.cur++,b};d.lower=this.lower=function(){var b;b=a.data[a.cur];if("a"<=b&&"z">=b)return a.cur++,b};d.upper=this.upper=function(){var b;b=a.data[a.cur];if("A"<=b&&"Z">=b)return a.cur++,b};d.identifier=this.identifier=function(){var b,e,c,d;c=a.data;d=e=a.cur;b=c[e];if("a"<=b&&"z">=b||"A"<=b&&"Z">=b||"$"===b||"_"===b){for(e++;;)if(b=c[e],"a"<=b&&"z">=b||"A"<=b&&"Z">=b||"0"<=b&&"9">=b||"$"===b||"_"===b)e++;else break;a.cur=e;return c.slice(d,e)}}; +d.number=this.number=function(){var b,e,c;c=a.data;e=a.cur;b=c[e];if("0"<=b&&"9">=b){for(e++;;)if(b=c[e],"0"<=b&&"9">=b)e++;else break;a.cur=e;return c.slice(start,e)}};d.string=this.string=function(){var b,e,c,d,f;f=a.data;d=e=a.cur;b=f[e];if('"'===b||"'"===b)for(c=b,e++;;)if(b=f[e],"\\"===b)e+=2;else{if(b===c)return a.cur=e+1,f.slice(d,+e+1||9E9);if(!b)break}};d.select=this.select=function(b,a){var c;console.log("select");if((c=a[b])||(c=a["default"]||a[""]))return c()}}}()})(require,exports,module); +"object"===typeof window&&(ts=twoside("peasy/lineparser.js"),require=ts.require,exports=ts.exports,module=ts.module); +(function(n,f,p){var h={}.hasOwnProperty,m=function(d,a){function b(){this.constructor=d}for(var e in a)h.call(a,e)&&(d[e]=a[e]);b.prototype=a.prototype;d.prototype=new b;d.__super__=a.prototype;return d};n=n("./parser");p.exports=function(d){function a(){var b;a.__super__.constructor.apply(this,arguments);b=this;this.parse=function(a,c,d,f,h){null==c&&(c=b.root);null==d&&(d=0);b.data=a;b.cur=d;b.trail=new Trail;b.ruleStack={};b.cache={};return c()}}m(a,d);return a}(n)})(require,exports,module); +"object"===typeof window&&(ts=twoside("peasy/logicparser.js"),require=ts.require,exports=ts.exports,module=ts.module); +(function(n,f,p){var h,m,d,a,b,e,c,l,v={}.hasOwnProperty,s=function(b,a){function u(){this.constructor=b}for(var q in a)v.call(a,q)&&(b[q]=a[q]);u.prototype=a.prototype;b.prototype=new u;b.__super__=a.prototype;return b},t=[].slice;n=n("./parser");f=p.exports=function(a){function g(){var a;g.__super__.constructor.apply(this,arguments);a=this;this.parse=function(b,g,c){null==g&&(g=a.root);null==c&&(c=0);a.data=b;a.cur=c;a.trail=new m;a.ruleStack={};a.cache={};return g()};this.bind=function(b,g){b.bind(a.trail.deref(g)); +return!0};this.unify=function(b,g,c){null==c&&(c=function(b,a){return b===a});return a.trail.unify(b,g,c)};this.unifyList=function(b,g,c){var d,e,r,f;null==c&&(c=function(b,a){return b===a});e=b.length;if(g.length!==e)return!1;f=a.trail.unify;for(d=r=0;0<=e?re;d=0<=e?++r:--r)if(!f(b[d],g[d],c))return!1;return!0};this.orp=function(){var b,g;g=1<=arguments.length?t.call(arguments,0):[];g=function(){var c,d,e;e=[];c=0;for(d=g.length;cc;b=0<=c?++e:--e){a.cur=d;a.trail=new m;if(q=g[b]())break;b!==c-1&&a.trail.undo()}return q}};this.unifyChar=function(g){return function(){var c;g=a.trail.deref(g);if(g instanceof b)return c=a.data[a.cur++],g.bind(c),c;if(a.data[a.cur]===g)return a.cur++,g}};this.unifyDigit=function(g){return function(){var c;c=a.data[a.cur];if("0"<=c&&"9">=c){g=a.trail.deref(g);if(g instanceof b)return a.cur++,g.bind(c),c;if(g===c)return a.cur++, +c}}};this.unifyLetter=function(b){return function(){var g;g=a.data[a.cur];if("a"<=b&&"z">=b||"A"<=b&&"Z">=b){b=a.trail.deref(b);if(b instanceof Va)return b.bind(g),a.cur++,g;if(b===g)return a.cur++,g}}};this.unifyLower=function(g){return function(){var c;c=a.data[a.cur];if("a"<=g&&"z">=g){g=a.trail.deref(g);if(g instanceof b)return g.bind(c),a.cur++,c;if(g===c)return a.cur++,c}}};this.unifyUpper=function(g){return function(){var c;c=a.data[a.cur];if("A"<=g&&"Z">=g){g=a.trail.deref(g);if(g instanceof +b)return g.bind(c),a.cur++,c;if(g===c)return a.cur++,c}}};this.unifyIdentifier=function(b){return function(){var g;if(g=a.identifier()&&a.unify(b,g))return g}}}s(g,a);return g}(n);f.Error=p=function(){function b(a,c,d){this.exp=a;this.message=null!=c?c:"";this.stack=null!=d?d:this}b.prototype.toString=function(){return""+this.constructor.name+": "+this.exp+" >>> "+this.message};return b}();f.BindingError=function(b){function a(){return a.__super__.constructor.apply(this,arguments)}s(a,b);return a}(p); +f.Trail=m=function(){function a(b){this.data=null!=b?b:{}}a.prototype.copy=function(){return new a(_.extend({},this.data))};a.prototype.set=function(b,a){var c;c=this.data;if(!c.hasOwnProperty(b.name))return c[b.name]=[b,a]};a.prototype.undo=function(){var b,a,c,d;c=this.data;d=[];for(b in c)a=c[b],d.push(a[0].binding=a[1]);return d};a.prototype.deref=function(b){return(null!=b?"function"===typeof b.deref?b.deref(this):void 0:void 0)||b};a.prototype.getvalue=function(b,a){var c;null==a&&(a={});return(c= +null!=b?b.getvalue:void 0)?c.call(b,this,a):b};a.prototype.unify=function(a,c,d){a=this.deref(a);c=this.deref(c);return a instanceof b?(this.set(a,a.binding),a.binding=c,!0):c instanceof b?(this.set(c,c.binding),c.binding=a,!0):(null!=a?"function"===typeof a.unify?a.unify(c,this):void 0:void 0)||(null!=c?"function"===typeof c.unify?c.unify(a,this):void 0:void 0)||d(a,c)};return a}();f.Var=b=function(){function b(a,c){this.name=null!=a?a:"";this.binding=null!=c?c:this}b.prototype.deref=function(a){var c, +d,e,f,h,k;e=this.binding;if(e!==this&&e instanceof b)for(c=[this],d=1;;){c.push(e);f=e;e=f.binding;d++;if(e===f){d=h=0;for(k=c.length-2;0<=k?hk;d=0<=k?++h:--h)f=c[d],f.binding=e,a.set(f,c[d+1]);return e}if(!(e instanceof b)){d=h=0;for(k=c.length-1;0<=k?hk;d=0<=k?++h:--h)f=c[d],f.binding=e,a.set(f,c[d+1]);return e}}else return e};b.prototype.bind=function(b,a){a.set(this,this.binding);return this.binding=a.deref(b)};b.prototype.getvalue=function(a,c){var d,e;null==c&&(c={});d=this.name;if(c.hasOwnProperty(d))return c[d]; +e=this.deref(a);e instanceof b||(e=a.getvalue(e,c));return c[d]=e};b.prototype.toString=function(){return"vari("+this.name+")"};return b}();l=/\s*,\s*|\s+/;c={};f.vari=function(a){var d;null==a&&(a="");d=c[a]||1;c[a]=d+1;return new b(a+d)};f.vars=function(b){var a,c,d,e;d=split(b,l);e=[];a=0;for(c=d.length;ad;a=0<=d?++h:--h)if(!b.unify(e[a],f[a],c))return!1;return!0};a.prototype.toString=function(){return this.data.toString()};return a}();f.uarray=function(a){return new d(a)};f.Cons=h=function(){function a(b,c){this.head=b;this.tail=c}a.prototype.getvalue=function(b,c){var d,e, +f,h;null==c&&(c={});d=this.head;f=this.tail;e=b.getvalue(d,c);h=b.getvalue(f,c);return e===d&&h===f?this:new a(e,h)};a.prototype.unify=function(b,c,d){null==d&&(d=function(a,b){return a===b});return b instanceof a?c.unify(this.head,b.head,d)?c.unify(this.tail,b.tail,d):!1:!1};a.prototype.flatString=function(){var b,c;b=""+this.head;c=this.tail;return b=null===c?b+"":c instanceof a?b+","+c.flatString():b+c.toString()};a.prototype.toString=function(){return"cons("+this.head+", "+this.tail+")"};return a}(); +f.cons=function(a,b){return new h(a,b)};f.conslist=function(){var a,b,c,d;a=1<=arguments.length?t.call(arguments,0):[];c=null;for(b=d=a.length-1;0<=d;b=d+=-1)c=new h([a[b],c]);return c};f.unifiable=function(b){return _.isArray(b)?new d(b):_.isObject(b)?new a(b):b}})(require,exports,module);"object"===typeof window&&(ts=twoside("peasy/index.js"),require=ts.require,exports=ts.exports,module=ts.module); +(function(n,f,p){f=p.exports={Parser:n("./parser"),LogicParser:n("./logicparser"),LineParser:n("./lineparser"),debugging:!1,testing:!1,debug:function(h){if(f.debugging)return console.log(h)},warn:function(h){if(f.debugging||f.testing)return console.log(h)},Charset:function(f){var m,d,a;d=0;for(a=f.length;d=f},isletter:function(f){return"a"<=f&&"z">=f||"A"<=f&&"Z">=f},islower:function(f){return"a"<=f&&"z">=f},isupper:function(f){return"A"<=f&&"Z">=f},isIdentifierLetter:function(f){return"$"===f||"_"===f||"a"<=f&&"z">=f||"A"<=f&&"Z">=f||"0"<=f&&"9">=f},digits:"0123456789",lowers:"abcdefghijklmnopqrstuvwxyz",uppers:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",letters:f.lowers+f.uppers,letterDigits:f.letterDigits};f.Charset.prototype.contain=function(f){return this.hasOwnProperty(f)}})(require, +exports,module); diff --git a/js/peasy.js b/js/peasy.js index 2bf45c9..1fa026d 100644 --- a/js/peasy.js +++ b/js/peasy.js @@ -1,75 +1,73 @@ -var exports, module, require, _ref, +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/parser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var Parser, exports, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, __slice = [].slice; -if (typeof window === 'object') { - _ref = twoside('/peasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var Charset, Parser, charset, digits, letterDigits, letters, lowers, uppers; - exports.Parser = Parser = (function() { - function Parser() { - var base, self; - self = this; - base = this.base = {}; - this.ruleIndex = 0; - base.parse = this.parse = function(data, root, cur) { - if (root == null) { - root = self.root; - } - if (cur == null) { - cur = 0; - } - self.data = data; - self.cur = cur; - self.ruleStack = {}; - self.cache = {}; - return root(); - }; - base.rec = this.rec = function(rule) { - var tag; - tag = self.ruleIndex++; - return function() { - var cache, callStack, m, result, ruleStack, start, _base; - ruleStack = self.ruleStack; - cache = (_base = self.cache)[tag] != null ? (_base = self.cache)[tag] : _base[tag] = {}; - start = self.cur; - callStack = ruleStack[start] != null ? ruleStack[start] : ruleStack[start] = []; - if (__indexOf.call(callStack, tag) < 0) { - callStack.push(tag); - m = cache[start] != null ? cache[start] : cache[start] = [void 0, start]; - while (1) { - self.cur = start; - result = rule(); - if (!result) { - result = m[0]; - self.cur = m[1]; - break; - } - if (m[1] === self.cur) { - m[0] = result; - break; - } +exports = module.exports = Parser = (function() { + function Parser() { + var base, self; + self = this; + base = this.base = {}; + this.ruleIndex = 0; + base.parse = this.parse = function(data, root, cur) { + if (root == null) { + root = self.root; + } + if (cur == null) { + cur = 0; + } + self.data = data; + self.cur = cur; + self.ruleStack = {}; + self.cache = {}; + return root(); + }; + base.rec = this.rec = function(rule) { + var tag; + tag = self.ruleIndex++; + return function() { + var cache, callStack, m, result, ruleStack, start, _base; + ruleStack = self.ruleStack; + cache = (_base = self.cache)[tag] != null ? _base[tag] : _base[tag] = {}; + start = self.cur; + callStack = ruleStack[start] != null ? ruleStack[start] : ruleStack[start] = []; + if (__indexOf.call(callStack, tag) < 0) { + callStack.push(tag); + m = cache[start] != null ? cache[start] : cache[start] = [void 0, start]; + while (1) { + self.cur = start; + result = rule(); + if (!result) { + result = m[0]; + self.cur = m[1]; + break; + } + if (m[1] === self.cur) { m[0] = result; - m[1] = self.cur; + break; } - callStack.pop(); - return result; - } else { - m = cache[start]; - self.cur = m[1]; - return m[0]; + m[0] = result; + m[1] = self.cur; } - }; + callStack.pop(); + return result; + } else { + m = cache[start]; + self.cur = m[1]; + return m[0]; + } }; - base.memo = this.memo = function(rule) { - var tag, - _this = this; - tag = self.ruleIndex++; + }; + base.memo = this.memo = function(rule) { + var tag; + tag = self.ruleIndex++; + return (function(_this) { return function() { var cache, m, result, start, _base; - cache = (_base = self.cache)[tag] != null ? (_base = self.cache)[tag] : _base[tag] = {}; + cache = (_base = self.cache)[tag] != null ? _base[tag] : _base[tag] = {}; start = self.cur; m = cache[start]; if (m) { @@ -81,24 +79,25 @@ if (typeof window === 'object') { return result; } }; - }; - base.orp = this.orp = function() { - var item, items, - _this = this; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if ((typeof item) === 'string') { - _results.push(self.literal(item)); - } else { - _results.push(item); - } + })(this); + }; + base.orp = this.orp = function() { + var item, items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + items = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if ((typeof item) === 'string') { + _results.push(self.literal(item)); + } else { + _results.push(item); } - return _results; - })(); + } + return _results; + })(); + return (function(_this) { return function() { var length, result, start, _i, _len; start = self.cur; @@ -111,47 +110,48 @@ if (typeof window === 'object') { } } }; - }; - base.andp = this.andp = function() { - var item, items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - items = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if ((typeof item) === 'string') { - _results.push(self.literal(item)); - } else { - _results.push(item); - } + })(this); + }; + base.andp = this.andp = function() { + var item, items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + items = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if ((typeof item) === 'string') { + _results.push(self.literal(item)); + } else { + _results.push(item); } - return _results; - })(); - return function() { - var result, _i, _len; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - if (!(result = item())) { - return; - } + } + return _results; + })(); + return function() { + var result, _i, _len; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (!(result = item())) { + return; } - return result; - }; - }; - base.notp = this.notp = function(item) { - if ((typeof item) === 'string') { - item = self.literal(item); } - return function() { - return !item(); - }; + return result; }; - base.may = this.may = function(item) { - var _this = this; - if ((typeof item) === 'string') { - item = self.literal(item); - } + }; + base.notp = this.notp = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + return !item(); + }; + }; + base.may = this.may = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return (function(_this) { return function() { var start, x; start = self.cur; @@ -162,12 +162,13 @@ if (typeof window === 'object') { return true; } }; - }; - base.any = this.any = function(item) { - var _this = this; - if ((typeof item) === 'string') { - item = self.literal(item); - } + })(this); + }; + base.any = this.any = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return (function(_this) { return function() { var result, x; result = []; @@ -176,94 +177,95 @@ if (typeof window === 'object') { } return result; }; - }; - base.some = this.some = function(item) { - if ((typeof item) === 'string') { - item = self.literal(item); + })(this); + }; + base.some = this.some = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + var result, x; + if (!(x = item())) { + return; } - return function() { - var result, x; - if (!(x = item())) { - return; - } - result = [x]; - while ((x = item())) { - result.push(x); - } - return result; - }; - }; - base.times = this.times = function(item, n) { - if ((typeof item) === 'string') { - item = self.literal(item); + result = [x]; + while ((x = item())) { + result.push(x); } - return function() { - var i, x; - i = 0; - while (i++ < n) { - if (x = item()) { - result.push(x); - } else { - return; - } - } - return result; - }; + return result; }; - base.list = this.list = function(item, separator) { - if (separator == null) { - separator = self.spaces; - } - if ((typeof item) === 'string') { - item = self.literal(item); - } - if ((typeof separator) === 'string') { - separator = self.literal(separator); - } - return function() { - var result, x; - if (!(x = item())) { - return; - } - result = [x]; - while (separator() && (x = item())) { + }; + base.times = this.times = function(item, n) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + var i, x; + i = 0; + while (i++ < n) { + if (x = item()) { result.push(x); + } else { + return; } - return result; - }; + } + return result; }; - base.listn = this.listn = function(item, n, separator) { - if (separator == null) { - separator = self.spaces; + }; + base.list = this.list = function(item, separator) { + if (separator == null) { + separator = self.spaces; + } + if ((typeof item) === 'string') { + item = self.literal(item); + } + if ((typeof separator) === 'string') { + separator = self.literal(separator); + } + return function() { + var result, x; + if (!(x = item())) { + return; } - if ((typeof item) === 'string') { - item = self.literal(item); + result = [x]; + while (separator() && (x = item())) { + result.push(x); } - if ((typeof separator) === 'string') { - separator = self.literal(separator); + return result; + }; + }; + base.listn = this.listn = function(item, n, separator) { + if (separator == null) { + separator = self.spaces; + } + if ((typeof item) === 'string') { + item = self.literal(item); + } + if ((typeof separator) === 'string') { + separator = self.literal(separator); + } + return function() { + var i, result, x; + if (!(x = item())) { + return; } - return function() { - var i, result, x; - if (!(x = item())) { + result = [x]; + i = 1; + while (i++ < n) { + if (separator() && (x = item())) { + result.push(x); + } else { return; } - result = [x]; - i = 1; - while (i++ < n) { - if (separator() && (x = item())) { - result.push(x); - } else { - return; - } - } - return result; - }; - }; - base.follow = this.follow = function(item) { - var _this = this; - if ((typeof item) === 'string') { - item = self.literal(item); } + return result; + }; + }; + base.follow = this.follow = function(item) { + if ((typeof item) === 'string') { + item = self.literal(item); + } + return (function(_this) { return function() { var start, x; start = self.cur; @@ -271,254 +273,949 @@ if (typeof window === 'object') { self.cur = start; return x; }; + })(this); + }; + base.literal = this.literal = function(string) { + return function() { + var len, start, stop; + len = string.length; + start = self.cur; + if (self.data.slice(start, stop = start + len) === string) { + self.cur = stop; + return true; + } }; - base.literal = this.literal = function(string) { - return function() { - var len, start, stop; - len = string.length; - start = self.cur; - if (self.data.slice(start, stop = start + len) === string) { - self.cur = stop; - return true; - } - }; + }; + base['char'] = this['char'] = function(c) { + return function() { + if (self.data[self.cur] === c) { + self.cur++; + return c; + } }; - base.char = this.char = function(c) { - return function() { - if (self.data[self.cur] === c) { - self.cur++; - return c; - } - }; + }; + base.wrap = this.wrap = function(item, left, right) { + if (left == null) { + left = self.spaces; + } + if (right == null) { + right = self.spaces; + } + if ((typeof item) === 'string') { + item = self.literal(item); + } + return function() { + var result; + if (left() && (result = item() && right())) { + return result; + } }; - base.wrap = this.wrap = function(item, left, right) { - if (left == null) { - left = self.spaces; + }; + base.spaces = this.spaces = function() { + var c, cur, data, len; + data = self.data; + len = 0; + cur = self.cur; + while (1) { + if ((c = data[cur++]) && (c === ' ' || c === '\t')) { + len++; + } else { + break; } - if (right == null) { - right = self.spaces; + } + self.cur += len; + return len + 1; + }; + base.spaces1 = this.spaces1 = function() { + var c, cur, data, len; + data = self.data; + cur = self.cur; + len = 0; + while (1) { + if ((c = data[cur++]) && (c === ' ' || c === '\t')) { + lent++; + } else { + break; } - if ((typeof item) === 'string') { - item = self.literal(item); + } + self.cur += len; + return len; + }; + base.eoi = this.eoi = function() { + return self.cur === self.data.length; + }; + base.identifierLetter = this.identifierLetter = function() { + var c; + c = self.data[self.cur]; + if (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { + self.cur++; + return true; + } + }; + base.followIdentifierLetter = this.followIdentifierLetter = function() { + var c; + c = self.data[self.cur]; + return (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) && c; + }; + base.digit = this.digit = function() { + var c; + c = self.data[self.cur]; + if (('0' <= c && c <= '9')) { + self.cur++; + return c; + } + }; + base.letter = this.letter = function() { + var c; + c = self.data[self.cur]; + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { + self.cur++; + return c; + } + }; + base.lower = this.lower = function() { + var c; + c = self.data[self.cur]; + if (('a' <= c && c <= 'z')) { + self.cur++; + return c; + } + }; + base.upper = this.upper = function() { + var c; + c = self.data[self.cur]; + if (('A' <= c && c <= 'Z')) { + self.cur++; + return c; + } + }; + base.identifier = this.identifier = function() { + var c, cur, data, start; + data = self.data; + start = cur = self.cur; + c = data[cur]; + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c === '$' || c === '_') { + cur++; + } else { + return; + } + while (1) { + c = data[cur]; + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c === '$' || c === '_') { + cur++; + } else { + break; } - return function() { - var result; - if (left() && (result = item() && right())) { - return result; - } - }; - }; - base.spaces = this.spaces = function() { - var c, cur, data, len; - data = self.data; - len = 0; - cur = self.cur; - while (1) { - if ((c = data[cur++]) && (c === ' ' || c === '\t')) { - len++; - } else { - break; + } + self.cur = cur; + return data.slice(start, cur); + }; + base.number = this.number = function() { + var c, cur, data; + data = self.data; + cur = self.cur; + c = data[cur]; + if (('0' <= c && c <= '9')) { + cur++; + } else { + return; + } + while (1) { + c = data[cur]; + if (('0' <= c && c <= '9')) { + cur++; + } else { + break; + } + } + self.cur = cur; + return data.slice(start, cur); + }; + base.string = this.string = function() { + var c, cur, quote, start, text; + text = self.data; + start = cur = self.cur; + c = text[cur]; + if (c === '"' || c === "'") { + quote = c; + } else { + return; + } + cur++; + while (1) { + c = text[cur]; + if (c === '\\') { + cur += 2; + } else if (c === quote) { + self.cur = cur + 1; + return text.slice(start, +cur + 1 || 9e9); + } else if (!c) { + return; + } + } + }; + base.select = this.select = function(item, actions) { + var action, defaultAction; + console.log('select'); + action = actions[item]; + if (action) { + return action(); + } + defaultAction = actions['default'] || actions['']; + if (defaultAction) { + return defaultAction(); + } + }; + } + + return Parser; + +})(); +})(require, exports, module); // wrap line by gulp-twoside +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/lineparser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { + +/* an extended parser with lineno and row support */ +var BaseParser, Parser, exports, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +BaseParser = require("./parser"); + +exports = module.exports = Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var self; + Parser.__super__.constructor.apply(this, arguments); + self = this; + this.parse = function(data, root, cur, lineno, row) { + if (root == null) { + root = self.root; + } + if (cur == null) { + cur = 0; + } + if (lineno == null) { + lineno = 0; + } + if (row == null) { + row = 0; + } + self.data = data; + self.cur = cur; + self.trail = new Trail; + self.ruleStack = {}; + self.cache = {}; + return root(); + }; + } + + return Parser; + +})(BaseParser); +})(require, exports, module); // wrap line by gulp-twoside +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/logicparser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { + +/* an extended parser with logic features */ +var BaseParser, BindingError, Cons, DummyVar, Error, Parser, Trail, UArray, UObject, Var, dummy, exports, nameToIndexMap, reElements, uarray, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + +BaseParser = require("./parser"); + +exports = module.exports = Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var self; + Parser.__super__.constructor.apply(this, arguments); + self = this; + this.parse = function(data, root, cur) { + if (root == null) { + root = self.root; + } + if (cur == null) { + cur = 0; + } + self.data = data; + self.cur = cur; + self.trail = new Trail; + self.ruleStack = {}; + self.cache = {}; + return root(); + }; + this.bind = function(vari, term) { + vari.bind(self.trail.deref(term)); + return true; + }; + this.unify = function(x, y, equal) { + if (equal == null) { + equal = (function(x, y) { + return x === y; + }); + } + return self.trail.unify(x, y, equal); + }; + this.unifyList = function(xs, ys, equal) { + var i, xlen, _i, _unify; + if (equal == null) { + equal = (function(x, y) { + return x === y; + }); + } + xlen = xs.length; + if (ys.length !== xlen) { + return false; + } else { + _unify = self.trail.unify; + for (i = _i = 0; 0 <= xlen ? _i < xlen : _i > xlen; i = 0 <= xlen ? ++_i : --_i) { + if (!_unify(xs[i], ys[i], equal)) { + return false; } } - self.cur += len; - return len + 1; - }; - base.spaces1 = this.spaces1 = function() { - var c, cur, data, len; - data = self.data; - cur = self.cur; - len = 0; - while (1) { - if ((c = data[cur++]) && (c === ' ' || c === '\t')) { - lent++; - } else { - break; + } + return true; + }; + this.orp = function() { + var item, items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + items = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push((typeof item) === 'string' ? self.literal(item) : item); + } + return _results; + })(); + return function() { + var i, length, result, start, _i; + start = self.cur; + length = items.length; + for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { + self.cur = start; + self.trail = new Trail; + if (result = items[i]()) { + return result; + } + if (i !== length - 1) { + self.trail.undo(); } } - self.cur += len; - return len; - }; - base.eoi = this.eoi = function() { - return self.cur === self.data.length; + return result; }; - base.identifierLetter = this.identifierLetter = function() { + }; + this.unifyChar = function(x) { + return function() { var c; - c = self.data[self.cur]; - if (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { + x = self.trail.deref(x); + if (x instanceof Var) { + c = self.data[self.cur++]; + x.bind(c); + return c; + } else if (self.data[self.cur] === x) { self.cur++; - return true; + return x; } }; - base.followIdentifierLetter = this.followIdentifierLetter = function() { - var c; - c = self.data[self.cur]; - return (c === '$' || c === '_' || ('a' <= c && c < 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) && c; - }; - base.digit = this.digit = function() { + }; + this.unifyDigit = function(x) { + return function() { var c; c = self.data[self.cur]; if (('0' <= c && c <= '9')) { - self.cur++; - return c; + x = self.trail.deref(x); + if (x instanceof Var) { + self.cur++; + x.bind(c); + return c; + } else if (x === c) { + self.cur++; + return c; + } } }; - base.letter = this.letter = function() { + }; + this.unifyLetter = function(x) { + return function() { var c; c = self.data[self.cur]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { - self.cur++; - return c; + if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) { + x = self.trail.deref(x); + if (x instanceof Va) { + x.bind(c); + self.cur++; + return c; + } else if (x === c) { + self.cur++; + return c; + } } }; - base.lower = this.lower = function() { + }; + this.unifyLower = function(x) { + return function() { var c; c = self.data[self.cur]; - if (('a' <= c && c <= 'z')) { - self.cur++; - return c; + if (('a' <= x && x <= 'z')) { + x = self.trail.deref(x); + if (x instanceof Var) { + x.bind(c); + self.cur++; + return c; + } else if (x === c) { + self.cur++; + return c; + } } }; - base.upper = this.upper = function() { + }; + this.unifyUpper = function(x) { + return function() { var c; c = self.data[self.cur]; - if (('A' <= c && c <= 'Z')) { - self.cur++; - return c; - } - }; - base.identifier = this.identifier = function() { - var c, cur, data, start; - data = self.data; - start = cur = self.cur; - c = data[cur]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c === '$' || c === '_') { - cur++; - } else { - return; - } - while (1) { - c = data[cur]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c === '$' || c === '_') { - cur++; - } else { - break; + if (('A' <= x && x <= 'Z')) { + x = self.trail.deref(x); + if (x instanceof Var) { + x.bind(c); + self.cur++; + return c; + } else if (x === c) { + self.cur++; + return c; } } - self.cur = cur; - return data.slice(start, cur); }; - base.number = this.number = function() { - var c, cur, data; - data = self.data; - cur = self.cur; - c = data[cur]; - if (('0' <= c && c <= '9')) { - cur++; - } else { - return; - } - while (1) { - c = data[cur]; - if (('0' <= c && c <= '9')) { - cur++; - } else { - break; - } + }; + this.unifyIdentifier = function(x) { + return function() { + var n; + if (n = self.identifier() && self.unify(x, n)) { + return n; } - self.cur = cur; - return data.slice(start, cur); }; - base.string = this.string = function() { - var c, cur, quote, start, text; - text = self.data; - start = cur = self.cur; - c = text[cur]; - if (c === '"' || c === "'") { - quote = c; - } else { - return; - } - cur++; - while (1) { - c = text[cur]; - if (c === '\\') { - cur += 2; - } else if (c === quote) { - self.cur = cur + 1; - return text.slice(start, +cur + 1 || 9e9); - } else if (!c) { - return; + }; + } + + return Parser; + +})(BaseParser); + +exports.Error = Error = (function() { + function Error(exp, message, stack) { + this.exp = exp; + this.message = message != null ? message : ''; + this.stack = stack != null ? stack : this; + } + + Error.prototype.toString = function() { + return "" + this.constructor.name + ": " + this.exp + " >>> " + this.message; + }; + + return Error; + +})(); + +exports.BindingError = BindingError = (function(_super) { + __extends(BindingError, _super); + + function BindingError() { + return BindingError.__super__.constructor.apply(this, arguments); + } + + return BindingError; + +})(Error); + +exports.Trail = Trail = (function() { + function Trail(data) { + this.data = data != null ? data : {}; + } + + Trail.prototype.copy = function() { + return new Trail(_.extend({}, this.data)); + }; + + Trail.prototype.set = function(vari, value) { + var data; + data = this.data; + if (!data.hasOwnProperty(vari.name)) { + return data[vari.name] = [vari, value]; + } + }; + + Trail.prototype.undo = function() { + var nam, pair, _ref, _results; + _ref = this.data; + _results = []; + for (nam in _ref) { + pair = _ref[nam]; + _results.push(pair[0].binding = pair[1]); + } + return _results; + }; + + Trail.prototype.deref = function(x) { + return (x != null ? typeof x.deref === "function" ? x.deref(this) : void 0 : void 0) || x; + }; + + Trail.prototype.getvalue = function(x, memo) { + var getvalue; + if (memo == null) { + memo = {}; + } + getvalue = x != null ? x.getvalue : void 0; + if (getvalue) { + return getvalue.call(x, this, memo); + } else { + return x; + } + }; + + Trail.prototype.unify = function(x, y, equal) { + x = this.deref(x); + y = this.deref(y); + if (x instanceof Var) { + this.set(x, x.binding); + x.binding = y; + return true; + } else if (y instanceof Var) { + this.set(y, y.binding); + y.binding = x; + return true; + } else { + return (x != null ? typeof x.unify === "function" ? x.unify(y, this) : void 0 : void 0) || (y != null ? typeof y.unify === "function" ? y.unify(x, this) : void 0 : void 0) || equal(x, y); + } + }; + + return Trail; + +})(); + +exports.Var = Var = (function() { + function Var(name, binding) { + this.name = name != null ? name : ''; + this.binding = binding != null ? binding : this; + } + + Var.prototype.deref = function(trail) { + var chains, i, length, next, v, x, _i, _j, _ref, _ref1; + v = this; + next = this.binding; + if (next === this || !(next instanceof Var)) { + return next; + } else { + chains = [v]; + length = 1; + while (1) { + chains.push(next); + v = next; + next = v.binding; + length++; + if (next === v) { + for (i = _i = 0, _ref = chains.length - 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + x = chains[i]; + x.binding = next; + trail.set(x, chains[i + 1]); } + return next; + } else if (!(next instanceof Var)) { + for (i = _j = 0, _ref1 = chains.length - 1; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) { + x = chains[i]; + x.binding = next; + trail.set(x, chains[i + 1]); + } + return next; } + } + } + }; + + Var.prototype.bind = function(value, trail) { + trail.set(this, this.binding); + return this.binding = trail.deref(value); + }; + + Var.prototype.getvalue = function(trail, memo) { + var name, result; + if (memo == null) { + memo = {}; + } + name = this.name; + if (memo.hasOwnProperty(name)) { + return memo[name]; + } + result = this.deref(trail); + if (result instanceof Var) { + memo[name] = result; + return result; + } else { + result = trail.getvalue(result, memo); + memo[name] = result; + return result; + } + }; + + Var.prototype.toString = function() { + return "vari(" + this.name + ")"; + }; + + return Var; + +})(); + +reElements = /\s*,\s*|\s+/; + +nameToIndexMap = {}; + +exports.vari = function(name) { + var index; + if (name == null) { + name = ''; + } + index = nameToIndexMap[name] || 1; + nameToIndexMap[name] = index + 1; + return new Var(name + index); +}; + +exports.vars = function(names) { + var name, _i, _len, _ref, _results; + _ref = split(names, reElements); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + _results.push(vari(name)); + } + return _results; +}; + +exports.DummyVar = DummyVar = (function(_super) { + __extends(DummyVar, _super); + + function DummyVar(name) { + this.name = '_$' + name; + } + + DummyVar.prototype.deref = function(trail) { + return this; + }; + + DummyVar.prototype.getvalue = function(trail, memo) { + var name, result; + if (memo == null) { + memo = {}; + } + name = this.name; + if (memo.hasOwnProperty(name)) { + return memo[name]; + } + result = this.binding; + if (result === this) { + memo[name] = result; + return result; + } else { + result = trail.getvalue(result, memo); + memo[name] = result; + return result; + } + }; + + return DummyVar; + +})(Var); + +exports.dummy = dummy = function(name) { + var index; + index = nameToIndexMap[name] || 1; + nameToIndexMap[name] = index + 1; + return new exports.DummyVar(name + index); +}; + +exports.dummies = function(names) { + var name, _i, _len, _ref, _results; + _ref = split(names, reElements); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + _results.push(new dummy(name)); + } + return _results; +}; + +exports.UObject = UObject = (function() { + function UObject(data) { + this.data = data; + } + + UObject.prototype.getvalue = function(trail, memo) { + var changed, key, result, v, value, _ref; + result = {}; + changed = false; + _ref = this.data; + for (key in _ref) { + value = _ref[key]; + v = trail.getvalue(value, memo); + if (v !== value) { + changed = true; + } + result[key] = v; + } + if (changed) { + return new UObject(result); + } else { + return this; + } + }; + + UObject.prototype.unify = function(y, trail, equal) { + var index, key, xdata, ydata, ykeys; + if (equal == null) { + equal = function(x, y) { + return x === y; }; - base.select = this.select = function(item, actions) { - var action, defaultAction; - console.log('select'); - action = actions[item]; - if (action) { - return action(); - } - defaultAction = actions['default'] || actions['']; - if (defaultAction) { - return defaultAction(); - } + } + xdata = this.data; + ydata = y instanceof UObject ? y.data : y; + ykeys = Object.keys(y); + for (key in xdata) { + index = ykeys.indexOf(key); + if (index === -1) { + return false; + } + if (!trail.unify(xdata[key], ydata[key], equal)) { + return false; + } + ykeys.splice(index, 1); + } + if (ykeys.length !== 0) { + return false; + } + return true; + }; + + return UObject; + +})(); + +exports.uobject = function(x) { + return new UObject(x); +}; + +exports.UArray = UArray = (function() { + function UArray(data) { + this.data = data; + } + + UArray.prototype.getvalue = function(trail, memo) { + var changed, result, v, x, _i, _len, _ref; + if (memo == null) { + memo = {}; + } + result = []; + changed = false; + _ref = this.data; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + x = _ref[_i]; + v = trail.getvalue(x, memo); + if (v !== x) { + changed = true; + } + result.push(v); + } + if (changed) { + return new UArray(result); + } else { + return this; + } + }; + + UArray.prototype.unify = function(y, trail, equal) { + var i, length, xdata, ydata, _i; + if (equal == null) { + equal = function(x, y) { + return x === y; }; } + xdata = this.data; + ydata = y.data || y; + length = this.data.length; + if (length !== y.length) { + return false; + } + for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) { + if (!trail.unify(xdata[i], ydata[i], equal)) { + return false; + } + } + return true; + }; + + UArray.prototype.toString = function() { + return this.data.toString(); + }; - return Parser; + return UArray; + +})(); + +exports.uarray = uarray = function(x) { + return new UArray(x); +}; + +exports.Cons = Cons = (function() { + function Cons(head, tail) { + this.head = head; + this.tail = tail; + } + + Cons.prototype.getvalue = function(trail, memo) { + var head, head1, tail, tail1; + if (memo == null) { + memo = {}; + } + head = this.head; + tail = this.tail; + head1 = trail.getvalue(head, memo); + tail1 = trail.getvalue(tail, memo); + if (head1 === head && tail1 === tail) { + return this; + } else { + return new Cons(head1, tail1); + } + }; + + Cons.prototype.unify = function(y, trail, equal) { + if (equal == null) { + equal = function(x, y) { + return x === y; + }; + } + if (!(y instanceof Cons)) { + return false; + } else if (!trail.unify(this.head, y.head, equal)) { + return false; + } else { + return trail.unify(this.tail, y.tail, equal); + } + }; + + Cons.prototype.flatString = function() { + var result, tail; + result = "" + this.head; + tail = this.tail; + if (tail === null) { + result += ''; + } else if (tail instanceof Cons) { + result += ','; + result += tail.flatString(); + } else { + result += tail.toString(); + } + return result; + }; - })(); - exports.debugging = false; - exports.testing = false; - exports.debug = function(message) { + Cons.prototype.toString = function() { + return "cons(" + this.head + ", " + this.tail + ")"; + }; + + return Cons; + +})(); + +exports.cons = function(x, y) { + return new Cons(x, y); +}; + +exports.conslist = function() { + var args, i, result, _i, _ref; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + result = null; + for (i = _i = _ref = args.length - 1; _i >= 0; i = _i += -1) { + result = new Cons([args[i], result]); + } + return result; +}; + +exports.unifiable = function(x) { + if (_.isArray(x)) { + return new UArray(x); + } else if (_.isObject(x)) { + return new UObject(x); + } else { + return x; + } +}; +})(require, exports, module); // wrap line by gulp-twoside +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/index.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var exports; + +exports = module.exports = { + Parser: require('./parser'), + LogicParser: require('./logicparser'), + LineParser: require('./lineparser'), + debugging: false, + testing: false, + debug: function(message) { if (exports.debugging) { return console.log(message); } - }; - exports.warn = function(message) { + }, + warn: function(message) { if (exports.debugging || exports.testing) { return console.log(message); } - }; - /* some utilities for parsing*/ + }, - Charset = function(string) { + /* some utilities for parsing */ + Charset: function(string) { var x, _i, _len; for (_i = 0, _len = string.length; _i < _len; _i++) { x = string[_i]; this[x] = true; } return this; - }; - Charset.prototype.contain = function(char) { - return this.hasOwnProperty(char); - }; - exports.charset = charset = function(string) { - return new Charset(string); - }; - exports.inCharset = exports.in_ = function(char, set) { + }, + charset: function(string) { + return new exports.Charset(string); + }, + inCharset: function(ch, chars) { exports.warn('peasy.inCharset(char, set) is deprecated, use set.contain(char) instead.'); - exports.warn(char + ':' + set.hasOwnProperty(char)); - return set.hasOwnProperty(char); - }; - exports.isdigit = function(c) { + return chars.hasOwnProperty(ch); + }, + in_: exports.inCharset, + isdigit: function(c) { return ('0' <= c && c <= '9'); - }; - exports.isletter = function(c) { + }, + isletter: function(c) { return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); - }; - exports.islower = function(c) { + }, + islower: function(c) { return ('a' <= c && c <= 'z'); - }; - exports.isupper = function(c) { + }, + isupper: function(c) { return ('A' <= c && c <= 'Z'); - }; - exports.isIdentifierLetter = function(c) { + }, + isIdentifierLetter: function(c) { return c === '$' || c === '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9'); - }; - exports.digits = digits = '0123456789'; - exports.lowers = lowers = 'abcdefghijklmnopqrstuvwxyz'; - exports.uppers = uppers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - exports.letters = letters = lowers + uppers; - return exports.letterDigits = letterDigits = letterDigits; -})(require, exports, module); + }, + digits: '0123456789', + lowers: 'abcdefghijklmnopqrstuvwxyz', + uppers: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + letters: exports.lowers + exports.uppers, + letterDigits: exports.letterDigits +}; + +exports.Charset.prototype.contain = function(ch) { + return this.hasOwnProperty(ch); +}; +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/peasy.min.js b/js/peasy.min.js deleted file mode 100644 index 427264a..0000000 --- a/js/peasy.min.js +++ /dev/null @@ -1 +0,0 @@ -var exports,module,require,_ref,__indexOf=[].indexOf||function(item){for(var i=0,l=this.length;l>i;i++)if(i in this&&this[i]===item)return i;return-1},__slice=[].slice;"object"==typeof window&&(_ref=twoside("/peasy"),require=_ref.require,exports=_ref.exports,module=_ref.module),function(require,exports){var Charset,Parser,charset,digits,letterDigits,letters,lowers,uppers;return exports.Parser=Parser=function(){function Parser(){var base,self;self=this,base=this.base={},this.ruleIndex=0,base.parse=this.parse=function(data,root,cur){return null==root&&(root=self.root),null==cur&&(cur=0),self.data=data,self.cur=cur,self.ruleStack={},self.cache={},root()},base.rec=this.rec=function(rule){var tag;return tag=self.ruleIndex++,function(){var cache,callStack,m,result,ruleStack,start,_base;if(ruleStack=self.ruleStack,cache=null!=(_base=self.cache)[tag]?(_base=self.cache)[tag]:_base[tag]={},start=self.cur,callStack=null!=ruleStack[start]?ruleStack[start]:ruleStack[start]=[],__indexOf.call(callStack,tag)<0){for(callStack.push(tag),m=null!=cache[start]?cache[start]:cache[start]=[void 0,start];;){if(self.cur=start,result=rule(),!result){result=m[0],self.cur=m[1];break}if(m[1]===self.cur){m[0]=result;break}m[0]=result,m[1]=self.cur}return callStack.pop(),result}return m=cache[start],self.cur=m[1],m[0]}},base.memo=this.memo=function(rule){var tag;return tag=self.ruleIndex++,function(){var cache,m,result,start,_base;return cache=null!=(_base=self.cache)[tag]?(_base=self.cache)[tag]:_base[tag]={},start=self.cur,m=cache[start],m?(self.cur=m[1],m[0]):(result=rule(),self.cache[tag][start]=[result,self.cur],result)}},base.orp=this.orp=function(){var item,items;return items=1<=arguments.length?__slice.call(arguments,0):[],items=function(){var _i,_len,_results;for(_results=[],_i=0,_len=items.length;_len>_i;_i++)item=items[_i],"string"==typeof item?_results.push(self.literal(item)):_results.push(item);return _results}(),function(){var length,result,start,_i,_len;for(start=self.cur,length=items.length,_i=0,_len=items.length;_len>_i;_i++)if(item=items[_i],self.cur=start,result=item())return result}},base.andp=this.andp=function(){var item,items;return items=1<=arguments.length?__slice.call(arguments,0):[],items=function(){var _i,_len,_results;for(_results=[],_i=0,_len=items.length;_len>_i;_i++)item=items[_i],"string"==typeof item?_results.push(self.literal(item)):_results.push(item);return _results}(),function(){var result,_i,_len;for(_i=0,_len=items.length;_len>_i;_i++)if(item=items[_i],!(result=item()))return;return result}},base.notp=this.notp=function(item){return"string"==typeof item&&(item=self.literal(item)),function(){return!item()}},base.may=this.may=function(item){return"string"==typeof item&&(item=self.literal(item)),function(){var start,x;return start=self.cur,(x=item())?x:(self.cur=start,!0)}},base.any=this.any=function(item){return"string"==typeof item&&(item=self.literal(item)),function(){var result,x;for(result=[];x=item();)result.push(x);return result}},base.some=this.some=function(item){return"string"==typeof item&&(item=self.literal(item)),function(){var result,x;if(x=item()){for(result=[x];x=item();)result.push(x);return result}}},base.times=this.times=function(item,n){return"string"==typeof item&&(item=self.literal(item)),function(){var i,x;for(i=0;i++="a"&&"z">c||c>="A"&&"Z">=c||c>="0"&&"9">=c?(self.cur++,!0):void 0},base.followIdentifierLetter=this.followIdentifierLetter=function(){var c;return c=self.data[self.cur],("$"===c||"_"===c||c>="a"&&"z">c||c>="A"&&"Z">=c||c>="0"&&"9">=c)&&c},base.digit=this.digit=function(){var c;return c=self.data[self.cur],c>="0"&&"9">=c?(self.cur++,c):void 0},base.letter=this.letter=function(){var c;return c=self.data[self.cur],c>="a"&&"z">=c||c>="A"&&"Z">=c?(self.cur++,c):void 0},base.lower=this.lower=function(){var c;return c=self.data[self.cur],c>="a"&&"z">=c?(self.cur++,c):void 0},base.upper=this.upper=function(){var c;return c=self.data[self.cur],c>="A"&&"Z">=c?(self.cur++,c):void 0},base.identifier=this.identifier=function(){var c,cur,data,start;if(data=self.data,start=cur=self.cur,c=data[cur],c>="a"&&"z">=c||c>="A"&&"Z">=c||"$"===c||"_"===c){for(cur++;;){if(c=data[cur],!(c>="a"&&"z">=c||c>="A"&&"Z">=c||c>="0"&&"9">=c||"$"===c||"_"===c))break;cur++}return self.cur=cur,data.slice(start,cur)}},base.number=this.number=function(){var c,cur,data;if(data=self.data,cur=self.cur,c=data[cur],c>="0"&&"9">=c){for(cur++;;){if(c=data[cur],!(c>="0"&&"9">=c))break;cur++}return self.cur=cur,data.slice(start,cur)}},base.string=this.string=function(){var c,cur,quote,start,text;if(text=self.data,start=cur=self.cur,c=text[cur],'"'===c||"'"===c)for(quote=c,cur++;;)if(c=text[cur],"\\"===c)cur+=2;else{if(c===quote)return self.cur=cur+1,text.slice(start,+cur+1||9e9);if(!c)return}},base.select=this.select=function(item,actions){var action,defaultAction;return console.log("select"),(action=actions[item])?action():(defaultAction=actions["default"]||actions[""],defaultAction?defaultAction():void 0)}}return Parser}(),exports.debugging=!1,exports.testing=!1,exports.debug=function(message){return exports.debugging?console.log(message):void 0},exports.warn=function(message){return exports.debugging||exports.testing?console.log(message):void 0},Charset=function(string){var x,_i,_len;for(_i=0,_len=string.length;_len>_i;_i++)x=string[_i],this[x]=!0;return this},Charset.prototype.contain=function(char){return this.hasOwnProperty(char)},exports.charset=charset=function(string){return new Charset(string)},exports.inCharset=exports.in_=function(char,set){return exports.warn("peasy.inCharset(char, set) is deprecated, use set.contain(char) instead."),exports.warn(char+":"+set.hasOwnProperty(char)),set.hasOwnProperty(char)},exports.isdigit=function(c){return c>="0"&&"9">=c},exports.isletter=function(c){return c>="a"&&"z">=c||c>="A"&&"Z">=c},exports.islower=function(c){return c>="a"&&"z">=c},exports.isupper=function(c){return c>="A"&&"Z">=c},exports.isIdentifierLetter=function(c){return"$"===c||"_"===c||c>="a"&&"z">=c||c>="A"&&"Z">=c||c>="0"&&"9">=c},exports.digits=digits="0123456789",exports.lowers=lowers="abcdefghijklmnopqrstuvwxyz",exports.uppers=uppers="ABCDEFGHIJKLMNOPQRSTUVWXYZ",exports.letters=letters=lowers+uppers,exports.letterDigits=letterDigits=letterDigits}(require,exports,module); \ No newline at end of file diff --git a/js/samples/arithmatic.js b/js/samples/arithmatic.js index 5dd3d1b..3106fe2 100644 --- a/js/samples/arithmatic.js +++ b/js/samples/arithmatic.js @@ -1,371 +1,376 @@ -var exports, module, require, _ref, +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/samples/arithmatic.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var Parser, charset, identifierCharSet, identifierChars, in_, letterDigits, parser, peasy, _in_, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -if (typeof window === 'object') { - _ref = twoside('/samples/arithmatic'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +peasy = require("../index"); -(function(require, exports, module) { - var Parser, charset, identifierCharSet, identifierChars, in_, letterDigits, parser, peasy, _in_; - peasy = require("../peasy"); - in_ = peasy.in_, charset = peasy.charset, letterDigits = peasy.letterDigits; - _in_ = in_; - identifierChars = '$_' + letterDigits; - identifierCharSet = charset(identifierChars); - exports.Parser = Parser = (function(_super) { - __extends(Parser, _super); +in_ = peasy.in_, charset = peasy.charset, letterDigits = peasy.letterDigits; - function Parser() { - var addassign, and1, and_, assign, assignExpr, assignExpr_, assignLeft, assignOperator, atom, attr, bitand, bitandassign, bitnot, bitor, bitorassign, bitxor, bitxorassign, bracketExpr, bracketExpr1, callProp, callPropTail, char, colon, comma, condition_, dec, delete_, div, divassign, dot, dotIdentifier, eoi, eq, eq2, error, expect, expr, ge, getExpr, gt, headAtom, headExpr, i, identifier, idiv, idivassign, inc, incDec, instanceof_, lbracket, le, literal, literalExpr, logicOrExpr, lpar, lshift, lshiftassign, lt, memo, minus, mod, modassign, mul, mulassign, myop, ne, ne2, negative, new_, not1, not_, number, operationFnList, operations, or1, or_, orp, param, paramExpr, paren, paren1, parenExpr, plus, posNeg, positive, prefixOperation, prefixSuffixExpr, property, question, rbracket, rec, rpar, rshift, rshiftassign, self, spaces, string, subassign, suffixOperation, typeof_, unaryOp, unaryTail, unary_, void_, wrap, wrapColon, wrapDot, wrapQuestion, zrshift, zrshiftassign, _i, _ref1; - Parser.__super__.constructor.apply(this, arguments); - self = this; - number = function() { - var base, c, cur, start, text; - text = self.data; - start = cur = self.cur; - base = 10; - c = text[cur]; - if (c === '+' || c === '-') { +_in_ = in_; + +identifierChars = '$_' + letterDigits; + +identifierCharSet = charset(identifierChars); + +exports.Parser = Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var addassign, and1, and_, assign, assignExpr, assignExpr_, assignLeft, assignOperator, atom, attr, bitand, bitandassign, bitnot, bitor, bitorassign, bitxor, bitxorassign, bracketExpr, bracketExpr1, callProp, callPropTail, char, colon, comma, condition_, dec, delete_, div, divassign, dot, dotIdentifier, eoi, eq, eq2, error, expect, expr, ge, getExpr, gt, headAtom, headExpr, i, identifier, idiv, idivassign, inc, incDec, instanceof_, lbracket, le, literal, literalExpr, logicOrExpr, lpar, lshift, lshiftassign, lt, memo, minus, mod, modassign, mul, mulassign, myop, ne, ne2, negative, new_, not1, not_, number, operationFnList, operations, or1, or_, orp, param, paramExpr, paren, paren1, parenExpr, plus, posNeg, positive, prefixOperation, prefixSuffixExpr, property, question, rbracket, rec, rpar, rshift, rshiftassign, self, spaces, string, subassign, suffixOperation, typeof_, unaryOp, unaryTail, unary_, void_, wrap, wrapColon, wrapDot, wrapQuestion, zrshift, zrshiftassign, _i, _ref; + Parser.__super__.constructor.apply(this, arguments); + self = this; + number = function() { + var base, c, cur, start, text; + text = self.data; + start = cur = self.cur; + base = 10; + c = text[cur]; + if (c === '+' || c === '-') { + cur++; + } + if (text[cur] === '0') { + c = text[++cur]; + if (c === 'x' || c === 'X') { + base = 16; cur++; } - if (text[cur] === '0') { - c = text[++cur]; - if (c === 'x' || c === 'X') { - base = 16; - cur++; + } + if (base === 16) { + while (c = text[cur]) { + if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) { + self.cur = cur; + return text.slice(start, cur); } + cur++; } - if (base === 16) { - while (c = text[cur]) { - if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) { - self.cur = cur; - return text.slice(start, cur); - } - cur++; - } + } + while (c = text[cur]) { + if (!(('0' <= c && c <= '9'))) { + break; } + cur++; + } + if (text[cur] === '.') { + cur++; while (c = text[cur]) { if (!(('0' <= c && c <= '9'))) { break; } cur++; } - if (text[cur] === '.') { - cur++; - while (c = text[cur]) { - if (!(('0' <= c && c <= '9'))) { - break; - } - cur++; - } - if (text[cur - 1] === '.' && (c = text[cur - 2]) && !(('0' <= c && c <= '9'))) { - return; - } - } - c = text[cur]; - if (c === 'E' || c === 'e') { - cur++; - while (c = text[cur]) { - if (!(('0' <= c && c <= '9'))) { - break; - } - cur++; - } - if ((c = text[cur - 1]) && (c === 'E' || c === 'e')) { - return; - } - } - self.cur = cur; - return text.slice(start, cur); - }; - string = function() { - var c, cur, quote, result, text; - text = self.data; - cur = self.cur; - c = text[cur]; - if (c === '"' || c === "'") { - quote = c; - } else { + if (text[cur - 1] === '.' && (c = text[cur - 2]) && !(('0' <= c && c <= '9'))) { return; } - result = ''; + } + c = text[cur]; + if (c === 'E' || c === 'e') { cur++; - while (1) { - c = text[cur]; - if (c === '\\') { - result += text[cur + 1]; - cur += 2; - } else if (c === quote) { - self.cur = cur + 1; - return quote + result + quote; - } else if (!c) { - error('expect ' + quote); - } else { - result += c; - cur++; + while (c = text[cur]) { + if (!(('0' <= c && c <= '9'))) { + break; } + cur++; } - }; - _ref1 = self = this, orp = _ref1.orp, rec = _ref1.rec, memo = _ref1.memo, wrap = _ref1.wrap, char = _ref1.char, literal = _ref1.literal, spaces = _ref1.spaces, eoi = _ref1.eoi, identifier = _ref1.identifier; - question = char('?'); - colon = char(':'); - comma = char(','); - dot = char('.'); - lpar = char('('); - rpar = char(')'); - lbracket = char('['); - rbracket = char(']'); - myop = function(op) { - var opFn; - if (op.length === 1) { - opFn = char(op); - } else { - opFn = literal(op); + if ((c = text[cur - 1]) && (c === 'E' || c === 'e')) { + return; } - if (_in_(op[0], identifierCharSet)) { - return function() { - return spaces() && (op = opFn()) && spaces() && !_in_(data[self.cur], identifierCharSet) && ' ' + op + ' '; - }; + } + self.cur = cur; + return text.slice(start, cur); + }; + string = function() { + var c, cur, quote, result, text; + text = self.data; + cur = self.cur; + c = text[cur]; + if (c === '"' || c === "'") { + quote = c; + } else { + return; + } + result = ''; + cur++; + while (1) { + c = text[cur]; + if (c === '\\') { + result += text[cur + 1]; + cur += 2; + } else if (c === quote) { + self.cur = cur + 1; + return quote + result + quote; + } else if (!c) { + error('expect ' + quote); } else { - return function() { - return spaces() && (op = opFn()) && spaces() && op; - }; + result += c; + cur++; } - }; - posNeg = function(op) { - var opFn; + } + }; + _ref = self = this, orp = _ref.orp, rec = _ref.rec, memo = _ref.memo, wrap = _ref.wrap, char = _ref.char, literal = _ref.literal, spaces = _ref.spaces, eoi = _ref.eoi, identifier = _ref.identifier; + question = char('?'); + colon = char(':'); + comma = char(','); + dot = char('.'); + lpar = char('('); + rpar = char(')'); + lbracket = char('['); + rbracket = char(']'); + myop = function(op) { + var opFn; + if (op.length === 1) { opFn = char(op); + } else { + opFn = literal(op); + } + if (_in_(op[0], identifierCharSet)) { return function() { - var c; - return spaces() && (op = opFn()) && (c = self.data[self.cur]) && c !== '.' && !(('0' <= c && c <= '9')) && spaces() && op; + return spaces() && (op = opFn()) && spaces() && !_in_(data[self.cur], identifierCharSet) && ' ' + op + ' '; }; - }; - positive = posNeg('+'); - negative = posNeg('-'); - new_ = myop('new'); - inc = myop('++'); - dec = myop('--'); - not1 = orp(myop('!'), myop('not')); - not_ = function() { - return not1() && '!'; - }; - bitnot = myop('~'); - typeof_ = myop('typeof'); - void_ = myop('void'); - delete_ = myop('delete'); - unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_); - plus = myop('+'); - minus = myop('-'); - mul = myop('*'); - div = myop('/'); - idiv = myop('//'); - mod = myop('%'); - lshift = myop('<<'); - rshift = myop('>>'); - zrshift = myop('>>>'); - lt = myop('<'); - le = myop('<='); - gt = myop('>'); - ge = myop('>='); - in_ = myop('in'); - instanceof_ = myop('instanceof'); - eq = myop('=='); - ne = myop('!='); - eq2 = myop('==='); - ne2 = myop('!=='); - bitand = myop('&'); - bitxor = myop('^'); - bitor = myop('|'); - and1 = orp(myop('&&'), myop('and')); - and_ = function() { - return and1() && '&&'; - }; - or1 = orp(myop('||'), myop('or')); - or_ = function() { - return or1() && '||'; - }; - comma = myop(','); - assign = myop('='); - addassign = myop('+='); - subassign = myop('-='); - mulassign = myop('*='); - divassign = myop('/='); - modassign = myop('%='); - idivassign = myop('//='); - rshiftassign = myop('>>='); - lshiftassign = myop('<<='); - zrshiftassign = myop('>>>='); - bitandassign = myop('&='); - bitxorassign = myop('^='); - bitorassign = myop('|='); - error = function(msg) { - throw self.data.slice(self.cur - 20, +(self.cur + 20) + 1 || 9e9) + ' ' + self.cur + ': ' + msg; - }; - expect = function(fn, msg) { - return fn() || error(msg); - }; - incDec = orp(inc, dec); - prefixOperation = function() { - var op, x; - return (op = incDec()) && (x = headExpr()) && op + x; - }; - suffixOperation = function() { - var op, x; - return (x = headExpr()) && (op = incDec()) && x + op; - }; - paren = function(item, left, right, msg) { - if (left == null) { - left = lpar; - } - if (right == null) { - right = rpar; - } - if (msg == null) { - msg = 'expect ) to match ('; - } - if ((typeof item) === 'string') { - left = self.literal(item); - } - if ((typeof left) === 'string') { - left = self.literal(left); - } - if ((typeof right) === 'string') { - right = self.literal(right); - } + } else { return function() { - var start, x; - start = self.cur; - return left() && (x = item()) && expect(right, msg + ' at: ' + start) && x; + return spaces() && (op = opFn()) && spaces() && op; }; + } + }; + posNeg = function(op) { + var opFn; + opFn = char(op); + return function() { + var c; + return spaces() && (op = opFn()) && (c = self.data[self.cur]) && c !== '.' && !(('0' <= c && c <= '9')) && spaces() && op; }; - paren1 = paren(function() { - var x; - return spaces() && (x = expr()) && spaces() && x; - }); - parenExpr = memo(function() { - var x; - return (x = paren1()) && '(' + x + ')'; - }); - literalExpr = orp(number, string, identifier); - atom = memo(orp(parenExpr, literalExpr)); - unaryTail = orp(prefixSuffixExpr, atom); - unary_ = function() { - var op, x; - return (op = unaryOp()) && (x = unaryTail()) && op + x; - }; - bracketExpr1 = wrap(paren(wrap(function() { - return commaExpr(); - }), lbracket, rbracket, 'expect ) to match (')); - bracketExpr = function() { - var x; - return (x = bracketExpr1()) && '[' + x + ']'; - }; - wrapDot = wrap(dot); - dotIdentifier = function() { - var id; - return wrapDot() && (id = expect(identifier, 'expect identifier')) && '.' + id; + }; + positive = posNeg('+'); + negative = posNeg('-'); + new_ = myop('new'); + inc = myop('++'); + dec = myop('--'); + not1 = orp(myop('!'), myop('not')); + not_ = function() { + return not1() && '!'; + }; + bitnot = myop('~'); + typeof_ = myop('typeof'); + void_ = myop('void'); + delete_ = myop('delete'); + unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_); + plus = myop('+'); + minus = myop('-'); + mul = myop('*'); + div = myop('/'); + idiv = myop('//'); + mod = myop('%'); + lshift = myop('<<'); + rshift = myop('>>'); + zrshift = myop('>>>'); + lt = myop('<'); + le = myop('<='); + gt = myop('>'); + ge = myop('>='); + in_ = myop('in'); + instanceof_ = myop('instanceof'); + eq = myop('=='); + ne = myop('!='); + eq2 = myop('==='); + ne2 = myop('!=='); + bitand = myop('&'); + bitxor = myop('^'); + bitor = myop('|'); + and1 = orp(myop('&&'), myop('and')); + and_ = function() { + return and1() && '&&'; + }; + or1 = orp(myop('||'), myop('or')); + or_ = function() { + return or1() && '||'; + }; + comma = myop(','); + assign = myop('='); + addassign = myop('+='); + subassign = myop('-='); + mulassign = myop('*='); + divassign = myop('/='); + modassign = myop('%='); + idivassign = myop('//='); + rshiftassign = myop('>>='); + lshiftassign = myop('<<='); + zrshiftassign = myop('>>>='); + bitandassign = myop('&='); + bitxorassign = myop('^='); + bitorassign = myop('|='); + error = function(msg) { + throw self.data.slice(self.cur - 20, +(self.cur + 20) + 1 || 9e9) + ' ' + self.cur + ': ' + msg; + }; + expect = function(fn, msg) { + return fn() || error(msg); + }; + incDec = orp(inc, dec); + prefixOperation = function() { + var op, x; + return (op = incDec()) && (x = headExpr()) && op + x; + }; + suffixOperation = function() { + var op, x; + return (x = headExpr()) && (op = incDec()) && x + op; + }; + paren = function(item, left, right, msg) { + if (left == null) { + left = lpar; + } + if (right == null) { + right = rpar; + } + if (msg == null) { + msg = 'expect ) to match ('; + } + if ((typeof item) === 'string') { + left = self.literal(item); + } + if ((typeof left) === 'string') { + left = self.literal(left); + } + if ((typeof right) === 'string') { + right = self.literal(right); + } + return function() { + var start, x; + start = self.cur; + return left() && (x = item()) && expect(right, msg + ' at: ' + start) && x; }; - attr = orp(bracketExpr, dotIdentifier); - param = paren(function() { - var x; - return (spaces() && (x = expr()) && spaces() && expect(rpar, 'expect )')) || ' '; - }); - paramExpr = memo(function() { + }; + paren1 = paren(function() { + var x; + return spaces() && (x = expr()) && spaces() && x; + }); + parenExpr = memo(function() { + var x; + return (x = paren1()) && '(' + x + ')'; + }); + literalExpr = orp(number, string, identifier); + atom = memo(orp(parenExpr, literalExpr)); + unaryTail = orp(prefixSuffixExpr, atom); + unary_ = function() { + var op, x; + return (op = unaryOp()) && (x = unaryTail()) && op + x; + }; + bracketExpr1 = wrap(paren(wrap(function() { + return commaExpr(); + }), lbracket, rbracket, 'expect ) to match (')); + bracketExpr = function() { + var x; + return (x = bracketExpr1()) && '[' + x + ']'; + }; + wrapDot = wrap(dot); + dotIdentifier = function() { + var id; + return wrapDot() && (id = expect(identifier, 'expect identifier')) && '.' + id; + }; + attr = orp(bracketExpr, dotIdentifier); + param = paren(function() { + var x; + return (spaces() && (x = expr()) && spaces() && expect(rpar, 'expect )')) || ' '; + }); + paramExpr = memo(function() { + var x; + return (x = param()) && '(' + x + ')'; + }); + callPropTail = orp(paramExpr, attr); + callProp = rec(function() { + var e, h; + return (h = headExpr()) && (((e = callPropTail()) && h + e) || h); + }); + property = rec(function() { + var e, h; + return (h = headExpr()) && (((e = attr()) && h + e) || h); + }); + headAtom = memo(orp(parenExpr, identifier)); + headExpr = memo(orp(callProp, headAtom)); + wrapQuestion = wrap(question); + wrapColon = wrap(colon); + condition_ = function() { + var x, y, z; + return (x = logicOrExpr()) && wrapQuestion() && (y = assignExpr()) && expect(wrapColon, 'expect :') && (z = assignExpr()) && x + '? ' + y + ': ' + z; + }; + assignLeft = property; + assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign, rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign); + assignExpr_ = function() { + var e, op, v; + return (v = assignLeft()) && (op = assignOperator()) && (e = assignExpr()) && v + op + e; + }; + 'Precedence Operator type Associativity Individual operators\n1 new right-to-left new\n2 function call left-to-right ()\nproperty access left-to-right .\nleft-to-right []\n3 ++ n/a --\n4 right-to-left ! ~ + - typeof void delete\n5 * / % //\n6 + -\n7 << >> >>>\n8 < <= > >= in instanceof\n9 == != === !==\n10 bitwise-and left-to-right &\n11 bitwise-xor left-to-right ^\n12 bitwise-or left-to-right |\n13 logical-and left-to-right &&\n14 logical-or left-to-right ||\n15 condition right-to-left ?:\n16 yield right-to-left yield\n17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |=\n18 comma left-to-right ,'; + operations = { + 0: atom, + 1: function() { var x; - return (x = param()) && '(' + x + ')'; - }); - callPropTail = orp(paramExpr, attr); - callProp = rec(function() { - var e, h; - return (h = headExpr()) && (((e = callPropTail()) && h + e) || h); - }); - property = rec(function() { - var e, h; - return (h = headExpr()) && (((e = attr()) && h + e) || h); - }); - headAtom = memo(orp(parenExpr, identifier)); - headExpr = memo(orp(callProp, headAtom)); - wrapQuestion = wrap(question); - wrapColon = wrap(colon); - condition_ = function() { - var x, y, z; - return (x = logicOrExpr()) && wrapQuestion() && (y = assignExpr()) && expect(wrapColon, 'expect :') && (z = assignExpr()) && x + '? ' + y + ': ' + z; - }; - assignLeft = property; - assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign, rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign); - assignExpr_ = function() { - var e, op, v; - return (v = assignLeft()) && (op = assignOperator()) && (e = assignExpr()) && v + op + e; - }; - 'Precedence Operator type Associativity Individual operators\n1 new right-to-left new\n2 function call left-to-right ()\nproperty access left-to-right .\nleft-to-right []\n3 ++ n/a --\n4 right-to-left ! ~ + - typeof void delete\n5 * / % //\n6 + -\n7 << >> >>>\n8 < <= > >= in instanceof\n9 == != === !==\n10 bitwise-and left-to-right &\n11 bitwise-xor left-to-right ^\n12 bitwise-or left-to-right |\n13 logical-and left-to-right &&\n14 logical-or left-to-right ||\n15 condition right-to-left ?:\n16 yield right-to-left yield\n17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |=\n18 comma left-to-right ,'; - operations = { - 0: atom, - 1: function() { - var x; - return new_() && (x = expr()) && 'new ' + x; - }, - 2: callProp, - 3: orp(prefixOperation, suffixOperation), - 4: unary_, - 5: [mul, div, idiv], - 6: [plus, minus], - 7: [lshift, rshift, zrshift], - 8: [lt, le, gt, ge, in_, instanceof_], - 9: [eq, ne, eq2, ne2], - 10: [bitand], - 11: [bitxor], - 12: [bitor], - 13: [and_], - 14: [or_], - 15: condition_, - 16: assignExpr_, - 17: [comma] - }; - operationFnList = [atom]; - getExpr = function(n) { - var binary, lower, operation, operator; - operation = operations[n]; - lower = operationFnList[n - 1]; - if (typeof operation === 'function') { - return orp(operation, lower); - } else { - operator = operation.length === 1 ? operation[0] : orp.apply(null, operation); - return binary = rec(function() { - n; - var op, start, x, y; - start = self.cur; - if ((x = binary())) { - if ((op = operator()) && (y = lower())) { - return x + op + y; - } else { - return x; - } + return new_() && (x = expr()) && 'new ' + x; + }, + 2: callProp, + 3: orp(prefixOperation, suffixOperation), + 4: unary_, + 5: [mul, div, idiv], + 6: [plus, minus], + 7: [lshift, rshift, zrshift], + 8: [lt, le, gt, ge, in_, instanceof_], + 9: [eq, ne, eq2, ne2], + 10: [bitand], + 11: [bitxor], + 12: [bitor], + 13: [and_], + 14: [or_], + 15: condition_, + 16: assignExpr_, + 17: [comma] + }; + operationFnList = [atom]; + getExpr = function(n) { + var binary, lower, operation, operator; + operation = operations[n]; + lower = operationFnList[n - 1]; + if (typeof operation === 'function') { + return orp(operation, lower); + } else { + operator = operation.length === 1 ? operation[0] : orp.apply(null, operation); + return binary = rec(function() { + n; + var op, start, x, y; + start = self.cur; + if ((x = binary())) { + if ((op = operator()) && (y = lower())) { + return x + op + y; } else { - self.cur = start; - return lower(); + return x; } - }); - } - }; - for (i = _i = 1; _i <= 17; i = ++_i) { - operationFnList[i] = getExpr(i); + } else { + self.cur = start; + return lower(); + } + }); } - prefixSuffixExpr = operationFnList[3]; - logicOrExpr = operationFnList[14]; - assignExpr = operationFnList[16]; - expr = operationFnList[16]; - this.root = function() { - var x; - return (x = expr()) && expect(eoi, 'expect end of input') && x; - }; + }; + for (i = _i = 1; _i <= 17; i = ++_i) { + operationFnList[i] = getExpr(i); } + prefixSuffixExpr = operationFnList[3]; + logicOrExpr = operationFnList[14]; + assignExpr = operationFnList[16]; + expr = operationFnList[16]; + this.root = function() { + var x; + return (x = expr()) && expect(eoi, 'expect end of input') && x; + }; + } + + return Parser; + +})(peasy.Parser); - return Parser; +exports.parser = parser = new Parser; - })(peasy.Parser); - exports.parser = parser = new Parser; - return exports.parse = function(text) { - return parser.parse(text); - }; -})(require, exports, module); +exports.parse = function(text) { + return parser.parse(text); +}; +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/samples/arithmatic2.js b/js/samples/arithmatic2.js index 9f3d607..ff6afa5 100644 --- a/js/samples/arithmatic2.js +++ b/js/samples/arithmatic2.js @@ -1,391 +1,395 @@ -var exports, module, require, _ref, +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/samples/arithmatic2.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { + +/*https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence +Precedence Operator type Associativity Individual operators +1 new right-to-left new +2 function call left-to-right () +property access left-to-right . +left-to-right [] +3 ++ n/a -- +4 right-to-left ! ~ + - typeof void delete +5 * / % // +6 + - +7 << >> >>> +8 < <= > >= in instanceof +9 == != === !== +10 bitwise-and left-to-right & +11 bitwise-xor left-to-right ^ +12 bitwise-or left-to-right | +13 logical-and left-to-right && +14 logical-or left-to-right || +15 condition right-to-left ?: +16 yield right-to-left yield +17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |= +18 comma left-to-right , + */ +var Parser, StateMachine, charset, identifierCharSet, identifierChars, in_, letterDigits, peasy, _in_, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -if (typeof window === 'object') { - _ref = twoside('/samples/arithmatic2'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +peasy = require("../index"); -(function(require, exports, module) { - /*https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence - Precedence Operator type Associativity Individual operators - 1 new right-to-left new - 2 function call left-to-right () - property access left-to-right . - left-to-right [] - 3 ++ n/a -- - 4 right-to-left ! ~ + - typeof void delete - 5 * / % // - 6 + - - 7 << >> >>> - 8 < <= > >= in instanceof - 9 == != === !== - 10 bitwise-and left-to-right & - 11 bitwise-xor left-to-right ^ - 12 bitwise-or left-to-right | - 13 logical-and left-to-right && - 14 logical-or left-to-right || - 15 condition right-to-left ?: - 16 yield right-to-left yield - 17 assignment right-to-left = += -= *= /= %= <<= >>= >>>= &= ^= |= - 18 comma left-to-right , - */ +StateMachine = require("./statemachine").StateMachine; - var Parser, StateMachine, charset, identifierCharSet, identifierChars, in_, letterDigits, peasy, _in_; - peasy = require("../peasy"); - StateMachine = require("./statemachine").StateMachine; - in_ = peasy.in_, charset = peasy.charset, letterDigits = peasy.letterDigits; - _in_ = in_; - identifierChars = '$_' + letterDigits; - identifierCharSet = charset(identifierChars); - return exports.Parser = Parser = (function(_super) { - __extends(Parser, _super); +in_ = peasy.in_, charset = peasy.charset, letterDigits = peasy.letterDigits; - function Parser() { - var addassign, assign, assignExpr, assignExpr_, assignOperator, atom, attr, binaryOpItems, binaryOpPriorityMap, binaryOperator, binarysm, bitandassign, bitnot, bitorassign, bitxorassign, bracketExpr, bracketExpr1, callPropExpr, callPropTail, char, colon, comma, condition, dec, delete_, divassign, dot, dotIdentifier, eoi, error, expect, expr, expression, expression_, headAtom, headExpr, identifier, idivassign, inc, incDec, lbracket, list, literal, logicOrExpr, lpar, lshiftassign, memo, modassign, mulassign, myop, negative, newExpr, new_, not1, not_, number, orBinary, orp, param, paramExpr, paren, paren1, parenExpr, posNeg, positive, prefixExpr, property, question, rbracket, rec, rpar, rshiftassign, self, simpleExpr, spaces, string, subassign, suffixExpr, typeof_, unaryExpr, unaryOp, unaryTail, void_, wrap, wrapColon, wrapDot, wrapQuestion, zrshiftassign, _ref1; - Parser.__super__.constructor.apply(this, arguments); - _ref1 = self = this, orp = _ref1.orp, list = _ref1.list, rec = _ref1.rec, memo = _ref1.memo, wrap = _ref1.wrap, char = _ref1.char, literal = _ref1.literal, spaces = _ref1.spaces, eoi = _ref1.eoi, identifier = _ref1.identifier; - number = function() { - var base, c, cur, start, text; - text = self.data; - start = cur = self.cur; - base = 10; - c = text[cur]; - if (c === '+' || c === '-') { +_in_ = in_; + +identifierChars = '$_' + letterDigits; + +identifierCharSet = charset(identifierChars); + +exports.Parser = Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var addassign, assign, assignExpr, assignExpr_, assignOperator, atom, attr, binaryOpItems, binaryOpPriorityMap, binaryOperator, binarysm, bitandassign, bitnot, bitorassign, bitxorassign, bracketExpr, bracketExpr1, callPropExpr, callPropTail, char, colon, comma, condition, dec, delete_, divassign, dot, dotIdentifier, eoi, error, expect, expr, expression, expression_, headAtom, headExpr, identifier, idivassign, inc, incDec, lbracket, list, literal, logicOrExpr, lpar, lshiftassign, memo, modassign, mulassign, myop, negative, newExpr, new_, not1, not_, number, orBinary, orp, param, paramExpr, paren, paren1, parenExpr, posNeg, positive, prefixExpr, property, question, rbracket, rec, rpar, rshiftassign, self, simpleExpr, spaces, string, subassign, suffixExpr, typeof_, unaryExpr, unaryOp, unaryTail, void_, wrap, wrapColon, wrapDot, wrapQuestion, zrshiftassign, _ref; + Parser.__super__.constructor.apply(this, arguments); + _ref = self = this, orp = _ref.orp, list = _ref.list, rec = _ref.rec, memo = _ref.memo, wrap = _ref.wrap, char = _ref.char, literal = _ref.literal, spaces = _ref.spaces, eoi = _ref.eoi, identifier = _ref.identifier; + number = function() { + var base, c, cur, start, text; + text = self.data; + start = cur = self.cur; + base = 10; + c = text[cur]; + if (c === '+' || c === '-') { + cur++; + } + if (text[cur] === '0') { + c = text[++cur]; + if (c === 'x' || c === 'X') { + base = 16; cur++; } - if (text[cur] === '0') { - c = text[++cur]; - if (c === 'x' || c === 'X') { - base = 16; - cur++; + } + if (base === 16) { + while (c = text[cur]) { + if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) { + self.cur = cur; + return text.slice(start, cur); } + cur++; } - if (base === 16) { - while (c = text[cur]) { - if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) { - self.cur = cur; - return text.slice(start, cur); - } - cur++; - } + } + while (c = text[cur]) { + if (!(('0' <= c && c <= '9'))) { + break; } + cur++; + } + if (text[cur] === '.') { + cur++; while (c = text[cur]) { if (!(('0' <= c && c <= '9'))) { break; } cur++; } - if (text[cur] === '.') { - cur++; - while (c = text[cur]) { - if (!(('0' <= c && c <= '9'))) { - break; - } - cur++; - } - if (text[cur - 1] === '.' && (c = text[cur - 2]) && !(('0' <= c && c <= '9'))) { - return; - } - } - c = text[cur]; - if (c === 'E' || c === 'e') { - cur++; - while (c = text[cur]) { - if (!(('0' <= c && c <= '9'))) { - break; - } - cur++; - } - if ((c = text[cur - 1]) && (c === 'E' || c === 'e')) { - return; - } - } - self.cur = cur; - return text.slice(start, cur); - }; - string = function() { - var c, cur, quote, result, text; - text = self.data; - cur = self.cur; - c = text[cur]; - if (c === '"' || c === "'") { - quote = c; - } else { + if (text[cur - 1] === '.' && (c = text[cur - 2]) && !(('0' <= c && c <= '9'))) { return; } - result = ''; + } + c = text[cur]; + if (c === 'E' || c === 'e') { cur++; - while (1) { - c = text[cur]; - if (c === '\\') { - result += text[cur + 1]; - cur += 2; - } else if (c === quote) { - self.cur = cur + 1; - return quote + result + quote; - } else if (!c) { - error('expect ' + quote); - } else { - result += c; - cur++; + while (c = text[cur]) { + if (!(('0' <= c && c <= '9'))) { + break; } + cur++; } - }; - question = char('?'); - colon = char(':'); - comma = char(','); - dot = char('.'); - lpar = char('('); - rpar = char(')'); - lbracket = char('['); - rbracket = char(']'); - myop = function(op) { - var opFn; - if (op.length === 1) { - opFn = char(op); - } else { - opFn = literal(op); + if ((c = text[cur - 1]) && (c === 'E' || c === 'e')) { + return; } - if (_in_(op[0], identifierCharSet)) { - return function() { - return spaces() && (op = opFn()) && spaces() && !_in_(data[self.cur], identifierCharSet) && ' ' + op + ' '; - }; + } + self.cur = cur; + return text.slice(start, cur); + }; + string = function() { + var c, cur, quote, result, text; + text = self.data; + cur = self.cur; + c = text[cur]; + if (c === '"' || c === "'") { + quote = c; + } else { + return; + } + result = ''; + cur++; + while (1) { + c = text[cur]; + if (c === '\\') { + result += text[cur + 1]; + cur += 2; + } else if (c === quote) { + self.cur = cur + 1; + return quote + result + quote; + } else if (!c) { + error('expect ' + quote); } else { - return function() { - return spaces() && (op = opFn()) && spaces() && op; - }; + result += c; + cur++; } - }; - posNeg = function(op) { - var opFn; + } + }; + question = char('?'); + colon = char(':'); + comma = char(','); + dot = char('.'); + lpar = char('('); + rpar = char(')'); + lbracket = char('['); + rbracket = char(']'); + myop = function(op) { + var opFn; + if (op.length === 1) { opFn = char(op); + } else { + opFn = literal(op); + } + if (_in_(op[0], identifierCharSet)) { return function() { - var c; - return spaces() && (op = opFn()) && (c = self.data[self.cur]) && c !== '.' && !(('0' <= c && c <= '9')) && spaces() && op; + return spaces() && (op = opFn()) && spaces() && !_in_(data[self.cur], identifierCharSet) && ' ' + op + ' '; }; - }; - positive = posNeg('+'); - negative = posNeg('-'); - new_ = myop('new'); - inc = myop('++'); - dec = myop('--'); - not1 = orp(myop('!'), myop('not')); - not_ = function() { - return not1(); - }; - bitnot = myop('~'); - typeof_ = myop('typeof'); - void_ = myop('void'); - delete_ = myop('delete'); - unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_); - comma = myop(','); - assign = myop('='); - addassign = myop('+='); - subassign = myop('-='); - mulassign = myop('*='); - divassign = myop('/='); - modassign = myop('%='); - idivassign = myop('//='); - rshiftassign = myop('>>='); - lshiftassign = myop('<<='); - zrshiftassign = myop('>>>='); - bitandassign = myop('&='); - bitxorassign = myop('^='); - bitorassign = myop('|='); - error = function(msg) { - throw self.data.slice(self.cur - 20, +(self.cur + 20) + 1 || 9e9) + ' ' + self.cur + ': ' + msg; - }; - expect = function(fn, msg) { - return fn() || error(msg); - }; - incDec = orp(inc, dec); - prefixExpr = function() { - var op, x; - return (op = incDec()) && (x = headExpr()) && op + x; - }; - suffixExpr = function() { - var op, x; - return (x = headExpr()) && (op = incDec()) && x + op; - }; - paren = function(item, left, right, msg) { - if (left == null) { - left = lpar; - } - if (right == null) { - right = rpar; - } - if (msg == null) { - msg = 'expect ) to match ('; - } - if ((typeof item) === 'string') { - left = self.literal(item); - } - if ((typeof left) === 'string') { - left = self.literal(left); - } - if ((typeof right) === 'string') { - right = self.literal(right); - } + } else { return function() { - var start, x; - start = self.cur; - return left() && (x = item()) && expect(right, msg + ' at: ' + start) && x; + return spaces() && (op = opFn()) && spaces() && op; }; + } + }; + posNeg = function(op) { + var opFn; + opFn = char(op); + return function() { + var c; + return spaces() && (op = opFn()) && (c = self.data[self.cur]) && c !== '.' && !(('0' <= c && c <= '9')) && spaces() && op; }; - paren1 = paren(function() { - var x; - return spaces() && (x = expression()) && spaces() && x; - }); - parenExpr = memo(function() { - var x; - return (x = paren1()) && '(' + x + ')'; - }); - atom = memo(orp(parenExpr, number, string, identifier)); - newExpr = function() { - var x; - return new_() && (x = callProp()) && 'new ' + x; + }; + positive = posNeg('+'); + negative = posNeg('-'); + new_ = myop('new'); + inc = myop('++'); + dec = myop('--'); + not1 = orp(myop('!'), myop('not')); + not_ = function() { + return not1(); + }; + bitnot = myop('~'); + typeof_ = myop('typeof'); + void_ = myop('void'); + delete_ = myop('delete'); + unaryOp = orp(not_, bitnot, positive, negative, typeof_, void_); + comma = myop(','); + assign = myop('='); + addassign = myop('+='); + subassign = myop('-='); + mulassign = myop('*='); + divassign = myop('/='); + modassign = myop('%='); + idivassign = myop('//='); + rshiftassign = myop('>>='); + lshiftassign = myop('<<='); + zrshiftassign = myop('>>>='); + bitandassign = myop('&='); + bitxorassign = myop('^='); + bitorassign = myop('|='); + error = function(msg) { + throw self.data.slice(self.cur - 20, +(self.cur + 20) + 1 || 9e9) + ' ' + self.cur + ': ' + msg; + }; + expect = function(fn, msg) { + return fn() || error(msg); + }; + incDec = orp(inc, dec); + prefixExpr = function() { + var op, x; + return (op = incDec()) && (x = headExpr()) && op + x; + }; + suffixExpr = function() { + var op, x; + return (x = headExpr()) && (op = incDec()) && x + op; + }; + paren = function(item, left, right, msg) { + if (left == null) { + left = lpar; + } + if (right == null) { + right = rpar; + } + if (msg == null) { + msg = 'expect ) to match ('; + } + if ((typeof item) === 'string') { + left = self.literal(item); + } + if ((typeof left) === 'string') { + left = self.literal(left); + } + if ((typeof right) === 'string') { + right = self.literal(right); + } + return function() { + var start, x; + start = self.cur; + return left() && (x = item()) && expect(right, msg + ' at: ' + start) && x; }; - unaryTail = orp(prefixExpr, suffixExpr, atom); - unaryExpr = function() { - var op, x; - return (op = unaryOp()) && (x = unaryTail()) && op + x; - }; - bracketExpr1 = wrap(paren(wrap(function() { - return commaExpr(); - }), lbracket, rbracket, 'expect ] to match [')); - bracketExpr = function() { - var x; - return (x = bracketExpr1()) && '[' + x + ']'; - }; - wrapDot = wrap(dot); - dotIdentifier = function() { - var id; - return wrapDot() && (id = expect(identifier, 'expect identifier')) && '.' + id; - }; - attr = orp(bracketExpr, dotIdentifier); - param = paren(function() { - var x; - return (spaces() && (x = expression()) && spaces() && expect(rpar, 'expect )')) || ' '; - }); - paramExpr = memo(function() { - var x; - return (x = param()) && '(' + x + ')'; - }); - callPropTail = orp(paramExpr, attr); - callPropExpr = rec(function() { - var e, h; - return (h = headExpr()) && (((e = callPropTail()) && h + e) || h); - }); - property = rec(function() { - var e, h; - return (h = headExpr()) && (((e = attr()) && h + e) || h); - }); - headAtom = memo(orp(parenExpr, identifier)); - headExpr = memo(orp(callPropExpr, headAtom)); - simpleExpr = memo(orp(unaryExpr, prefixExpr, suffixExpr, callPropExpr, newExpr, atom)); - binaryOpPriorityMap = { - 5: ['*', '/', '//', '%'], - 6: ['+', '-'], - 7: ['<<', '>>', '>>>'], - 8: ['<', '<=', '>', '>=', 'in ', 'in\t', 'instanceof ', 'instanceof\t'], - 9: ['==', '!=', '==', '==='], - 10: ['&'], - 11: ['|'], - 12: ['^'], - 13: ['&&'], - 14: ['||'], - 17: [','] - }; - binaryOpItems = []; - (function() { - var k, op, ops, _results; - _results = []; - for (k in binaryOpPriorityMap) { - ops = binaryOpPriorityMap[k]; - _results.push((function() { - var _i, _len, _results1; - _results1 = []; - for (_i = 0, _len = ops.length; _i < _len; _i++) { - op = ops[_i]; - _results1.push(binaryOpItems.push([ - op, { - text: op, - pri: parseInt(k) - } - ])); - } - return _results1; - })()); - } - return _results; - })(); - binarysm = new StateMachine(binaryOpItems); - binaryOperator = memo(function() { - var m; - m = binarysm.match(self.data, self.cur); - if (m[0]) { - self.cur = m[1]; - return m[0]; - } - }); - expr = function(n) { - var binary; - return binary = rec(function() { - var beforeOp, fn, op, x, y, _ref2; - if (x = binary()) { - beforeOp = self.cur; - if ((op = binaryOperator()) && ((n >= (_ref2 = op.pri) && _ref2 >= x.pri)) && (fn = expr(op.pri)) && (y = fn())) { - return { - text: x.text + op.text + y.text, - pri: op.pri - }; - } else { - self.cur = beforeOp; - return x; - } - } else if (x = simpleExpr()) { + }; + paren1 = paren(function() { + var x; + return spaces() && (x = expression()) && spaces() && x; + }); + parenExpr = memo(function() { + var x; + return (x = paren1()) && '(' + x + ')'; + }); + atom = memo(orp(parenExpr, number, string, identifier)); + newExpr = function() { + var x; + return new_() && (x = callProp()) && 'new ' + x; + }; + unaryTail = orp(prefixExpr, suffixExpr, atom); + unaryExpr = function() { + var op, x; + return (op = unaryOp()) && (x = unaryTail()) && op + x; + }; + bracketExpr1 = wrap(paren(wrap(function() { + return commaExpr(); + }), lbracket, rbracket, 'expect ] to match [')); + bracketExpr = function() { + var x; + return (x = bracketExpr1()) && '[' + x + ']'; + }; + wrapDot = wrap(dot); + dotIdentifier = function() { + var id; + return wrapDot() && (id = expect(identifier, 'expect identifier')) && '.' + id; + }; + attr = orp(bracketExpr, dotIdentifier); + param = paren(function() { + var x; + return (spaces() && (x = expression()) && spaces() && expect(rpar, 'expect )')) || ' '; + }); + paramExpr = memo(function() { + var x; + return (x = param()) && '(' + x + ')'; + }); + callPropTail = orp(paramExpr, attr); + callPropExpr = rec(function() { + var e, h; + return (h = headExpr()) && (((e = callPropTail()) && h + e) || h); + }); + property = rec(function() { + var e, h; + return (h = headExpr()) && (((e = attr()) && h + e) || h); + }); + headAtom = memo(orp(parenExpr, identifier)); + headExpr = memo(orp(callPropExpr, headAtom)); + simpleExpr = memo(orp(unaryExpr, prefixExpr, suffixExpr, callPropExpr, newExpr, atom)); + binaryOpPriorityMap = { + 5: ['*', '/', '//', '%'], + 6: ['+', '-'], + 7: ['<<', '>>', '>>>'], + 8: ['<', '<=', '>', '>=', 'in ', 'in\t', 'instanceof ', 'instanceof\t'], + 9: ['==', '!=', '==', '==='], + 10: ['&'], + 11: ['|'], + 12: ['^'], + 13: ['&&'], + 14: ['||'], + 17: [','] + }; + binaryOpItems = []; + (function() { + var k, op, ops, _results; + _results = []; + for (k in binaryOpPriorityMap) { + ops = binaryOpPriorityMap[k]; + _results.push((function() { + var _i, _len, _results1; + _results1 = []; + for (_i = 0, _len = ops.length; _i < _len; _i++) { + op = ops[_i]; + _results1.push(binaryOpItems.push([ + op, { + text: op, + pri: parseInt(k) + } + ])); + } + return _results1; + })()); + } + return _results; + })(); + binarysm = new StateMachine(binaryOpItems); + binaryOperator = memo(function() { + var m; + m = binarysm.match(self.data, self.cur); + if (m[0]) { + self.cur = m[1]; + return m[0]; + } + }); + expr = function(n) { + var binary; + return binary = rec(function() { + var beforeOp, fn, op, x, y, _ref1; + if (x = binary()) { + beforeOp = self.cur; + if ((op = binaryOperator()) && ((n >= (_ref1 = op.pri) && _ref1 >= x.pri)) && (fn = expr(op.pri)) && (y = fn())) { return { - text: x, - pri: 4 + text: x.text + op.text + y.text, + pri: op.pri }; + } else { + self.cur = beforeOp; + return x; } - }); - }; - orBinary = expr(15); - logicOrExpr = function() { - var x; - return (x = orBinary()) && x.text; - }; - wrapQuestion = wrap(question); - wrapColon = wrap(colon); - condition = function() { - var x, y, z; - return (x = logicOrExpr()) && ((wrapQuestion() && (y = assignExpr()) && expect(wrapColon, 'expect :') && (z = assignExpr()) && x + '? ' + y + ': ' + z) || x); - }; - assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign, rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign); - assignExpr_ = function() { - var e, op, v; - if ((v = property()) && (op = assignOperator())) { - return (e = expect(assignExpr, 'expect the right hand side of assign.')) && v + op + e; - } - }; - assignExpr = orp(assignExpr_, condition); - expression_ = list(assignExpr, wrap(comma)); - expression = function() { - var x; - x = expression_(); - if (x) { - return x.join(','); + } else if (x = simpleExpr()) { + return { + text: x, + pri: 4 + }; } - }; - this.root = function() { - var x; - return (x = expression()) && expect(eoi, 'expect end of input') && x; - }; - } + }); + }; + orBinary = expr(15); + logicOrExpr = function() { + var x; + return (x = orBinary()) && x.text; + }; + wrapQuestion = wrap(question); + wrapColon = wrap(colon); + condition = function() { + var x, y, z; + return (x = logicOrExpr()) && ((wrapQuestion() && (y = assignExpr()) && expect(wrapColon, 'expect :') && (z = assignExpr()) && x + '? ' + y + ': ' + z) || x); + }; + assignOperator = orp(assign, addassign, subassign, mulassign, divassign, modassign, idivassign, rshiftassign, lshiftassign, zrshiftassign, bitandassign, bitxorassign, bitorassign); + assignExpr_ = function() { + var e, op, v; + if ((v = property()) && (op = assignOperator())) { + return (e = expect(assignExpr, 'expect the right hand side of assign.')) && v + op + e; + } + }; + assignExpr = orp(assignExpr_, condition); + expression_ = list(assignExpr, wrap(comma)); + expression = function() { + var x; + x = expression_(); + if (x) { + return x.join(','); + } + }; + this.root = function() { + var x; + return (x = expression()) && expect(eoi, 'expect end of input') && x; + }; + } - return Parser; + return Parser; - })(peasy.Parser); -})(require, exports, module); +})(peasy.Parser); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/samples/dsl.js b/js/samples/dsl.js index 4215041..5cc532d 100644 --- a/js/samples/dsl.js +++ b/js/samples/dsl.js @@ -1,55 +1,66 @@ -var exports, module, require, _ref, +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/samples/dsl.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var TemplateParser, charset, endTextCharset, identifierHeadChars, identifierHeadCharset, inCharset, letters, parseTemplate, peasy, templateParser, _ref, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; -if (typeof window === 'object') { - _ref = twoside('/samples/dsl'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +_ref = peasy = require('../index'), inCharset = _ref.inCharset, letters = _ref.letters, charset = _ref.charset; -(function(require, exports, module) { - var TemplateParser, charset, endTextCharset, identifierHeadChars, identifierHeadCharset, inCharset, letters, parseTemplate, peasy, templateParser, _ref1; - _ref1 = peasy = require('../peasy'), inCharset = _ref1.inCharset, letters = _ref1.letters, charset = _ref1.charset; - identifierHeadChars = '$_' + letters; - endTextCharset = charset(')@' + identifierHeadChars); - identifierHeadCharset = charset(identifierHeadChars); - exports.TemplateParser = TemplateParser = (function(_super) { - __extends(TemplateParser, _super); +identifierHeadChars = '$_' + letters; + +endTextCharset = charset(')@' + identifierHeadChars); + +identifierHeadCharset = charset(identifierHeadChars); + +exports.TemplateParser = TemplateParser = (function(_super) { + __extends(TemplateParser, _super); - function TemplateParser() { - var anySegment, at, c, error, exclam, field, lpar, mayExclam, rpar, tcall, template, text, tfield, _ref2, - _this = this; - TemplateParser.__super__.constructor.apply(this, arguments); - _ref2 = (function() { - var _i, _len, _ref2, _results, - _this = this; - _ref2 = '@()!'; - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - c = _ref2[_i]; - _results.push((function(c) { + function TemplateParser() { + var anySegment, at, c, error, exclam, field, lpar, mayExclam, rpar, tcall, template, text, tfield, _ref1; + TemplateParser.__super__.constructor.apply(this, arguments); + _ref1 = (function() { + var _i, _len, _ref1, _results; + _ref1 = '@()!'; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + c = _ref1[_i]; + _results.push((function(_this) { + return function(c) { return _this.char(c); - })(c)); - } - return _results; - }).call(this), at = _ref2[0], lpar = _ref2[1], rpar = _ref2[2], exclam = _ref2[3]; - mayExclam = this.may(exclam); - error = function(msg) { + }; + })(this)(c)); + } + return _results; + }).call(this), at = _ref1[0], lpar = _ref1[1], rpar = _ref1[2], exclam = _ref1[3]; + mayExclam = this.may(exclam); + error = (function(_this) { + return function(msg) { throw _this.data.slice(_this.cur - 20, +(_this.cur + 20) + 1 || 9e9) + ' ' + _this.cur + ': ' + msg; }; - tcall = function() { + })(this); + tcall = (function(_this) { + return function() { var args, f; return (f = tfield()) && lpar() && (args = template()) && ((rpar() && f + '(' + args + ')') || error('expect )')); }; - tfield = this.memo(function() { + })(this); + tfield = this.memo((function(_this) { + return function() { var id; return at() && (((id = _this.identifier()) && mayExclam() && 't.' + id) || error('expect @identifier')); - }); - field = function() { + }; + })(this)); + field = (function(_this) { + return function() { var id; return (id = _this.identifier()) && mayExclam() && ("t.transform(e." + id + ")"); }; - text = function() { + })(this); + text = (function(_this) { + return function() { var cur, data, id, result, start; data = _this.data; start = cur = _this.cur; @@ -95,22 +106,29 @@ if (typeof window === 'object') { return '"' + result + '"'; } }; - anySegment = this.any(this.orp(tcall, tfield, field, text)); - template = function() { + })(this); + anySegment = this.any(this.orp(tcall, tfield, field, text)); + template = (function(_this) { + return function() { var x; return (x = anySegment()) && x.join(','); }; - this.root = function() { + })(this); + this.root = (function(_this) { + return function() { var t; return (t = template()) && ((_this.eoi() && t) || error('unexpected )')); }; - } + })(this); + } + + return TemplateParser; + +})(peasy.Parser); - return TemplateParser; +templateParser = new TemplateParser; - })(peasy.Parser); - templateParser = new TemplateParser; - return exports.parseTemplate = parseTemplate = function(text) { - return templateParser.parse(text); - }; -})(require, exports, module); +exports.parseTemplate = parseTemplate = function(text) { + return templateParser.parse(text); +}; +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/samples/latex.js b/js/samples/latex.js index a38b763..3d9f16c 100644 --- a/js/samples/latex.js +++ b/js/samples/latex.js @@ -1,3 +1,8 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/samples/latex.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { + /* {-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-} {- @@ -19,75 +24,74 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -} {- | - Module : Text.Pandoc.Readers.LaTeX - Copyright : Copyright (C) 2006-2012 John MacFarlane - License : GNU GPL, version 2 or above + Module : Text.Pandoc.Readers.LaTeX + Copyright : Copyright (C) 2006-2012 John MacFarlane + License : GNU GPL, version 2 or above - Maintainer : John MacFarlane - Stability : alpha - Portability : portable + Maintainer : John MacFarlane + Stability : alpha + Portability : portable Conversion of LaTeX to 'Pandoc' document. -} -*/ - -var exports, module, require, _ref, + */ +var Parser, StateMachine, charset, identifierCharSet, identifierChars, in_, letterDigits, peasy, _in_, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -if (typeof window === 'object') { - _ref = twoside('/samples/latex'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +peasy = require("../index"); -(function(require, exports, module) { - var Parser, StateMachine, charset, identifierCharSet, identifierChars, in_, letterDigits, peasy, _in_; - peasy = require("../peasy"); - StateMachine = require("./statemachine").StateMachine; - in_ = peasy.in_, charset = peasy.charset, letterDigits = peasy.letterDigits; - _in_ = in_; - identifierChars = '$_' + letterDigits; - identifierCharSet = charset(identifierChars); - return exports.Parser = Parser = (function(_super) { - __extends(Parser, _super); - - function Parser() { - var anyControlSeq, block, blocks, ch, char, comment, controlSeq, dim, dimenarg, eoi, identifier, isLowerHex, list, literal, mayNewLine, memo, num, orp, percent, rec, self, skipLine, spaces, wrap, _ref1; - Parser.__super__.constructor.apply(this, arguments); - _ref1 = self = this, orp = _ref1.orp, list = _ref1.list, rec = _ref1.rec, memo = _ref1.memo, wrap = _ref1.wrap, char = _ref1.char, literal = _ref1.literal, spaces = _ref1.spaces, eoi = _ref1.eoi, identifier = _ref1.identifier; - mayNewLine = may(newline); - anyControlSeq = function() { - return slash() && orp(NewLine, anyChar)(); - }; - controlSeq = function(name) { - return slash(); - }; - dimenarg = (ch = orp("", literal('='))()) && (num = many1(digit)()) && (dim = oneOfStrings("pt", "pc", "in", "bp", "cm", "mm", "dd", "cc", "sp")()) && ch + num + dim; - isLowerHex = function(x) { - return x >= '0' && x <= '9' || x >= 'a' && x <= 'f'; - }; - anyCharUnless('\n'); - skipLine = function() { - var c, cur, text; - text = self.data; - cur = self.cur; - while (1) { - c = text[cur++]; - if (c === '\n') { - return true; - } +StateMachine = require("./statemachine").StateMachine; + +in_ = peasy.in_, charset = peasy.charset, letterDigits = peasy.letterDigits; + +_in_ = in_; + +identifierChars = '$_' + letterDigits; + +identifierCharSet = charset(identifierChars); + +exports.Parser = Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var anyControlSeq, block, blocks, ch, char, comment, controlSeq, dim, dimenarg, eoi, identifier, isLowerHex, list, literal, mayNewLine, memo, num, orp, percent, rec, self, skipLine, spaces, wrap, _ref; + Parser.__super__.constructor.apply(this, arguments); + _ref = self = this, orp = _ref.orp, list = _ref.list, rec = _ref.rec, memo = _ref.memo, wrap = _ref.wrap, char = _ref.char, literal = _ref.literal, spaces = _ref.spaces, eoi = _ref.eoi, identifier = _ref.identifier; + mayNewLine = may(newline); + anyControlSeq = function() { + return slash() && orp(NewLine, anyChar)(); + }; + controlSeq = function(name) { + return slash(); + }; + dimenarg = (ch = orp("", literal('='))()) && (num = many1(digit)()) && (dim = oneOfStrings("pt", "pc", "in", "bp", "cm", "mm", "dd", "cc", "sp")()) && ch + num + dim; + isLowerHex = function(x) { + return x >= '0' && x <= '9' || x >= 'a' && x <= 'f'; + }; + anyCharUnless('\n'); + skipLine = function() { + var c, cur, text; + text = self.data; + cur = self.cur; + while (1) { + c = text[cur++]; + if (c === '\n') { + return true; } - }; - percent = char('%'); - comment = percent() && skipLine(); - block = orp(comment, emptyLines, environment, macro, blockCommand, groupedBlock, paragraph, charAt); - blocks = any(block); - this.root = function() { - var x; - return (x = blocks()) && x; - }; - } - - return Parser; - - })(peasy.Parser); -})(require, exports, module); + } + }; + percent = char('%'); + comment = percent() && skipLine(); + block = orp(comment, emptyLines, environment, macro, blockCommand, groupedBlock, paragraph, charAt); + blocks = any(block); + this.root = function() { + var x; + return (x = blocks()) && x; + }; + } + + return Parser; + +})(peasy.Parser); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/samples/statemachine.js b/js/samples/statemachine.js index 6c535a6..76504b2 100644 --- a/js/samples/statemachine.js +++ b/js/samples/statemachine.js @@ -1,93 +1,92 @@ -var exports, module, require, _ref; +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/samples/statemachine.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var StateMachine, hasOwnProperty; -if (typeof window === 'object') { - _ref = twoside('/samples/statemachine'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +hasOwnProperty = Object.hasOwnProperty; -(function(require, exports, module) { - var StateMachine, hasOwnProperty; - hasOwnProperty = Object.hasOwnProperty; - return exports.StateMachine = StateMachine = (function() { - function StateMachine(items) { - var item, _i, _len; - if (items == null) { - items = []; - } - this.index = 1; - this.stateMap = {}; - this.stateMap[0] = {}; - this.tagMap = {}; - for (_i = 0, _len = items.length; _i < _len; _i++) { - item = items[_i]; - this.add(item[0], item[1] || item[0]); - } +exports.StateMachine = StateMachine = (function() { + function StateMachine(items) { + var item, _i, _len; + if (items == null) { + items = []; + } + this.index = 1; + this.stateMap = {}; + this.stateMap[0] = {}; + this.tagMap = {}; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + this.add(item[0], item[1] || item[0]); } + } - StateMachine.prototype.add = function(word, tag) { - var c, i, length, newState, s, state, stateMap; - if (tag == null) { - tag = word; - } - length = word.length; - state = 0; - i = 0; - stateMap = this.stateMap; - while (i < length - 1) { - c = word[i++]; - if (hasOwnProperty.call(stateMap[state], c)) { - state = stateMap[state][c]; - if (state < 0) { - state = -state; - } - } else { - newState = this.index++; - stateMap[state][c] = newState; - stateMap[newState] = {}; - state = newState; - } - } - c = word[i]; + StateMachine.prototype.add = function(word, tag) { + var c, i, length, newState, s, state, stateMap; + if (tag == null) { + tag = word; + } + length = word.length; + state = 0; + i = 0; + stateMap = this.stateMap; + while (i < length - 1) { + c = word[i++]; if (hasOwnProperty.call(stateMap[state], c)) { - s = stateMap[state][c]; - if (s > 0) { - stateMap[state][c] = -s; - return this.tagMap[s] = tag; + state = stateMap[state][c]; + if (state < 0) { + state = -state; } } else { newState = this.index++; - stateMap[state][c] = -newState; + stateMap[state][c] = newState; stateMap[newState] = {}; - return this.tagMap[newState] = tag; + state = newState; } - }; - - StateMachine.prototype.match = function(text, i) { - var cursor, length, state, stateMap, succeedState; - if (i == null) { - i = 0; - } - state = 0; - length = text.length; - stateMap = this.stateMap; - while (i < length) { - state = stateMap[state][text[i++]]; - if (state === void 0) { - i--; - break; - } else if (state < 0) { - state = -state; - succeedState = state; - cursor = i; - } + } + c = word[i]; + if (hasOwnProperty.call(stateMap[state], c)) { + s = stateMap[state][c]; + if (s > 0) { + stateMap[state][c] = -s; + return this.tagMap[s] = tag; } - if (succeedState) { - return [this.tagMap[succeedState], cursor]; - } else { - return [null, i]; + } else { + newState = this.index++; + stateMap[state][c] = -newState; + stateMap[newState] = {}; + return this.tagMap[newState] = tag; + } + }; + + StateMachine.prototype.match = function(text, i) { + var cursor, length, state, stateMap, succeedState; + if (i == null) { + i = 0; + } + state = 0; + length = text.length; + stateMap = this.stateMap; + while (i < length) { + state = stateMap[state][text[i++]]; + if (state === void 0) { + i--; + break; + } else if (state < 0) { + state = -state; + succeedState = state; + cursor = i; } - }; + } + if (succeedState) { + return [this.tagMap[succeedState], cursor]; + } else { + return [null, i]; + } + }; - return StateMachine; + return StateMachine; - })(); -})(require, exports, module); +})(); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/test/karma-conf.js b/js/test/karma-conf.js index 5295e86..fbd622d 100644 --- a/js/test/karma-conf.js +++ b/js/test/karma-conf.js @@ -7,7 +7,7 @@ module.exports = function(config) { outputDir: 'js/test/karma/html', templatePath: 'coffee/test/jasmine-template.html' }, - files: ['twoside.js', 'peasy.js', 'logicpeasy.js', 'deprecated/logic.js', 'deprecated/autopeasy.js', 'deprecated/modularpeasy.js', 'deprecated/nonmodularpeasy.js', 'samples/dsl.js', 'samples/arithmatic.js', 'samples/statemachine.js', 'samples/arithmatic2.js', 'test/karma/testpeasy.js', 'test/karma/testlogicpeasy.js', 'test/karma/deprecated/testlogic.js', 'test/karma/deprecated/testautopeasy.js', 'test/karma/deprecated/testmodularpeasy.js', 'test/karma/deprecated/testnonmodularpeasy.js', 'test/karma/samples/testdsl.js', 'test/karma/samples/testarithmatic.js', 'test/karma/samples/testarithmatic2.js'], + files: ['twoside.js', 'peasy.js', 'logicpeasy.js', 'samples/dsl.js', 'samples/arithmatic.js', 'samples/statemachine.js', 'samples/arithmatic2.js', 'test/karma/testpeasy.js', 'test/karma/testlogicpeasy.js', 'test/karma/samples/testdsl.js', 'test/karma/samples/testarithmatic.js', 'test/karma/samples/testarithmatic2.js'], exclude: [], port: 9876, logLevel: config.LOG_INFO, diff --git a/js/test/karma/deprecated/testautopeasy.js b/js/test/karma/deprecated/testautopeasy.js deleted file mode 100644 index ba73065..0000000 --- a/js/test/karma/deprecated/testautopeasy.js +++ /dev/null @@ -1,104 +0,0 @@ -var exports, module, require, _ref; - -if (typeof window === 'object') { - _ref = twoside('/test/karma/deprecated/testautopeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var a, autoComputeLeftRecursives, b, char, hasOwnProperty, initialize, p, parse1, parse2, parse3, parser, x, _ref1; - _ref1 = parser = p = require("../../../deprecated/autopeasy"), char = _ref1.char, initialize = _ref1.initialize, autoComputeLeftRecursives = _ref1.autoComputeLeftRecursives; - hasOwnProperty = Object.hasOwnProperty; - a = char('a'); - b = char('b'); - x = char('x'); - parse1 = function(text) { - var rules; - rules = { - A: function(start) { - var m; - return (m = rules.A(start)) && x(p.cur()) && m + 'x' || m || a(start); - }, - rootSymbol: 'A' - }; - initialize(); - autoComputeLeftRecursives(rules); - return parser.parse(text, rules); - }; - parse2 = function(text) { - var rules; - rules = { - A: function(start) { - var m; - return (m = rules.B(start)) && x(p.cur()) && m + 'x' || m || a(start); - }, - B: function(start) { - return rules.A(start) || b(start); - }, - rootSymbol: 'A' - }; - initialize(); - autoComputeLeftRecursives(rules); - return parser.parse(text, rules); - }; - parse3 = function(text) { - var rules; - rules = { - A: function(start) { - var m; - return (m = rules.B(start)) && x(p.cur()) && m + 'x' || m || a(start); - }, - B: function(start) { - return rules.C(start); - }, - C: function(start) { - return rules.A(start) || b(start); - }, - rootSymbol: 'A' - }; - initialize(); - autoComputeLeftRecursives(rules); - return parser.parse(text, rules); - }; - return describe('auto peasy', function() { - it("test A: Ax|a", function() { - var parse; - parse = parse1; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - return expect(parse('axxx')).toBe('axxx'); - }); - it("test A: Bx|a; B:A|b", function() { - var parse; - parse = parse2; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - return it("test A: Bx|a; B:C; C:A|b", function() { - var parse; - parse = parse3; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - }); -})(require, exports, module); diff --git a/js/test/karma/deprecated/testlogic.js b/js/test/karma/deprecated/testlogic.js deleted file mode 100644 index a8e601e..0000000 --- a/js/test/karma/deprecated/testlogic.js +++ /dev/null @@ -1,111 +0,0 @@ -var exports, module, require, _ref; - -if (typeof window === 'object') { - _ref = twoside('/test/karma/deprecated/testlogic'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var cons, logic, makeCmd, makeInfo, uarray, uobject, vari, _ref1; - _ref1 = logic = require("../../../deprecated/logic"), vari = _ref1.vari, cons = _ref1.cons, uarray = _ref1.uarray, uobject = _ref1.uobject, makeInfo = _ref1.makeInfo; - makeCmd = function() { - var info; - info = makeInfo(''); - return { - unify: logic.unify(info), - orp: logic.orp(info) - }; - }; - return describe('logic', function() { - it("test unify 1 1, 1 2", function() { - var orp, unify, _ref2, _ref3; - _ref2 = makeCmd(), unify = _ref2.unify, orp = _ref2.orp; - expect(unify(1, 1)).toBe(true); - _ref3 = makeCmd(), unify = _ref3.unify, orp = _ref3.orp; - return expect(unify(1, 2)).toBe(false); - }); - it("test unify logicvar", function() { - var $a, orp, unify, _ref2, _ref3, _ref4; - _ref2 = makeCmd(), unify = _ref2.unify, orp = _ref2.orp; - expect(unify(vari(), 1)).toBe(true); - _ref3 = makeCmd(), unify = _ref3.unify, orp = _ref3.orp; - expect(($a = vari()) && unify($a, 1) && unify($a, 2)).toBe(false); - _ref4 = makeCmd(), unify = _ref4.unify, orp = _ref4.orp; - return expect(($a = vari()) && orp((function() { - return unify($a, 1) && unify($a, 2); - }), function() { - return unify($a, 2); - })()).toBe(true); - }); - it("test unify cons", function() { - var $a, orp, unify, _ref2, _ref3, _ref4, _ref5; - _ref2 = makeCmd(), unify = _ref2.unify, orp = _ref2.orp; - expect(unify(cons(1, null), cons(1, null))).toBe(true); - _ref3 = makeCmd(), unify = _ref3.unify, orp = _ref3.orp; - expect(unify(cons(vari(), null), cons(1, null))).toBe(true); - _ref4 = makeCmd(), unify = _ref4.unify, orp = _ref4.orp; - expect(($a = vari()) && unify(cons($a, null), cons(1, null)) && unify($a, 2)).toBe(false); - _ref5 = makeCmd(), unify = _ref5.unify, orp = _ref5.orp; - return expect(($a = vari()) && orp((function() { - return unify(cons($a, null), cons(1, null)) && unify($a, 2); - }), function() { - return unify($a, 2); - })()).toBe(true); - }); - it("test unify uobject", function() { - var $a, orp, unify, _ref2, _ref3, _ref4, _ref5, _ref6; - _ref2 = makeCmd(), unify = _ref2.unify, orp = _ref2.orp; - expect(unify(uobject({ - a: 1 - }), { - a: 1 - })).toBe(true); - _ref3 = makeCmd(), unify = _ref3.unify, orp = _ref3.orp; - expect(unify(uobject({ - a: 1 - }), { - a: 2 - })).toBe(false); - _ref4 = makeCmd(), unify = _ref4.unify, orp = _ref4.orp; - expect(unify(uobject({ - a: vari() - }), { - a: 1 - })).toBe(true); - _ref5 = makeCmd(), unify = _ref5.unify, orp = _ref5.orp; - expect(($a = vari()) && unify(uobject({ - a: $a - }), { - a: 1 - }) && unify($a, 2)).toBe(false); - _ref6 = makeCmd(), unify = _ref6.unify, orp = _ref6.orp; - return expect(($a = vari()) && orp((function() { - return unify(uobject({ - a: $a - }), { - a: 1 - }) && unify($a, 2); - }), function() { - return unify($a, 2); - })()).toBe(true); - }); - return it("test unify array, uarray", function() { - var $a, orp, unify, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; - _ref2 = makeCmd(), unify = _ref2.unify, orp = _ref2.orp; - expect(unify([], [])).toBe(false); - _ref3 = makeCmd(), unify = _ref3.unify, orp = _ref3.orp; - expect(unify(uarray([]), [])).toBe(true); - _ref4 = makeCmd(), unify = _ref4.unify, orp = _ref4.orp; - expect(unify(uarray([vari()]), [])).toBe(false); - _ref5 = makeCmd(), unify = _ref5.unify, orp = _ref5.orp; - expect(unify(uarray([vari()]), [1])).toBe(true); - _ref6 = makeCmd(), unify = _ref6.unify, orp = _ref6.orp; - expect(($a = vari()) && unify(uarray([$a]), [1]) && unify($a, 2)).toBe(false); - _ref7 = makeCmd(), unify = _ref7.unify, orp = _ref7.orp; - return expect(($a = vari()) && orp((function() { - return unify(uarray([$a]), [1]) && unify($a, 2); - }), function() { - return unify($a, 2); - })()).toBe(true); - }); - }); -})(require, exports, module); diff --git a/js/test/karma/deprecated/testmodularpeasy.js b/js/test/karma/deprecated/testmodularpeasy.js deleted file mode 100644 index 54653b9..0000000 --- a/js/test/karma/deprecated/testmodularpeasy.js +++ /dev/null @@ -1,205 +0,0 @@ -var exports, module, require, _ref; - -if (typeof window === 'object') { - _ref = twoside('/test/karma/deprecated/testmodularpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var combinators, letters, makeInfo, parse1, parse2, parse3, parse4, parse5, _ref1; - _ref1 = require("../../../deprecated/modularpeasy"), makeInfo = _ref1.makeInfo, letters = _ref1.letters, combinators = _ref1.combinators; - parse1 = function(text) { - var grammar, makeGrammar; - makeGrammar = function(info) { - var a, orp, rec, rules, x, _ref2, _ref3; - _ref2 = letters(info), a = _ref2.a, x = _ref2.x; - _ref3 = combinators(info), rec = _ref3.rec, orp = _ref3.orp; - return rules = { - A: rec(orp((function() { - var m; - return (m = rules.A()) && x() && m + 'x' || m; - }), a)) - }; - }; - grammar = makeGrammar(makeInfo(text)); - return grammar.A(0); - }; - parse2 = function(text) { - var grammar, makeGrammar; - makeGrammar = function(info) { - var a, b, orp, rec, rules, x, _ref2, _ref3; - _ref2 = letters(info), a = _ref2.a, b = _ref2.b, x = _ref2.x; - _ref3 = combinators(info), rec = _ref3.rec, orp = _ref3.orp; - rules = {}; - rules.A = rec(orp((function() { - var m; - return (m = rules.B()) && x() && m + 'x' || m; - }), a)); - rules.B = rec(orp(rules.A, b)); - return rules; - }; - grammar = makeGrammar(makeInfo(text)); - return grammar.A(0); - }; - parse3 = function(text) { - var grammar, makeGrammar; - makeGrammar = function(info) { - var a, b, orp, rec, rules, x, _ref2, _ref3; - _ref2 = letters(info), a = _ref2.a, b = _ref2.b, x = _ref2.x; - _ref3 = combinators(info), rec = _ref3.rec, orp = _ref3.orp; - rules = {}; - rules.A = rec(orp((function() { - var m; - return (m = rules.B()) && x() && m + 'x' || m; - }), a)); - rules.B = rec(function() { - return rules.C(); - }); - rules.C = rec(orp(rules.A, b)); - return rules; - }; - grammar = makeGrammar(makeInfo(text)); - return grammar.A(0); - }; - parse4 = function(text) { - var grammar, makeGrammar; - makeGrammar = function(info) { - var a, b, orp, rec, rules, x, y, _ref2, _ref3; - _ref2 = letters(info), a = _ref2.a, b = _ref2.b, x = _ref2.x, y = _ref2.y; - _ref3 = combinators(info), rec = _ref3.rec, orp = _ref3.orp; - return rules = { - A: rec(function() { - return orp((function() { - var m; - return (m = rules.B()) && x() && m + 'x' || m; - }), a)(); - }), - B: rec(function() { - return orp((function() { - var m; - return (m = rules.A()) && y() && m + 'y'; - }), rules.C)(); - }), - C: rec(function() { - return orp(rules.A, b)(); - }) - }; - }; - grammar = makeGrammar(makeInfo(text)); - return grammar.A(0); - }; - parse5 = function(text) { - var grammar, makeGrammar; - makeGrammar = function(info) { - var a, b, orp, rec, rules, x, y, z, _ref2, _ref3; - _ref2 = letters(info), a = _ref2.a, b = _ref2.b, x = _ref2.x, y = _ref2.y, z = _ref2.z; - _ref3 = combinators(info), rec = _ref3.rec, orp = _ref3.orp; - return rules = { - Root: function() { - var m; - return (m = rules.A()) && z() && m + 'z'; - }, - A: rec(orp((function() { - var m; - return (m = rules.B()) && x() && m + 'x' || m; - }), a)), - B: rec(orp((function() { - var m; - return (m = rules.A()) && y() && m + 'y'; - }), function() { - return rules.C(); - })), - C: rec(orp((function() { - return rules.A(); - }), b)) - }; - }; - grammar = makeGrammar(makeInfo(text)); - return grammar.Root(0); - }; - return describe('modular peasy', function() { - it("test A: Ax|a", function() { - var parse; - parse = parse1; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - return expect(parse('axxx')).toBe('axxx'); - }); - it("test A: Bx|a; B:A|b", function() { - var parse; - parse = parse2; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - it("test A: Bx|a; B:C; C:A|b", function() { - var parse; - parse = parse3; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - it("test A: Bx|a; B:C|Ay; C:A|b", function() { - var parse; - parse = parse4; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('ay')).toBe('ay'); - expect(parse('ayx')).toBe('ayx'); - expect(parse('ayxyx')).toBe('ayxyx'); - expect(parse('bxx')).toBe('bxx'); - expect(parse('ayxxx')).toBe('ayxxx'); - expect(parse('ayxmxx')).toBe('ayx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - return it("test Start: Az; A: Bx|a; B:C|Ay; C:A|b", function() { - var parse; - parse = parse5; - expect(parse('az')).toBe('az'); - expect(parse('axz')).toBe('axz'); - expect(parse('axxz')).toBe('axxz'); - expect(parse('axxxz')).toBe('axxxz'); - expect(parse('ayz')).toBe('ayz'); - expect(parse('ayxz')).toBe('ayxz'); - expect(parse('ayxyxz')).toBe('ayxyxz'); - expect(parse('bxxz')).toBe('bxxz'); - expect(parse('ayxxxz')).toBe('ayxxxz'); - expect(parse('ayxmxxz')).toBe(void 0); - expect(parse('bz')).toBe('bz'); - expect(parse('bxz')).toBe('bxz'); - expect(parse('bxxxz')).toBe('bxxxz'); - expect(parse('bxgz')).toBe(void 0); - expect(parse('bxxgz')).toBe(void 0); - expect(parse('bxxxgz')).toBe(void 0); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - }); -})(require, exports, module); diff --git a/js/test/karma/deprecated/testnonmodularpeasy.js b/js/test/karma/deprecated/testnonmodularpeasy.js deleted file mode 100644 index 0ba98b5..0000000 --- a/js/test/karma/deprecated/testnonmodularpeasy.js +++ /dev/null @@ -1,108 +0,0 @@ -var exports, module, require, _ref; - -if (typeof window === 'object') { - _ref = twoside('/test/karma/deprecated/testnonmodularpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var a, addRecursiveCircles, b, char, computeLeftRecursives, hasOwnProperty, initialize, memo, memoA, p, parse1, parse2, parse3, parser, setRules, x, _ref1; - _ref1 = parser = p = require("../../../deprecated/nonmodularpeasy"), initialize = _ref1.initialize, char = _ref1.char, memo = _ref1.memo, setRules = _ref1.setRules, addRecursiveCircles = _ref1.addRecursiveCircles, computeLeftRecursives = _ref1.computeLeftRecursives; - hasOwnProperty = Object.hasOwnProperty; - a = char('a'); - b = char('b'); - x = char('x'); - memoA = memo('A'); - parse1 = function(text) { - var rules; - rules = { - A: function(start) { - var m; - return (m = memoA(start)) && x(p.cur()) && m + 'x' || m || a(start); - }, - rootSymbol: 'A' - }; - initialize(); - addRecursiveCircles(rules, ['A']); - computeLeftRecursives(rules); - return parser.parse(text, rules); - }; - parse2 = function(text) { - var rules; - rules = { - A: function(start) { - var m; - return (m = rules.B(start)) && x(p.cur()) && m + 'x' || m || a(start); - }, - B: function(start) { - return memoA(start) || b(start); - }, - rootSymbol: 'A' - }; - initialize(); - addRecursiveCircles(rules, ['A', 'B']); - computeLeftRecursives(rules); - return parser.parse(text, rules); - }; - parse3 = function(text) { - var rules; - rules = { - A: function(start) { - var m; - return (m = rules.B(start)) && x(p.cur()) && m + 'x' || m || a(start); - }, - B: function(start) { - return rules.C(start); - }, - C: function(start) { - return memoA(start) || b(start); - }, - rootSymbol: 'A' - }; - initialize(); - addRecursiveCircles(rules, ['A', 'B', 'C']); - computeLeftRecursives(rules); - return parser.parse(text, rules); - }; - return describe('non modular peasy', function() { - it("test A: Ax|a", function() { - var parse; - parse = parse1; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - return expect(parse('axxx')).toBe('axxx'); - }); - it("test A: Bx|a; B:A|b", function() { - var parse; - parse = parse2; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - return it("test A: Bx|a; B:C; C:A|b", function() { - var parse; - parse = parse3; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - }); -})(require, exports, module); diff --git a/js/test/karma/karma-bundle.js b/js/test/karma/karma-bundle.js new file mode 100644 index 0000000..0363e60 --- /dev/null +++ b/js/test/karma/karma-bundle.js @@ -0,0 +1,14 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/test/karma/karma-bundle.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +require('./testparser.js'); + +require('./testlogicparser'); + +require('./samples/testdsl'); + +require('./samples/testarithmatic'); + +require('./samples/testarithmatic2'); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/test/karma/samples/testarithmatic.js b/js/test/karma/samples/testarithmatic.js index 98f01f2..b1a4734 100644 --- a/js/test/karma/samples/testarithmatic.js +++ b/js/test/karma/samples/testarithmatic.js @@ -1,84 +1,84 @@ -var exports, module, require, _ref; +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/test/karma/samples/testarithmatic.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var arithmatic, parse; -if (typeof window === 'object') { - _ref = twoside('/test/mocha/samples/testarithmatic'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +parse = (arithmatic = require('../../../samples/arithmatic')).parse; -(function(require, exports, module) { - var arithmatic, parse; - parse = (arithmatic = require('../../../samples/arithmatic')).parse; - describe("run samples/testarithmatic:", function() { - return it('', function() {}); - }); - return describe("arithmatic", function() { - it("parse number", function() { - expect(parse('1')).toBe('1'); - expect(parse('01')).toBe('01'); - expect(parse('0x01')).toBe('0x01'); - expect(parse('.1')).toBe('.1'); - expect(parse('1.')).toBe('1.'); - expect(parse('+1.')).toBe('+1.'); - expect(parse('+1.e0')).toBe('+1.e0'); - expect(parse('+1.e023')).toBe('+1.e023'); - expect(parse('+1.e')).toBe(void 0); - expect(parse('+.e')).toBe(void 0); - expect(parse('+.')).toBe(void 0); - expect(parse('-.')).toBe(void 0); - return expect(parse('-.1')).toBe('-.1'); - }); - it("parse identifier", function() { - expect(parse('a')).toBe('a'); - expect(parse('$a')).toBe('$a'); - expect(parse('$a_')).toBe('$a_'); - expect(parse('$a_1')).toBe('$a_1'); - return expect(parse('_1')).toBe('_1'); - }); - it("parse string", function() { - expect(parse('"a\\"b"')).toBe('"a\"b"'); - expect(parse('"a"')).toBe('"a"'); - return expect(parse("'a'")).toBe("'a'"); - }); - it("parse a.b", function() { - return expect(parse('a.b')).toBe('a.b'); - }); - it("parse 1+1", function() { - return expect(parse('1+1')).toBe('1+1'); - }); - it("parse 1+1*1", function() { - return expect(parse('1+1*1')).toBe('1+1*1'); - }); - it("parse 1*1+1", function() { - return expect(parse('1*1+1')).toBe('1*1+1'); - }); - it("parse 1*1", function() { - return expect(parse('1*1')).toBe('1*1'); - }); - it("parse 1*1*1", function() { - return expect(parse('1*1*1')).toBe('1*1*1'); - }); - it("parse (1*1)", function() { - return expect(parse('(1*1)')).toBe('(1*1)'); - }); - it("parse (1*1)", function() { - return expect(parse('(1*1)')).toBe('(1*1)'); - }); - it("parse (1*1)+(2*3)", function() { - return expect(parse('(1*1)+(2*3)')).toBe('(1*1)+(2*3)'); - }); - it("parse a=1", function() { - return expect(parse('a=1')).toBe('a=1'); - }); - it("parse a = 1", function() { - return expect(parse('a = 1')).toBe('a=1'); - }); - it("parse a = b = 1", function() { - return expect(parse('a = b = 1')).toBe('a=b=1'); - }); - it("parse 1? a = 3: b = 4", function() { - return expect(parse('1? a = 3: b = 4')).toBe('1? a=3: b=4'); - }); - return it("parse 1?a=3:b=4", function() { - return expect(parse('1?a=3:b=4')).toBe('1? a=3: b=4'); - }); - }); -})(require, exports, module); +describe("run samples/testarithmatic:", function() { + return it('', function() {}); +}); + +describe("arithmatic", function() { + it("parse number", function() { + expect(parse('1')).toBe('1'); + expect(parse('01')).toBe('01'); + expect(parse('0x01')).toBe('0x01'); + expect(parse('.1')).toBe('.1'); + expect(parse('1.')).toBe('1.'); + expect(parse('+1.')).toBe('+1.'); + expect(parse('+1.e0')).toBe('+1.e0'); + expect(parse('+1.e023')).toBe('+1.e023'); + expect(parse('+1.e')).toBe(void 0); + expect(parse('+.e')).toBe(void 0); + expect(parse('+.')).toBe(void 0); + expect(parse('-.')).toBe(void 0); + return expect(parse('-.1')).toBe('-.1'); + }); + it("parse identifier", function() { + expect(parse('a')).toBe('a'); + expect(parse('$a')).toBe('$a'); + expect(parse('$a_')).toBe('$a_'); + expect(parse('$a_1')).toBe('$a_1'); + return expect(parse('_1')).toBe('_1'); + }); + it("parse string", function() { + expect(parse('"a\\"b"')).toBe('"a\"b"'); + expect(parse('"a"')).toBe('"a"'); + return expect(parse("'a'")).toBe("'a'"); + }); + it("parse a.b", function() { + return expect(parse('a.b')).toBe('a.b'); + }); + it("parse 1+1", function() { + return expect(parse('1+1')).toBe('1+1'); + }); + it("parse 1+1*1", function() { + return expect(parse('1+1*1')).toBe('1+1*1'); + }); + it("parse 1*1+1", function() { + return expect(parse('1*1+1')).toBe('1*1+1'); + }); + it("parse 1*1", function() { + return expect(parse('1*1')).toBe('1*1'); + }); + it("parse 1*1*1", function() { + return expect(parse('1*1*1')).toBe('1*1*1'); + }); + it("parse (1*1)", function() { + return expect(parse('(1*1)')).toBe('(1*1)'); + }); + it("parse (1*1)", function() { + return expect(parse('(1*1)')).toBe('(1*1)'); + }); + it("parse (1*1)+(2*3)", function() { + return expect(parse('(1*1)+(2*3)')).toBe('(1*1)+(2*3)'); + }); + it("parse a=1", function() { + return expect(parse('a=1')).toBe('a=1'); + }); + it("parse a = 1", function() { + return expect(parse('a = 1')).toBe('a=1'); + }); + it("parse a = b = 1", function() { + return expect(parse('a = b = 1')).toBe('a=b=1'); + }); + it("parse 1? a = 3: b = 4", function() { + return expect(parse('1? a = 3: b = 4')).toBe('1? a=3: b=4'); + }); + return it("parse 1?a=3:b=4", function() { + return expect(parse('1?a=3:b=4')).toBe('1? a=3: b=4'); + }); +}); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/test/karma/samples/testarithmatic2.js b/js/test/karma/samples/testarithmatic2.js index b906b2d..42b7487 100644 --- a/js/test/karma/samples/testarithmatic2.js +++ b/js/test/karma/samples/testarithmatic2.js @@ -1,88 +1,90 @@ -var exports, module, require, _ref; +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/test/karma/samples/testarithmatic2.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var Parser, parse, parser; -if (typeof window === 'object') { - _ref = twoside('/test/mocha/samples/testarithmatic2'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +Parser = require('../../../samples/arithmatic2').Parser; -(function(require, exports, module) { - var Parser, parse, parser; - Parser = require('../../../samples/arithmatic2').Parser; - parser = new Parser; - parse = function(text) { - return parser.parse(text); - }; - describe("run samples/testarithmatic2:", function() { - return it('', function() {}); - }); - return describe("testarithmatic2", function() { - it("testaritmatic2: parse number", function() { - expect(parse('1')).toBe('1'); - expect(parse('01')).toBe('01'); - expect(parse('0x01')).toBe('0x01'); - expect(parse('.1')).toBe('.1'); - expect(parse('1.')).toBe('1.'); - expect(parse('+1.')).toBe('+1.'); - expect(parse('+1.e0')).toBe('+1.e0'); - expect(parse('+1.e023')).toBe('+1.e023'); - expect(parse('+1.e')).toBe(void 0); - expect(parse('+.e')).toBe(void 0); - expect(parse('+.')).toBe(void 0); - expect(parse('-.')).toBe(void 0); - return expect(parse('-.1')).toBe('-.1'); - }); - it("testaritmatic2: parse identifier", function() { - expect(parse('a')).toBe('a'); - expect(parse('$a')).toBe('$a'); - expect(parse('$a_')).toBe('$a_'); - expect(parse('$a_1')).toBe('$a_1'); - return expect(parse('_1')).toBe('_1'); - }); - it("testaritmatic2: parse string", function() { - expect(parse('"a\\"b"')).toBe('"a\"b"'); - expect(parse('"a"')).toBe('"a"'); - return expect(parse("'a'")).toBe("'a'"); - }); - it("testaritmatic2: parse a.b", function() { - return expect(parse('a.b')).toBe('a.b'); - }); - it("testaritmatic2: parse 1+1", function() { - return expect(parse('1+1')).toBe('1+1'); - }); - it("testaritmatic2: parse 1+1*1", function() { - return expect(parse('1+1*1')).toBe('1+1*1'); - }); - it("testaritmatic2: parse 1*1+1", function() { - return expect(parse('1*1+1')).toBe('1*1+1'); - }); - it("testaritmatic2: parse 1*1", function() { - return expect(parse('1*1')).toBe('1*1'); - }); - it("testaritmatic2: parse 1*1*1 ", function() { - return expect(parse('1*1*1')).toBe('1*1*1'); - }); - it("testaritmatic2: parse (1*1) ", function() { - return expect(parse('(1*1)')).toBe('(1*1)'); - }); - it("testaritmatic2: parse (1*1)", function() { - return expect(parse('(1*1)')).toBe('(1*1)'); - }); - it("testaritmatic2: parse (1*1)+(2*3)", function() { - return expect(parse('(1*1)+(2*3)')).toBe('(1*1)+(2*3)'); - }); - it("testaritmatic2: parse a=1", function() { - return expect(parse('a=1')).toBe('a=1'); - }); - it("testaritmatic2: parse a = 1", function() { - return expect(parse('a = 1')).toBe('a=1'); - }); - it("testaritmatic2: parse a = b = 1", function() { - return expect(parse('a = b = 1')).toBe('a=b=1'); - }); - it("testaritmatic2: parse 1? a = 3: b = 4", function() { - return expect(parse('1? a = 3: b = 4')).toBe('1? a=3: b=4'); - }); - return it("testaritmatic2: parse 1?a=3:b=4", function() { - return expect(parse('1?a=3:b=4')).toBe('1? a=3: b=4'); - }); - }); -})(require, exports, module); +parser = new Parser; + +parse = function(text) { + return parser.parse(text); +}; + +describe("run samples/testarithmatic2:", function() { + return it('', function() {}); +}); + +describe("testarithmatic2", function() { + it("testaritmatic2: parse number", function() { + expect(parse('1')).toBe('1'); + expect(parse('01')).toBe('01'); + expect(parse('0x01')).toBe('0x01'); + expect(parse('.1')).toBe('.1'); + expect(parse('1.')).toBe('1.'); + expect(parse('+1.')).toBe('+1.'); + expect(parse('+1.e0')).toBe('+1.e0'); + expect(parse('+1.e023')).toBe('+1.e023'); + expect(parse('+1.e')).toBe(void 0); + expect(parse('+.e')).toBe(void 0); + expect(parse('+.')).toBe(void 0); + expect(parse('-.')).toBe(void 0); + return expect(parse('-.1')).toBe('-.1'); + }); + it("testaritmatic2: parse identifier", function() { + expect(parse('a')).toBe('a'); + expect(parse('$a')).toBe('$a'); + expect(parse('$a_')).toBe('$a_'); + expect(parse('$a_1')).toBe('$a_1'); + return expect(parse('_1')).toBe('_1'); + }); + it("testaritmatic2: parse string", function() { + expect(parse('"a\\"b"')).toBe('"a\"b"'); + expect(parse('"a"')).toBe('"a"'); + return expect(parse("'a'")).toBe("'a'"); + }); + it("testaritmatic2: parse a.b", function() { + return expect(parse('a.b')).toBe('a.b'); + }); + it("testaritmatic2: parse 1+1", function() { + return expect(parse('1+1')).toBe('1+1'); + }); + it("testaritmatic2: parse 1+1*1", function() { + return expect(parse('1+1*1')).toBe('1+1*1'); + }); + it("testaritmatic2: parse 1*1+1", function() { + return expect(parse('1*1+1')).toBe('1*1+1'); + }); + it("testaritmatic2: parse 1*1", function() { + return expect(parse('1*1')).toBe('1*1'); + }); + it("testaritmatic2: parse 1*1*1 ", function() { + return expect(parse('1*1*1')).toBe('1*1*1'); + }); + it("testaritmatic2: parse (1*1) ", function() { + return expect(parse('(1*1)')).toBe('(1*1)'); + }); + it("testaritmatic2: parse (1*1)", function() { + return expect(parse('(1*1)')).toBe('(1*1)'); + }); + it("testaritmatic2: parse (1*1)+(2*3)", function() { + return expect(parse('(1*1)+(2*3)')).toBe('(1*1)+(2*3)'); + }); + it("testaritmatic2: parse a=1", function() { + return expect(parse('a=1')).toBe('a=1'); + }); + it("testaritmatic2: parse a = 1", function() { + return expect(parse('a = 1')).toBe('a=1'); + }); + it("testaritmatic2: parse a = b = 1", function() { + return expect(parse('a = b = 1')).toBe('a=b=1'); + }); + it("testaritmatic2: parse 1? a = 3: b = 4", function() { + return expect(parse('1? a = 3: b = 4')).toBe('1? a=3: b=4'); + }); + return it("testaritmatic2: parse 1?a=3:b=4", function() { + return expect(parse('1?a=3:b=4')).toBe('1? a=3: b=4'); + }); +}); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/test/karma/samples/testdsl.js b/js/test/karma/samples/testdsl.js index 029099f..3dd471c 100644 --- a/js/test/karma/samples/testdsl.js +++ b/js/test/karma/samples/testdsl.js @@ -1,103 +1,106 @@ -var exports, module, require, _ref; +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/test/karma/samples/testdsl.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var parseTemplate, peasy; -if (typeof window === 'object') { - _ref = twoside('/test/karma//testdsl'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} +peasy = require('../../../index'); -(function(require, exports, module) { - var parseTemplate, peasy; - peasy = require('../../../peasy'); - console.log('peasy is required:', peasy); - peasy.testing = true; - parseTemplate = require('../../../samples/dsl').parseTemplate; - describe("run samples/testdsl:", function() { - return it('', function() {}); - }); - return describe("parse template", function() { - it("parse @) shold throw error", function() { - return expect(function() { - return parseTemplate('@)'); - }).toThrow(); - }); - it("parse @x()) shold throw error", function() { - return expect(function() { - return parseTemplate('@x())'); - }).toThrow(); - }); - it("should parse 'x'", function() { - return expect(parseTemplate('x')).toBe('t.transform(e.x)'); - }); - it("should parse 'x!y'", function() { - return expect(parseTemplate('x!y')).toBe('t.transform(e.x),t.transform(e.y)'); - }); - it("should parse '@if_(x!y)'", function() { - return expect(parseTemplate('@if_(x!y)')).toBe('t.if_(t.transform(e.x),t.transform(e.y))'); - }); - it("should parse '@if_(x!!!y)'", function() { - return expect(parseTemplate('@if_(x!!!y)')).toBe('t.if_(t.transform(e.x),"!",t.transform(e.y))'); - }); - it("should parse '@x", function() { - return expect(parseTemplate('@x')).toBe('t.x'); - }); - it("should parse '@x@y", function() { - return expect(parseTemplate('@x@y')).toBe('t.x,t.y'); - }); - it("should parsen !)", function() { - return expect(parseTemplate('!)')).toBe('")"'); - }); - it("should parsen ;23445", function() { - return expect(parseTemplate(';23445')).toBe('";23445"'); - }); - it("should parsen ;23445qwe", function() { - return expect(parseTemplate(';23445qwe')).toBe('";23445",t.transform(e.qwe)'); - }); - it("should parsen ;23445!qwe", function() { - return expect(parseTemplate(';23445!qwe')).toBe('";23445qwe"'); - }); - it("should parsen ;23445!!qwe", function() { - return expect(parseTemplate(';23445!!qwe')).toBe('";23445!",t.transform(e.qwe)'); - }); - it("should parsen @whileLoop(!while @paren(item)\n@block(body))", function() { - return expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe("t.whileLoop(\"while \",t.paren(t.transform(e.item)),\"\\n\",t.block(t.transform(e.body)))"); - }); - it('should parse "value"', function() { - return expect(parseTemplate('"value"')).toBe('\'"\',t.transform(e.value),\'"\''); - }); - it("should parse @array(items)", function() { - return expect(parseTemplate('@array(items)')).toBe('t.array(t.transform(e.items))'); - }); - it("should parse @if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))", function() { - return expect(parseTemplate('@if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))')).toBe('t.if_("if ",t.paren(t.transform(e.test)),"\\n",t.block(t.transform(e.then_)),t.may("\\nelse ",t.block(t.transform(e.else_))))'); - }); - it("should parse '@forInLoop(!for @paren(item !in range)\n@block(body))'", function() { - return expect(parseTemplate('@forInLoop(!for @paren(item !in range)\n@block(body))')).toBe('t.forInLoop("for ",t.paren(t.transform(e.item)," in ",t.transform(e.range)),"\\n",t.block(t.transform(e.body)))'); - }); - it("should parse @whileLoop(!while @paren(item)\n@block(body))", function() { - return expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe('t.whileLoop("while ",t.paren(t.transform(e.item)),"\\n",t.block(t.transform(e.body)))'); - }); - it("should parse @tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))", function() { - return expect(parseTemplate('@tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))')).toBe('t.tryCatch("try ",t.block(t.transform(e.test)),"\\n",t.transform(e.catcher),t.may("\\nfinally ",t.block(t.transform(e.final))))'); - }); - it("should parsen !catch @paren(variable@may(!if test))@block(\nbody)", function() { - return expect(parseTemplate('!catch @paren(variable@may(!if test))@block(\nbody)')).toBe('"catch ",t.paren(t.transform(e.variable),t.may("if ",t.transform(e.test))),t.block("\\n",t.transform(e.body))'); - }); - it("should parsen !throw value", function() { - return expect(parseTemplate('!throw value')).toBe('"throw ",t.transform(e.value)'); - }); - it("should parsen caller@paren(@list(args))", function() { - return expect(parseTemplate('caller@paren(@list(args))')).toBe('t.transform(e.caller),t.paren(t.list(t.transform(e.args)))'); - }); - it("should parsen !var @list(vars)", function() { - return expect(parseTemplate('left = right')).toBe('t.transform(e.left)," = ",t.transform(e.right)'); - }); - it("left @op(operator) = right", function() { - return expect(parseTemplate('left @op(operator) = right')).toBe('t.transform(e.left)," ",t.op(t.transform(e.operator))," = ",t.transform(e.right)'); - }); - it("should parsen @switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))", function() { - return expect(parseTemplate('@switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))')).toBe('t.switch_("switch ",t.paren(t.transform(e.expression))," \\n",t.block(t.list(t.transform(e.cases)," ",t.empty))," ",t.may("\\ndefault: ",t.block(t.transform(e.else))))'); - }); - return it("!case test: \n@block(body)", function() { - return expect(parseTemplate('!case test: \n@block(body)')).toBe('"case ",t.transform(e.test),": \\n",t.block(t.transform(e.body))'); - }); - }); -})(require, exports, module); +console.log('peasy is required:', peasy); + +peasy.testing = true; + +parseTemplate = require('../../../samples/dsl').parseTemplate; + +describe("run samples/testdsl:", function() { + return it('', function() {}); +}); + +describe("parse template", function() { + it("parse @) shold throw error", function() { + return expect(function() { + return parseTemplate('@)'); + }).toThrow(); + }); + it("parse @x()) shold throw error", function() { + return expect(function() { + return parseTemplate('@x())'); + }).toThrow(); + }); + it("should parse 'x'", function() { + return expect(parseTemplate('x')).toBe('t.transform(e.x)'); + }); + it("should parse 'x!y'", function() { + return expect(parseTemplate('x!y')).toBe('t.transform(e.x),t.transform(e.y)'); + }); + it("should parse '@if_(x!y)'", function() { + return expect(parseTemplate('@if_(x!y)')).toBe('t.if_(t.transform(e.x),t.transform(e.y))'); + }); + it("should parse '@if_(x!!!y)'", function() { + return expect(parseTemplate('@if_(x!!!y)')).toBe('t.if_(t.transform(e.x),"!",t.transform(e.y))'); + }); + it("should parse '@x", function() { + return expect(parseTemplate('@x')).toBe('t.x'); + }); + it("should parse '@x@y", function() { + return expect(parseTemplate('@x@y')).toBe('t.x,t.y'); + }); + it("should parsen !)", function() { + return expect(parseTemplate('!)')).toBe('")"'); + }); + it("should parsen ;23445", function() { + return expect(parseTemplate(';23445')).toBe('";23445"'); + }); + it("should parsen ;23445qwe", function() { + return expect(parseTemplate(';23445qwe')).toBe('";23445",t.transform(e.qwe)'); + }); + it("should parsen ;23445!qwe", function() { + return expect(parseTemplate(';23445!qwe')).toBe('";23445qwe"'); + }); + it("should parsen ;23445!!qwe", function() { + return expect(parseTemplate(';23445!!qwe')).toBe('";23445!",t.transform(e.qwe)'); + }); + it("should parsen @whileLoop(!while @paren(item)\n@block(body))", function() { + return expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe("t.whileLoop(\"while \",t.paren(t.transform(e.item)),\"\\n\",t.block(t.transform(e.body)))"); + }); + it('should parse "value"', function() { + return expect(parseTemplate('"value"')).toBe('\'"\',t.transform(e.value),\'"\''); + }); + it("should parse @array(items)", function() { + return expect(parseTemplate('@array(items)')).toBe('t.array(t.transform(e.items))'); + }); + it("should parse @if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))", function() { + return expect(parseTemplate('@if_(!if @paren(test)\n@block(then_)@may(\n!else @block(else_)))')).toBe('t.if_("if ",t.paren(t.transform(e.test)),"\\n",t.block(t.transform(e.then_)),t.may("\\nelse ",t.block(t.transform(e.else_))))'); + }); + it("should parse '@forInLoop(!for @paren(item !in range)\n@block(body))'", function() { + return expect(parseTemplate('@forInLoop(!for @paren(item !in range)\n@block(body))')).toBe('t.forInLoop("for ",t.paren(t.transform(e.item)," in ",t.transform(e.range)),"\\n",t.block(t.transform(e.body)))'); + }); + it("should parse @whileLoop(!while @paren(item)\n@block(body))", function() { + return expect(parseTemplate('@whileLoop(!while @paren(item)\n@block(body))')).toBe('t.whileLoop("while ",t.paren(t.transform(e.item)),"\\n",t.block(t.transform(e.body)))'); + }); + it("should parse @tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))", function() { + return expect(parseTemplate('@tryCatch(!try @block(test)\ncatcher@may(\n!finally @block(final)))')).toBe('t.tryCatch("try ",t.block(t.transform(e.test)),"\\n",t.transform(e.catcher),t.may("\\nfinally ",t.block(t.transform(e.final))))'); + }); + it("should parsen !catch @paren(variable@may(!if test))@block(\nbody)", function() { + return expect(parseTemplate('!catch @paren(variable@may(!if test))@block(\nbody)')).toBe('"catch ",t.paren(t.transform(e.variable),t.may("if ",t.transform(e.test))),t.block("\\n",t.transform(e.body))'); + }); + it("should parsen !throw value", function() { + return expect(parseTemplate('!throw value')).toBe('"throw ",t.transform(e.value)'); + }); + it("should parsen caller@paren(@list(args))", function() { + return expect(parseTemplate('caller@paren(@list(args))')).toBe('t.transform(e.caller),t.paren(t.list(t.transform(e.args)))'); + }); + it("should parsen !var @list(vars)", function() { + return expect(parseTemplate('left = right')).toBe('t.transform(e.left)," = ",t.transform(e.right)'); + }); + it("left @op(operator) = right", function() { + return expect(parseTemplate('left @op(operator) = right')).toBe('t.transform(e.left)," ",t.op(t.transform(e.operator))," = ",t.transform(e.right)'); + }); + it("should parsen @switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))", function() { + return expect(parseTemplate('@switch_(!switch @paren(expression) \n@block(@list(cases @empty)) @may(\n!default: @block(else)))')).toBe('t.switch_("switch ",t.paren(t.transform(e.expression))," \\n",t.block(t.list(t.transform(e.cases)," ",t.empty))," ",t.may("\\ndefault: ",t.block(t.transform(e.else))))'); + }); + return it("!case test: \n@block(body)", function() { + return expect(parseTemplate('!case test: \n@block(body)')).toBe('"case ",t.transform(e.test),": \\n",t.block(t.transform(e.body))'); + }); +}); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/test/karma/testlogicparser.js b/js/test/karma/testlogicparser.js new file mode 100644 index 0000000..6c8e62e --- /dev/null +++ b/js/test/karma/testlogicparser.js @@ -0,0 +1,131 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/test/karma/testlogicparser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var Parser, Trail, cons, uarray, uobject, vari, _ref, + __slice = [].slice; + +_ref = require('../../logicparser'), vari = _ref.vari, cons = _ref.cons, uobject = _ref.uobject, uarray = _ref.uarray, Trail = _ref.Trail, Parser = _ref.Parser; + +describe('logicparser', function() { + var orp, unify; + orp = unify = null; + beforeEach(function() { + var parser; + parser = new Parser; + parser.trail = new Trail; + unify = function(x, y) { + return parser.unify(x, y); + }; + return orp = function() { + var items; + items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return parser.orp.apply(parser, items)(); + }; + }); + it("should unify 1 1", function() { + return expect(unify(1, 1)).toBe(true); + }); + it("should unify 1 2", function() { + return expect(unify(1, 2)).toBe(false); + }); + it("should unify logicvar", function() { + return expect(unify(vari(), 1)).toBe(true); + }); + it("should sequential unify logicvar", function() { + var $a; + return expect(($a = vari()) && unify($a, 1) && unify($a, 2)).toBe(false); + }); + it("should unify logicvar with backtracking", function() { + var $a; + return expect(($a = vari()) && orp((function() { + return unify($a, 1) && unify($a, 2); + }), function() { + return unify($a, 2); + })).toBe(true); + }); + it("should unify cons 1", function() { + return expect(unify(cons(1, null), cons(1, null))).toBe(true); + }); + it("should unify cons 2", function() { + return expect(unify(cons(vari(), null), cons(1, null))).toBe(true); + }); + it("should unify cons 3", function() { + var $a; + return expect(($a = vari()) && unify(cons($a, null), cons(1, null)) && unify($a, 2)).toBe(false); + }); + it("should unify cons 4", function() { + var $a; + return expect(($a = vari()) && orp((function() { + return unify(cons($a, null), cons(1, null)) && unify($a, 2); + }), function() { + return unify($a, 2); + })).toBe(true); + }); + it("should unify uobject 1", function() { + return expect(unify(uobject({ + a: 1 + }), { + a: 1 + })).toBe(true); + }); + it("should unify uobject 2", function() { + return expect(unify(uobject({ + a: 1 + }), { + a: 2 + })).toBe(false); + }); + it("should unify uobject 3", function() { + return expect(unify(uobject({ + a: vari() + }), { + a: 1 + })).toBe(true); + }); + it("should unify uobject 4", function() { + var $a; + return expect(($a = vari()) && unify(uobject({ + a: $a + }), { + a: 1 + }) && unify($a, 2)).toBe(false); + }); + it("should unify uobject 5", function() { + var $a; + return expect(($a = vari()) && orp((function() { + return unify(uobject({ + a: $a + }), { + a: 1 + }) && unify($a, 2); + }), function() { + return unify($a, 2); + })).toBe(true); + }); + it("should unify array, uarray 1", function() { + return expect(unify([], [])).toBe(false); + }); + it("should unify array, uarray 2", function() { + return expect(unify(uarray([]), [])).toBe(true); + }); + it("should unify array, uarray 3", function() { + return expect(unify(uarray([vari()]), [])).toBe(false); + }); + it("should unify array, uarray 4", function() { + return expect(unify(uarray([vari()]), [1])).toBe(true); + }); + it("should unify array, uarray 5", function() { + var $a; + return expect(($a = vari()) && unify(uarray([$a]), [1]) && unify($a, 2)).toBe(false); + }); + return it("should unify array, uarray 6", function() { + var $a; + return expect(($a = vari()) && orp((function() { + return unify(uarray([$a]), [1]) && unify($a, 2); + }), function() { + return unify($a, 2); + })).toBe(true); + }); +}); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/test/karma/testlogicpeasy.js b/js/test/karma/testlogicpeasy.js deleted file mode 100644 index 2dfa028..0000000 --- a/js/test/karma/testlogicpeasy.js +++ /dev/null @@ -1,132 +0,0 @@ -var exports, module, require, _ref, - __slice = [].slice; - -if (typeof window === 'object') { - _ref = twoside('/test/karma/testlogicpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var Parser, Trail, cons, uarray, uobject, vari, _ref1; - _ref1 = require('../../logicpeasy'), vari = _ref1.vari, cons = _ref1.cons, uobject = _ref1.uobject, uarray = _ref1.uarray, Trail = _ref1.Trail, Parser = _ref1.Parser; - return describe('logicpeasy', function() { - var orp, unify; - orp = unify = null; - beforeEach(function() { - var parser; - parser = new Parser; - parser.trail = new Trail; - unify = function(x, y) { - return parser.unify(x, y); - }; - return orp = function() { - var items; - items = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return parser.orp.apply(parser, items)(); - }; - }); - it("should unify 1 1", function() { - return expect(unify(1, 1)).toBe(true); - }); - it("should unify 1 2", function() { - return expect(unify(1, 2)).toBe(false); - }); - it("should unify logicvar", function() { - return expect(unify(vari(), 1)).toBe(true); - }); - it("should sequential unify logicvar", function() { - var $a; - return expect(($a = vari()) && unify($a, 1) && unify($a, 2)).toBe(false); - }); - it("should unify logicvar with backtracking", function() { - var $a; - return expect(($a = vari()) && orp((function() { - return unify($a, 1) && unify($a, 2); - }), function() { - return unify($a, 2); - })).toBe(true); - }); - it("should unify cons 1", function() { - return expect(unify(cons(1, null), cons(1, null))).toBe(true); - }); - it("should unify cons 2", function() { - return expect(unify(cons(vari(), null), cons(1, null))).toBe(true); - }); - it("should unify cons 3", function() { - var $a; - return expect(($a = vari()) && unify(cons($a, null), cons(1, null)) && unify($a, 2)).toBe(false); - }); - it("should unify cons 4", function() { - var $a; - return expect(($a = vari()) && orp((function() { - return unify(cons($a, null), cons(1, null)) && unify($a, 2); - }), function() { - return unify($a, 2); - })).toBe(true); - }); - it("should unify uobject 1", function() { - return expect(unify(uobject({ - a: 1 - }), { - a: 1 - })).toBe(true); - }); - it("should unify uobject 2", function() { - return expect(unify(uobject({ - a: 1 - }), { - a: 2 - })).toBe(false); - }); - it("should unify uobject 3", function() { - return expect(unify(uobject({ - a: vari() - }), { - a: 1 - })).toBe(true); - }); - it("should unify uobject 4", function() { - var $a; - return expect(($a = vari()) && unify(uobject({ - a: $a - }), { - a: 1 - }) && unify($a, 2)).toBe(false); - }); - it("should unify uobject 5", function() { - var $a; - return expect(($a = vari()) && orp((function() { - return unify(uobject({ - a: $a - }), { - a: 1 - }) && unify($a, 2); - }), function() { - return unify($a, 2); - })).toBe(true); - }); - it("should unify array, uarray 1", function() { - return expect(unify([], [])).toBe(false); - }); - it("should unify array, uarray 2", function() { - return expect(unify(uarray([]), [])).toBe(true); - }); - it("should unify array, uarray 3", function() { - return expect(unify(uarray([vari()]), [])).toBe(false); - }); - it("should unify array, uarray 4", function() { - return expect(unify(uarray([vari()]), [1])).toBe(true); - }); - it("should unify array, uarray 5", function() { - var $a; - return expect(($a = vari()) && unify(uarray([$a]), [1]) && unify($a, 2)).toBe(false); - }); - return it("should unify array, uarray 6", function() { - var $a; - return expect(($a = vari()) && orp((function() { - return unify(uarray([$a]), [1]) && unify($a, 2); - }), function() { - return unify($a, 2); - })).toBe(true); - }); - }); -})(require, exports, module); diff --git a/js/test/karma/testparser.js b/js/test/karma/testparser.js new file mode 100644 index 0000000..0b9dd8e --- /dev/null +++ b/js/test/karma/testparser.js @@ -0,0 +1,247 @@ +// wrap lines by gulp-twoside for providing twoside module +var exports, module, require, ts; +if (typeof window === 'object') { ts = twoside('peasy/test/karma/testparser.js'), require = ts.require, exports = ts.exports, module = ts.module;} +(function(require, exports, module) { +var peasy, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +peasy = require('../../index.js'); + +describe("run testparser:", function() { + return it('', function() {}); +}); + +describe("peasy", function() { + it("should parse with A: Ax|a", function() { + var Parser, parse, parser; + Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var a, x; + Parser.__super__.constructor.apply(this, arguments); + a = this.char('a'); + x = this.char('x'); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = _this.A()) && x() && m + 'x' || m; + }; + })(this)), a)); + } + + return Parser; + + })(peasy.Parser); + parser = new Parser(); + parse = function(text) { + return parser.parse(text, parser.A); + }; + expect(parse('a')).toBe('a'); + expect(parse('ax')).toBe('ax'); + expect(parse('axx')).toBe('axx'); + return expect(parse('axxx')).toBe('axxx'); + }); + it("should parse with A: Bx|a; B:A|b", function() { + var Parser, parse, parser; + Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var B, a, b, x; + Parser.__super__.constructor.apply(this, arguments); + a = this.char('a'); + b = this.char('b'); + x = this.char('x'); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); + B = this.rec(this.orp(this.A, b)); + } + + return Parser; + + })(peasy.Parser); + parser = new Parser(); + parse = function(text) { + return parser.parse(text, parser.A); + }; + expect(parse('a')).toBe('a'); + expect(parse('ax')).toBe('ax'); + expect(parse('axx')).toBe('axx'); + expect(parse('axxx')).toBe('axxx'); + expect(parse('b')).toBe('b'); + expect(parse('bx')).toBe('bx'); + expect(parse('bxxx')).toBe('bxxx'); + expect(parse('bxg')).toBe('bx'); + expect(parse('bxxg')).toBe('bxx'); + expect(parse('bxxxg')).toBe('bxxx'); + expect(parse('fg')).toBe(void 0); + return expect(parse('')).toBe(void 0); + }); + it("should parse with A: Bx|a; B:C; C:A|b", function() { + var Parser, parse, parser; + Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var B, C, a, b, x; + Parser.__super__.constructor.apply(this, arguments); + a = this.char('a'); + b = this.char('b'); + x = this.char('x'); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); + B = this.rec(function() { + return C(); + }); + C = this.rec(this.orp(this.A, b)); + } + + return Parser; + + })(peasy.Parser); + parser = new Parser(); + parse = function(text) { + return parser.parse(text, parser.A); + }; + expect(parse('a')).toBe('a'); + expect(parse('ax')).toBe('ax'); + expect(parse('axx')).toBe('axx'); + expect(parse('axxx')).toBe('axxx'); + expect(parse('b')).toBe('b'); + expect(parse('bx')).toBe('bx'); + expect(parse('bxxx')).toBe('bxxx'); + expect(parse('bxg')).toBe('bx'); + expect(parse('bxxg')).toBe('bxx'); + expect(parse('bxxxg')).toBe('bxxx'); + expect(parse('fg')).toBe(void 0); + return expect(parse('')).toBe(void 0); + }); + it("should parse with A: Bx|a; B:C|Ay; C:A|b", function() { + var Parser, parse, parser; + Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var B, C, a, b, x, y; + Parser.__super__.constructor.apply(this, arguments); + a = this.char('a'); + b = this.char('b'); + x = this.char('x'); + y = this.char('y'); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); + B = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = _this.A()) && y() && m + 'y'; + }; + })(this)), function() { + return C(); + })); + C = this.rec(this.orp(this.A, b)); + } + + return Parser; + + })(peasy.Parser); + parser = new Parser(); + parse = function(text) { + return parser.parse(text, parser.A); + }; + expect(parse('a')).toBe('a'); + expect(parse('ax')).toBe('ax'); + expect(parse('axx')).toBe('axx'); + expect(parse('axxx')).toBe('axxx'); + expect(parse('ay')).toBe('ay'); + expect(parse('ayx')).toBe('ayx'); + expect(parse('ayxyx')).toBe('ayxyx'); + expect(parse('bxx')).toBe('bxx'); + expect(parse('ayxxx')).toBe('ayxxx'); + expect(parse('ayxmxx')).toBe('ayx'); + expect(parse('b')).toBe('b'); + expect(parse('bx')).toBe('bx'); + expect(parse('bxxx')).toBe('bxxx'); + expect(parse('bxg')).toBe('bx'); + expect(parse('bxxg')).toBe('bxx'); + expect(parse('bxxxg')).toBe('bxxx'); + expect(parse('fg')).toBe(void 0); + return expect(parse('')).toBe(void 0); + }); + return it("should parse with Root: Az; A: Bx|a; B:C|Ay; C:A|b", function() { + var Parser, parse, parser; + Parser = (function(_super) { + __extends(Parser, _super); + + function Parser() { + var B, C, a, b, x, y, z; + Parser.__super__.constructor.apply(this, arguments); + a = this.char('a'); + b = this.char('b'); + x = this.char('x'); + y = this.char('y'); + z = this.char('z'); + this.root = (function(_this) { + return function() { + var m; + return (m = _this.A()) && z() && m + 'z'; + }; + })(this); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); + B = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = _this.A()) && y() && m + 'y'; + }; + })(this)), function() { + return C(); + })); + C = this.rec(this.orp(this.A, b)); + } + + return Parser; + + })(peasy.Parser); + parser = new Parser(); + parse = function(text) { + return parser.parse(text); + }; + expect(parse('az')).toBe('az'); + expect(parse('axz')).toBe('axz'); + expect(parse('axxz')).toBe('axxz'); + expect(parse('axxxz')).toBe('axxxz'); + expect(parse('ayz')).toBe('ayz'); + expect(parse('ayxz')).toBe('ayxz'); + expect(parse('ayxyxz')).toBe('ayxyxz'); + expect(parse('bxxz')).toBe('bxxz'); + expect(parse('ayxxxz')).toBe('ayxxxz'); + expect(parse('ayxmxxz')).toBe(void 0); + expect(parse('bz')).toBe('bz'); + expect(parse('bxz')).toBe('bxz'); + expect(parse('bxxxz')).toBe('bxxxz'); + expect(parse('bxgz')).toBe(void 0); + expect(parse('bxxgz')).toBe(void 0); + expect(parse('bxxxgz')).toBe(void 0); + expect(parse('fg')).toBe(void 0); + return expect(parse('')).toBe(void 0); + }); +}); +})(require, exports, module); // wrap line by gulp-twoside \ No newline at end of file diff --git a/js/test/karma/testpeasy.js b/js/test/karma/testpeasy.js deleted file mode 100644 index 5775729..0000000 --- a/js/test/karma/testpeasy.js +++ /dev/null @@ -1,236 +0,0 @@ -var exports, module, require, _ref, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - -if (typeof window === 'object') { - _ref = twoside('/test/karma/testpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; -} - -(function(require, exports, module) { - var peasy; - peasy = require('../../peasy'); - describe("run testpeasy:", function() { - return it('', function() {}); - }); - return describe("peasy", function() { - it("should parse with A: Ax|a", function() { - var Parser, parse, parser; - Parser = (function(_super) { - __extends(Parser, _super); - - function Parser() { - var a, x, - _this = this; - Parser.__super__.constructor.apply(this, arguments); - a = this.char('a'); - x = this.char('x'); - this.A = this.rec(this.orp((function() { - var m; - return (m = _this.A()) && x() && m + 'x' || m; - }), a)); - } - - return Parser; - - })(peasy.Parser); - parser = new Parser(); - parse = function(text) { - return parser.parse(text, parser.A); - }; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - return expect(parse('axxx')).toBe('axxx'); - }); - it("should parse with A: Bx|a; B:A|b", function() { - var Parser, parse, parser; - Parser = (function(_super) { - __extends(Parser, _super); - - function Parser() { - var B, a, b, x, - _this = this; - Parser.__super__.constructor.apply(this, arguments); - a = this.char('a'); - b = this.char('b'); - x = this.char('x'); - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); - B = this.rec(this.orp(this.A, b)); - } - - return Parser; - - })(peasy.Parser); - parser = new Parser(); - parse = function(text) { - return parser.parse(text, parser.A); - }; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - it("should parse with A: Bx|a; B:C; C:A|b", function() { - var Parser, parse, parser; - Parser = (function(_super) { - __extends(Parser, _super); - - function Parser() { - var B, C, a, b, x, - _this = this; - Parser.__super__.constructor.apply(this, arguments); - a = this.char('a'); - b = this.char('b'); - x = this.char('x'); - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); - B = this.rec(function() { - return C(); - }); - C = this.rec(this.orp(this.A, b)); - } - - return Parser; - - })(peasy.Parser); - parser = new Parser(); - parse = function(text) { - return parser.parse(text, parser.A); - }; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - it("should parse with A: Bx|a; B:C|Ay; C:A|b", function() { - var Parser, parse, parser; - Parser = (function(_super) { - __extends(Parser, _super); - - function Parser() { - var B, C, a, b, x, y, - _this = this; - Parser.__super__.constructor.apply(this, arguments); - a = this.char('a'); - b = this.char('b'); - x = this.char('x'); - y = this.char('y'); - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); - B = this.rec(this.orp((function() { - var m; - return (m = _this.A()) && y() && m + 'y'; - }), function() { - return C(); - })); - C = this.rec(this.orp(this.A, b)); - } - - return Parser; - - })(peasy.Parser); - parser = new Parser(); - parse = function(text) { - return parser.parse(text, parser.A); - }; - expect(parse('a')).toBe('a'); - expect(parse('ax')).toBe('ax'); - expect(parse('axx')).toBe('axx'); - expect(parse('axxx')).toBe('axxx'); - expect(parse('ay')).toBe('ay'); - expect(parse('ayx')).toBe('ayx'); - expect(parse('ayxyx')).toBe('ayxyx'); - expect(parse('bxx')).toBe('bxx'); - expect(parse('ayxxx')).toBe('ayxxx'); - expect(parse('ayxmxx')).toBe('ayx'); - expect(parse('b')).toBe('b'); - expect(parse('bx')).toBe('bx'); - expect(parse('bxxx')).toBe('bxxx'); - expect(parse('bxg')).toBe('bx'); - expect(parse('bxxg')).toBe('bxx'); - expect(parse('bxxxg')).toBe('bxxx'); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - return it("should parse with Root: Az; A: Bx|a; B:C|Ay; C:A|b", function() { - var Parser, parse, parser; - Parser = (function(_super) { - __extends(Parser, _super); - - function Parser() { - var B, C, a, b, x, y, z, - _this = this; - Parser.__super__.constructor.apply(this, arguments); - a = this.char('a'); - b = this.char('b'); - x = this.char('x'); - y = this.char('y'); - z = this.char('z'); - this.root = function() { - var m; - return (m = _this.A()) && z() && m + 'z'; - }; - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); - B = this.rec(this.orp((function() { - var m; - return (m = _this.A()) && y() && m + 'y'; - }), function() { - return C(); - })); - C = this.rec(this.orp(this.A, b)); - } - - return Parser; - - })(peasy.Parser); - parser = new Parser(); - parse = function(text) { - return parser.parse(text); - }; - expect(parse('az')).toBe('az'); - expect(parse('axz')).toBe('axz'); - expect(parse('axxz')).toBe('axxz'); - expect(parse('axxxz')).toBe('axxxz'); - expect(parse('ayz')).toBe('ayz'); - expect(parse('ayxz')).toBe('ayxz'); - expect(parse('ayxyxz')).toBe('ayxyxz'); - expect(parse('bxxz')).toBe('bxxz'); - expect(parse('ayxxxz')).toBe('ayxxxz'); - expect(parse('ayxmxxz')).toBe(void 0); - expect(parse('bz')).toBe('bz'); - expect(parse('bxz')).toBe('bxz'); - expect(parse('bxxxz')).toBe('bxxxz'); - expect(parse('bxgz')).toBe(void 0); - expect(parse('bxxgz')).toBe(void 0); - expect(parse('bxxxgz')).toBe(void 0); - expect(parse('fg')).toBe(void 0); - return expect(parse('')).toBe(void 0); - }); - }); -})(require, exports, module); diff --git a/js/test/mocha/testpeasy.js b/js/test/mocha/testparser.js similarity index 77% rename from js/test/mocha/testpeasy.js rename to js/test/mocha/testparser.js index 768ff28..40964fb 100644 --- a/js/test/mocha/testpeasy.js +++ b/js/test/mocha/testparser.js @@ -3,19 +3,19 @@ var exports, module, require, _ref, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; if (typeof window === 'object') { - _ref = twoside('/test/mocha/testpeasy'), require = _ref.require, exports = _ref.exports, module = _ref.module; + _ref = twoside('/test/mocha/testparser'), require = _ref.require, exports = _ref.exports, module = _ref.module; } (function(require, exports, module) { var chai, charset, expect, inCharset, peasy, _ref1; chai = require('chai'); expect = chai.expect; - _ref1 = peasy = require('../../peasy'), charset = _ref1.charset, inCharset = _ref1.inCharset; + _ref1 = peasy = require('../../index'), charset = _ref1.charset, inCharset = _ref1.inCharset; describe("run testpeasy:", function() { return it('', function() {}); }); describe("peasy", function() { - return it.only("charset('ab') should contain 'a'", function() { + return it("charset('ab') should contain 'a'", function() { var set; set = charset('ab'); expect(inCharset('a', set)).to.equal(true); @@ -29,15 +29,16 @@ if (typeof window === 'object') { __extends(Parser, _super); function Parser() { - var a, x, - _this = this; + var a, x; Parser.__super__.constructor.apply(this, arguments); a = this.char('a'); x = this.char('x'); - this.A = this.rec(this.orp((function() { - var m; - return (m = _this.A()) && x() && m + 'x' || m; - }), a)); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = _this.A()) && x() && m + 'x' || m; + }; + })(this)), a)); } return Parser; @@ -58,16 +59,17 @@ if (typeof window === 'object') { __extends(Parser, _super); function Parser() { - var B, a, b, x, - _this = this; + var B, a, b, x; Parser.__super__.constructor.apply(this, arguments); a = this.char('a'); b = this.char('b'); x = this.char('x'); - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); B = this.rec(this.orp(this.A, b)); } @@ -97,16 +99,17 @@ if (typeof window === 'object') { __extends(Parser, _super); function Parser() { - var B, C, a, b, x, - _this = this; + var B, C, a, b, x; Parser.__super__.constructor.apply(this, arguments); a = this.char('a'); b = this.char('b'); x = this.char('x'); - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); B = this.rec(function() { return C(); }); @@ -139,21 +142,24 @@ if (typeof window === 'object') { __extends(Parser, _super); function Parser() { - var B, C, a, b, x, y, - _this = this; + var B, C, a, b, x, y; Parser.__super__.constructor.apply(this, arguments); a = this.char('a'); b = this.char('b'); x = this.char('x'); y = this.char('y'); - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); - B = this.rec(this.orp((function() { - var m; - return (m = _this.A()) && y() && m + 'y'; - }), function() { + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); + B = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = _this.A()) && y() && m + 'y'; + }; + })(this)), function() { return C(); })); C = this.rec(this.orp(this.A, b)); @@ -191,26 +197,31 @@ if (typeof window === 'object') { __extends(Parser, _super); function Parser() { - var B, C, a, b, x, y, z, - _this = this; + var B, C, a, b, x, y, z; Parser.__super__.constructor.apply(this, arguments); a = this.char('a'); b = this.char('b'); x = this.char('x'); y = this.char('y'); z = this.char('z'); - this.root = function() { - var m; - return (m = _this.A()) && z() && m + 'z'; - }; - this.A = this.rec(this.orp((function() { - var m; - return (m = B()) && x() && m + 'x' || m; - }), a)); - B = this.rec(this.orp((function() { - var m; - return (m = _this.A()) && y() && m + 'y'; - }), function() { + this.root = (function(_this) { + return function() { + var m; + return (m = _this.A()) && z() && m + 'z'; + }; + })(this); + this.A = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = B()) && x() && m + 'x' || m; + }; + })(this)), a)); + B = this.rec(this.orp(((function(_this) { + return function() { + var m; + return (m = _this.A()) && y() && m + 'y'; + }; + })(this)), function() { return C(); })); C = this.rec(this.orp(this.A, b)); diff --git a/js/twoside.js b/js/twoside.js index c61292f..8f56b73 100644 --- a/js/twoside.js +++ b/js/twoside.js @@ -1,10 +1,7 @@ -/* modules/twoside -# make modules can be used on both server side and client side. -github.com/chaosim/twoside -npmjs.org/package/twoside -npm install twoside -*/ +/* modules/twoside + * make modules can be used on both server side and client side. + */ (function() { var getStackTrace, normalize, oldexports, oldmodule, oldrequire, twoside; oldrequire = window.require; @@ -17,28 +14,34 @@ npm install twoside return obj.stack; }; twoside = window.twoside = function(path) { - var exports, module, modulePath, require; + var exports, filename, module, modulePath, require; window.require = oldrequire; window.exports = oldexports; window.module = oldmodule; - path = normalize(path); + path = normalize(path).slice(0, path.lastIndexOf(".")); + modulePath = path.slice(0, path.lastIndexOf("/")); + filename = path.slice(path.lastIndexOf("/") + 1); exports = {}; module = twoside._modules[path] = { exports: exports }; - modulePath = path.slice(0, path.lastIndexOf("/") + 1); + if (filename === 'index') { + twoside._modules[modulePath] = module; + } require = function(path) { - module = twoside._modules[path]; - if (module) { - return module; + var requiredModule; + requiredModule = twoside._modules[path]; + if (requiredModule) { + return requiredModule; } - path = normalize(modulePath + path); - module = twoside._modules[path]; - if (!module) { + path = path.slice(0, path.lastIndexOf(".")); + path = normalize(modulePath + '/' + path); + requiredModule = twoside._modules[path]; + if (!requiredModule) { console.log(getStackTrace()); throw path + ' is a wrong twoside module path.'; } - return module.exports; + return requiredModule.exports; }; return { require: require, @@ -47,13 +50,12 @@ npm install twoside }; }; twoside._modules = {}; - /* we can alias some external modules.*/ + /* we can alias some external modules. */ twoside.alias = function(path, object) { return twoside._modules[path] = object; }; - /* e.g. n browser, if underscore have been imported before, we can alias it like below:*/ - + twoside.alias('lodash', _); return normalize = function(path) { var head, target, token, _i, _len, _ref; if (!path || path === '/') { @@ -69,17 +71,9 @@ npm install twoside target.push(token); } } - /* for IE 6 & 7 - use path.charAt(i), not path[i]*/ + /* for IE 6 & 7 - use path.charAt(i), not path[i] */ head = path.charAt(0) === '/' || path.charAt(0) === '.' ? '/' : ''; return head + target.join('/').replace(/[\/]{2,}/g, '/'); }; })(); - -/* javascript sample -if (typeof window==='object'){ var m = twoside('/module1'), exports= m.exports, module = m.module, require = m.module; } -(function(require, exports, module){ - // wrapped module definition -})(require, exports, module); -*/ - diff --git a/js/twoside.min.js b/js/twoside.min.js deleted file mode 100644 index 5921199..0000000 --- a/js/twoside.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){var getStackTrace,normalize,oldexports,oldmodule,oldrequire,twoside;return oldrequire=window.require,oldexports=window.exports,oldmodule=window.module,getStackTrace=function(){var obj;return obj={},Error.captureStackTrace(obj,getStackTrace),obj.stack},twoside=window.twoside=function(path){var exports,module,modulePath,require;return window.require=oldrequire,window.exports=oldexports,window.module=oldmodule,path=normalize(path),exports={},module=twoside._modules[path]={exports:exports},modulePath=path.slice(0,path.lastIndexOf("/")+1),require=function(path){if(module=twoside._modules[path])return module;if(path=normalize(modulePath+path),module=twoside._modules[path],!module)throw console.log(getStackTrace()),path+" is a wrong twoside module path.";return module.exports},{require:require,exports:exports,module:module}},twoside._modules={},twoside.alias=function(path,object){return twoside._modules[path]=object},normalize=function(path){var head,target,token,_i,_len,_ref;if(!path||"/"===path)return"/";for(target=[],_ref=path.split("/"),_i=0,_len=_ref.length;_len>_i;_i++)token=_ref[_i],".."===token?target.pop():""!==token&&"."!==token&&target.push(token);return head="/"===path.charAt(0)||"."===path.charAt(0)?"/":"",head+target.join("/").replace(/[\/]{2,}/g,"/")}}(); \ No newline at end of file diff --git a/package.json b/package.json index 74bd0b8..79b95ac 100644 --- a/package.json +++ b/package.json @@ -27,14 +27,7 @@ }, "dependencies": {}, "devDependencies": { - "grunt": "~0.4.1", - "grunt-contrib-coffee": "~0.7.0", - "grunt-contrib-clean": "~0.5.0", - "grunt-contrib-watch": "~0.5.2", - "grunt-karma": "~0.6.2", - "karma-html-reporter": "~0.1.1", - "grunt-mocha-test": "~0.8.1", - "grunt-contrib-uglify": "~0.2.7" + "karma-html-reporter": "~0.1.1" }, "scripts": { "test": "grunt test"