| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 | start = methodseparator      = [ \t\v\f\u00A0\uFEFF\n\r\u2028\u2029]+comments       = (["][^"]*["])+ws             = (separator / comments)*identifier     = first:[a-zA-Z] others:[a-zA-Z0-9]* {return first + others.join("")}varIdentifier  = first:[a-z] others:[a-zA-Z0-9]* {return first + others.join("")}keyword        = first:identifier last:[:] {return first + last}className      = first:[A-Z] others:[a-zA-Z0-9]* {return first + others.join("")}string         = ['] val:(("''" {return "'"} / [^'])*) ['] {                     return smalltalk.ValueNode._new()                            ._value_(val.join("").replace(/\"/ig, '"'))                 }symbol         = "#"val:(                         digits:[a-zA-Z0-9\:]+ {return digits.join("")}                       / node:string {return node._value()})*                  {                      return smalltalk.ValueNode._new()                             ._value_(smalltalk.symbolFor(val.join("").replace(/\"/ig, '"')))                  }number         = n:(hex / float / integer) {                     return smalltalk.ValueNode._new()                            ._value_(n)                 }hex            = neg:[-]? "16r" num:[0-9a-fA-F]+ {return parseInt((neg + num.join("")), 16)}float          = neg:[-]?int:[0-9]+ "." dec:[0-9]+ {return parseFloat((neg + int.join("") + "." + dec.join("")), 10)}integer        = neg:[-]?digits:[0-9]+ {return (parseInt(neg+digits.join(""), 10))}literalArray   = "#(" ws lits:(lit:literal ws {return lit._value()})* ws ")" {                     return smalltalk.ValueNode._new()                            ._value_(lits)                 }dynamicArray   = "{" ws expressions:expressions? ws "."? "}" {                     return smalltalk.DynamicArrayNode._new()                            ._nodes_(expressions)                 }dynamicDictionary = "#{" ws expressions: expressions? ws "}" {                        return smalltalk.DynamicDictionaryNode._new()                               ._nodes_(expressions)                    }pseudoVariable = val:(                   'true' {return true}                 / 'false' {return false}                 / 'nil' {return nil}) {                       return smalltalk.ValueNode._new()                              ._value_(val)                   }literal        = pseudoVariable / number / literalArray / dynamicDictionary / dynamicArray / string / symbol / blockvariable       = identifier:varIdentifier {                     return smalltalk.VariableNode._new()                            ._value_(identifier)                 }classReference = className:className {                     return smalltalk.ClassReferenceNode._new()                            ._value_(className)                 }reference      = variable / classReferencekeywordPair    = key:keyword ws arg:binarySend ws {return {key:key, arg: arg}}binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("")}unarySelector  = identifierkeywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg: arg}})+ {                     var keywords = [];                     var params = [];                     for(var i=0;i<pairs.length;i++){                         keywords.push(pairs[i].key);                     }                     for(var i=0;i<pairs.length;i++){                         params.push(pairs[i].arg);                     }                     return [keywords.join(""), params]                 }binaryPattern  = ws selector:binarySelector ws arg:identifier {return [selector, [arg]]}unaryPattern   = ws selector:unarySelector {return [selector, []]}expression     = assignment / cascade / keywordSend / binarySendexpressionList = ws "." ws expression:expression {return expression}expressions    = first:expression others:expressionList* {                     var result = [first];                     for(var i=0;i<others.length;i++) {                         result.push(others[i]);                     }                     return result;                 }assignment     = variable:variable ws ':=' ws expression:expression {                     return smalltalk.AssignmentNode._new()                            ._left_(variable)                            ._right_(expression)                 }ret            = '^' ws expression:expression ws '.'? {                     return smalltalk.ReturnNode._new()                            ._nodes_([expression])                 }  temps          = "|" vars:(ws variable:identifier ws {return variable})* "|" {return vars}blockParamList = params:((ws ":" ws param:identifier {return param})+) ws "|" {return params}subexpression  = '(' ws expression:expression ws ')' {return expression}statements     = ret:ret [.]* {return [ret]}                 / exps:expressions ws [.]+ ws ret:ret [.]* {                       var expressions = exps;                       expressions.push(ret);                       return expressions                   }                 / expressions:expressions? [.]* {                       return expressions || []                   }sequence       = jsSequence / stSequencestSequence     = temps:temps? ws statements:statements? ws {                     return smalltalk.SequenceNode._new()                            ._temps_(temps || [])                            ._nodes_(statements || [])                 }jsSequence     = jsStatementblock          = '[' ws params:blockParamList? ws sequence:sequence? ws ']' {                     return smalltalk.BlockNode._new()                            ._parameters_(params || [])                            ._nodes_([sequence._asBlockSequenceNode()])                 }operand        = literal / reference / subexpressionunaryMessage   = ws selector:unarySelector ![:] {                     return smalltalk.SendNode._new()                            ._selector_(selector)                 }unaryTail      = message:unaryMessage ws tail:unaryTail? ws {                     if(tail) {                         return tail._valueForReceiver_(message);                     }                     else {                         return message;                     }                 }unarySend      = receiver:operand ws tail:unaryTail? {                     if(tail) {                         return tail._valueForReceiver_(receiver);                     }                     else {                         return receiver;                     }                 }binaryMessage  = ws selector:binarySelector ws arg:(unarySend / operand) {                     return smalltalk.SendNode._new()                            ._selector_(selector)                            ._arguments_([arg])                 }binaryTail     = message:binaryMessage tail:binaryTail? {                     if(tail) {                         return tail._valueForReceiver_(message);                      }                     else {                         return message;                     }                 }binarySend     = receiver:unarySend tail:binaryTail? {                     if(tail) {                         return tail._valueForReceiver_(receiver);                     }                     else {                         return receiver;                     }                 }keywordMessage = ws pairs:(pair:keywordPair ws {return pair})+ {                     var selector = [];                     var args = [];                      for(var i=0;i<pairs.length;i++) {                          selector.push(pairs[i].key);                          args.push(pairs[i].arg);                      }                      return smalltalk.SendNode._new()                             ._selector_(selector.join(""))                             ._arguments_(args)                 }keywordSend    = receiver:binarySend tail:keywordMessage {                     return tail._valueForReceiver_(receiver);                 }message        = binaryMessage / unaryMessage / keywordMessagecascade        = ws send:(keywordSend / binarySend) messages:(ws ";" ws mess:message ws {return mess})+ {                     var cascade = [];                     cascade.push(send);                     for(var i=0;i<messages.length;i++) {                         cascade.push(messages[i]);                     }                     return smalltalk.CascadeNode._new()                            ._receiver_(send._receiver())                            ._nodes_(cascade)                 }jsStatement    = "<" val:((">>" {return ">"} / [^>])*) ">" {                     return smalltalk.JSStatementNode._new()                            ._source_(val.join(""))                 }method         = ws pattern:(keywordPattern / binaryPattern / unaryPattern) ws sequence:sequence? ws {                      return smalltalk.MethodNode._new()                             ._selector_(pattern[0])                             ._arguments_(pattern[1])                             ._nodes_([sequence])                 }
 |