parser.pegjs 7.2 KB

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