| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | 
							- 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()
 
- }
 
 
  |