Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implemented initial conversion into ometajsnode. ( Parsing and Interp…

…reting )

Converted core OMetaJS code using Sergey's code as example.
Added usage examples and more explanation to README.md
Implemented parsing and interpreting modes.
Created logly module to handle logging and debug/verbose modes
Changed vesion to 0.1.0
  • Loading branch information...
commit 909b0adfb34db5ce7427f3e9a0063fc541f79e7c 1 parent 0b0e599
@tristanls authored
Showing with 1,880 additions and 7,466 deletions.
  1. +0 −48 Not_Quite_JS.txt
  2. +0 −150 OMeta_Tutorial.txt
  3. +0 −624 OMeta_WJS.wjs
  4. +0 −110 OMeta_WJS_Mods.js
  5. +58 −0 README.md
  6. +0 −149 Things_You_Should_Know.txt
  7. +0 −112 Worlds2.js
  8. +0 −311 Worlds2_Library.js
  9. +0 −35 arrays.wjs
  10. +177 −0 bin/ometajsnode
  11. +2 −0  bin/output.file
  12. +0 −211 bs-js-compiler.txt
  13. +0 −124 bs-ometa-compiler.txt
  14. +0 −9 bs-ometa-js-compiler.txt
  15. +0 −93 bs-ometa-optimizer.txt
  16. +0 −3  bs-project-list-parser.js
  17. +0 −5 bs-project-list-parser.txt
  18. +14 −0 examples/grammar_and_interpreter.ometajs
  19. +12 −0 examples/grammar_only.ometajs
  20. +14 −0 examples/grammar_to_ir.ometajs
  21. +7 −0 examples/interpreter.ometajs
  22. +1 −0  examples/program.file
  23. +1 −0  examples/program2.file
  24. +0 −166 index.html
  25. +62 −0 node_modules/logly/logly.js
  26. +2 −0  node_modules/logly/package.json
  27. +1 −1  { → node_modules/ometajsnode/lib}/bs-js-compiler.js
  28. +1 −1  { → node_modules/ometajsnode/lib}/bs-ometa-compiler.js
  29. +1 −1  { → node_modules/ometajsnode/lib}/bs-ometa-js-compiler.js
  30. +1 −1  { → node_modules/ometajsnode/lib}/bs-ometa-optimizer.js
  31. +77 −77 { → node_modules/ometajsnode/lib}/lib.js
  32. +219 −220 { → node_modules/ometajsnode/lib}/ometa-base.js
  33. +10 −11 { → node_modules/ometajsnode/lib}/parser.js
  34. +932 −0 node_modules/ometajsnode/ometajs/ometajs.js
  35. +286 −0 node_modules/ometajsnode/ometajsnode.js
  36. +2 −0  node_modules/ometajsnode/package.json
  37. +0 −19 ometa-rhino.js
  38. +0 −21 ometa-script-tag.js
  39. +0 −2  oshell
  40. +0 −91 prototype-fix.js
  41. +0 −4,222 prototype.js
  42. +0 −10 readme-rhino.txt
  43. +0 −21 standalone.html
  44. +0 −320 v8-shell.cc
  45. +0 −2  w2shell
  46. +0 −73 wiki.js
  47. +0 −223 workspace.js
