| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 | 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:(float / integer) {		  return smalltalk.ValueNode._new()               	   	._value_(n)               	 }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("").replace(/\\/g, '\\\\')}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 / binarySend / jsStatementexpressionList = 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      = temps:temps? ws statements:statements? ws {	      	  return smalltalk.SequenceNode._new()	      	  	._temps_(temps || [])	      	  	._nodes_(statements || [])		}block         = '[' 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])	      }
 |