parser.pegjs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. start = method
  2. separator = [ \t\v\f\u00A0\uFEFF\n\r\u2028\u2029]+
  3. comments = ('"' [^"]* '"')+
  4. ws = (separator / comments)*
  5. identifier = first:[a-zA-Z] others:[a-zA-Z0-9]* {return first + others.join("");}
  6. keyword = first:identifier last:":" {return first + last;}
  7. selector = first:[a-zA-Z] others:[a-zA-Z0-9\:]* {return first + others.join("");}
  8. className = first:[A-Z] others:[a-zA-Z0-9]* {return first + others.join("");}
  9. string = "'" val:(("''" {return "'";} / [^'])*) "'" {
  10. return $globals.ValueNode._new()
  11. ._position_((line()).__at(column()))
  12. ._source_(text())
  13. ._value_(val.join(""));
  14. }
  15. character = "$" char:.
  16. {
  17. return $globals.ValueNode._new()
  18. ._position_((line()).__at(column()))
  19. ._source_(text())
  20. ._value_(char);
  21. }
  22. symbol = "#" rest:bareSymbol {return rest;}
  23. bareSymbol = val:(selector / binarySelector / node:string {return node._value();})
  24. {
  25. return $globals.ValueNode._new()
  26. ._position_((line()).__at(column()))
  27. ._source_(text())
  28. ._value_(val);
  29. }
  30. number = n:(numberExp / hex / float / integer) {
  31. return $globals.ValueNode._new()
  32. ._position_((line()).__at(column()))
  33. ._source_(text())
  34. ._value_(n);
  35. }
  36. numberExp = n:((float / integer) "e" integer) {return parseFloat(n.join(""));}
  37. hex = neg:"-"? "16r" num:[0-9a-fA-F]+ {return parseInt(((neg || '') + num.join("")), 16);}
  38. float = neg:"-"? digits:[0-9]+ "." dec:[0-9]+ {return parseFloat(((neg || '') + digits.join("") + "." + dec.join("")), 10);}
  39. integer = neg:"-"? digits:[0-9]+ {return (parseInt((neg || '') + digits.join(""), 10));}
  40. literalArray = "#(" rest:literalArrayRest {return rest;}
  41. bareLiteralArray = "(" rest:literalArrayRest {return rest;}
  42. literalArrayRest = lits:(ws lit:(parseTimeLiteral / bareLiteralArray / bareSymbol) {return lit._value();})* ws ")" {
  43. return $globals.ValueNode._new()
  44. ._position_((line()).__at(column()))
  45. ._source_(text())
  46. ._value_(lits);
  47. }
  48. dynamicArray = "{" ws expressions:expressions? ws "."? "}" {
  49. return $globals.DynamicArrayNode._new()
  50. ._position_((line()).__at(column()))
  51. ._source_(text())
  52. ._nodes_(expressions || []);
  53. }
  54. dynamicDictionary = "#{" ws expressions:associations? ws "}" {
  55. return $globals.DynamicDictionaryNode._new()
  56. ._position_((line()).__at(column()))
  57. ._source_(text())
  58. ._nodes_(expressions || []);
  59. }
  60. pseudoVariable = val:(
  61. 'true' {return true;}
  62. / 'false' {return false;}
  63. / 'nil' {return nil;}) {
  64. return $globals.ValueNode._new()
  65. ._position_((line()).__at(column()))
  66. ._source_(text())
  67. ._value_(val);
  68. }
  69. parseTimeLiteral = pseudoVariable / number / literalArray / string / symbol / character
  70. runtimeLiteral = dynamicDictionary / dynamicArray / block
  71. literal = runtimeLiteral / parseTimeLiteral
  72. variable = identifier:identifier {
  73. return $globals.VariableNode._new()
  74. ._position_((line()).__at(column()))
  75. ._source_(text())
  76. ._value_(identifier);
  77. }
  78. reference = variable
  79. keywordPair = ws key:keyword ws arg:binarySend {return {key:key, arg:arg};}
  80. binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("");}
  81. unarySelector = identifier
  82. keywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg:arg};})+ {
  83. var selector = "";
  84. var params = [];
  85. for(var i = 0; i < pairs.length; i++){
  86. selector += pairs[i].key;
  87. params.push(pairs[i].arg);
  88. }
  89. return [selector, params];
  90. }
  91. binaryPattern = ws selector:binarySelector ws arg:identifier {return [selector, [arg]];}
  92. unaryPattern = ws selector:unarySelector {return [selector, []];}
  93. expression = assignment / cascade / keywordSend
  94. expressionList = ws "." ws expression:expression {return expression;}
  95. expressions = first:expression others:expressionList* { return [first].concat(others); }
  96. assignment = variable:variable ws ':=' ws expression:expression {
  97. return $globals.AssignmentNode._new()
  98. ._position_((line()).__at(column()))
  99. ._source_(text())
  100. ._left_(variable)
  101. ._right_(expression);
  102. }
  103. ret = '^' ws expression:expression ws '.'? {
  104. return $globals.ReturnNode._new()
  105. ._position_((line()).__at(column()))
  106. ._source_(text())
  107. ._nodes_([expression]);
  108. }
  109. temps = "|" vars:(ws variable:identifier {return variable;})* ws "|" {return vars;}
  110. blockParamList = params:((ws ":" ws param:identifier {return param;})+) ws "|" {return params;}
  111. subexpression = '(' ws expression:expression ws ')' {return expression;}
  112. statements = ret:ret "."* {return [ret];}
  113. / exps:expressions ws "."+ ws ret:ret "."* {
  114. var expressions = exps;
  115. expressions.push(ret);
  116. return expressions;
  117. }
  118. / expressions:expressions? "."* {
  119. return expressions || [];
  120. }
  121. sequence = jsSequence / stSequence
  122. stSequence = temps:temps? ws statements:statements? ws {
  123. return $globals.SequenceNode._new()
  124. ._position_((line()).__at(column()))
  125. ._source_(text())
  126. ._temps_(temps || [])
  127. ._nodes_(statements || []);
  128. }
  129. jsSequence = jsStatement
  130. block = '[' params:blockParamList? ws sequence:sequence? ws ']' {
  131. return $globals.BlockNode._new()
  132. ._position_((line()).__at(column()))
  133. ._source_(text())
  134. ._parameters_(params || [])
  135. ._nodes_([sequence._asBlockSequenceNode()]);
  136. }
  137. operand = literal / reference / subexpression
  138. unaryMessage = ws selector:unarySelector !":" {
  139. return $globals.SendNode._new()
  140. ._position_((line()).__at(column()))
  141. ._source_(text())
  142. ._selector_(selector);
  143. }
  144. unaryTail = message:unaryMessage ws tail:unaryTail? ws {
  145. if(tail) {
  146. return tail._valueForReceiver_(message);
  147. }
  148. else {
  149. return message;
  150. }
  151. }
  152. unarySend = receiver:operand ws tail:unaryTail? {
  153. if(tail) {
  154. return tail._valueForReceiver_(receiver);
  155. }
  156. else {
  157. return receiver;
  158. }
  159. }
  160. binaryMessage = ws selector:binarySelector ws arg:(unarySend / operand) {
  161. return $globals.SendNode._new()
  162. ._position_((line()).__at(column()))
  163. ._source_(text())
  164. ._selector_(selector)
  165. ._arguments_([arg]);
  166. }
  167. binaryTail = message:binaryMessage tail:binaryTail? {
  168. if(tail) {
  169. return tail._valueForReceiver_(message);
  170. }
  171. else {
  172. return message;
  173. }
  174. }
  175. binarySend = receiver:unarySend tail:binaryTail? {
  176. if(tail) {
  177. return tail._valueForReceiver_(receiver);
  178. }
  179. else {
  180. return receiver;
  181. }
  182. }
  183. keywordMessage = pairs:keywordPair+ {
  184. var selector = "";
  185. var args = [];
  186. for(var i = 0; i < pairs.length; i++) {
  187. selector += pairs[i].key;
  188. args.push(pairs[i].arg);
  189. }
  190. return $globals.SendNode._new()
  191. ._position_((line()).__at(column()))
  192. ._source_(text())
  193. ._selector_(selector)
  194. ._arguments_(args);
  195. }
  196. keywordSend = receiver:binarySend tail:keywordMessage? {
  197. if(tail) {
  198. return tail._valueForReceiver_(receiver);
  199. }
  200. else {
  201. return receiver;
  202. }
  203. }
  204. message = binaryMessage / unaryMessage / keywordMessage
  205. cascade = ws send:keywordSend & { return send._isSendNode(); } messages:(ws ";" ws mess:message {return mess;})+ {
  206. messages.unshift(send);
  207. return $globals.CascadeNode._new()
  208. ._position_((line()).__at(column()))
  209. ._source_(text())
  210. ._receiver_(send._receiver())
  211. ._nodes_(messages);
  212. }
  213. jsStatement = "<" val:((">>" {return ">";} / [^>])*) ">" {
  214. return $globals.JSStatementNode._new()
  215. ._position_((line()).__at(column()))
  216. ._source_(val.join(""))
  217. }
  218. method = pattern:(keywordPattern / binaryPattern / unaryPattern) ws sequence:sequence? ws {
  219. return $globals.MethodNode._new()
  220. ._position_((line()).__at(column()))
  221. ._source_(text())
  222. ._selector_(pattern[0])
  223. ._arguments_(pattern[1])
  224. ._nodes_([sequence]);
  225. }
  226. associationSend = send:binarySend & { return send._isSendNode() && send._selector() === "->" } { return [send._receiver(), send._arguments()[0]]; }
  227. associationList = ws "." ws expression:associationSend {return expression;}
  228. associations = first:associationSend others:associationList* { return first.concat.apply(first, others); }