parser.pegjs 6.9 KB

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