View
48 Not_Quite_JS.txt
@@ -1,48 +0,0 @@
-The language supported in this workspace is not quite JavaScript; it is rather a (large) subset of JavaScript, extended with some
-new syntax.
-
-
-One such extension allows string literals to be written as
-
- '`' <identifier> or '#' <identifier>
-
-For example, instead of writing
- "foo"
-you can write
- `foo
-And of course,
- "foo" == `foo && `foo == #foo
-
-I did this because I think parse trees, like
- ["plus", ["lit", 2], ["lit", 5]]
-look better when you write them like this
- [`plus, [`lit, 2], [`lit, 5]]
-
-
-Another extension is that string literals, as in Smalltalk, can span multiple lines, e.g.,
-
-" this whole thing
-is a string
-yay!
-"
-
-This is useful because it lets you put an entire program into a string (I do this in the Prolog, Logo, and MetaToo projects). Keep in mind that, as in Python, you can put escape sequences inside multi-line strings. So if you want a '\' character inside one of these guys, you need to type '\\'.
-
-And because it's usually annoying to have to escape double quotes inside these big strings, you can also write multi-line string literals in Python-like syntax, e.g.,
-
-"""
-1+2
-alert("hello world")
-"""
-
-
--Alex
-
-------------------------------------------------------------------------------------------------------------------------------------
-
-Hey, Alex -- How about using a symbol that is less in one's face than "#"? What about tilde ~ or ` or underline, etc.? -- Alan
-
-Hi Alan - this is funny, because the # was inspired by ST-80, heh heh... anyway, I like the idea of using ` instead. Try it now, it works. --- Alex
-
-Hi Alex -- I have always hated that convention in ST-80 (I was not around to protest when that went in). ST-80 had the interesting problem of moving from an environment at PARC in which any glyphs desired could be authored, displayed and printed, to the "outside world" in the early 80s in which none of those things could be done. So they had to go back to ASCII conventions and this was painful. Thanks for the change. --- Alan
-
View
150 OMeta_Tutorial.txt
@@ -1,150 +0,0 @@
-// a simple recognizer, produces no useful value
-
-ometa L {
- number = digit+,
- addExpr = addExpr '+' mulExpr
- | addExpr '-' mulExpr
- | mulExpr,
- mulExpr = mulExpr '*' primExpr
- | mulExpr '/' primExpr
- | primExpr,
- primExpr = '(' expr ')'
- | number,
- expr = addExpr
-}
-
-L.matchAll('6*(4+3)', 'expr')
-
-
-
-
-
-
-// a recognizer that also interprets
-
-ometa Calc {
- digit = ^digit:d -> d.digitValue(),
- number = number:n digit:d -> (n * 10 + d)
- | digit,
- addExpr = addExpr:x '+' mulExpr:y -> (x + y)
- | addExpr:x '-' mulExpr:y -> (x - y)
- | mulExpr,
- mulExpr = mulExpr:x '*' primExpr:y -> (x * y)
- | mulExpr:x '/' primExpr:y -> (x / y)
- | primExpr,
- primExpr = '(' expr:x ')' -> x
- | number,
- expr = addExpr
-}
-
-Calc.matchAll('6**(4+3)', 'expr')
-
-
-
-
-
-
-// parser and simple interpreter combo
-
-ometa CalcParser {
- digit = ^digit:d -> d.digitValue(),
- number = number:n digit:d -> (n * 10 + d)
- | digit,
- addExpr = addExpr:x '+' mulExpr:y -> ['add', x, y]
- | addExpr:x '-' mulExpr:y -> ['sub', x, y]
- | mulExpr,
- mulExpr = mulExpr:x '*' primExpr:y -> ['mul', x, y]
- | mulExpr:x '/' primExpr:y -> ['div', x, y]
- | primExpr,
- primExpr = '(' expr:x ')' -> x
- | number:n -> ['num', n],
- expr = addExpr
-}
-
-tree = CalcParser.matchAll('6*(4+3)', 'expr')
-
-ometa CalcInterpreter {
- interp = ['num' anything:x] -> x
- | ['add' interp:x interp:y] -> (x + y)
- | ['sub' interp:x interp:y] -> (x - y)
- | ['mul' interp:x interp:y] -> (x * y)
- | ['div' interp:x interp:y] -> (x / y)
-}
-
-CalcInterpreter.match(tree, 'interp')
-
-
-
-
-
-
-
-// we can write a "compiler" instead
-
-ometa CalcCompiler {
- comp = ['num' anything:x] -> x.toString()
- | ['add' comp:x comp:y] -> ('(' + x + '+' + y + ')')
- | ['sub' comp:x comp:y] -> ('(' + x + '-' + y + ')')
- | ['mul' comp:x comp:y] -> ('(' + x + '*' + y + ')')
- | ['div' comp:x comp:y] -> ('(' + x + '/' + y + ')')
-}
-
-code = CalcCompiler.match(tree, 'comp')
-eval(code)
-
-
-
-
-
-
-
-
-
-
-
-
-// spice things up with ML-like syntax
-
-ometa CalcCompiler {
- comp ['num' anything:x] -> x.toString(),
- comp ['add' comp:x comp:y] -> ('(' + x + '+' + y + ')'),
- comp ['sub' comp:x comp:y] -> ('(' + x + '-' + y + ')'),
- comp ['mul' comp:x comp:y] -> ('(' + x + '*' + y + ')'),
- comp ['div' comp:x comp:y] -> ('(' + x + '/' + y + ')')
-}
-
-code = CalcCompiler.match(tree, 'comp')
-eval(code)
-
-
-
-
-
-
-
-
-
-
-
-
-// a neat trick: dispatch on node tags using higher-order rule "apply"
-
-ometa CalcCompiler {
- comp [anything:t apply(t):ans] -> ans,
- num anything:x -> x.toString(),
- add comp:x comp:y -> ('(' + x + '+' + y + ')'),
- sub comp:x comp:y -> ('(' + x + '-' + y + ')'),
- mul comp:x comp:y -> ('(' + x + '*' + y + ')'),
- div comp:x comp:y -> ('(' + x + '/' + y + ')')
-}
-
-code = CalcCompiler.match(tree, 'comp')
-eval(code)
-
-
-
-
-
-
-
-
View
624 OMeta_WJS.wjs
@@ -1,624 +0,0 @@
-// TODO: rewrite _apply to use worlds
-
-
-//////// lib.js
-
-/*
- Copyright (c) 2007, 2008 Alessandro Warth <awarth@cs.ucla.edu>
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-// try to use StringBuffer instead of string concatenation to improve performance
-
-function StringBuffer() {
- this.strings = []
- for (var idx = 0; idx < arguments.length; idx++)
- this.nextPutAll(arguments[idx])
-}
-StringBuffer.prototype.nextPutAll = function(s) { this.strings.push(s) }
-StringBuffer.prototype.contents = function() { return this.strings.join("") }
-String.prototype.writeStream = function() { return new StringBuffer(this) }
-
-// make Arrays print themselves sensibly
-
-Object.prototype.printOn = function(ws) { ws.nextPutAll(this.toString()) }
-
-Array.prototype.toString = function() { var ws = "".writeStream(); this.printOn(ws); return ws.contents() }
-Array.prototype.printOn = function(ws) {
- ws.nextPutAll("[")
- for (var idx = 0; idx < this.length; idx++) {
- if (idx > 0)
- ws.nextPutAll(", ")
- this[idx].printOn(ws)
- }
- ws.nextPutAll("]")
-}
-
-// delegation
-
-Object.prototype.delegated = function(props) {
- var f = function() { }
- f.prototype = this
- var r = new f()
- for (var p in props)
- if (props.hasOwn(p))
- r[p] = props[p]
- return r
-}
-
-// some reflective stuff
-
-Object.prototype.ownPropertyNames = function() {
- var r = []
- for (name in this)
- if (this.hasOwn(name))
- r.push(name)
- return r
-}
-
-Object.prototype.hasProperty = function(p) { return this[p] != undefined }
-
-Object.prototype.isNumber = function() { return false }
-Number.prototype.isNumber = function() { return true }
-
-Object.prototype.isString = function() { return false }
-String.prototype.isString = function() { return true }
-
-Object.prototype.isCharacter = function() { return false }
-
-String.prototype.isCharacter = function() { return this.length == 1 }
-String.prototype.isSpace = function() { return this.isCharacter() && this.charCodeAt(0) <= 32 }
-String.prototype.isDigit = function() { return this.isCharacter() && this >= "0" && this <= "9" }
-String.prototype.isLower = function() { return this.isCharacter() && this >= "a" && this <= "z" }
-String.prototype.isUpper = function() { return this.isCharacter() && this >= "A" && this <= "Z" }
-
-String.prototype.digitValue = function() { return this.charCodeAt(0) - "0".charCodeAt(0) }
-
-Object.prototype.isSequenceable = false
-Array.prototype.isSequenceable = true
-String.prototype.isSequenceable = true
-
-// some functional programming stuff
-
-Array.prototype.map = function(f) {
- var r = []
- for (var idx = 0; idx < this.length; idx++)
- r[idx] = f(this[idx])
- return r
-}
-
-Array.prototype.reduce = function(f, z) {
- var r = z
- for (var idx = 0; idx < this.length; idx++)
- r = f(r, this[idx])
- return r
-}
-
-Array.prototype.delimWith = function(d) {
- return this.reduce(
- function(xs, x) {
- if (xs.length > 0)
- xs.push(d)
- xs.push(x)
- return xs
- },
- [])
-}
-
-// Squeak's ReadStream, kind of
-
-function ReadStream(anArrayOrString) {
- this.src = anArrayOrString
- this.pos = 0
-}
-ReadStream.prototype.atEnd = function() { return this.pos >= this.src.length }
-ReadStream.prototype.next = function() { return this.src[this.pos++] }
-
-// escape characters
-
-escapeStringFor = new Object()
-for (var c = 0; c < 256; c++)
- escapeStringFor[c] = String.fromCharCode(c)
-escapeStringFor["\\".charCodeAt(0)] = "\\\\"
-escapeStringFor['"'.charCodeAt(0)] = '\\"'
-escapeStringFor["'".charCodeAt(0)] = "\\'"
-escapeStringFor["\r".charCodeAt(0)] = "\\r"
-escapeStringFor["\n".charCodeAt(0)] = "\\n"
-escapeStringFor["\t".charCodeAt(0)] = "\\t"
-escapeChar = function(c) {
- var charCode = c.charCodeAt(0)
- return charCode > 255 ? String.fromCharCode(charCode) : escapeStringFor[charCode]
-}
-
-function unescape(s) {
- if (s[0] == '\\')
- switch (s[1]) {
- case '\\': return '\\'
- case 'r': return '\r'
- case 'n': return '\n'
- case 't': return '\t'
- default: return s[1]
- }
- else
- return s
-}
-
-String.prototype.toProgramString = function() {
- var ws = "\"".writeStream()
- for (var idx = 0; idx < this.length; idx++)
- ws.nextPutAll(escapeChar(this[idx]))
- ws.nextPutAll("\"")
- return ws.contents()
-}
-
-// C-style tempnam function
-
-function tempnam(s) { return (s ? s : "_tmpnam_") + tempnam.n++ }
-tempnam.n = 0
-
-
-//////// ometa-base.js
-
-/*
- Copyright (c) 2007, 2008 Alessandro Warth <awarth@cs.ucla.edu>
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-/*
- new syntax:
- #foo match the string object 'foo' (should also be accepted in JS)
- 'abc' match the string object 'abc'
- 'c' match the string object 'c'
- ``abc'' match the sequence of string objects 'a', 'b', 'c'
- "abc" token('abc')
- [1 2 3] match the array object [1, 2, 3]
- foo(bar) apply rule foo with argument bar
- -> ... do semantic actions in JS (no more ST). allow multiple statements, but no declarations
- probably don't even need {}s, because newlines can terminate it!
-*/
-
-/*
-// ometa M {
-// number = number:n digit:d -> { n * 10 + d.digitValue() }
-// | digit:d -> { d.digitValue() }.
-// }
-
-try {
- M = OMeta.delegated({
- number: function() {
- var $elf = this
- return $elf._or(
- function() {
- var n, d
- n = $elf._apply("number")
- d = $elf._apply("digit")
- return n * 10 + d.digitValue()
- },
- function() {
- var d
- d = $elf._apply("digit")
- return d.digitValue()
- }
- )
- }
- })
- M.matchAll("123456789", "number")
-} catch (f) { alert(f) }
-*/
-
-// the failure exception
-
-fail = { toString: function() { return "match failed" } }
-
-// streams and memoization
-
-function OMInputStream(hd, tl) {
- this.memo = { }
- this.hd = hd
- this.tl = tl
-}
-OMInputStream.prototype.head = function() { return this.hd }
-OMInputStream.prototype.tail = function() { return this.tl }
-
-function OMInputStreamEnd() { this.memo = { } }
-OMInputStreamEnd.prototype.head = function() { throw fail }
-OMInputStreamEnd.prototype.tail = function() { throw fail }
-
-Array.prototype.toOMInputStream = function() { return makeArrayOMInputStream(this, 0) }
-String.prototype.toOMInputStream = Array.prototype.toOMInputStream
-
-function makeArrayOMInputStream(arr, idx) { return idx < arr.length ? new ArrayOMInputStream(arr, idx) : new OMInputStreamEnd() }
-
-function ArrayOMInputStream(arr, idx) {
- this.memo = { }
- this.arr = arr
- this.idx = idx
- this.hd = arr[idx]
-}
-ArrayOMInputStream.prototype.head = function() { return this.hd }
-ArrayOMInputStream.prototype.tail = function() {
- if (this.tl == undefined)
- this.tl = makeArrayOMInputStream(this.arr, this.idx + 1)
- return this.tl
-}
-
-function makeOMInputStreamProxy(target) {
- return target.delegated({
- memo: { },
- target: target,
- tail: function() { return makeOMInputStreamProxy(target.tail()) }
- })
-}
-
-// Failer (i.e., that which makes things fail) is used to detect (direct) left recursion and memoize failures
-
-function Failer() { }
-Failer.prototype.used = false
-
-// the OMeta "class" and basic functionality
-
-OMeta = {
- _apply: function(rule) {
- var memoRec = this.input.memo[rule]
- if (memoRec == undefined) {
- var origInput = this.input,
- failer = new Failer()
- this.input.memo[rule] = failer
- this.input.memo[rule] = memoRec = {ans: this[rule].apply(this), nextInput: this.input}
- if (failer.used) {
- var sentinel = this.input
- while (true) {
- try {
- this.input = origInput
- var ans = this[rule].apply(this)
- if (this.input == sentinel)
- throw fail
- memoRec.ans = ans
- memoRec.nextInput = this.input
- }
- catch (f) {
- if (f != fail)
- throw f
- break
- }
- }
- }
- }
- else if (memoRec instanceof Failer) {
- memoRec.used = true
- throw fail
- }
- this.input = memoRec.nextInput
- return memoRec.ans
- },
-
- // note: _applyWithArgs and _superApplyWithArgs are not memoized, so they can't be left-recursive
- _applyWithArgs: function(rule) {
- for (var idx = arguments.length - 1; idx > 0; idx--)
- this.input = new OMInputStream(arguments[idx], this.input)
- return this[rule].apply(this)
- },
- _superApplyWithArgs: function($elf, rule) {
- for (var idx = arguments.length - 1; idx > 1; idx--)
- $elf.input = new OMInputStream(arguments[idx], $elf.input)
- return this[rule].apply($elf)
- },
- _pred: function(b) {
- if (b)
- return true
- throw fail
- },
- _not: function(x) {
- var origInput = this.input
- try { x() }
- catch (f) {
- if (f != fail)
- throw f
- this.input = origInput
- return true
- }
- throw fail
- },
- _lookahead: function(x) {
- var origInput = this.input,
- r = x()
- this.input = origInput
- return r
- },
- _or: function() {
- var origInput = this.input
- for (var idx = 0; idx < arguments.length; idx++)
- try { this.input = origInput; return arguments[idx]() }
- catch (f) {
- if (f != fail)
- throw f
- }
- throw fail
- },
- _many: function(x) {
- var ans = arguments[1] != undefined ? [arguments[1]] : []
- while (true) {
- var origInput = this.input
- try { ans.push(x()) }
- catch (f) {
- if (f != fail)
- throw f
- this.input = origInput
- break
- }
- }
- return ans
- },
- _many1: function(x) { return this._many(x, x()) },
- _form: function(x) {
- var v = this._apply("anything")
- if (!v.isSequenceable)
- throw fail
- var origInput = this.input
- this.input = makeArrayOMInputStream(v, 0)
- var r = x()
- this._apply("end")
- this.input = origInput
- return v
- },
-
- // some basic rules
- anything: function() {
- var r = this.input.head()
- this.input = this.input.tail()
- return r
- },
- end: function() {
- var $elf = this
- return this._not(function() { return $elf._apply("anything") })
- },
- pos: function() {
- return this.input.idx
- },
- empty: function() { return true },
- apply: function() {
- var r = this._apply("anything")
- return this._apply(r)
- },
- foreign: function() {
- var g = this._apply("anything"),
- r = this._apply("anything"),
- gi = g.delegated({input: makeOMInputStreamProxy(this.input)})
- var ans = gi._apply(r)
- this.input = gi.input.target
- return ans
- },
-
- // some useful "derived" rules
- exactly: function() {
- var wanted = this._apply("anything")
- if (wanted === this._apply("anything"))
- return wanted
- throw fail
- },
- "true": function() {
- var r = this._apply("anything")
- this._pred(r == true)
- return r
- },
- "false": function() {
- var r = this._apply("anything")
- this._pred(r == false)
- return r
- },
- "undefined": function() {
- var r = this._apply("anything")
- this._pred(r == undefined)
- return r
- },
- number: function() {
- var r = this._apply("anything")
- this._pred(r.isNumber())
- return r
- },
- string: function() {
- var r = this._apply("anything")
- this._pred(r.isString())
- return r
- },
- "char": function() {
- var r = this._apply("anything")
- this._pred(r.isCharacter())
- return r
- },
- space: function() {
- var r = this._apply("char")
- this._pred(r.charCodeAt(0) <= 32)
- return r
- },
- spaces: function() {
- var $elf = this
- return this._many(function() { return $elf._apply("space") })
- },
- digit: function() {
- var r = this._apply("char")
- this._pred(r.isDigit())
- return r
- },
- lower: function() {
- var r = this._apply("char")
- this._pred(r.isLower())
- return r
- },
- upper: function() {
- var r = this._apply("char")
- this._pred(r.isUpper())
- return r
- },
- letter: function() {
- var $elf = this
- return this._or(function() { return $elf._apply("lower") },
- function() { return $elf._apply("upper") })
- },
- letterOrDigit: function() {
- var $elf = this
- return this._or(function() { return $elf._apply("letter") },
- function() { return $elf._apply("digit") })
- },
- firstAndRest: function() {
- var $elf = this,
- first = this._apply("anything"),
- rest = this._apply("anything")
- return this._many(function() { return $elf._apply(rest) }, this._apply(first))
- },
- seq: function() {
- var xs = this._apply("anything")
- for (var idx = 0; idx < xs.length; idx++)
- this._applyWithArgs("exactly", xs[idx])
- return xs
- },
- notLast: function() {
- var $elf = this,
- rule = this._apply("anything"),
- r = this._apply(rule)
- this._lookahead(function() { return $elf._apply(rule) })
- return r
- },
-
- initialize: function() { },
- // match and matchAll are a grammar's "public interface"
- _genericMatch: function(input, rule, args, matchFailed) {
- if (args == undefined)
- args = []
- var realArgs = [rule]
- for (var idx = 0; idx < args.length; idx++)
- realArgs.push(args[idx])
- var m = this.delegated({input: input})
- m.initialize()
- try { return realArgs.length == 1 ? m._apply.call(m, realArgs[0]) : m._applyWithArgs.apply(m, realArgs) }
- catch (f) {
- if (f == fail && matchFailed != undefined) {
- var input = m.input
- if (input.idx != undefined) {
- while (input.tl != undefined && input.tl.idx != undefined)
- input = input.tl
- input.idx--
- }
- return matchFailed(m, input.idx)
- }
- throw f
- }
- },
- match: function(obj, rule, args, matchFailed) {
- return this._genericMatch([obj].toOMInputStream(), rule, args, matchFailed)
- },
- matchAll: function(listyObj, rule, args, matchFailed) {
- return this._genericMatch(listyObj.toOMInputStream(), rule, args, matchFailed)
- }
-}
-
-
-//////// parser.js
-
-/*
- Copyright (c) 2007, 2008 Alessandro Warth <awarth@cs.ucla.edu>
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-Parser = OMeta.delegated({
- listOf: function() {
- var $elf = this,
- rule = this._apply("anything"),
- delim = this._apply("anything")
- return this._or(function() {
- var r = $elf._apply(rule)
- return $elf._many(function() {
- $elf._applyWithArgs("token", delim)
- return $elf._apply(rule)
- },
- r)
- },
- function() { return [] })
- },
- token: function() {
- var cs = this._apply("anything")
- this._apply("spaces")
- return this._applyWithArgs("seq", cs)
- }
-})
-
-
-//////// bs-js-compiler.js
-
-{BSJSParser=Parser.delegated({"fromTo":function(){var $elf=this,x,y;return (function(){x=$elf._apply("anything");y=$elf._apply("anything");$elf._applyWithArgs("seq",x);$elf._many(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("seq",y)});return $elf._apply("char")})()});return $elf._applyWithArgs("seq",y)})()},"space":function(){var $elf=this;return $elf._or((function(){return Parser._superApplyWithArgs($elf,"space")}),(function(){return $elf._applyWithArgs("fromTo","//","\n")}),(function(){return $elf._applyWithArgs("fromTo","/*","*/")}))},"nameFirst":function(){var $elf=this;return $elf._or((function(){return $elf._apply("letter")}),(function(){return $elf._applyWithArgs("exactly","$")}),(function(){return $elf._applyWithArgs("exactly","_")}))},"nameRest":function(){var $elf=this;return $elf._or((function(){return $elf._apply("nameFirst")}),(function(){return $elf._apply("digit")}))},"iName":function(){var $elf=this,r;return (function(){r=$elf._applyWithArgs("firstAndRest","nameFirst","nameRest");return r.join("")})()},"isKeyword":function(){var $elf=this,x;return (function(){x=$elf._apply("anything");return $elf._pred(BSJSParser._isKeyword(x))})()},"name":function(){var $elf=this,n;return (function(){n=$elf._apply("iName");$elf._not(function(){return $elf._applyWithArgs("isKeyword",n)});return ["name",(n == "self")?"$elf":n]})()},"keyword":function(){var $elf=this,k;return (function(){k=$elf._apply("iName");$elf._applyWithArgs("isKeyword",k);return [k,k]})()},"number":function(){var $elf=this,ws,fs;return (function(){ws=$elf._many1(function(){return $elf._apply("digit")});fs=$elf._or((function(){return (function(){$elf._applyWithArgs("exactly",".");return $elf._many1(function(){return $elf._apply("digit")})})()}),(function(){return (function(){$elf._apply("empty");return []})()}));return ["number",parseFloat(((ws.join("") + ".") + fs.join("")))]})()},"escapeChar":function(){var $elf=this,c;return (function(){$elf._applyWithArgs("exactly","\\");c=$elf._apply("char");return unescape(("\\" + c))})()},"str":function(){var $elf=this,cs,cs,cs,n;return $elf._or((function(){return (function(){$elf._applyWithArgs("seq","\"\"\"");cs=$elf._many(function(){return $elf._or((function(){return $elf._apply("escapeChar")}),(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("seq","\"\"\"")});return $elf._apply("char")})()}))});$elf._applyWithArgs("seq","\"\"\"");return ["string",cs.join("")]})()}),(function(){return (function(){$elf._applyWithArgs("exactly","\'");cs=$elf._many(function(){return $elf._or((function(){return $elf._apply("escapeChar")}),(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("exactly","\'")});return $elf._apply("char")})()}))});$elf._applyWithArgs("exactly","\'");return ["string",cs.join("")]})()}),(function(){return (function(){$elf._applyWithArgs("exactly","\"");cs=$elf._many(function(){return $elf._or((function(){return $elf._apply("escapeChar")}),(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("exactly","\"")});return $elf._apply("char")})()}))});$elf._applyWithArgs("exactly","\"");return ["string",cs.join("")]})()}),(function(){return (function(){$elf._or((function(){return $elf._applyWithArgs("exactly","#")}),(function(){return $elf._applyWithArgs("exactly","`")}));n=$elf._apply("iName");return ["string",n]})()}))},"special":function(){var $elf=this,s;return (function(){s=$elf._or((function(){return $elf._applyWithArgs("exactly","(")}),(function(){return $elf._applyWithArgs("exactly",")")}),(function(){return $elf._applyWithArgs("exactly","{")}),(function(){return $elf._applyWithArgs("exactly","}")}),(function(){return $elf._applyWithArgs("exactly","[")}),(function(){return $elf._applyWithArgs("exactly","]")}),(function(){return $elf._applyWithArgs("exactly",",")}),(function(){return $elf._applyWithArgs("exactly",";")}),(function(){return $elf._applyWithArgs("exactly","?")}),(function(){return $elf._applyWithArgs("exactly",":")}),(function(){return $elf._applyWithArgs("seq","!==")}),(function(){return $elf._applyWithArgs("seq","!=")}),(function(){return $elf._applyWithArgs("seq","===")}),(function(){return $elf._applyWithArgs("seq","==")}),(function(){return $elf._applyWithArgs("seq","=")}),(function(){return $elf._applyWithArgs("seq",">=")}),(function(){return $elf._applyWithArgs("exactly",">")}),(function(){return $elf._applyWithArgs("seq","<=")}),(function(){return $elf._applyWithArgs("exactly","<")}),(function(){return $elf._applyWithArgs("seq","++")}),(function(){return $elf._applyWithArgs("seq","+=")}),(function(){return $elf._applyWithArgs("exactly","+")}),(function(){return $elf._applyWithArgs("seq","--")}),(function(){return $elf._applyWithArgs("seq","-=")}),(function(){return $elf._applyWithArgs("exactly","-")}),(function(){return $elf._applyWithArgs("seq","*=")}),(function(){return $elf._applyWithArgs("exactly","*")}),(function(){return $elf._applyWithArgs("seq","/=")}),(function(){return $elf._applyWithArgs("exactly","/")}),(function(){return $elf._applyWithArgs("seq","%=")}),(function(){return $elf._applyWithArgs("exactly","%")}),(function(){return $elf._applyWithArgs("seq","&&=")}),(function(){return $elf._applyWithArgs("seq","&&")}),(function(){return $elf._applyWithArgs("seq","||=")}),(function(){return $elf._applyWithArgs("seq","||")}),(function(){return $elf._applyWithArgs("exactly",".")}),(function(){return $elf._applyWithArgs("exactly","!")}));return [s,s]})()},"tok":function(){var $elf=this;return (function(){$elf._apply("spaces");return $elf._or((function(){return $elf._apply("name")}),(function(){return $elf._apply("keyword")}),(function(){return $elf._apply("number")}),(function(){return $elf._apply("str")}),(function(){return $elf._apply("special")}))})()},"toks":function(){var $elf=this,ts;return (function(){ts=$elf._many(function(){return $elf._apply("token")});$elf._apply("spaces");$elf._apply("end");return ts})()},"token":function(){var $elf=this,tt,t;return (function(){tt=$elf._apply("anything");t=$elf._apply("tok");$elf._pred((t[(0)] == tt));return t[(1)]})()},"spacesNoNl":function(){var $elf=this;return $elf._many(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("exactly","\n")});return $elf._apply("space")})()})},"expr":function(){var $elf=this,e,t,f,rhs,rhs,rhs,rhs,rhs,rhs,rhs,rhs;return (function(){e=$elf._apply("orExpr");return $elf._or((function(){return (function(){$elf._applyWithArgs("token","?");t=$elf._apply("expr");$elf._applyWithArgs("token",":");f=$elf._apply("expr");return ["condExpr",e,t,f]})()}),(function(){return (function(){$elf._applyWithArgs("token","=");rhs=$elf._apply("expr");return ["set",e,rhs]})()}),(function(){return (function(){$elf._applyWithArgs("token","+=");rhs=$elf._apply("expr");return ["mset",e,"+",rhs]})()}),(function(){return (function(){$elf._applyWithArgs("token","-=");rhs=$elf._apply("expr");return ["mset",e,"-",rhs]})()}),(function(){return (function(){$elf._applyWithArgs("token","*=");rhs=$elf._apply("expr");return ["mset",e,"*",rhs]})()}),(function(){return (function(){$elf._applyWithArgs("token","/=");rhs=$elf._apply("expr");return ["mset",e,"/",rhs]})()}),(function(){return (function(){$elf._applyWithArgs("token","%=");rhs=$elf._apply("expr");return ["mset",e,"%",rhs]})()}),(function(){return (function(){$elf._applyWithArgs("token","&&=");rhs=$elf._apply("expr");return ["mset",e,"&&",rhs]})()}),(function(){return (function(){$elf._applyWithArgs("token","||=");rhs=$elf._apply("expr");return ["mset",e,"||",rhs]})()}),(function(){return (function(){$elf._apply("empty");return e})()}))})()},"orExpr":function(){var $elf=this,x,y;return $elf._or((function(){return (function(){x=$elf._apply("orExpr");$elf._applyWithArgs("token","||");y=$elf._apply("andExpr");return ["binop","||",x,y]})()}),(function(){return $elf._apply("andExpr")}))},"andExpr":function(){var $elf=this,x,y;return $elf._or((function(){return (function(){x=$elf._apply("andExpr");$elf._applyWithArgs("token","&&");y=$elf._apply("eqExpr");return ["binop","&&",x,y]})()}),(function(){return $elf._apply("eqExpr")}))},"eqExpr":function(){var $elf=this,x,y,y,y,y;return $elf._or((function(){return (function(){x=$elf._apply("eqExpr");return $elf._or((function(){return (function(){$elf._applyWithArgs("token","==");y=$elf._apply("relExpr");return ["binop","==",x,y]})()}),(function(){return (function(){$elf._applyWithArgs("token","!=");y=$elf._apply("relExpr");return ["binop","!=",x,y]})()}),(function(){return (function(){$elf._applyWithArgs("token","===");y=$elf._apply("relExpr");return ["binop","===",x,y]})()}),(function(){return (function(){$elf._applyWithArgs("token","!==");y=$elf._apply("relExpr");return ["binop","!==",x,y]})()}))})()}),(function(){return $elf._apply("relExpr")}))},"relExpr":function(){var $elf=this,x,y,y,y,y,y;return $elf._or((function(){return (function(){x=$elf._apply("relExpr");return $elf._or((function(){return (function(){$elf._applyWithArgs("token",">");y=$elf._apply("addExpr");return ["binop",">",x,y]})()}),(function(){return (function(){$elf._applyWithArgs("token",">=");y=$elf._apply("addExpr");return ["binop",">=",x,y]})()}),(function(){return (function(){$elf._applyWithArgs("token","<");y=$elf._apply("addExpr");return ["binop","<",x,y]})()}),(function(){return (function(){$elf._applyWithArgs("token","<=");y=$elf._apply("addExpr");return ["binop","<=",x,y]})()}),(function(){return (function(){$elf._applyWithArgs("token","instanceof");y=$elf._apply("addExpr");return ["binop","instanceof",x,y]})()}))})()}),(function(){return $elf._apply("addExpr")}))},"addExpr":function(){var $elf=this,x,y,x,y;return $elf._or((function(){return (function(){x=$elf._apply("addExpr");$elf._applyWithArgs("token","+");y=$elf._apply("mulExpr");return ["binop","+",x,y]})()}),(function(){return (function(){x=$elf._apply("addExpr");$elf._applyWithArgs("token","-");y=$elf._apply("mulExpr");return ["binop","-",x,y]})()}),(function(){return $elf._apply("mulExpr")}))},"mulExpr":function(){var $elf=this,x,y,x,y,x,y;return $elf._or((function(){return (function(){x=$elf._apply("mulExpr");$elf._applyWithArgs("token","*");y=$elf._apply("unary");return ["binop","*",x,y]})()}),(function(){return (function(){x=$elf._apply("mulExpr");$elf._applyWithArgs("token","/");y=$elf._apply("unary");return ["binop","/",x,y]})()}),(function(){return (function(){x=$elf._apply("mulExpr");$elf._applyWithArgs("token","%");y=$elf._apply("unary");return ["binop","%",x,y]})()}),(function(){return $elf._apply("unary")}))},"unary":function(){var $elf=this,p,p,p,p,p;return $elf._or((function(){return (function(){$elf._applyWithArgs("token","-");p=$elf._apply("postfix");return ["unop","-",p]})()}),(function(){return (function(){$elf._applyWithArgs("token","+");p=$elf._apply("postfix");return p})()}),(function(){return (function(){$elf._applyWithArgs("token","++");p=$elf._apply("postfix");return ["preop","++",p]})()}),(function(){return (function(){$elf._applyWithArgs("token","--");p=$elf._apply("postfix");return ["preop","--",p]})()}),(function(){return (function(){$elf._applyWithArgs("token","!");p=$elf._apply("postfix");return ["unop","!",p]})()}),(function(){return $elf._apply("postfix")}))},"postfix":function(){var $elf=this,p;return (function(){p=$elf._apply("primExpr");return $elf._or((function(){return (function(){$elf._apply("spacesNoNl");$elf._applyWithArgs("token","++");return ["postop","++",p]})()}),(function(){return (function(){$elf._apply("spacesNoNl");$elf._applyWithArgs("token","--");return ["postop","--",p]})()}),(function(){return (function(){$elf._apply("empty");return p})()}))})()},"primExpr":function(){var $elf=this,p,i,m,as,f,as;return $elf._or((function(){return (function(){p=$elf._apply("primExpr");return $elf._or((function(){return (function(){$elf._applyWithArgs("token","[");i=$elf._apply("expr");$elf._applyWithArgs("token","]");return ["getp",i,p]})()}),(function(){return (function(){$elf._applyWithArgs("token",".");m=$elf._applyWithArgs("token","name");$elf._applyWithArgs("token","(");as=$elf._applyWithArgs("listOf","expr",",");$elf._applyWithArgs("token",")");return ["send",m,p].concat(as)})()}),(function(){return (function(){$elf._applyWithArgs("token",".");f=$elf._applyWithArgs("token","name");return ["getp",["string",f],p]})()}),(function(){return (function(){$elf._applyWithArgs("token","(");as=$elf._applyWithArgs("listOf","expr",",");$elf._applyWithArgs("token",")");return ["call",p].concat(as)})()}))})()}),(function(){return $elf._apply("primExprHd")}))},"primExprHd":function(){var $elf=this,e,n,n,s,n,as,es;return $elf._or((function(){return (function(){$elf._applyWithArgs("token","(");e=$elf._apply("expr");$elf._applyWithArgs("token",")");return e})()}),(function(){return (function(){$elf._applyWithArgs("token","this");return ["this"]})()}),(function(){return (function(){n=$elf._applyWithArgs("token","name");return ["get",n]})()}),(function(){return (function(){n=$elf._applyWithArgs("token","number");return ["number",n]})()}),(function(){return (function(){s=$elf._applyWithArgs("token","string");return ["string",s]})()}),(function(){return (function(){$elf._applyWithArgs("token","function");return $elf._apply("funcRest")})()}),(function(){return (function(){$elf._applyWithArgs("token","new");n=$elf._applyWithArgs("token","name");$elf._applyWithArgs("token","(");as=$elf._applyWithArgs("listOf","expr",",");$elf._applyWithArgs("token",")");return ["new",n].concat(as)})()}),(function(){return (function(){$elf._applyWithArgs("token","[");es=$elf._applyWithArgs("listOf","expr",",");$elf._applyWithArgs("token","]");return ["arr"].concat(es)})()}),(function(){return $elf._apply("json")}))},"json":function(){var $elf=this,bs;return (function(){$elf._applyWithArgs("token","{");bs=$elf._applyWithArgs("listOf","jsonBinding",",");$elf._applyWithArgs("token","}");return ["json"].concat(bs)})()},"jsonBinding":function(){var $elf=this,n,v;return (function(){n=$elf._apply("jsonPropName");$elf._applyWithArgs("token",":");v=$elf._apply("expr");return ["binding",n,v]})()},"jsonPropName":function(){var $elf=this;return $elf._or((function(){return $elf._applyWithArgs("token","name")}),(function(){return $elf._applyWithArgs("token","number")}),(function(){return $elf._applyWithArgs("token","string")}))},"formal":function(){var $elf=this;return (function(){$elf._apply("spaces");return $elf._applyWithArgs("token","name")})()},"funcRest":function(){var $elf=this,fs,body;return (function(){$elf._applyWithArgs("token","(");fs=$elf._applyWithArgs("listOf","formal",",");$elf._applyWithArgs("token",")");$elf._applyWithArgs("token","{");body=$elf._apply("srcElems");$elf._applyWithArgs("token","}");return ["func",fs,body]})()},"sc":function(){var $elf=this;return $elf._or((function(){return (function(){$elf._apply("spacesNoNl");return $elf._or((function(){return $elf._applyWithArgs("exactly","\n")}),(function(){return $elf._lookahead(function(){return $elf._applyWithArgs("exactly","}")})}),(function(){return $elf._apply("end")}))})()}),(function(){return $elf._applyWithArgs("token",";")}))},"binding":function(){var $elf=this,n,v;return (function(){n=$elf._applyWithArgs("token","name");v=$elf._or((function(){return (function(){$elf._applyWithArgs("token","=");return $elf._apply("expr")})()}),(function(){return (function(){$elf._apply("empty");return ["get","undefined"]})()}));return ["var",n,v]})()},"block":function(){var $elf=this,ss;return (function(){$elf._applyWithArgs("token","{");ss=$elf._apply("srcElems");$elf._applyWithArgs("token","}");return ss})()},"stmt":function(){var $elf=this,bs,c,t,f,c,s,s,c,i,c,u,s,n,v,e,s,e,c,cs,cs,cs,e,t,e,c,f,e,x,s,e;return $elf._or((function(){return $elf._apply("block")}),(function(){return (function(){$elf._applyWithArgs("token","var");bs=$elf._applyWithArgs("listOf","binding",",");$elf._apply("sc");return ["begin"].concat(bs)})()}),(function(){return (function(){$elf._applyWithArgs("token","if");$elf._applyWithArgs("token","(");c=$elf._apply("expr");$elf._applyWithArgs("token",")");t=$elf._apply("stmt");f=$elf._or((function(){return (function(){$elf._applyWithArgs("token","else");return $elf._apply("stmt")})()}),(function(){return (function(){$elf._apply("empty");return ["get","undefined"]})()}));return ["if",c,t,f]})()}),(function(){return (function(){$elf._applyWithArgs("token","while");$elf._applyWithArgs("token","(");c=$elf._apply("expr");$elf._applyWithArgs("token",")");s=$elf._apply("stmt");return ["while",c,s]})()}),(function(){return (function(){$elf._applyWithArgs("token","do");s=$elf._apply("stmt");$elf._applyWithArgs("token","while");$elf._applyWithArgs("token","(");c=$elf._apply("expr");$elf._applyWithArgs("token",")");$elf._apply("sc");return ["doWhile",s,c]})()}),(function(){return (function(){$elf._applyWithArgs("token","for");$elf._applyWithArgs("token","(");i=$elf._or((function(){return (function(){$elf._applyWithArgs("token","var");return $elf._apply("binding")})()}),(function(){return $elf._apply("expr")}),(function(){return (function(){$elf._apply("empty");return ["get","undefined"]})()}));$elf._applyWithArgs("token",";");c=$elf._or((function(){return $elf._apply("expr")}),(function(){return (function(){$elf._apply("empty");return ["get","true"]})()}));$elf._applyWithArgs("token",";");u=$elf._or((function(){return $elf._apply("expr")}),(function(){return (function(){$elf._apply("empty");return ["get","undefined"]})()}));$elf._applyWithArgs("token",")");s=$elf._apply("stmt");return ["for",i,c,u,s]})()}),(function(){return (function(){$elf._applyWithArgs("token","for");$elf._applyWithArgs("token","(");v=$elf._or((function(){return (function(){$elf._applyWithArgs("token","var");n=$elf._applyWithArgs("token","name");return ["var",n,["get","undefined"]]})()}),(function(){return $elf._apply("expr")}));$elf._applyWithArgs("token","in");e=$elf._apply("expr");$elf._applyWithArgs("token",")");s=$elf._apply("stmt");return ["forIn",v,e,s]})()}),(function(){return (function(){$elf._applyWithArgs("token","switch");$elf._applyWithArgs("token","(");e=$elf._apply("expr");$elf._applyWithArgs("token",")");$elf._applyWithArgs("token","{");cs=$elf._many(function(){return $elf._or((function(){return (function(){$elf._applyWithArgs("token","case");c=$elf._apply("expr");$elf._applyWithArgs("token",":");cs=$elf._apply("srcElems");return ["case",c,cs]})()}),(function(){return (function(){$elf._applyWithArgs("token","default");$elf._applyWithArgs("token",":");cs=$elf._apply("srcElems");return ["default",cs]})()}))});$elf._applyWithArgs("token","}");return ["switch",e].concat(cs)})()}),(function(){return (function(){$elf._applyWithArgs("token","break");$elf._apply("sc");return ["break"]})()}),(function(){return (function(){$elf._applyWithArgs("token","continue");$elf._apply("sc");return ["continue"]})()}),(function(){return (function(){$elf._applyWithArgs("token","throw");$elf._apply("spacesNoNl");e=$elf._apply("expr");$elf._apply("sc");return ["throw",e]})()}),(function(){return (function(){$elf._applyWithArgs("token","try");t=$elf._apply("block");$elf._applyWithArgs("token","catch");$elf._applyWithArgs("token","(");e=$elf._applyWithArgs("token","name");$elf._applyWithArgs("token",")");c=$elf._apply("block");f=$elf._or((function(){return (function(){$elf._applyWithArgs("token","finally");return $elf._apply("block")})()}),(function(){return (function(){$elf._apply("empty");return ["get","undefined"]})()}));return ["try",t,e,c,f]})()}),(function(){return (function(){$elf._applyWithArgs("token","return");e=$elf._or((function(){return $elf._apply("expr")}),(function(){return (function(){$elf._apply("empty");return ["get","undefined"]})()}));$elf._apply("sc");return ["return",e]})()}),(function(){return (function(){$elf._applyWithArgs("token","with");$elf._applyWithArgs("token","(");x=$elf._apply("expr");$elf._applyWithArgs("token",")");s=$elf._apply("stmt");return ["with",x,s]})()}),(function(){return (function(){e=$elf._apply("expr");$elf._apply("sc");return e})()}),(function(){return (function(){$elf._applyWithArgs("token",";");return ["get","undefined"]})()}))},"srcElem":function(){var $elf=this,n,f;return $elf._or((function(){return (function(){$elf._applyWithArgs("token","function");n=$elf._applyWithArgs("token","name");f=$elf._apply("funcRest");return ["var",n,f]})()}),(function(){return $elf._apply("stmt")}))},"srcElems":function(){var $elf=this,ss;return (function(){ss=$elf._many(function(){return $elf._apply("srcElem")});return ["begin"].concat(ss)})()},"topLevel":function(){var $elf=this,r;return (function(){r=$elf._apply("srcElems");$elf._apply("spaces");$elf._apply("end");return r})()},"curlySemAction":function(){var $elf=this,s,ss,r,r;return $elf._or((function(){return (function(){$elf._applyWithArgs("token","{");ss=$elf._many1(function(){return (function(){s=$elf._apply("srcElem");$elf._lookahead(function(){return $elf._apply("srcElem")});return s})()});r=$elf._apply("expr");$elf._apply("sc");$elf._applyWithArgs("token","}");$elf._apply("spaces");return (function (){ss.push(["return",r]);return ["call",["func",[],["begin"].concat(ss)]]})()})()}),(function(){return (function(){$elf._applyWithArgs("token","{");r=$elf._apply("expr");$elf._applyWithArgs("token","}");$elf._apply("spaces");return r})()}))},"semAction":function(){var $elf=this,r;return $elf._or((function(){return $elf._apply("curlySemAction")}),(function(){return (function(){r=$elf._apply("primExpr");$elf._apply("spaces");return r})()}))}});BSJSParser["keywords"]=({});keywords=["break","case","catch","continue","default","delete","do","else","finally","for","function","if","in","instanceof","new","return","switch","this","throw","try","typeof","var","void","while","with","ometa"];for(var idx=(0);(idx < keywords["length"]);idx++){BSJSParser["keywords"][keywords[idx]]=true}BSJSParser["_isKeyword"]=(function (k){return (this["keywords"].hasProperty(k) && (!Object["prototype"].hasProperty(k)))});BSJSTranslator=OMeta.delegated({"trans":function(){var $elf=this,t,ans;return (function(){$elf._form(function(){return (function(){t=$elf._apply("anything");return ans=$elf._applyWithArgs("apply",t)})()});return ans})()},"curlyTrans":function(){var $elf=this,r,rs,r;return $elf._or((function(){return (function(){$elf._form(function(){return (function(){$elf._applyWithArgs("exactly","begin");return r=$elf._apply("curlyTrans")})()});return r})()}),(function(){return (function(){$elf._form(function(){return (function(){$elf._applyWithArgs("exactly","begin");return rs=$elf._many(function(){return $elf._apply("trans")})})()});return (("{" + rs.join(";")) + "}")})()}),(function(){return (function(){r=$elf._apply("trans");return (("{" + r) + "}")})()}))},"this":function(){var $elf=this;return "this"},"break":function(){var $elf=this;return "break"},"continue":function(){var $elf=this;return "continue"},"number":function(){var $elf=this,n;return (function(){n=$elf._apply("anything");return (("(" + n) + ")")})()},"string":function(){var $elf=this,s;return (function(){s=$elf._apply("anything");return s.toProgramString()})()},"arr":function(){var $elf=this,xs;return (function(){xs=$elf._many(function(){return $elf._apply("trans")});return (("[" + xs.join(",")) + "]")})()},"unop":function(){var $elf=this,op,x;return (function(){op=$elf._apply("anything");x=$elf._apply("trans");return ((("(" + op) + x) + ")")})()},"getp":function(){var $elf=this,fd,x;return (function(){fd=$elf._apply("trans");x=$elf._apply("trans");return (((x + "[") + fd) + "]")})()},"get":function(){var $elf=this,x;return (function(){x=$elf._apply("anything");return x})()},"set":function(){var $elf=this,lhs,rhs;return (function(){lhs=$elf._apply("trans");rhs=$elf._apply("trans");return ((lhs + "=") + rhs)})()},"mset":function(){var $elf=this,lhs,op,rhs;return (function(){lhs=$elf._apply("trans");op=$elf._apply("anything");rhs=$elf._apply("trans");return (((lhs + op) + "=") + rhs)})()},"binop":function(){var $elf=this,op,x,y;return (function(){op=$elf._apply("anything");x=$elf._apply("trans");y=$elf._apply("trans");return (((((("(" + x) + " ") + op) + " ") + y) + ")")})()},"preop":function(){var $elf=this,op,x;return (function(){op=$elf._apply("anything");x=$elf._apply("trans");return (op + x)})()},"postop":function(){var $elf=this,op,x;return (function(){op=$elf._apply("anything");x=$elf._apply("trans");return (x + op)})()},"return":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ("return " + x)})()},"with":function(){var $elf=this,x,s;return (function(){x=$elf._apply("trans");s=$elf._apply("curlyTrans");return ((("with(" + x) + ")") + s)})()},"if":function(){var $elf=this,cond,t,e;return (function(){cond=$elf._apply("trans");t=$elf._apply("curlyTrans");e=$elf._apply("curlyTrans");return ((((("if(" + cond) + ")") + t) + "else") + e)})()},"condExpr":function(){var $elf=this,cond,t,e;return (function(){cond=$elf._apply("trans");t=$elf._apply("trans");e=$elf._apply("trans");return (((((("(" + cond) + "?") + t) + ":") + e) + ")")})()},"while":function(){var $elf=this,cond,body;return (function(){cond=$elf._apply("trans");body=$elf._apply("curlyTrans");return ((("while(" + cond) + ")") + body)})()},"doWhile":function(){var $elf=this,body,cond;return (function(){body=$elf._apply("curlyTrans");cond=$elf._apply("trans");return (((("do" + body) + "while(") + cond) + ")")})()},"for":function(){var $elf=this,init,cond,upd,body;return (function(){init=$elf._apply("trans");cond=$elf._apply("trans");upd=$elf._apply("trans");body=$elf._apply("curlyTrans");return ((((((("for(" + init) + ";") + cond) + ";") + upd) + ")") + body)})()},"forIn":function(){var $elf=this,x,arr,body;return (function(){x=$elf._apply("trans");arr=$elf._apply("trans");body=$elf._apply("curlyTrans");return ((((("for(" + x) + " in ") + arr) + ")") + body)})()},"begin":function(){var $elf=this,x,x,xs;return $elf._or((function(){return (function(){x=$elf._apply("trans");$elf._apply("end");return x})()}),(function(){return (function(){xs=$elf._many(function(){return (function(){x=$elf._apply("trans");return $elf._or((function(){return (function(){$elf._or((function(){return $elf._pred((x[(x["length"] - (1))] == "}"))}),(function(){return $elf._apply("end")}));return x})()}),(function(){return (function(){$elf._apply("empty");return (x + ";")})()}))})()});return (("{" + xs.join("")) + "}")})()}))},"func":function(){var $elf=this,args,body;return (function(){args=$elf._apply("anything");body=$elf._apply("curlyTrans");return (((("(function (" + args.join(",")) + ")") + body) + ")")})()},"call":function(){var $elf=this,fn,args;return (function(){fn=$elf._apply("trans");args=$elf._many(function(){return $elf._apply("trans")});return (((fn + "(") + args.join(",")) + ")")})()},"send":function(){var $elf=this,msg,recv,args;return (function(){msg=$elf._apply("anything");recv=$elf._apply("trans");args=$elf._many(function(){return $elf._apply("trans")});return (((((recv + ".") + msg) + "(") + args.join(",")) + ")")})()},"new":function(){var $elf=this,cls,args;return (function(){cls=$elf._apply("anything");args=$elf._many(function(){return $elf._apply("trans")});return (((("new " + cls) + "(") + args.join(",")) + ")")})()},"var":function(){var $elf=this,name,val;return (function(){name=$elf._apply("anything");val=$elf._apply("trans");return ((("var " + name) + "=") + val)})()},"throw":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ("throw " + x)})()},"try":function(){var $elf=this,x,name,c,f;return (function(){x=$elf._apply("curlyTrans");name=$elf._apply("anything");c=$elf._apply("curlyTrans");f=$elf._apply("curlyTrans");return ((((((("try " + x) + "catch(") + name) + ")") + c) + "finally") + f)})()},"json":function(){var $elf=this,props;return (function(){props=$elf._many(function(){return $elf._apply("trans")});return (("({" + props.join(",")) + "})")})()},"binding":function(){var $elf=this,name,val;return (function(){name=$elf._apply("anything");val=$elf._apply("trans");return ((name.toProgramString() + ": ") + val)})()},"switch":function(){var $elf=this,x,cases;return (function(){x=$elf._apply("trans");cases=$elf._many(function(){return $elf._apply("trans")});return (((("switch(" + x) + "){") + cases.join(";")) + "}")})()},"case":function(){var $elf=this,x,y;return (function(){x=$elf._apply("trans");y=$elf._apply("trans");return ((("case " + x) + ": ") + y)})()},"default":function(){var $elf=this,y;return (function(){y=$elf._apply("trans");return ("default: " + y)})()}})}
-
-
-//////// bs-ometa-compiler.js
-
-{BSOMetaParser=Parser.delegated({"fromTo":function(){var $elf=this,x,y;return (function(){x=$elf._apply("anything");y=$elf._apply("anything");$elf._applyWithArgs("seq",x);$elf._many(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("seq",y)});return $elf._apply("char")})()});return $elf._applyWithArgs("seq",y)})()},"space":function(){var $elf=this;return $elf._or((function(){return Parser._superApplyWithArgs($elf,"space")}),(function(){return $elf._applyWithArgs("fromTo","//","\n")}),(function(){return $elf._applyWithArgs("fromTo","/*","*/")}))},"nameFirst":function(){var $elf=this;return $elf._or((function(){return $elf._applyWithArgs("exactly","_")}),(function(){return $elf._applyWithArgs("exactly","$")}),(function(){return $elf._apply("letter")}))},"nameRest":function(){var $elf=this;return $elf._or((function(){return $elf._apply("nameFirst")}),(function(){return $elf._apply("digit")}))},"tsName":function(){var $elf=this,xs;return (function(){xs=$elf._applyWithArgs("firstAndRest","nameFirst","nameRest");return xs.join("")})()},"name":function(){var $elf=this;return (function(){$elf._apply("spaces");return $elf._apply("tsName")})()},"eChar":function(){var $elf=this,c;return $elf._or((function(){return (function(){$elf._applyWithArgs("exactly","\\");c=$elf._apply("char");return unescape(("\\" + c))})()}),(function(){return $elf._apply("char")}))},"tsString":function(){var $elf=this,xs;return (function(){$elf._applyWithArgs("exactly","\'");xs=$elf._many(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("exactly","\'")});return $elf._apply("eChar")})()});$elf._applyWithArgs("exactly","\'");return xs.join("")})()},"characters":function(){var $elf=this,xs;return (function(){$elf._applyWithArgs("exactly","`");$elf._applyWithArgs("exactly","`");xs=$elf._many(function(){return (function(){$elf._not(function(){return (function(){$elf._applyWithArgs("exactly","\'");return $elf._applyWithArgs("exactly","\'")})()});return $elf._apply("eChar")})()});$elf._applyWithArgs("exactly","\'");$elf._applyWithArgs("exactly","\'");return ["App","seq",xs.join("").toProgramString()]})()},"sCharacters":function(){var $elf=this,xs;return (function(){$elf._applyWithArgs("exactly","\"");xs=$elf._many(function(){return (function(){$elf._not(function(){return $elf._applyWithArgs("exactly","\"")});return $elf._apply("eChar")})()});$elf._applyWithArgs("exactly","\"");return ["App","token",xs.join("").toProgramString()]})()},"string":function(){var $elf=this,xs;return (function(){xs=$elf._or((function(){return (function(){$elf._or((function(){return $elf._applyWithArgs("exactly","#")}),(function(){return $elf._applyWithArgs("exactly","`")}));return $elf._apply("tsName")})()}),(function(){return $elf._apply("tsString")}));return ["App","exactly",xs.toProgramString()]})()},"number":function(){var $elf=this,sign,ds;return (function(){sign=$elf._or((function(){return $elf._applyWithArgs("exactly","-")}),(function(){return (function(){$elf._apply("empty");return ""})()}));ds=$elf._many1(function(){return $elf._apply("digit")});return ["App","exactly",(sign + ds.join(""))]})()},"keyword":function(){var $elf=this,xs;return (function(){xs=$elf._apply("anything");$elf._applyWithArgs("token",xs);$elf._not(function(){return $elf._apply("letterOrDigit")});return xs})()},"args":function(){var $elf=this,xs;return $elf._or((function(){return (function(){$elf._applyWithArgs("exactly","(");xs=$elf._applyWithArgs("listOf","hostExpr",",");$elf._applyWithArgs("token",")");return xs})()}),(function(){return (function(){$elf._apply("empty");return []})()}))},"application":function(){var $elf=this,rule,as;return (function(){rule=$elf._apply("name");as=$elf._apply("args");return ["App",rule].concat(as)})()},"hostExpr":function(){var $elf=this,r;return (function(){r=$elf._applyWithArgs("foreign",BSJSParser,"expr");return $elf._applyWithArgs("foreign",BSJSTranslator,"trans",r)})()},"atomicHostExpr":function(){var $elf=this,r;return (function(){r=$elf._applyWithArgs("foreign",BSJSParser,"semAction");return $elf._applyWithArgs("foreign",BSJSTranslator,"trans",r)})()},"curlyHostExpr":function(){var $elf=this,r;return (function(){r=$elf._applyWithArgs("foreign",BSJSParser,"curlySemAction");return $elf._applyWithArgs("foreign",BSJSTranslator,"trans",r)})()},"semAction":function(){var $elf=this,x,x;return $elf._or((function(){return (function(){$elf._or((function(){return $elf._applyWithArgs("token","!")}),(function(){return $elf._applyWithArgs("token","->")}));x=$elf._apply("atomicHostExpr");return ["Act",x]})()}),(function(){return (function(){x=$elf._apply("curlyHostExpr");return ["Act",x]})()}))},"semPred":function(){var $elf=this,x;return (function(){$elf._applyWithArgs("token","?");x=$elf._apply("atomicHostExpr");return ["Pred",x]})()},"expr":function(){var $elf=this,xs;return (function(){xs=$elf._applyWithArgs("listOf","expr4","|");return ["Or"].concat(xs)})()},"expr4":function(){var $elf=this,xs;return (function(){xs=$elf._many(function(){return $elf._apply("expr3")});return ["And"].concat(xs)})()},"optIter":function(){var $elf=this,x;return (function(){x=$elf._apply("anything");return $elf._or((function(){return (function(){$elf._applyWithArgs("token","*");return ["Many",x]})()}),(function(){return (function(){$elf._applyWithArgs("token","+");return ["Many1",x]})()}),(function(){return (function(){$elf._apply("empty");return x})()}))})()},"expr3":function(){var $elf=this,x,x,n,n;return $elf._or((function(){return (function(){x=$elf._apply("expr2");x=$elf._applyWithArgs("optIter",x);return $elf._or((function(){return (function(){$elf._applyWithArgs("exactly",":");n=$elf._apply("name");return (function (){$elf["locals"].push(n);return ["Set",n,x]})()})()}),(function(){return (function(){$elf._apply("empty");return x})()}))})()}),(function(){return (function(){$elf._applyWithArgs("token",":");n=$elf._apply("name");return (function (){$elf["locals"].push(n);return ["Set",n,["App","anything"]]})()})()}))},"expr2":function(){var $elf=this,x,x;return $elf._or((function(){return (function(){$elf._applyWithArgs("token","~");x=$elf._apply("expr2");return ["Not",x]})()}),(function(){return (function(){$elf._applyWithArgs("token","&");x=$elf._apply("expr1");return ["Lookahead",x]})()}),(function(){return $elf._apply("expr1")}))},"expr1":function(){var $elf=this,x,x,x;return $elf._or((function(){return $elf._apply("application")}),(function(){return $elf._apply("semAction")}),(function(){return $elf._apply("semPred")}),(function(){return (function(){x=$elf._or((function(){return $elf._applyWithArgs("keyword","undefined")}),(function(){return $elf._applyWithArgs("keyword","nil")}),(function(){return $elf._applyWithArgs("keyword","true")}),(function(){return $elf._applyWithArgs("keyword","false")}));return ["App","exactly",x]})()}),(function(){return (function(){$elf._apply("spaces");return $elf._or((function(){return $elf._apply("characters")}),(function(){return $elf._apply("sCharacters")}),(function(){return $elf._apply("string")}),(function(){return $elf._apply("number")}))})()}),(function(){return (function(){$elf._applyWithArgs("token","[");x=$elf._apply("expr");$elf._applyWithArgs("token","]");return ["Form",x]})()}),(function(){return (function(){$elf._applyWithArgs("token","(");x=$elf._apply("expr");$elf._applyWithArgs("token",")");return x})()}))},"ruleName":function(){var $elf=this;return $elf._or((function(){return $elf._apply("name")}),(function(){return (function(){$elf._apply("spaces");return $elf._apply("tsString")})()}))},"rule":function(){var $elf=this,n,x,xs;return (function(){$elf._lookahead(function(){return n=$elf._apply("ruleName")});$elf["locals"]=["$elf=this"];x=$elf._applyWithArgs("rulePart",n);xs=$elf._many(function(){return (function(){$elf._applyWithArgs("token",",");return $elf._applyWithArgs("rulePart",n)})()});return ["Rule",n,$elf["locals"],["Or",x].concat(xs)]})()},"rulePart":function(){var $elf=this,rn,n,b1,b2;return (function(){rn=$elf._apply("anything");n=$elf._apply("ruleName");$elf._pred((n == rn));b1=$elf._apply("expr4");return $elf._or((function(){return (function(){$elf._applyWithArgs("token","=");b2=$elf._apply("expr");return ["And",b1,b2]})()}),(function(){return (function(){$elf._apply("empty");return b1})()}))})()},"grammar":function(){var $elf=this,n,sn,rs;return (function(){$elf._applyWithArgs("keyword","ometa");n=$elf._apply("name");sn=$elf._or((function(){return (function(){$elf._applyWithArgs("token","<:");return $elf._apply("name")})()}),(function(){return (function(){$elf._apply("empty");return "OMeta"})()}));$elf._applyWithArgs("token","{");rs=$elf._applyWithArgs("listOf","rule",",");$elf._applyWithArgs("token","}");return $elf._applyWithArgs("foreign",BSOMetaOptimizer,"optimizeGrammar",["Grammar",n,sn].concat(rs))})()}});BSOMetaTranslator=OMeta.delegated({"trans":function(){var $elf=this,t,ans;return (function(){$elf._form(function(){return (function(){t=$elf._apply("anything");return ans=$elf._applyWithArgs("apply",t)})()});return ans})()},"App":function(){var $elf=this,args,rule,args,rule;return $elf._or((function(){return (function(){$elf._applyWithArgs("exactly","super");args=$elf._many1(function(){return $elf._apply("anything")});return [$elf["sName"],"._superApplyWithArgs($elf,",args.join(","),")"].join("")})()}),(function(){return (function(){rule=$elf._apply("anything");args=$elf._many1(function(){return $elf._apply("anything")});return ["$elf._applyWithArgs(\"",rule,"\",",args.join(","),")"].join("")})()}),(function(){return (function(){rule=$elf._apply("anything");return ["$elf._apply(\"",rule,"\")"].join("")})()}))},"Act":function(){var $elf=this,expr;return (function(){expr=$elf._apply("anything");return expr})()},"Pred":function(){var $elf=this,expr;return (function(){expr=$elf._apply("anything");return ["$elf._pred(",expr,")"].join("")})()},"Or":function(){var $elf=this,xs;return (function(){xs=$elf._many(function(){return $elf._apply("transFn")});return ["$elf._or(",xs.join(","),")"].join("")})()},"And":function(){var $elf=this,xs,y;return $elf._or((function(){return (function(){xs=$elf._many(function(){return $elf._applyWithArgs("notLast","trans")});y=$elf._apply("trans");return (function (){xs.push(("return " + y));return ["(function(){",xs.join(";"),"})()"].join("")})()})()}),(function(){return "(function(){})"}))},"Many":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ["$elf._many(function(){return ",x,"})"].join("")})()},"Many1":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ["$elf._many1(function(){return ",x,"})"].join("")})()},"Set":function(){var $elf=this,n,v;return (function(){n=$elf._apply("anything");v=$elf._apply("trans");return [n,"=",v].join("")})()},"Not":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ["$elf._not(function(){return ",x,"})"].join("")})()},"Lookahead":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ["$elf._lookahead(function(){return ",x,"})"].join("")})()},"Form":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ["$elf._form(function(){return ",x,"})"].join("")})()},"Rule":function(){var $elf=this,name,ls,body;return (function(){name=$elf._apply("anything");ls=$elf._apply("locals");body=$elf._apply("trans");return ["\"",name,"\":function(){",ls,"return ",body,"}"].join("")})()},"Grammar":function(){var $elf=this,name,sName,rules;return (function(){name=$elf._apply("anything");sName=$elf._apply("anything");$elf["sName"]=sName;rules=$elf._many(function(){return $elf._apply("trans")});return [name,"=",sName,".delegated({",rules.join(","),"})"].join("")})()},"locals":function(){var $elf=this,vs;return $elf._or((function(){return (function(){$elf._form(function(){return vs=$elf._many1(function(){return $elf._apply("string")})});return ["var ",vs.join(","),";"].join("")})()}),(function(){return (function(){$elf._form(function(){return (function(){})});return ""})()}))},"transFn":function(){var $elf=this,x;return (function(){x=$elf._apply("trans");return ["(function(){return ",x,"})"].join("")})()}})}
-
-
-//////// bs-ometa-optimizer.js
-
-{BSNullOptimization=OMeta.delegated();BSNullOptimization['setHelped']=function() {var $elf=this;return $elf["_didSomething"]=true};BSNullOptimization['helped']=function() {var $elf=this;return $elf._pred($elf["_didSomething"])};BSNullOptimization['trans']=function() {var $elf=this,t,ans;return $elf._or((function(){return (function(){$elf._form(function(){return (function(){t=$elf._apply("anything");$elf._pred($elf.hasProperty(t));return ans=$elf._applyWithArgs("apply", t)})()});return ans})()}),(function(){return $elf._apply("anything")}))};BSNullOptimization['optimize']=function() {var $elf=this,x;return (function(){x=$elf._apply("trans");$elf._apply("helped");return x})()};BSNullOptimization['Or']=function() {var $elf=this,xs;return (function(){xs=$elf._many(function(){return $elf._apply("trans")});return ["Or"].concat(xs)})()};BSNullOptimization['And']=function() {var $elf=this,xs;return (function(){xs=$elf._many(function(){return $elf._apply("trans")});return ["And"].concat(xs)})()};BSNullOptimization['Many']=function() {var $elf=this,x;return (function(){x=$elf._apply("trans");return ["Many",x]})()};BSNullOptimization['Many1']=function() {var $elf=this,x;return (function(){x=$elf._apply("trans");return ["Many1",x]})()};BSNullOptimization['Set']=function() {var $elf=this,n,v;return (function(){n=$elf._apply("anything");v=$elf._apply("trans");return ["Set",n,v]})()};BSNullOptimization['Not']=function() {var $elf=this,x;return (function(){x=$elf._apply("trans");return ["Not",x]})()};BSNullOptimization['Lookahead']=function() {var $elf=this,x;return (function(){x=$elf._apply("trans");return ["Lookahead",x]})()};BSNullOptimization['Form']=function() {var $elf=this,x;return (function(){x=$elf._apply("trans");return ["Form",x]})()};BSNullOptimization['Rule']=function() {var $elf=this,name,ls,body;return (function(){name=$elf._apply("anything");ls=$elf._apply("anything");body=$elf._apply("trans");return ["Rule",name,ls,body]})()};BSNullOptimization.prototype=BSNullOptimization;;BSNullOptimization["initialize"]=(function () {this["_didSomething"]=false});BSAndOrOptimization=BSNullOptimization.delegated();BSAndOrOptimization['And']=function() {var $elf=this,x,xs;return $elf._or((function(){return (function(){x=$elf._apply("trans");$elf._apply("end");$elf._apply("setHelped");return x})()}),(function(){return (function(){xs=$elf._applyWithArgs("transInside", "And");return ["And"].concat(xs)})()}))};BSAndOrOptimization['Or']=function() {var $elf=this,x,xs;return $elf._or((function(){return (function(){x=$elf._apply("trans");$elf._apply("end");$elf._apply("setHelped");return x})()}),(function(){return (function(){xs=$elf._applyWithArgs("transInside", "Or");return ["Or"].concat(xs)})()}))};BSAndOrOptimization['transInside']=function() {var $elf=this,t,xs,ys,x,xs;return (function(){t=$elf._apply("anything");return $elf._or((function(){return (function(){$elf._form(function(){return (function(){$elf._applyWithArgs("exactly", t);return xs=$elf._applyWithArgs("transInside", t)})()});ys=$elf._applyWithArgs("transInside", t);$elf._apply("setHelped");return xs.concat(ys)})()}),(function(){return (function(){x=$elf._apply("trans");xs=$elf._applyWithArgs("transInside", t);return [x].concat(xs)})()}),(function(){return []}))})()};BSAndOrOptimization.prototype=BSAndOrOptimization;;BSOMetaOptimizer=OMeta.delegated();BSOMetaOptimizer['optimizeGrammar']=function() {var $elf=this,n,sn,rs;return (function(){$elf._form(function(){return (function(){$elf._applyWithArgs("exactly", "Grammar");n=$elf._apply("anything");sn=$elf._apply("anything");return rs=$elf._many(function(){return $elf._apply("optimizeRule")})})()});return ["Grammar",n,sn].concat(rs)})()};BSOMetaOptimizer['optimizeRule']=function() {var $elf=this,r,r;return (function(){r=$elf._apply("anything");$elf._many(function(){return r=$elf._applyWithArgs("foreign", BSAndOrOptimization, "optimize", r)});return r})()};BSOMetaOptimizer.prototype=BSOMetaOptimizer;}
-
-
-//////// bs-ometa-js-compiler.js
-
-{BSOMetaJSParser=BSJSParser.delegated();BSOMetaJSParser['srcElem']=function() {var $elf=this,r;return $elf._or((function(){return (function(){$elf._apply("spaces");r=$elf._applyWithArgs("foreign", BSOMetaParser, "grammar");$elf._apply("sc");return r})()}),(function(){return BSJSParser._superApplyWithArgs($elf,"srcElem")}))};BSOMetaJSParser.prototype=BSOMetaJSParser;;BSOMetaJSTranslator=BSJSTranslator.delegated();BSOMetaJSTranslator['Grammar']=function() {var $elf=this;return $elf._applyWithArgs("foreign", BSOMetaTranslator, "Grammar")};BSOMetaJSTranslator.prototype=BSOMetaJSTranslator;}
-
View
110 OMeta_WJS_Mods.js
@@ -1,110 +0,0 @@
-OMeta._or = function() {
- for (var idx = 0; idx < arguments.length; idx++) {
- var ok = true
- in thisWorld.sprout() {
- try { return arguments[idx]() }
- catch (f) {
- ok = false
- if (f != fail)
- throw f
- }
- finally { if (ok) thisWorld.commit() }
- }
- }
- throw fail
-}
-
-OMeta._many = function(x) {
- var ans = arguments[1] != undefined ? [arguments[1]] : []
- while (true) {
- in thisWorld.sprout() {
- try {
- ans.push(x())
- //print("committing " + ans.toString())
- thisWorld.commit()
- }
- catch (f) {
- if (f != fail)
- throw f
- break
- }
- }
- }
- return ans
-}
-
-OMeta._not = function(x) {
- in thisWorld.sprout() {
- try { x() }
- catch (f) {
- if (f != fail)
- throw f
- return true
- }
- }
- throw fail
-}
-
-/*
-OMeta._lookahead = function(x) {
- in thisWorld.sprout() {
- var r = x()
- //print("la = " + r.toString())
- return x
- }
-}
-*/
-
-/*
-OMeta._apply = function(rule) {
- var memoRec = this.input.memo[rule]
- if (memoRec == undefined) {
- var origInput = this.input,
- failer = new Failer()
- this.input.memo[rule] = failer
- this.input.memo[rule] = memoRec = {ans: this[rule].apply(this), nextInput: this.input}
- if (failer.used) {
- var sentinel = this.input
- while (true) {
- try {
- this.input = origInput
- var ans = this[rule].apply(this)
- if (this.input == sentinel)
- throw fail
- memoRec.ans = ans
- memoRec.nextInput = this.input
- }
- catch (f) {
- if (f != fail)
- throw f
- break
- }
- }
- }
- }
- else if (memoRec instanceof Failer) {
- memoRec.used = true
- throw fail
- }
- this.input = memoRec.nextInput
- return memoRec.ans
-}
-*/
-
-
-print("defining example 1")
-eval(BSOMetaJSTranslator.match(BSOMetaJSParser.matchAll("ometa M { ones = (1 -> 2)* }", "srcElem"), "trans"))
-print("running example 1")
-print(M.matchAll([1, 1, 1, 1], "ones"))
-
-print("defining example 2")
-eval(BSOMetaJSTranslator.match(BSOMetaJSParser.matchAll("ometa M { foo = &(:x) anything*:ys -> [x, ys] }", "srcElem"), "trans"))
-print("running example 2")
-print(M.matchAll([1, 2, 3, 4], "foo"))
-
-print("defining example 3")
-eval(BSOMetaJSTranslator.match(BSOMetaJSParser.matchAll("ometa M { ones = {count=0} ({count++} 1 -> 2)* }", "srcElem"), "trans"))
-print("running example 3")
-print(M.matchAll([1, 1, 1, 1], "ones"))
-print("count = " + count)
-
View
58 README.md
@@ -16,3 +16,61 @@ To learn more:
* [OMeta mailing list](http://vpri.org/mailman/listinfo/ometa)
* [mailing list archirves](http://vpri.org/pipermail/ometa/)
+About
+----
+The goal of this project is to provide a tool-chain tool for easily working with OMetaJS. `ometajsnode` allows one to specify grammar file, interpreter file, ( in future also compiler files/modules ), and program files via command line, and offers a number of options of execution such as parse mode, interpreter mode, and compile mode.
+
+Work in progress
+----
+Incorporating compiler / code emitting code is going to get worked on soon.
+I'm not sure if packaging works with `npm` yet, but I'll get there.
+`stdin` input is not working yet.
+
+Usage
+----
+
+Currently, parsing and interpreting works. See below walkthrough.
+
+see usage via `./ometajsnode -h` or `./ometajsnode --help`
+
+#### Parser example:
+
+from the `bin` directory:
+
+`./ometajsnode -P -g ../examples/grammar_to_ir.ometajs --parser-root expr -o output.file ../examples/program.file ../examples/program2.file --debug`
+
+Let's breakdown that command step by step:
+`-P` sets `ometajsnode` into Parse mode, which will essentially output the Abstract Syntax Tree for each of the programs
+`-g ../examples/grammar_to_ir.ometajs` specifies the file containing ometajs grammar to use
+`--parser-root expr` specifies 'expr' as the root element of the grammar for the parser to try to match
+`-o output.file` specifies the file to which output will be written ( if `-o` is not present, output is directed to `stdout` )
+`../examples/program.file ../examples/program2.file` specifies two programs to process
+`--debug` sets mode to debug, which will display a lot of information detailing the execution process
+
+#### Combined parser and interpreter example:
+
+from the `bin` directory:
+
+`./ometajsnode -I -g ../examples/grammar_and_interpreter.ometajs --interpreter-root expr -o output.file ../examples/program.file ../examples/program2.file --verbose`
+
+This command is similar to the one above with some differences:
+`-I` sets `ometajsnode` into Interpret mode, which will actually interpret each of the programs and display the result
+`--interpreter-root expr` similarly to `--parser-root`, this specifies the root element of the grammar for the interpreter to try to match
+`--verbose` sets mode to verbose, which is not as detailed as `debug`, but will give you more detailed information
+
+#### Parser to intermediate representation which then is interpreted example:
+
+from the `bin` directory:
+
+`./ometajsnode -I -g ../examples/grammar_to_ir.ometajs --parser-root expr -i ../examples/interpreter.ometajs --interpreter-root interp -o output.file ../examples/program.file ../examples/program2.file --debug`
+
+We have little bit more going on here:
+`-i` in addition to `-g` which specified the grammar file, we add an interpreter file that will work with the output of parsing according to grammar file
+because we specified both a grammar and an interpreter, we need to provide both `--parser-root` and `--interpreter-root`
+
+Feedback
+----
+
+I welcome your input and feedback.
+
+Cheers!
View
149 Things_You_Should_Know.txt
@@ -1,149 +0,0 @@
-OMeta/JS is a new version of OMeta, a language for pattern-directed metaprogramming first described in
-
- Alessandro Warth and Ian Piumarta, "OMeta: An Object-Oriented Language for Pattern-Matching," in Proceedings of the Dynamic
- Languages Symposium, 2007. (Available at http://www.cs.ucla.edu/~awarth/papers/dls07.pdf)
-
-This page contains the information necessary for someone who has read the OMeta paper to be able to use OMeta/JS.
-
-
-Pattern Syntax
---------------
-
-+------------------------------------------------------------------------+
-| "kind of thing" OMeta OMeta/JS |
-+------------------------------------------------------------------------+
-| boolean true true |
-| number 123 123 |
-| character 'x' 'x' | (see note #1)
-| string "foo" 'foo' |
-| `foo |
-| #foo |
-| atom foo N/A |
-| rule application <expr> expr |
-| <r x y> r(x, y) | (see note #3)
-| <super stmt> ^stmt | (see note #4)
-| list ("hello" 42 answer ()) ['hello' 42 `answer []] |
-| negation ~'x' ~'x' |
-| look-ahead ~~'x' ~~'x' |
-| &'x' |
-| semantic predicate ?(> x y) ?(x > y) | (see note #2)
-| semantic action => (+ x y) -> (x + y) |
-| !(+ x y) !(x + y) |
-| binding <expr>:x expr:x | (in OMeta/JS, spaces are not allowed before the colon)
-| :x | (this is shorthand for "anything:x")
-+------------------------------------------------------------------------+
-
-
-Note #1: There is no such thing as a character in JavaScript. Even though the language lets you access each "character" of a string via indexing, e.g, "foo"[0], the answer is not a character, but rather a string of length 1.
-
-
-Note #2: In the version of OMeta described in the paper, semantic actions and predicates were written in COLA (kind of a mix between Scheme and Smalltalk). In OMeta/JS, they are written in JavaScript. More specifically, they are either primary expressions, e.g.,
-
- 123
- x
- foo.bar()
- new Person()
- (x + y) // note that you need parentheses around "x + y" in order to make it into a primary expression
-
-or something I made up called "statement expressions", which have the form
-
- "{" <statement>* <expr> "}"
-
-For example,
-
- { x += 2; y = "foo"; f(x) }
-
-The value of a statement expression is equal to that of its last expression.
-
-
-Note #3: The arguments you pass to a rule don't have to be statement expressions - they can be any JavaScript expression.
-
-Note #4: In OMeta/JS, "super" is just like any other rule (not a special form), so you have to quote the rule name that you pass in as an argument, e.g., both ^r(1, 2) and super("r", 1, 2) are valid super-sends.
-
-
-A "Handy" New Shorthand
------------------------
-
-In OMeta/JS, the pattern
-
- "foo"
-
-does not match the string 'foo'; it is instead shorthand for
-
- token('foo')
-
-The Parser grammar provides a definition for token that skips any number of spaces, then tries to match the sequence of characters that was passed to it as an argument. I have used this in many of the example projects, and have found it to be very useful.
-
-Still, there are times when this is not what you want. But that's not a problem, because you can define it to do whatever you want (see the JavaScript Compiler project for an example).
-
-
-Rules
------
-
-Here is a parameterized rule taken from the paper, in the original OMeta syntax:
-
- cRange x y ::= <char>:c ?(>= c x)
- ?(<= c y) => c;
-
-And here is the same rule rule, in the new OMeta/JS syntax:
-
- cRange :x :y = char:c ?(c >= x)
- ?(c <= y) -> c
-
-
-A couple of (purely syntactic) differences:
-
-(1) rule declarations now use "=" instead of "::=", and
-(2) they are no longer terminated with a ";"
-
-
-A more significant difference has to do with the rule's arguments; note that in the OMeta/JS version, they are preceded by a ':'. This is actually shorthand for
-
- cRange anything:x anything:y = ...
-
-This change has to do with an improvement in the parameter-passing mechanism, which now allows a rule's parameters to be pattern-matched against. (See the paper's "Future Work" section for more details.)
-
-The "=" is actually optional in rule declarations... this, combined with some new syntax that allows a rule to have multiple definitions that are tried in lexicographic order, allows programmers to write rules that have an "ML flavor":
-
- ometa M {
- fact 0 -> 1,
- fact :n ?(n > 0) fact(n - 1):m -> (n * m)
- }
- M.match(5, "fact")
-
-
-Grammar Syntax
---------------
-
-The only change here has to do with rule declarations, which now must be separated by commas:
-
- ometa M {
- x = y z,
- y = "foo" "bar",
- z = "baz"
- }
-
-
-Using Grammars "from the outside"
-----------------------------------
-
-The public interface provided by an OMeta/JS grammar object to the rest of the world consists of two methods:
-
- match(object, ruleName)
-
-and
-
- matchAll(arrayOrStringObject, ruleName)
-
-
-Here's an example that hopefully explains the difference between the two. The key to understanding it is that a string is just a list of characters.
-
- ometa M <: Parser {
- theCharacters = "the" "cat" "sat" "on" "the" "mat",
- theWholeString = [theCharacters]
- }
-
- input = "the cat sat on the mat"
- M.matchAll(input, "theCharacters")
- M.match(input, "theWholeString")
-
View
112 Worlds2.js
@@ -1,112 +0,0 @@
-/*
- Copyright (c) 2008, 2010 Alessandro Warth <awarth@cs.ucla.edu>
-
- Limitations:
- * assignments into the properties of "arguments" (e.g., arguments[5] = 1234) don't modify their respective variables
- * for-in doesn't work when the loop variable is a property access (e.g., for (x.y in ys) ...)
-*/
-
-Array.prototype.each = function(f) {
- for (var idx = 0; idx < this.length; idx++)
- f(this[idx], idx)
-}
-
-ometa WJSParser <: BSJSParser {
- isKeyword :x = ?(x == 'thisWorld')
- | super('isKeyword', x),
- primExprHd = "thisWorld" -> ['thisWorld']
- | super('primExprHd'),
- stmt = "in" expr:w block:b -> ['in', w, b]
- | super('stmt')
-}
-
-makeFunction = function(fs, body) {
- return '(function() { var staticScope = thisScope;' +
- ' var r = function() {' +
- ' var oldScope = thisScope;' +
- ' thisScope = staticScope.makeChild();' +
- ' thisScope.set("arguments", arguments);' +
- ' thisWorld.set(arguments, "length", arguments.length);' +
- ' for (var i = 0; i < arguments.length; i++) thisWorld.set(arguments, i, arguments[i]);' +
- ' try { ' + fs + body + '}' +
- ' finally { thisScope = oldScope }};' +
- ' baseWorld.set(r, "prototype", {parent: Object.prototype});' +
- ' return r })()' }
-
-makeIn = function(w, body) {
- return '{ try { worldStack.push(thisWorld); thisWorld = ' + w + '; ' + body + '} ' +
- 'finally { thisWorld = worldStack.pop() }' +
- 'undefined }'
-}
-
-makeForIn = function(v, e, s, decl) {
- var p = tempnam(), ps = tempnam()
- var r = 'for (var ' + p + ' in ' + ps + ' = thisWorld.props(' + e + ', {})) {' +
- 'if (!' + ps + '.hasOwnProperty(' + p + ')) continue; ' +
- 'thisScope.set("' + v + '", ' + p + '); ' + s +
- '}'
- if (decl)
- r = 'thisScope.decl("' + v + '", undefined); ' + r
- r = '{ var ' + ps + ' = undefined; ' + r + '}'
- return r
-}
-
-ometa WJSTranslator <: BSJSTranslator {
- initialize = { self.level = 0 },
- fargs = [anything*:fs] -> { var ss = []
- fs.each(function(v, i) { ss.push('thisScope.decl("' + v +
- '", arguments[' + i + ']);') })
- ss.join('') },
- thisWorld -> 'thisWorld',
- var :n trans:v -> ('thisScope.decl("' + n + '", ' + v + ')'),
- get :n -> ('thisScope.get("' + n + '")'),
- getp trans:p ['get' 'arguments'] -> ('arguments[' + p + ']'),
- getp trans:p trans:x -> ('thisWorld.get(' + x + ', ' + p + ')'),
- set ['get' :n] trans:v -> ('thisScope.set("' + n + '", ' + v + ')'),
- set ['getp' trans:p ['get' 'arguments']] trans:v -> 'UNSUPPORTED OPERATION',
- set ['getp' trans:p trans:x] trans:v -> ('thisWorld.set(' + x + ', ' + p + ', ' + v + ')'),
- mset ['get' :n] :op trans:rhs -> ('thisScope.set("' + n + '", thisScope.get("' + n + '")' + op + rhs + ')'),
- mset ['getp' trans:p trans:x] :op trans:rhs -> ('(function(r, p) { return thisWorld.set(r, p, thisWorld.get(r, p) ' +
- op + ' ' + rhs + ') })(' + x + ', ' + p + ')'),
- preop :op ['get' :n] -> ('thisScope.set("' + n + '", thisScope.get("' + n + '")' + op[0] + '1)'),
- preop :op ['getp' trans:p trans:x] -> ('(function(r, p) { return thisWorld.set(r, p, thisWorld.get(r, p) ' +
- op[0] + ' 1) })(' + x + ', ' + p + ')'),
- postop :op ['get' :n] -> ('(function(n) { var ans = thisScope.get(n); ' +
- 'thisScope.set(n, ans ' + op[0] + ' 1); ' +
- 'return ans })("' + n + '")'),
- postop :op ['getp' trans:p trans:x] -> ('(function(r, p) { var ans = thisWorld.get(r, p); ' +
- 'thisWorld.set(r, p, ans ' + op[0] + ' 1); ' +
- 'return ans })(' + x + ', ' + p + ')'),
- binop 'instanceof' trans:x trans:y -> ('instanceOf(' + x + ', ' + y + ')'),
- binop :op trans:x trans:y -> ('(' + x + ' ' + op + ' ' + y + ')'),
- call trans:f trans*:as -> ('(' + f + ')(' + as.join(',') + ')'),
- send :m trans:r trans*:as -> ('send("' + m + '", ' + r + ', [' + as.join(',') + '])'),
- new :x trans*:as -> ('thisScope.get("' + x + '").worldsNew(' + as.join(',') + ')'),
- func fargs:fs {self.level++} trans:body
- {self.level--} -> makeFunction(fs, body),
- in trans:w trans:b -> makeIn(w, b),
- arr trans*:xs -> ('[' + xs.join(',') + '].toWJSArray()'),
- json trans*:xs -> ('({' + xs.join(',') + '}).toWJSObject()'),
- try curlyTrans:x :name curlyTrans:c curlyTrans:f -> { var e = tempnam()
- 'try ' + x +
- 'catch(' + e + ') {thisScope.decl("' + name + '", ' + e + '); ' + c + '}' +
- 'finally' + f },
- forIn ['get' :v ] trans:e trans:s -> makeForIn(v, e, s, false),
- forIn ['var' :v :init] trans:e trans:s -> makeForIn(v, e, s, true)
-}
-
-compileWJS = function(code) {
- var tree = WJSParser.matchAll(code, "topLevel", undefined, function(m, i) { throw fail.delegated({errorPos: i}) })
- //print("parsed: " + tree)
- var code = WJSTranslator.match(tree, 'trans')
- //print("compiled: " + code)
- return code
-}
-
-thisScope.decl("eval", function(s) { return eval(compileWJS(s)) })
-
-oldPrint = print
-print = function(x) { oldPrint(x == undefined || x == null ? x : send("toString", x)) }
-
-translateCode = compileWJS
-
View
311 Worlds2_Library.js
@@ -1,311 +0,0 @@
-// Copyright (c) 2008, 2010 Alessandro Warth <awarth@cs.ucla.edu>
-
-DEBUG = false;
-
-// getTag: object -> unique id
-// tagToRef: unique id -> object
-
-// Note: this hashing scheme causes a huge memory leak (all b/c JS doesn't support weak references)
-
-(function() {
- var numIdx = 0, tagToRef = {}
- var _getTag = function(r) {
- if (r === null || r === undefined)
- return r
- switch (typeof r) {
- case "boolean": return r == true ? "Btrue" : "Bfalse"
- case "string": return "S" + r
- case "number": return "N" + r
- default: return r.hasOwnProperty("_id_") ? r._id_ : r._id_ = "R" + numIdx++
- }
- }
- getTag = function(r) {
- var tag = _getTag(r)
- tagToRef[tag] = r
- return tag
- }
- getRef = function(t) {
- return tagToRef[t]
- }
-})()
-
-// implementation of possible worlds
-
-worldProto = {}
-
-baseWorld = thisWorld = (function() {
- var writes = {}
- return {
- parent: worldProto,
- writes: writes,
- hasOwn: function(r, p) {
- var id = getTag(r)
- return writes.hasOwnProperty(id) && writes[id].hasOwnProperty(p)
- },
- has: function(r, p) {
- return this.hasOwn(r, p) ||
- r !== Object.prototype && this.has(r === null || r === undefined ? Object.prototype : r.parent, p)
- },
- props: function(r, ps) {
- var id = getTag(r)
- if (writes.hasOwnProperty(id))
- for (var p in writes[id])
- if (writes[id].hasOwnProperty(p))
- ps[p] = true
- if (r !== Object.prototype)
- this.props(r === null || r === undefined ? Object.prototype : r.parent, ps)
- return ps
- },
- _get: function(r, p) {
- var id = getTag(r)
- if (DEBUG) console.log("? top-level world looking up " + id + "." + p)
- if (writes.hasOwnProperty(id) && writes[id].hasOwnProperty(p))
- return writes[id][p]
- else if (r !== Object.prototype)
- return thisWorld._get(r === null || r === undefined ? Object.prototype : r.parent, p)
- else
- return undefined
- },
- get: function(r, p) {
- // the top-level world's commit operation is a no-op, so reads don't have to be recorded
- if (typeof r === "string" && (typeof p === "number" || p === "length"))
- return r[p]
- else
- return this._get(r, p)
- },
- set: function(r, p, v) {
- if (typeof r === "string" && (typeof p === "number" || p === "length"))
- throw "the indices and length of a string are immutable, and you tried to change them!"
- var id = getTag(r)
- if (DEBUG) console.log("! top-level world assigning to " + id + "." + p)
- if (!writes.hasOwnProperty(id))
- writes[id] = {}
- writes[id][p] = v
- return v
- },
- commit: function() { },
- sprout: function() {
- var parentWorld = this, writes = {}, reads = {}
- return {
- parent: worldProto,
- writes: writes,
- reads: reads,
- hasOwn: function(r, p) {
- var id = getTag(r)
- return writes.hasOwnProperty(id) && writes[id].hasOwnProperty(p) ||
- reads.hasOwnProperty(id) && reads[id].hasOwnProperty(p) ||
- parentWorld.hasOwn(r, p)
- },
- has: function(r, p) {
- return this.hasOwn(r, p) ||
- r !== Object.prototype && this.has(r === null || r === undefined ? Object.prototype : r.parent, p)
- },
- props: function(r, ps) {
- var id = getTag(r)
- if (writes.hasOwnProperty(id))
- for (var p in writes[id])
- if (writes[id].hasOwnProperty(p))
- ps[p] = true
- if (reads.hasOwnProperty(id))
- for (var p in reads[id])
- if (reads[id].hasOwnProperty(p))
- ps[p] = true
- if (r !== Object.prototype)
- this.props(r === null || r === undefined ? Object.prototype : r.parent, ps)
- parentWorld.props(r, ps)
- return ps
- },
- _get: function(r, p) {
- var id = getTag(r)
- if (DEBUG) console.log("? child world looking up " + id + "." + p)
- if (writes.hasOwnProperty(id) && writes[id].hasOwnProperty(p))
- return writes[id][p]
- else if (reads.hasOwnProperty(id) && reads[id].hasOwnProperty(p))
- return reads[id][p]
- else
- return parentWorld._get(r, p)
- },
- get: function(r, p) {
- if (typeof r === "string" && (typeof p === "number" || p === "length"))
- return r[p]
- var id = getTag(r), ans = this._get(r, p)
- if (!reads.hasOwnProperty(id) && !(writes.hasOwnProperty(id) && writes[id].hasOwnProperty(p))) {
- reads[id] = {}
- if (!reads[id].hasOwnProperty(p))
- reads[id][p] = ans
- }
- return ans
- },
- set: function(r, p, v) {
- if (typeof r === "string" && (typeof p === "number" || p === "length"))
- throw "the indices and length of a string are immutable, and you tried to change them!"
- var id = getTag(r)
- if (DEBUG) console.log("! child world assigning to " + id + "." + p)
- if (!writes.hasOwnProperty(id))
- writes[id] = {}
- writes[id][p] = v
- return v
- },
- commit: function() {
- // serializability check
- for (var id in reads) {
- if (!reads.hasOwnProperty(id))
- continue
- for (var p in reads[id]) {
- if (!reads[id].hasOwnProperty(p))
- continue
- else if (reads[id][p] !== parentWorld._get(getRef(id), p))
- throw "commit failed"
- }
- }
- // propagation of side effects
- for (var id in writes) {
- if (!writes.hasOwnProperty(id))
- continue
- for (var p in writes[id]) {
- if (!writes[id].hasOwnProperty(p))
- continue
- if (!parentWorld.writes.hasOwnProperty(id))
- parentWorld.writes[id] = {}
- if (DEBUG) console.log("committing " + id + "." + p)
- parentWorld.writes[id][p] = writes[id][p]
- }
- }
- writes = {}
- reads = {}
- },
- sprout: parentWorld.sprout
- }
- }
- }
-})()
-worldStack = [thisWorld]
-
-// Lexical scopes
-
-GlobalScope = function() { }
-GlobalScope.prototype = {
- parent: Object.prototype,
- hasOwn: function(n) { return thisWorld.hasOwn(this, n) },
- has: function(n) { return thisWorld.has(this, n) },
- get: function(n) { return thisWorld.get(this, n) },
- set: function(n, v) { return thisWorld.set(this, n, v) },
- decl: function(n, v) { return baseWorld.set(this, n, v) },
- makeChild: function() { return new ActivationRecord(this) }
-}
-
-ActivationRecord = function(parent) { this.parent = parent }
-ActivationRecord.prototype = new GlobalScope()
-ActivationRecord.prototype.get = function(n) { return thisWorld.has(this, n) ?
- thisWorld.get(this, n) :
- this.parent.get(n) }
-ActivationRecord.prototype.set = function(n, v) { return thisWorld.has(this, n) ?
- thisWorld.set(this, n, v) :
- this.parent.set(n, v) }
-
-thisScope = new GlobalScope()
-
-// Sends
-
-send = function(sel, recv, args) {
- //alert("doing a send, sel=" + sel + ", recv=" + recv + ", args=" + args)
- return thisWorld.get(recv, sel).apply(recv, args)
-}
-
-// New
-
-Function.prototype.worldsNew = function() {
- var r = {parent: thisWorld.get(this, "prototype")}
- this.apply(r, arguments)
- return r
-}
-
-// instanceof
-
-instanceOf = function(x, C) {
- var p = x.parent, Cp = thisWorld.get(C, "prototype")
- while (p != undefined) {
- if (p == Cp)
- return true
- p = p.parent
- }
- return false
-}
-
-// Some globals, etc.
-
-wObject = function() { }
-thisScope.decl("Object", wObject)
-thisWorld.set(wObject, "prototype", Object.prototype)
-thisWorld.set(Object.prototype, "hasOwn", function(p) { return thisWorld.has(this, p) })
-thisWorld.set(Object.prototype, "toString", function() { return "" + this })
-
-thisWorld.set(worldProto, "sprout", function() { return this.sprout() })
-thisWorld.set(worldProto, "commit", function() { return this.commit() })
-thisWorld.set(worldProto, "toString", function() { return "[World " + this.getTag() + "]" })
-
-wWorld = function() { }; thisScope.decl("World", wWorld); thisWorld.set(wWorld, "prototype", worldProto)
-wBoolean = function() { }; thisScope.decl("Boolean", wBoolean); thisWorld.set(wBoolean, "prototype", {parent: Object.prototype})
-wNumber = function() { }; thisScope.decl("Number", wNumber); thisWorld.set(wNumber, "prototype", {parent: Object.prototype})
-wString = function() { }; thisScope.decl("String", wString); thisWorld.set(wString, "prototype", {parent: Object.prototype})
-wArray = function() { }; thisScope.decl("Array", wArray); thisWorld.set(wArray, "prototype", {parent: Object.prototype})
-wFunction = function() { }; thisScope.decl("Function", wFunction); thisWorld.set(wFunction, "prototype", {parent: Object.prototype})
-
-Boolean.prototype.parent = thisWorld.get(wBoolean, "prototype")
-Number.prototype.parent = thisWorld.get(wNumber, "prototype")
-String.prototype.parent = thisWorld.get(wString, "prototype")
-Function.prototype.parent = thisWorld.get(wFunction, "prototype")
-// Don't need to do this for Array because Worlds/JS arrays are not JS arrays
-
-thisWorld.set(wString, "fromCharCode", function(x) { return String.fromCharCode(x) })
-thisWorld.set(String.prototype.parent, "charCodeAt", function(x) { return this.charCodeAt(x) })
-
-thisWorld.set(Function.prototype.parent, "apply", function(recv, args) {
- var jsArgs
- if (args && thisWorld.get(args, "length") > 0) {
- jsArgs = []
- for (var idx = 0; idx < thisWorld.get(args, "length"); idx++)
- jsArgs.push(thisWorld.get(args, idx))
- }
- return this.apply(recv, jsArgs)
-})
-thisWorld.set(Function.prototype.parent, "call", function(recv) {
- var jsArgs = []
- for (var idx = 1; idx < arguments.length; idx++)
- jsArgs.push(arguments[idx])
- return this.apply(recv, jsArgs)
-})
-
-thisScope.decl("null", null)
-thisScope.decl("undefined", undefined)
-thisScope.decl("true", true)
-thisScope.decl("false", false)
-
-thisScope.decl("jsEval", function(s) { return eval(thisWorld.get(s, "toString").call(s)) })
-thisScope.decl("print", function(s) { print(thisWorld.get(s, "toString").call(s)) })
-thisScope.decl("alert", function(s) { alert(thisWorld.get(s, "toString").call(s)) })
-thisScope.decl("prompt", function(s) { return prompt(thisWorld.get(s, "toString").call(s)) })
-thisScope.decl("confirm", function(s) { return confirm(thisWorld.get(s, "toString").call(s)) })
-
-thisScope.decl("parseInt", function(s) { return parseInt(s) })
-thisScope.decl("parseFloat", function(s) { return parseFloat(s) })
-
-WorldsConsole = {}
-thisScope.decl("console", WorldsConsole)
-thisWorld.set(WorldsConsole, "log", function(s) { Transcript.show(thisWorld.get(s, "toString").apply(s)) })
-
-Array.prototype.toWJSArray = function() {
- var r = wArray.worldsNew()
- for (var idx = 0; idx < this.length; idx++)
- thisWorld.set(r, idx, this[idx])
- thisWorld.set(r, "length", this.length)
- return r
-}
-Object.prototype.toWJSObject = function() {
- var r = wObject.worldsNew()
- for (var p in this)
- if (this.hasOwnProperty(p))
- thisWorld.set(r, p, this[p])
- return r
-}
-
View
35 arrays.wjs
@@ -1,35 +0,0 @@
-Array.prototype.toString = function() {
- var r = "["
- for (var idx = 0; idx < this.length; idx = idx + 1) {
- if (idx > 0)
- r = r + ", "
- r = r + this[idx].toString()
- }
- return r + "]"
-}
-Array.prototype.push = function(x) {
- this[this.length] = x
- this.length = this.length + 1
- return x
-}
-Array.prototype.pop = function() {
- var r = this[this.length - 1]
- this[this.length - 1] = undefined
- this.length = this.length - 1
- return r
-}
-Array.prototype.join = function(delim) {
- var r = ""
- for (var idx = 0; idx < this.length; idx++) {
- if (idx > 0)
- r += delim
- r += this[idx]
- }
- return r
-}
-Array.prototype.concat = function(xs) {
- for (var idx = 0; idx < xs.length; idx++)
- this.push(xs[idx])
- return this
-}
-
View
177 bin/ometajsnode
@@ -0,0 +1,177 @@
+#!/usr/bin/env node
+
+var logly = require( 'logly' );
+
+logly.name('ometajsnode');
+
+var usage = "Usage: ometajsnode <-C|-I|-P> <-g|--grammar grammar_file> [options] input_file";
+var help1 = [
+ usage,
+ "",
+ "Operational Modes: Only one mode is supported at a time, last mode specified will be used",
+ " -C Compile the program using provided grammar and compiler",
+ " -I Interpret the program using provided grammar and interpreter",
+ " -P Parse the program only, using the provided grammar",
+ ""
+].join( '\n' );
+var help2 = [
+ "Options:",
+ " -c, --compiler <file> Specifies compiler file to use (*.omc)",
+ " --compiler-root <root> Name of the root expression in the compiler grammar",
+ " --debug Run in debug mode",
+ " -g, --grammar <file> Specifies grammar file to use (*.omg)",
+ " -h, --help Displays this information",
+ " -i, --interpreter <file> Specifies interpreter file to use (*.omi)",
+ " --interpreter-root <root> Name of the root expression in the interpreter grammar",
+ " -o, --output <file> Place the output into file",
+ " --parser-root <root> Name of the root expression in the parser grammar",
+ " --verbose Run in verbose mode",
+ " --version Version"
+].join( '\n' );
+
+var ometajsnode = require( 'ometajsnode' );
+
+// Retrieve command-line parameters
+var arg, args = [], argv = process.argv.slice( 2 ),
+ options = {
+ input: [],
+ loglyMode: 'standard'
+ };
+
+// Parse command-line parameters
+while ( arg = argv.shift() ) {
+ if ( arg === __filename ) continue;
+
+ if ( arg[ 0 ] !== '-' ) {
+ options.input.push( arg );
+ } else {
+ arg = arg.match( /^--?(.+)/ )[ 1 ];
+
+ switch ( arg ) {
+ case 'C':
+ options.mode = 'compile';
+ break;
+ case 'compiler':
+ case 'c':
+ options.compiler = argv.shift();
+ break;
+ case 'compiler-root':
+ options.rootCompilerExpression = argv.shift();
+ break;
+ case 'debug':
+ options.loglyMode = 'debug';
+ logly.mode('debug');
+ break;
+ case 'grammar':
+ case 'g':
+ options.grammar = argv.shift();
+ break;
+ case 'help':
+ case 'h':
+ process.stdout.write( help1 );
+ process.stdout.write( help2 + '\n' );
+ process.exit( 0 );
+ break;
+ case 'I':
+ options.mode = 'interpret';
+ break;
+ case 'interpreter':
+ case 'i':
+ options.interpreter = argv.shift();
+ break;
+ case 'interpreter-root':
+ options.rootInterpreterExpression = argv.shift();
+ break;
+ case 'output':
+ case 'o':
+ options.output = argv.shift();
+ break;
+ case 'P':
+ options.mode = 'parse';
+ break;
+ case 'parser-root':
+ options.rootParserExpression = argv.shift();
+ break;
+ case 'verbose':
+ options.loglyMode = 'verbose';
+ logly.mode('verbose');
+ break;
+ case 'version':
+ // using console instead of logly cause we don't want ':'
+ console.log( "ometajsnode " + ometajsnode.version );
+ process.exit( 0 );
+ break;
+ }
+ }
+}
+
+// dump options in debug mode
+logly.debug( function() {
+ for ( option in options ) {
+ if ( !options.hasOwnProperty( option ) ) continue;
+ logly.debug( '[OPTION] ' + option + ": " + options[ option ] );
+ }
+});
+
+// Check that we have input files
+if ( options.input.length < 1 ) {
+ logly.log( "no input files" );
+ process.exit( 0 );
+}
+
+// Check that we specified we want to do something
+if ( !options.mode ) {
+ logly.log( "no operational mode specified\n" + usage );
+ process.exit( 0 );
+}
+
+// Verify that grammar is specified
+if ( !options.grammar ) {
+ logly.log( "no grammar specified\n" + usage );
+ process.exit( 0 );
+}
+
+// Execute the program
+if ( 'compile' == options.mode ) {
+
+ // Verify we have a compiler and compiler-root specified if in compile mode
+ if ( !options.compiler ) {
+ logly.log( "no compiler specified for Compile mode\n" + usage );
+ process.exit( 0 );
+ }
+ if ( !options.rootCompilerExpression ) {
+ logly.log( "no compiler-root specified for Compile mode\n" + usage );
+ process.exit( 0 );
+ }
+
+ ometajsnode.execute( 'compile', options.loglyMode, options.grammar,
+ options.input, options.compiler, undefined, options.output,
+ options.rootParserExpression, options.rootInterpreterExpression,
+ options.rootCompilerExpression);
+
+} else if ( 'interpret' == options.mode ) {
+
+ // Verify we have an interpreter-root specified if in interpreter mode
+ if ( !options.rootInterpreterExpression ) {
+ logly.log( "no interpreter-root specified for Interpreter mode\n" + usage );
+ process.exit( 0 );
+ }
+
+ ometajsnode.execute( 'interpret', options.loglyMode, options.grammar,
+ options.input, undefined, options.interpreter, options.output,
+ options.rootParserExpression, options.rootInterpreterExpression,
+ options.rootCompilerExpression);
+
+} else if ( 'parse' == options.mode ) {
+
+ //Verify we have a parser-root specified if in interpreter mode
+ if ( !options.rootParserExpression ) {
+ logly.log( "no parser-root specified for Parser mode\n" + usage );
+ process.exit( 0 );
+ }
+
+ ometajsnode.execute( 'parse', options.loglyMode, options.grammar,
+ options.input, undefined, undefined, options.output,
+ options.rootParserExpression, options.rootInterpreterExpression,
+ options.rootCompilerExpression );
+}
View
2  bin/output.file
@@ -0,0 +1,2 @@
+[mul, [num, 6], [add, [num, 4], [num, 3]]]
+[add, [div, [sub, [num, 16], [num, 6]], [mul, [num, 6], [add, [num, 4], [num, 3]]]], [mul, [div, [num, 22], [num, 3]], [add, [add, [num, 17], [num, 9]], [num, 3]]]]
View
211 bs-js-compiler.txt
@@ -1,211 +0,0 @@
-ometa BSJSParser <: Parser {
- fromTo :x :y = seq(x) (~seq(y) char)* seq(y),
- space = ^space | fromTo('//', '\n') | fromTo('/*', '*/'),
- nameFirst = letter | '$' | '_',
- nameRest = nameFirst | digit,
- iName = firstAndRest(#nameFirst, #nameRest):r -> r.join(''),
- isKeyword :x = ?BSJSParser._isKeyword(x),
- name = iName:n ~isKeyword(n) -> [#name, n=='self' ? '$elf' : n],
- keyword = iName:k isKeyword(k) -> [k, k],
- hexDigit = char:x {this.hexDigits.indexOf(x.toLowerCase())}:v ?(v >= 0) -> v,
- hexLit = hexLit:n hexDigit:d -> (n * 16 + d)
- | hexDigit,
- number = ``0x'' hexLit:n -> [#number, n]
- | digit+:ws ('.' digit+ | empty -> []):fs -> [#number, parseFloat(ws.join('') + '.' +
- fs.join(''))],
- escapeChar = '\\' char:c -> unescape('\\' + c),
- str = seq('"""') (escapeChar | ~seq('"""') char)*:cs seq('"""') -> [#string, cs.join('')]
- | '\'' (escapeChar | ~'\'' char)*:cs '\'' -> [#string, cs.join('')]
- | '"' (escapeChar | ~'"' char)*:cs '"' -> [#string, cs.join('')]
- | ('#' | '`') iName:n -> [#string, n],
- special = ( '(' | ')' | '{' | '}' | '[' | ']' | ','
- | ';' | '?' | ':' | ``!=='' | ``!='' | ``==='' | ``==''
- | ``='' | ``>='' | '>' | ``<='' | '<' | ``++'' | ``+=''
- | '+' | ``--'' | ``-='' | '-' | ``*='' | '*' | ``/=''
- | '/' | ``%='' | '%' | ``&&='' | ``&&'' | ``||='' | ``||''
- | '.' | '!' ):s -> [s, s],
- tok = spaces (name | keyword | number | str | special),
- toks = token*:ts spaces end -> ts,
- token :tt = tok:t ?(t[0] == tt) -> t[1],
- spacesNoNl = (~'\n' space)*,
-
- expr = orExpr:e ( "?" expr:t ":" expr:f -> [#condExpr, e, t, f]
- | "=" expr:rhs -> [#set, e, rhs]
- | "+=" expr:rhs -> [#mset, e, "+", rhs]
- | "-=" expr:rhs -> [#mset, e, "-", rhs]
- | "*=" expr:rhs -> [#mset, e, "*", rhs]
- | "/=" expr:rhs -> [#mset, e, "/", rhs]
- | "%=" expr:rhs -> [#mset, e, "%", rhs]
- | "&&=" expr:rhs -> [#mset, e, "&&", rhs]
- | "||=" expr:rhs -> [#mset, e, "||", rhs]
- | empty -> e
- ),
- orExpr = orExpr:x "||" andExpr:y -> [#binop, "||", x, y]
- | andExpr,
- andExpr = andExpr:x "&&" eqExpr:y -> [#binop, "&&", x, y]
- | eqExpr,
- eqExpr = eqExpr:x ( "==" relExpr:y -> [#binop, "==", x, y]
- | "!=" relExpr:y -> [#binop, "!=", x, y]
- | "===" relExpr:y -> [#binop, "===", x, y]
- | "!==" relExpr:y -> [#binop, "!==", x, y]
- )
- | relExpr,
- relExpr = relExpr:x ( ">" addExpr:y -> [#binop, ">", x, y]
- | ">=" addExpr:y -> [#binop, ">=", x, y]
- | "<" addExpr:y -> [#binop, "<", x, y]
- | "<=" addExpr:y -> [#binop, "<=", x, y]
- | "instanceof" addExpr:y -> [#binop, "instanceof", x, y]
- )
- | addExpr,
- addExpr = addExpr:x "+" mulExpr:y -> [#binop, "+", x, y]
- | addExpr:x "-" mulExpr:y -> [#binop, "-", x, y]
- | mulExpr,
- mulExpr = mulExpr:x "*" unary:y -> [#binop, "*", x, y]
- | mulExpr:x "/" unary:y -> [#binop, "/", x, y]
- | mulExpr:x "%" unary:y -> [#binop, "%", x, y]
- | unary,
- unary = "-" postfix:p -> [#unop, "-", p]
- | "+" postfix:p -> [#unop, "+", p]
- | "++" postfix:p -> [#preop, "++", p]
- | "--" postfix:p -> [#preop, "--", p]
- | "!" unary:p -> [#unop, "!", p]
- | "void" unary:p -> [#unop, "void", p]
- | "delete" unary:p -> [#unop, "delete", p]
- | "typeof" unary:p -> [#unop, "typeof", p]
- | postfix,
- postfix = primExpr:p ( spacesNoNl "++" -> [#postop, "++", p]
- | spacesNoNl "--" -> [#postop, "--", p]
- | empty -> p
- ),
- primExpr = primExpr:p ( "[" expr:i "]" -> [#getp, i, p]
- | "." "name":m "(" listOf(#expr, ','):as ")" -> [#send, m, p].concat(as)
- | "." "name":f -> [#getp, [#string, f], p]
- | "(" listOf(#expr, ','):as ")" -> [#call, p].concat(as)
- )
- | primExprHd,
- primExprHd = "(" expr:e ")" -> e
- | "this" -> [#this]
- | "name":n -> [#get, n]
- | "number":n -> [#number, n]
- | "string":s -> [#string, s]
- | "function" funcRest
- | "new" "name":n "(" listOf(#expr, ','):as ")" -> [#new, n].concat(as)
- | "[" listOf(#expr, ','):es "]" -> [#arr].concat(es)
- | json,
- json = "{" listOf(#jsonBinding, ','):bs "}" -> [#json].concat(bs),
- jsonBinding = jsonPropName:n ":" expr:v -> [#binding, n, v],
- jsonPropName = "name" | "number" | "string",
- formal = spaces "name",
- funcRest = "(" listOf(#formal, ','):fs ")" "{" srcElems:body "}" -> [#func, fs, body],
- sc = spacesNoNl ('\n' | &'}' | end)
- | ";",
- binding = "name":n ( "=" expr
- | empty -> [#get, 'undefined'] ):v -> [#var, n, v],
- block = "{" srcElems:ss "}" -> ss,
- stmt = block
- | "var" listOf(#binding, ','):bs sc -> [#begin].concat(bs)
- | "if" "(" expr:c ")" stmt:t ( "else" stmt
- | empty -> [#get, 'undefined'] ):f -> [#if, c, t, f]
- | "while" "(" expr:c ")" stmt:s -> [#while, c, s]
- | "do" stmt:s "while" "(" expr:c ")" sc -> [#doWhile, s, c]
- | "for" "(" ( "var" binding
- | expr
- | empty -> [#get, 'undefined'] ):i
- ";" ( expr
- | empty -> [#get, 'true'] ):c
- ";" ( expr
- | empty -> [#get, 'undefined'] ):u
- ")" stmt:s -> [#for, i, c, u, s]
- | "for" "(" ( "var" "name":n -> [#var, n, [#get, 'undefined']]
- | expr ):v
- "in" expr:e
- ")" stmt:s -> [#forIn, v, e, s]
- | "switch" "(" expr:e ")" "{"
- ( "case" expr:c ":" srcElems:cs -> [#case, c, cs]
- | "default" ":" srcElems:cs -> [#default, cs] )*:cs
- "}" -> [#switch, e].concat(cs)
- | "break" sc -> [#break]
- | "continue" sc -> [#continue]
- | "throw" spacesNoNl expr:e sc -> [#throw, e]
- | "try" block:t "catch" "(" "name":e ")" block:c
- ( "finally" block
- | empty -> [#get, 'undefined'] ):f -> [#try, t, e, c, f]
- | "return" ( expr
- | empty -> [#get, 'undefined'] ):e sc -> [#return, e]
- | "with" "(" expr:x ")" stmt:s -> [#with, x, s]
- | expr:e sc -> e
- | ";" -> [#get, "undefined"],
- srcElem = "function" "name":n funcRest:f -> [#var, n, f]
- | stmt,
- srcElems = srcElem*:ss -> [#begin].concat(ss),
-
- topLevel = srcElems:r spaces end -> r
-}
-BSJSParser.hexDigits = "0123456789abcdef"
-BSJSParser.keywords = { }
-keywords = ["break", "case", "catch", "continue", "default", "delete", "do", "else", "finally", "for", "function", "if", "in",
- "instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "ometa"]
-for (var idx = 0; idx < keywords.length; idx++)
- BSJSParser.keywords[keywords[idx]] = true
-BSJSParser._isKeyword = function(k) { return this.keywords.hasOwnProperty(k) }
-
-
-ometa BSSemActionParser <: BSJSParser {
- curlySemAction = "{" expr:r sc "}" spaces -> r
- | "{" (srcElem:s &srcElem -> s)*:ss
- ( expr:r sc -> [#return, r] | srcElem):s {ss.push(s)}
- "}" spaces -> [#send, #call,
- [#func, [], [#begin].concat(ss)],
- [#this]],
- semAction = curlySemAction
- | primExpr:r spaces -> r
-}
-
-ometa BSJSTranslator {
- trans = [:t apply(t):ans] -> ans,
- curlyTrans = [#begin curlyTrans:r] -> r
- | [#begin trans*:rs] -> ('{' + rs.join(';') + '}')
- | trans:r -> ('{' + r + '}'),
-
- this -> 'this',
- break -> 'break',
- continue -> 'continue',
- number :n -> ('(' + n + ')'),
- string :s -> s.toProgramString(),
- arr trans*:xs -> ('[' + xs.join(',') + ']'),
- unop :op trans:x -> ('(' + op + ' ' + x + ')'),
- getp trans:fd trans:x -> (x + '[' + fd + ']'),
- get :x -> x,
- set trans:lhs trans:rhs -> ('(' + lhs + '=' + rhs + ')'),
- mset trans:lhs :op trans:rhs -> ('(' + lhs + op + '=' + rhs + ')'),
- binop :op trans:x trans:y -> ('(' + x + ' ' + op + ' ' + y + ')'),
- preop :op trans:x -> (op + x),
- postop :op trans:x -> (x + op),
- return trans:x -> ('return ' + x),
- with trans:x curlyTrans:s -> ('with(' + x + ')' + s),
- if trans:cond curlyTrans:t curlyTrans:e -> ('if(' + cond + ')' + t + 'else' + e),
- condExpr trans:cond trans:t trans:e -> ('(' + cond + '?' + t + ':' + e + ')'),
- while trans:cond curlyTrans:body -> ('while(' + cond + ')' + body),
- doWhile curlyTrans:body trans:cond -> ('do' + body + 'while(' + cond + ')'),
- for trans:init trans:cond trans:upd
- curlyTrans:body -> ('for(' + init + ';' + cond + ';' + upd + ')' + body),
- forIn trans:x trans:arr curlyTrans:body -> ('for(' + x + ' in ' + arr + ')' + body),
- begin trans:x end -> x,
- begin (trans:x
- ( (?(x[x.length - 1] == '}') | end) -> x
- | empty -> (x + ';')
- )
- )*:xs -> ('{' + xs.join('') + '}'),
- func :args curlyTrans:body -> ('(function (' + args.join(',') + ')' + body + ')'),
- call trans:fn trans*:args -> (fn + '(' + args.join(',') + ')'),
- send :msg trans:recv trans*:args -> (recv + '.' + msg + '(' + args.join(',') + ')'),
- new :cls trans*:args -> ('new ' + cls + '(' + args.join(',') + ')'),
- var :name trans:val -> ('var ' + name + '=' + val),
- throw trans:x -> ('throw ' + x),
- try curlyTrans:x :name curlyTrans:c curlyTrans:f -> ('try ' + x + 'catch(' + name + ')' + c + 'finally' + f),
- json trans*:props -> ('({' + props.join(',') + '})'),
- binding :name trans:val -> (name.toProgramString() + ': ' + val),
- switch trans:x trans*:cases -> ('switch(' + x + '){' + cases.join(';') + '}'),
- case trans:x trans:y -> ('case ' + x + ': '+ y),
- default trans:y -> ('default: ' + y)
-}
View
124 bs-ometa-compiler.txt
@@ -1,124 +0,0 @@
-ometa BSOMetaParser <: Parser {
- fromTo :x :y = seq(x) (~seq(y) char)* seq(y),
- space = ^space | fromTo('//', '\n') | fromTo('/*', '*/'),
- nameFirst = '_' | '$' | letter,
- nameRest = nameFirst | digit,
- tsName = firstAndRest(#nameFirst, #nameRest):xs -> xs.join(''),
- name = spaces tsName,
- eChar = '\\' char:c -> unescape('\\' +c)
- | char,
- tsString = '\'' (~'\'' eChar)*:xs '\'' -> xs.join(''),
- characters = '`' '`' (~('\'' '\'') eChar)*:xs '\'' '\'' -> [#App, #seq, xs.join('').toProgramString()],
- sCharacters = '"' (~'"' eChar)*:xs '"' -> [#App, #token, xs.join('').toProgramString()],
- string = (('#' | '`') tsName | tsString):xs -> [#App, #exactly, xs.toProgramString()],
- number = ('-' | empty -> ''):sign digit+:ds -> [#App, #exactly, sign + ds.join('')],
- keyword :xs = token(xs) ~letterOrDigit -> xs,
- args = '(' listOf(#hostExpr, ','):xs ")" -> xs
- | empty -> [],
- application = "^" name:rule args:as -> [#App, "super", "'" + rule + "'"].concat(as)
- | name:grm "." name:rule args:as -> [#App, "foreign", grm, "'" + rule + "'"].concat(as)
- | name:rule args:as -> [#App, rule].concat(as),
- hostExpr = BSSemActionParser.expr:r BSJSTranslator.trans(r),
- curlyHostExpr = BSSemActionParser.curlySemAction:r BSJSTranslator.trans(r),
- primHostExpr = BSSemActionParser.semAction:r BSJSTranslator.trans(r),
- atomicHostExpr = curlyHostExpr | primHostExpr,
- semAction = curlyHostExpr:x -> [#Act, x]
- | "!" atomicHostExpr:x -> [#Act, x],
- arrSemAction = "->" atomicHostExpr:x -> [#Act, x],
- semPred = "?" atomicHostExpr:x -> [#Pred, x],
- expr = expr5(true):x ("|" expr5(true))+:xs -> [#Or, x].concat(xs)
- | expr5(true):x ("||" expr5(true))+:xs -> [#XOr, x].concat(xs)
- | expr5(false),
- expr5 :ne = interleavePart:x ("&&" interleavePart)+:xs -> [#Interleave, x].concat(xs)
- | expr4(ne),
- interleavePart = "(" expr4(true):part ")" -> ["1", part]
- | expr4(true):part modedIPart(part),
- modedIPart = [#And [#Many :part]] -> ["*", part]
- | [#And [#Many1 :part]] -> ["+", part]
- | [#And [#Opt :part]] -> ["?", part]
- | :part -> ["1", part],
- expr4 :ne = expr3*:xs arrSemAction:act -> [#And].concat(xs).concat([act])
- | ?ne expr3+:xs -> [#And].concat(xs)
- | ?(ne == false) expr3*:xs -> [#And].concat(xs),
- optIter :x = '*' -> [#Many, x]
- | '+' -> [#Many1, x]
- | '?' -> [#Opt, x]
- | empty -> x,
- optBind :x = ':' name:n -> { this.locals.push(n); [#Set, n, x] }
- | empty -> x,
- expr3 = ":" name:n -> { this.locals.push(n); [#Set, n, [#App, #anything]] }
- | (expr2:x optIter(x) | semAction):e optBind(e)
- | semPred,
- expr2 = "~" expr2:x -> [#Not, x]
- | "&" expr1:x -> [#Lookahead, x]
- | expr1,
- expr1 = application
- | ( keyword('undefined') | keyword('nil')
- | keyword('true') | keyword('false') ):x -> [#App, #exactly, x]
- | spaces (characters | sCharacters | string | number)
- | "[" expr:x "]" -> [#Form, x]
- | "<" expr:x ">" -> [#ConsBy, x]
- | "@<" expr:x ">" -> [#IdxConsBy, x]
- | "(" expr:x ")" -> x,
- ruleName = name
- | spaces tsString,
- rule = &(ruleName:n) !(this.locals = ['$elf=this', '_fromIdx=this.input.idx'])
- rulePart(n):x ("," rulePart(n))*:xs -> [#Rule, n, this.locals, [#Or, x].concat(xs)],
- rulePart :rn = ruleName:n ?(n == rn) expr4:b1 ( "=" expr:b2 -> [#And, b1, b2]
- | empty -> b1
- ),
- grammar = keyword('ometa') name:n
- ( "<:" name | empty -> 'OMeta' ):sn
- "{" listOf(#rule, ','):rs "}" BSOMetaOptimizer.optimizeGrammar(
- [#Grammar, n, sn].concat(rs)
- )
-}
-
-// By dispatching on the head of a list, the following idiom allows translators to avoid doing a linear search.
-// (Note that the "=" in a rule definition is optional, so you can give your rules an "ML feel".)
-ometa BSOMetaTranslator {
- App 'super' anything+:args -> [this.sName, '._superApplyWithArgs(this,', args.join(','), ')'] .join(''),
- App :rule anything+:args -> ['this._applyWithArgs("', rule, '",', args.join(','), ')'] .join(''),
- App :rule -> ['this._apply("', rule, '")'] .join(''),
- Act :expr -> expr,
- Pred :expr -> ['this._pred(', expr, ')'] .join(''),
- Or transFn*:xs -> ['this._or(', xs.join(','), ')'] .join(''),
- XOr transFn*:xs {xs.unshift((this.name + "." + this.rName).toProgramString())}
- -> ['this._xor(', xs.join(','), ')'] .join(''),
- And notLast(#trans)*:xs trans:y
- {xs.push('return ' + y)} -> ['(function(){', xs.join(';'), '}).call(this)'] .join(''),
- And -> 'undefined',
- Opt transFn:x -> ['this._opt(', x, ')'] .join(''),
- Many transFn:x -> ['this._many(', x, ')'] .join(''),
- Many1 transFn:x -> ['this._many1(', x, ')'] .join(''),
- Set :n trans:v -> [n, '=', v] .join(''),
- Not transFn:x -> ['this._not(', x, ')'] .join(''),
- Lookahead transFn:x -> ['this._lookahead(', x, ')'] .join(''),
- Form transFn:x -> ['this._form(', x, ')'] .join(''),
- ConsBy transFn:x -> ['this._consumedBy(', x, ')'] .join(''),
- IdxConsBy transFn:x -> ['this._idxConsumedBy(', x, ')'] .join(''),
- JumpTable jtCase*:cases -> this.jumpTableCode(cases),
- Interleave intPart*:xs -> ['this._interleave(', xs.join(','), ')'] .join(''),
-
- Rule :name {this.rName = name}
- locals:ls trans:body -> ['\n"', name, '":function(){', ls, 'return ', body, '}'] .join(''),
- Grammar :name :sName
- {this.name = name}
- {this.sName = sName}
- trans*:rules -> [name, '=objectThatDelegatesTo(', sName, ',{', rules.join(','), '})'].join(''),
- intPart = [:mode transFn:part] -> (mode.toProgramString() + "," + part),
- jtCase = [:x trans:e] -> [x.toProgramString(), e],
- locals = [string+:vs] -> ['var ', vs.join(','), ';'] .join('')
- | [] -> '',
- trans = [:t apply(t):ans] -> ans,
- transFn = trans:x -> ['(function(){return ', x, '})'] .join('')
-}
-BSOMetaTranslator.jumpTableCode = function(cases) {
- var buf = new StringBuffer()
- buf.nextPutAll("(function(){switch(this._apply('anything')){")
- for (var i = 0; i < cases.length; i += 1)
- buf.nextPutAll("case " + cases[i][0] + ":return " + cases[i][1] + ";")
- buf.nextPutAll("default: throw fail}}).call(this)")
- return buf.contents()
-}
-
View
9 bs-ometa-js-compiler.txt
@@ -1,9 +0,0 @@
-ometa BSOMetaJSParser <: BSJSParser {
- srcElem = spaces BSOMetaParser.grammar:r sc -> r
- | ^srcElem
-}
-
-ometa BSOMetaJSTranslator <: BSJSTranslator {
- Grammar = BSOMetaTranslator.Grammar
-}
-
View
93 bs-ometa-optimizer.txt
@@ -1,93 +0,0 @@
-// TODO: turn off the "seq" inliner when G.seq !== OMeta.seq (will require some refactoring)
-// TODO: add a factorizing optimization (will make jumptables more useful)
-
-ometa BSNullOptimization {
- setHelped = !(this._didSomething = true),
- helped = ?this._didSomething,
- trans = [:t ?(this[t] != undefined) apply(t):ans] -> ans,
- optimize = trans:x helped -> x,
-
- App :rule anything*:args -> ['App', rule].concat(args),
- Act :expr -> ['Act', expr],
- Pred :expr -> ['Pred', expr],
- Or trans*:xs -> ['Or'].concat(xs),
- XOr trans*:xs -> ['XOr'].concat(xs),
- And trans*:xs -> ['And'].concat(xs),
- Opt trans:x -> ['Opt', x],
- Many trans:x -> ['Many', x],
- Many1 trans:x -> ['Many1', x],
- Set :n trans:v -> ['Set', n, v],
- Not trans:x -> ['Not', x],
- Lookahead trans:x -> ['Lookahead', x],
- Form trans:x -> ['Form', x],
- ConsBy trans:x -> ['ConsBy', x],
- IdxConsBy trans:x -> ['IdxConsBy', x],
- JumpTable ([:c trans:e] -> [c, e])*:ces -> ['JumpTable'].concat(ces),
- Interleave ([:m trans:p] -> [m, p])*:xs -> ['Interleave'].concat(xs),
- Rule :name :ls trans:body -> ['Rule', name, ls, body]
-}
-BSNullOptimization.initialize = function() { this._didSomething = false }
-
-ometa BSAssociativeOptimization <: BSNullOptimization {
- And trans:x end setHelped -> x,
- And transInside('And'):xs -> ['And'].concat(xs),
- Or trans:x end setHelped -> x,
- Or transInside('Or'):xs -> ['Or'].concat(xs),
- XOr trans:x end setHelped -> x,
- XOr transInside('XOr'):xs -> ['XOr'].concat(xs),
-
- transInside :t = [exactly(t) transInside(t):xs] transInside(t):ys setHelped -> xs.concat(ys)
- | trans:x transInside(t):xs -> [x].concat(xs)
- | -> []
-}
-
-ometa BSSeqInliner <: BSNullOptimization {
- App = 'seq' :s end seqString(s):cs setHelped -> ['And'].concat(cs).concat([['Act', s]])
- | :rule anything*:args -> ['App', rule].concat(args),
- inlineChar = BSOMetaParser.eChar:c ~end -> ['App', 'exactly', c.toProgramString()],
- seqString = &(:s ?(typeof s === 'string'))
- ( ['"' inlineChar*:cs '"' ] -> cs
- | ['\'' inlineChar*:cs '\''] -> cs
- )
-}
-
-JumpTable = function(choiceOp, choice) {
- this.choiceOp = choiceOp
- this.choices = {}
- this.add(choice)
-}
-JumpTable.prototype.add = function(choice) {
- var c = choice[0], t = choice[1]
- if (this.choices[c]) {
- if (this.choices[c][0] == this.choiceOp)
- this.choices[c].push(t)
- else
- this.choices[c] = [this.choiceOp, this.choices[c], t]
- }
- else
- this.choices[c] = t
-}
-JumpTable.prototype.toTree = function() {
- var r = ['JumpTable'], choiceKeys = ownPropertyNames(this.choices)
- for (var i = 0; i < choiceKeys.length; i += 1)
- r.push([choiceKeys[i], this.choices[choiceKeys[i]]])
- return r
-}
-ometa BSJumpTableOptimization <: BSNullOptimization {
- Or (jtChoices('Or') | trans)*:cs -> ['Or'].concat(cs),
- XOr (jtChoices('XOr') | trans)*:cs -> ['XOr'].concat(cs),
- quotedString = &string [ '"' (BSOMetaParser.eChar:c ~end -> c)*:cs '"'
- | '\'' (BSOMetaParser.eChar:c ~end -> c)*:cs '\''] -> cs.join(''),
- jtChoice = ['And' ['App' 'exactly' quotedString:x] anything*:rest] -> [x, ['And'].concat(rest)]
- | ['App' 'exactly' quotedString:x] -> [x, ['Act', x.toProgramString()]],
- jtChoices :op = jtChoice:c {new JumpTable(op, c)}:jt (jtChoice:c {jt.add(c)})* setHelped -> jt.toTree()
-}
-
-ometa BSOMetaOptimizer {
- optimizeGrammar = ['Grammar' :n :sn optimizeRule*:rs] -> ['Grammar', n, sn].concat(rs),
- optimizeRule = :r (BSSeqInliner.optimize(r):r | empty)
- ( BSAssociativeOptimization.optimize(r):r
- | BSJumpTableOptimization.optimize(r):r
- )* -> r
-}
-
View
3  bs-project-list-parser.js
@@ -1,3 +0,0 @@
-ProjectListPars