123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- start = method
- separator = [ \t\v\f\u00A0\uFEFF\n\r\u2028\u2029]+
- comments = ('"' [^"]* '"')+
- ws = (separator / comments)*
- maybeDotsWs = ("." / separator / comments)*
- identifier = first:[a-zA-Z] others:[a-zA-Z0-9]* {return first + others.join("");}
- keyword = first:identifier last:":" {return first + last;}
- selector = first:[a-zA-Z] others:[a-zA-Z0-9\:]* {return first + others.join("");}
- className = first:[A-Z] others:[a-zA-Z0-9]* {return first + others.join("");}
- string = "'" val:(("''" {return "'";} / [^'])*) "'" {
- return $globals.ValueNode._new()
- ._location_(location())
- ._source_(text())
- ._value_(val.join(""));
- }
- character = "$" char:.
- {
- return $globals.ValueNode._new()
- ._location_(location())
- ._source_(text())
- ._value_(char);
- }
- symbol = "#" rest:bareSymbol {return rest;}
- bareSymbol = val:(selector / binarySelector / node:string {return node._value();})
- {
- return $globals.ValueNode._new()
- ._location_(location())
- ._source_(text())
- ._value_(val);
- }
- number = n:(numberExp / hex / float / integer) {
- return $globals.ValueNode._new()
- ._location_(location())
- ._source_(text())
- ._value_(n);
- }
- numberExp = n:((float / integer) "e" integer) {return parseFloat(n.join(""));}
- hex = neg:"-"? "16r" num:[0-9a-fA-F]+ {return parseInt(((neg || '') + num.join("")), 16);}
- float = neg:"-"? digits:[0-9]+ "." dec:[0-9]+ {return parseFloat(((neg || '') + digits.join("") + "." + dec.join("")), 10);}
- integer = neg:"-"? digits:[0-9]+ {return (parseInt((neg || '') + digits.join(""), 10));}
- literalArray = "#(" rest:wsLiteralArrayContents ws ")" {
- return rest
- ._location_(location())
- ._source_(text());
- }
- bareLiteralArray = "(" rest:wsLiteralArrayContents ws ")" {
- return rest
- ._location_(location())
- ._source_(text());
- }
- literalArrayElement = parseTimeLiteral / bareLiteralArray / bareSymbol
- wsLiteralArrayContents = lits:(ws lit:literalArrayElement {return lit._value();})* {
- return $globals.ValueNode._new()
- ._value_(lits);
- }
- dynamicArray = "{" ws expressions:expressions? maybeDotsWs "}" {
- return $globals.DynamicArrayNode._new()
- ._location_(location())
- ._source_(text())
- ._dagChildren_(expressions || []);
- }
- dynamicDictionary = "#{" ws expressions:associations? maybeDotsWs "}" {
- return $globals.DynamicDictionaryNode._new()
- ._location_(location())
- ._source_(text())
- ._dagChildren_(expressions || []);
- }
- pseudoVariable = val:(
- 'true' {return true;}
- / 'false' {return false;}
- / 'nil' {return nil;}) {
- return $globals.ValueNode._new()
- ._location_(location())
- ._source_(text())
- ._value_(val);
- }
- parseTimeLiteral = pseudoVariable / number / literalArray / string / symbol / character
- runtimeLiteral = dynamicDictionary / dynamicArray / block
- literal = runtimeLiteral / parseTimeLiteral
- variable = identifier:identifier {
- return $globals.VariableNode._new()
- ._location_(location())
- ._source_(text())
- ._value_(identifier);
- }
- reference = variable
- binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("");}
- unarySelector = identifier
- wsKeywordPattern = 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 / keywordSend
- wsExpressionsRest = ws "." maybeDotsWs expression:expression {return expression;}
- expressions = 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;}
- statementsWs = ret:ret maybeDotsWs {return [ret];}
- / exps:expressions ws "." maybeDotsWs ret:ret maybeDotsWs {
- var expressions = exps;
- expressions.push(ret);
- return expressions;
- }
- / expressions:expressions? maybeDotsWs {
- return expressions || [];
- }
- wsSequenceWs = (ws js:jsSequence ws { return js; }) / wsStSequenceWs
- wsStSequenceWs = ws temps:temps? maybeDotsWs statements:statementsWs? {
- return $globals.SequenceNode._new()
- ._location_(location())
- ._source_(text())
- ._temps_(temps || [])
- ._dagChildren_(statements || []);
- }
- jsSequence = jsStatement
- block = '[' params:wsBlockParamList? sequence:wsSequenceWs? ']' {
- return $globals.BlockNode._new()
- ._location_(location())
- ._source_(text())
- ._parameters_(params || [])
- ._dagChildren_([sequence._asBlockSequenceNode()]);
- }
- operand = literal / reference / subexpression
- wsUnaryMessage = 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 / wsKeywordMessage
- cascade = 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 / legacyJsStatement
- legacyJsStatement = "<" val:((">>" {return ">";} / [^>])*) ">" {
- 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:string ws ">" {
- return $globals.JSStatementNode._new()
- ._location_(location())
- ._source_(val._value())
- }
- 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;}
- associations = first:associationSend others:wsAssociationsRest* { return first.concat.apply(first, others); }
|