| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 | start = methodseparator =	[ \t\v\f\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF\n\r\u2028\u2029]+comments = ('"' [^"]* '"')+ws = (separator / comments)*maybeDotsWs = ('.' / separator / comments)*identifier = $([a-zA-Z] [a-zA-Z0-9]*)keyword = $(identifier ':')className = $([A-Z] [a-zA-Z0-9]*)string = val:rawString {	return $globals.ValueNode._new()		._location_(location())		._source_(text())		._value_(val);}rawString = '\'' val:(('\'\'' {return '\'';} / [^'])*) '\'' {return val.join('');}character = '$' char:. {	return $globals.ValueNode._new()		._location_(location())		._source_(text())		._value_(char);}symbol = '#' rest:bareSymbol {return rest;}bareSymbol = val:($(keyword+) / binarySelector / unarySelector / rawString) {	return $globals.ValueNode._new()		._location_(location())		._source_(text())		._value_(val);}number = val:rawNumber {	return $globals.ValueNode._new()		._location_(location())		._source_(text())		._value_(val);}rawNumber = numberExp / hex / float / integernumberExp = n:$((float / integer) 'e' integer) {return parseFloat(n);}hex = neg:'-'? '16r' num:$[0-9a-fA-F]+ {	return parseInt(((neg || '') + num), 16);}float = n:$('-'? [0-9]+ '.' [0-9]+) {return parseFloat(n, 10);}integer = n:$('-'? [0-9]+) {return parseInt(n, 10);}literalArray = '#(' rest:wsLiteralArrayContents ws ')' {	return rest		._location_(location())		._source_(text());}bareLiteralArray = '(' rest:wsLiteralArrayContents ws ')' {	return rest		._location_(location())		._source_(text());}literalArrayElement = parseTimeLiteral / bareLiteralArray / bareSymbolwsLiteralArrayContents =	lits:(ws lit:literalArrayElement {return lit._value();})* {		return $globals.ValueNode._new()			._value_(lits);	}dynamicArray = '{' expressions:wsExpressions? maybeDotsWs '}' {	return $globals.DynamicArrayNode._new()		._location_(location())		._source_(text())		._dagChildren_(expressions || []);}dynamicDictionary = '#{' expressions:wsAssociations? maybeDotsWs  '}' {	return $globals.DynamicDictionaryNode._new()		._location_(location())		._source_(text())		._dagChildren_(expressions || []);}pseudoVariable = val:(	'true' {return true;} /	'false' {return false;} /	'nil' {return null;}) {	return $globals.ValueNode._new()		._location_(location())		._source_(text())		._value_(val);}parseTimeLiteral =	pseudoVariable / number / literalArray / string / symbol / characterruntimeLiteral = dynamicDictionary / dynamicArray / blockliteral = runtimeLiteral / parseTimeLiteralvariable = identifier:identifier {	return $globals.VariableNode._new()		._location_(location())		._source_(text())		._value_(identifier);}reference = variablebinarySelector = $[\\+*/=><,@%~|&-]+unarySelector = identifierwsKeywordPattern =	pairs:(ws key:keyword ws arg:identifier {return {key:key, arg:arg};})+ {		var selector = '';		var params = [];		for(var i = 0; i < pairs.length; i++) {			selector += pairs[i].key;			params.push(pairs[i].arg);		}		return [selector, params];	}wsBinaryPattern = ws selector:binarySelector ws arg:identifier {	return [selector, [arg]];}wsUnaryPattern = ws selector:unarySelector {return [selector, []];}expression = assignment / cascade / keywordSendwsExpressionsRest = ws '.' maybeDotsWs expression:expression {	return expression;}wsExpressions = maybeDotsWs first:expression others:wsExpressionsRest* {	return [first].concat(others);}assignment = variable:variable ws ':=' ws expression:expression {	return $globals.AssignmentNode._new()		._location_(location())		._source_(text())		._left_(variable)		._right_(expression);}ret = '^' ws expression:expression {	return $globals.ReturnNode._new()		._location_(location())		._source_(text())		._dagChildren_([expression]);}  temps = '|' vars:(ws variable:identifier {return variable;})* ws '|' {	return vars;}wsBlockParamList =	params:((ws ':' ws param:identifier {return param;})+) ws '|' {		return params;	}subexpression = '(' ws expression:expression ws ')' {	return expression;}wsStatementsWs =	maybeDotsWs ret:ret maybeDotsWs {return [ret];} /	exps:wsExpressions ws '.' maybeDotsWs ret:ret maybeDotsWs {		var expressions = exps;		expressions.push(ret);		return expressions;	} /	expressions:wsExpressions? maybeDotsWs {return expressions || [];}wsSequenceWs = (ws js:jsSequence ws {return js;}) / wsStSequenceWswsStSequenceWs = ws temps:temps? statements:wsStatementsWs? {	return $globals.SequenceNode._new()		._location_(location())		._source_(text())		._temps_(temps || [])		._dagChildren_(statements || []);}jsSequence = jsStatementblock = '[' params:wsBlockParamList? sequence:wsSequenceWs ']' {	return $globals.BlockNode._new()		._location_(location())		._source_(text())		._parameters_(params || [])		._dagChildren_([sequence._asBlockSequenceNode()]);}operand = literal / reference / subexpressionwsUnaryMessage = ws selector:unarySelector !':' {	return $globals.SendNode._new()		._location_(location())		._source_(text())		._selector_(selector);}unarySend = receiver:operand tail:wsUnaryMessage* {	return receiver._withTail_(tail);}wsBinaryMessage = ws selector:binarySelector ws arg:unarySend {	return $globals.SendNode._new()		._location_(location())		._source_(text())		._selector_(selector)		._arguments_([arg]);}binarySend = receiver:unarySend tail:wsBinaryMessage* {	return receiver._withTail_(tail);}wsKeywordMessage =	pairs:(ws key:keyword ws arg:binarySend {return {key:key, arg:arg};})+ {		var selector = '';		var args = [];		for(var i = 0; i < pairs.length; i++) {			selector += pairs[i].key;			args.push(pairs[i].arg);		}		return $globals.SendNode._new()			._location_(location())			._source_(text())			._selector_(selector)			._arguments_(args);	}keywordSend = receiver:binarySend tail:wsKeywordMessage? {	return tail ? receiver._withTail_([tail]) : receiver;}wsMessage = wsBinaryMessage / wsUnaryMessage / wsKeywordMessagecascade =	send:keywordSend & {return send._isSendNode();}	messages:(ws ';' mess:wsMessage {return mess;})+ {		messages.unshift(send);		return $globals.CascadeNode._new()			._location_(location())			._source_(text())			._dagChildren_(messages);	}jsStatement = pragmaJsStatement / legacyJsStatementlegacyJsStatement =	'<' val:(('>>' {return '>';} / [^>])*) '>'	& {return !/^\s*inlineJS/.test(val.join(''));} {		console.warn('Use of <...js code...> is deprecated, in:\n' + val.join(''));		return $globals.JSStatementNode._new()			._location_(location())			._source_(val.join(''))	}pragmaJsStatement = '<' ws 'inlineJS:' ws val:rawString ws '>' {	return $globals.JSStatementNode._new()		._location_(location())		._source_(val)}method =	pattern:(wsKeywordPattern / wsBinaryPattern / wsUnaryPattern)	sequence:wsSequenceWs {		return $globals.MethodNode._new()			._location_(location())			._source_(text())			._selector_(pattern[0])			._arguments_(pattern[1])			._dagChildren_([sequence]);	}associationSend =	send:binarySend	& { return send._isSendNode() && send._selector() === '->' } {		return [send._receiver(), send._arguments()[0]];	}wsAssociationsRest = ws '.' maybeDotsWs expression:associationSend {	return expression;}wsAssociations = maybeDotsWs first:associationSend others:wsAssociationsRest* {	return first.concat.apply(first, others);}
 |