parser.pegjs 9.9 KB

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