parser.pegjs 11 KB

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