parser.pegjs 9.1 KB

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