parser.pegjs 11 KB

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