parser.pegjs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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 keywords = [];
  84. var params = [];
  85. var i = 0;
  86. for(i = 0; i < pairs.length; i++){
  87. keywords.push(pairs[i].key);
  88. }
  89. for(i = 0; i < pairs.length; i++){
  90. params.push(pairs[i].arg);
  91. }
  92. return [keywords.join(""), params];
  93. }
  94. binaryPattern = ws selector:binarySelector ws arg:identifier {return [selector, [arg]];}
  95. unaryPattern = ws selector:unarySelector {return [selector, []];}
  96. expression = assignment / cascade / keywordSend / binarySend
  97. expressionList = ws "." ws expression:expression {return expression;}
  98. expressions = first:expression others:expressionList* { return [first].concat(others); }
  99. assignment = variable:variable ws ':=' ws expression:expression {
  100. return $globals.AssignmentNode._new()
  101. ._position_((line()).__at(column()))
  102. ._source_(text())
  103. ._left_(variable)
  104. ._right_(expression);
  105. }
  106. ret = '^' ws expression:expression ws '.'? {
  107. return $globals.ReturnNode._new()
  108. ._position_((line()).__at(column()))
  109. ._source_(text())
  110. ._nodes_([expression]);
  111. }
  112. temps = "|" vars:(ws variable:identifier {return variable;})* ws "|" {return vars;}
  113. blockParamList = params:((ws ":" ws param:identifier {return param;})+) ws "|" {return params;}
  114. subexpression = '(' ws expression:expression ws ')' {return expression;}
  115. statements = ret:ret "."* {return [ret];}
  116. / exps:expressions ws "."+ ws ret:ret "."* {
  117. var expressions = exps;
  118. expressions.push(ret);
  119. return expressions;
  120. }
  121. / expressions:expressions? "."* {
  122. return expressions || [];
  123. }
  124. sequence = jsSequence / stSequence
  125. stSequence = temps:temps? ws statements:statements? ws {
  126. return $globals.SequenceNode._new()
  127. ._position_((line()).__at(column()))
  128. ._source_(text())
  129. ._temps_(temps || [])
  130. ._nodes_(statements || []);
  131. }
  132. jsSequence = jsStatement
  133. block = '[' params:blockParamList? ws sequence:sequence? ws ']' {
  134. return $globals.BlockNode._new()
  135. ._position_((line()).__at(column()))
  136. ._source_(text())
  137. ._parameters_(params || [])
  138. ._nodes_([sequence._asBlockSequenceNode()]);
  139. }
  140. operand = literal / reference / subexpression
  141. unaryMessage = ws selector:unarySelector !":" {
  142. return $globals.SendNode._new()
  143. ._position_((line()).__at(column()))
  144. ._source_(text())
  145. ._selector_(selector);
  146. }
  147. unaryTail = message:unaryMessage ws tail:unaryTail? ws {
  148. if(tail) {
  149. return tail._valueForReceiver_(message);
  150. }
  151. else {
  152. return message;
  153. }
  154. }
  155. unarySend = receiver:operand ws tail:unaryTail? {
  156. if(tail) {
  157. return tail._valueForReceiver_(receiver);
  158. }
  159. else {
  160. return receiver;
  161. }
  162. }
  163. binaryMessage = ws selector:binarySelector ws arg:(unarySend / operand) {
  164. return $globals.SendNode._new()
  165. ._position_((line()).__at(column()))
  166. ._source_(text())
  167. ._selector_(selector)
  168. ._arguments_([arg]);
  169. }
  170. binaryTail = message:binaryMessage tail:binaryTail? {
  171. if(tail) {
  172. return tail._valueForReceiver_(message);
  173. }
  174. else {
  175. return message;
  176. }
  177. }
  178. binarySend = receiver:unarySend tail:binaryTail? {
  179. if(tail) {
  180. return tail._valueForReceiver_(receiver);
  181. }
  182. else {
  183. return receiver;
  184. }
  185. }
  186. keywordMessage = pairs:keywordPair+ {
  187. var selector = [];
  188. var args = [];
  189. for(var i = 0; i < pairs.length; i++) {
  190. selector.push(pairs[i].key);
  191. args.push(pairs[i].arg);
  192. }
  193. return $globals.SendNode._new()
  194. ._position_((line()).__at(column()))
  195. ._source_(text())
  196. ._selector_(selector.join(""))
  197. ._arguments_(args);
  198. }
  199. keywordSend = receiver:binarySend tail:keywordMessage {
  200. return tail._valueForReceiver_(receiver);
  201. }
  202. message = binaryMessage / unaryMessage / keywordMessage
  203. cascade = ws send:(keywordSend / binarySend) messages:(ws ";" ws mess:message {return mess;})+ {
  204. var cascade = [];
  205. cascade.push(send);
  206. for(var i = 0; i < messages.length; i++) {
  207. cascade.push(messages[i]);
  208. }
  209. return $globals.CascadeNode._new()
  210. ._position_((line()).__at(column()))
  211. ._source_(text())
  212. ._receiver_(send._receiver())
  213. ._nodes_(cascade);
  214. }
  215. jsStatement = "<" val:((">>" {return ">";} / [^>])*) ">" {
  216. return $globals.JSStatementNode._new()
  217. ._position_((line()).__at(column()))
  218. ._source_(val.join(""))
  219. }
  220. method = pattern:(keywordPattern / binaryPattern / unaryPattern) ws sequence:sequence? ws {
  221. return $globals.MethodNode._new()
  222. ._position_((line()).__at(column()))
  223. ._source_(text())
  224. ._selector_(pattern[0])
  225. ._arguments_(pattern[1])
  226. ._nodes_([sequence]);
  227. }
  228. associationSend = send:binarySend & { return send._selector() === "->" } { return [send._receiver(), send._arguments()[0]]; }
  229. associationList = ws "." ws expression:associationSend {return expression;}
  230. associations = first:associationSend others:associationList* { return first.concat.apply(first, others); }