tenderlove-rkelly 0.0.0.20080909095845

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. data/CHANGELOG.txt +7 -0
  2. data/Manifest.txt +197 -0
  3. data/README.txt +49 -0
  4. data/Rakefile +85 -0
  5. data/lib/parser.y +870 -0
  6. data/lib/rkelly.rb +8 -0
  7. data/lib/rkelly/constants.rb +3 -0
  8. data/lib/rkelly/js.rb +14 -0
  9. data/lib/rkelly/js/array.rb +15 -0
  10. data/lib/rkelly/js/base.rb +91 -0
  11. data/lib/rkelly/js/boolean.rb +21 -0
  12. data/lib/rkelly/js/function.rb +39 -0
  13. data/lib/rkelly/js/function_prototype.rb +15 -0
  14. data/lib/rkelly/js/global_object.rb +52 -0
  15. data/lib/rkelly/js/math.rb +10 -0
  16. data/lib/rkelly/js/nan.rb +18 -0
  17. data/lib/rkelly/js/number.rb +22 -0
  18. data/lib/rkelly/js/object.rb +30 -0
  19. data/lib/rkelly/js/object_prototype.rb +14 -0
  20. data/lib/rkelly/js/property.rb +20 -0
  21. data/lib/rkelly/js/scope.rb +6 -0
  22. data/lib/rkelly/js/string.rb +21 -0
  23. data/lib/rkelly/lexeme.rb +18 -0
  24. data/lib/rkelly/nodes.rb +5 -0
  25. data/lib/rkelly/nodes/binary_node.rb +18 -0
  26. data/lib/rkelly/nodes/bracket_accessor_node.rb +11 -0
  27. data/lib/rkelly/nodes/case_clause_node.rb +11 -0
  28. data/lib/rkelly/nodes/comma_node.rb +11 -0
  29. data/lib/rkelly/nodes/conditional_node.rb +11 -0
  30. data/lib/rkelly/nodes/dot_accessor_node.rb +11 -0
  31. data/lib/rkelly/nodes/for_in_node.rb +12 -0
  32. data/lib/rkelly/nodes/for_node.rb +13 -0
  33. data/lib/rkelly/nodes/function_call_node.rb +16 -0
  34. data/lib/rkelly/nodes/function_decl_node.rb +6 -0
  35. data/lib/rkelly/nodes/function_expr_node.rb +12 -0
  36. data/lib/rkelly/nodes/if_node.rb +12 -0
  37. data/lib/rkelly/nodes/label_node.rb +11 -0
  38. data/lib/rkelly/nodes/new_expr_node.rb +11 -0
  39. data/lib/rkelly/nodes/node.rb +80 -0
  40. data/lib/rkelly/nodes/not_strict_equal_node.rb +6 -0
  41. data/lib/rkelly/nodes/op_equal_node.rb +16 -0
  42. data/lib/rkelly/nodes/postfix_node.rb +11 -0
  43. data/lib/rkelly/nodes/prefix_node.rb +6 -0
  44. data/lib/rkelly/nodes/property_node.rb +13 -0
  45. data/lib/rkelly/nodes/resolve_node.rb +19 -0
  46. data/lib/rkelly/nodes/strict_equal_node.rb +6 -0
  47. data/lib/rkelly/nodes/try_node.rb +13 -0
  48. data/lib/rkelly/nodes/var_decl_node.rb +15 -0
  49. data/lib/rkelly/parser.rb +98 -0
  50. data/lib/rkelly/runtime.rb +36 -0
  51. data/lib/rkelly/runtime/ruby_function.rb +13 -0
  52. data/lib/rkelly/runtime/scope_chain.rb +57 -0
  53. data/lib/rkelly/token.rb +15 -0
  54. data/lib/rkelly/tokenizer.rb +122 -0
  55. data/lib/rkelly/visitable.rb +16 -0
  56. data/lib/rkelly/visitors.rb +4 -0
  57. data/lib/rkelly/visitors/dot_visitor.rb +228 -0
  58. data/lib/rkelly/visitors/ecma_visitor.rb +314 -0
  59. data/lib/rkelly/visitors/enumerable_visitor.rb +18 -0
  60. data/lib/rkelly/visitors/evaluation_visitor.rb +419 -0
  61. data/lib/rkelly/visitors/function_visitor.rb +46 -0
  62. data/lib/rkelly/visitors/pointcut_visitor.rb +18 -0
  63. data/lib/rkelly/visitors/sexp_visitor.rb +374 -0
  64. data/lib/rkelly/visitors/visitor.rb +136 -0
  65. data/test/ecma_script_test_case.rb +21 -0
  66. data/test/execute_test_case.rb +16 -0
  67. data/test/execution_contexts/test_10_1_3-1.rb +32 -0
  68. data/test/expressions/test_11_3_1.rb +64 -0
  69. data/test/expressions/test_11_3_2.rb +64 -0
  70. data/test/expressions/test_11_4_2.rb +13 -0
  71. data/test/expressions/test_11_4_3.rb +52 -0
  72. data/test/expressions/test_11_4_4.rb +68 -0
  73. data/test/expressions/test_11_4_5.rb +69 -0
  74. data/test/expressions/test_11_4_6.rb +88 -0
  75. data/test/expressions/test_11_4_8.rb +28 -0
  76. data/test/expressions/test_11_4_9.rb +103 -0
  77. data/test/expressions/test_11_5_1.rb +51 -0
  78. data/test/expressions/test_11_5_2.rb +80 -0
  79. data/test/expressions/test_11_5_3.rb +88 -0
  80. data/test/expressions/test_11_6_1-1.rb +19 -0
  81. data/test/expressions/test_11_9_1.rb +19 -0
  82. data/test/function/test_15_3_1_1-1.rb +34 -0
  83. data/test/global_object/test_15_1_1_1.rb +29 -0
  84. data/test/global_object/test_15_1_1_2.rb +17 -0
  85. data/test/global_object/test_15_1_1_3.rb +9 -0
  86. data/test/helper.rb +5 -0
  87. data/test/node_test_case.rb +11 -0
  88. data/test/object/test_15_2_1_1.rb +257 -0
  89. data/test/object/test_15_2_1_2.rb +21 -0
  90. data/test/object/test_15_2_2_1.rb +52 -0
  91. data/test/statements/test_12_5-1.rb +27 -0
  92. data/test/test_add_node.rb +8 -0
  93. data/test/test_arguments_node.rb +8 -0
  94. data/test/test_array_node.rb +9 -0
  95. data/test/test_assign_expr_node.rb +8 -0
  96. data/test/test_automatic_semicolon_insertion.rb +137 -0
  97. data/test/test_bit_and_node.rb +8 -0
  98. data/test/test_bit_or_node.rb +8 -0
  99. data/test/test_bit_x_or_node.rb +8 -0
  100. data/test/test_bitwise_not_node.rb +8 -0
  101. data/test/test_block_node.rb +14 -0
  102. data/test/test_bracket_accessor_node.rb +16 -0
  103. data/test/test_break_node.rb +11 -0
  104. data/test/test_case_block_node.rb +11 -0
  105. data/test/test_case_clause_node.rb +15 -0
  106. data/test/test_comma_node.rb +13 -0
  107. data/test/test_comments.rb +44 -0
  108. data/test/test_conditional_node.rb +17 -0
  109. data/test/test_const_statement_node.rb +14 -0
  110. data/test/test_continue_node.rb +11 -0
  111. data/test/test_delete_node.rb +8 -0
  112. data/test/test_divide_node.rb +8 -0
  113. data/test/test_do_while_node.rb +13 -0
  114. data/test/test_dot_accessor_node.rb +9 -0
  115. data/test/test_ecma_visitor.rb +192 -0
  116. data/test/test_element_node.rb +8 -0
  117. data/test/test_empty_statement_node.rb +8 -0
  118. data/test/test_equal_node.rb +8 -0
  119. data/test/test_evaluation_visitor.rb +66 -0
  120. data/test/test_expression_statement_node.rb +10 -0
  121. data/test/test_false_node.rb +8 -0
  122. data/test/test_for_in_node.rb +17 -0
  123. data/test/test_for_node.rb +24 -0
  124. data/test/test_function_body_node.rb +8 -0
  125. data/test/test_function_call_node.rb +10 -0
  126. data/test/test_function_decl_node.rb +16 -0
  127. data/test/test_function_expr_node.rb +16 -0
  128. data/test/test_function_visitor.rb +26 -0
  129. data/test/test_getter_property_node.rb +10 -0
  130. data/test/test_global_object.rb +49 -0
  131. data/test/test_greater_node.rb +8 -0
  132. data/test/test_greater_or_equal_node.rb +8 -0
  133. data/test/test_if_node.rb +17 -0
  134. data/test/test_in_node.rb +8 -0
  135. data/test/test_instance_of_node.rb +8 -0
  136. data/test/test_label_node.rb +13 -0
  137. data/test/test_left_shift_node.rb +8 -0
  138. data/test/test_less_node.rb +8 -0
  139. data/test/test_less_or_equal_node.rb +8 -0
  140. data/test/test_line_number.rb +23 -0
  141. data/test/test_logical_and_node.rb +8 -0
  142. data/test/test_logical_not_node.rb +8 -0
  143. data/test/test_logical_or_node.rb +8 -0
  144. data/test/test_modulus_node.rb +8 -0
  145. data/test/test_multiply_node.rb +8 -0
  146. data/test/test_new_expr_node.rb +9 -0
  147. data/test/test_not_equal_node.rb +8 -0
  148. data/test/test_not_strict_equal_node.rb +8 -0
  149. data/test/test_null_node.rb +8 -0
  150. data/test/test_number_node.rb +8 -0
  151. data/test/test_object_literal_node.rb +9 -0
  152. data/test/test_op_and_equal_node.rb +10 -0
  153. data/test/test_op_divide_equal_node.rb +10 -0
  154. data/test/test_op_equal_node.rb +10 -0
  155. data/test/test_op_l_shift_equal_node.rb +10 -0
  156. data/test/test_op_minus_equal_node.rb +10 -0
  157. data/test/test_op_mod_equal_node.rb +10 -0
  158. data/test/test_op_multiply_equal_node.rb +10 -0
  159. data/test/test_op_or_equal_node.rb +10 -0
  160. data/test/test_op_plus_equal_node.rb +10 -0
  161. data/test/test_op_r_shift_equal_node.rb +10 -0
  162. data/test/test_op_u_r_shift_equal_node.rb +10 -0
  163. data/test/test_op_x_or_equal_node.rb +10 -0
  164. data/test/test_parameter_node.rb +8 -0
  165. data/test/test_parser.rb +1355 -0
  166. data/test/test_pointcut_visitor.rb +34 -0
  167. data/test/test_postfix_node.rb +8 -0
  168. data/test/test_prefix_node.rb +8 -0
  169. data/test/test_property_node.rb +8 -0
  170. data/test/test_regexp_node.rb +8 -0
  171. data/test/test_resolve_node.rb +22 -0
  172. data/test/test_return_node.rb +11 -0
  173. data/test/test_right_shift_node.rb +8 -0
  174. data/test/test_runtime.rb +12 -0
  175. data/test/test_scope_chain.rb +50 -0
  176. data/test/test_setter_property_node.rb +10 -0
  177. data/test/test_source_elements.rb +9 -0
  178. data/test/test_strict_equal_node.rb +8 -0
  179. data/test/test_string_node.rb +8 -0
  180. data/test/test_subtract_node.rb +8 -0
  181. data/test/test_switch_node.rb +12 -0
  182. data/test/test_this_node.rb +8 -0
  183. data/test/test_throw_node.rb +7 -0
  184. data/test/test_tokenizer.rb +143 -0
  185. data/test/test_true_node.rb +8 -0
  186. data/test/test_try_node.rb +59 -0
  187. data/test/test_type_of_node.rb +8 -0
  188. data/test/test_unary_minus_node.rb +8 -0
  189. data/test/test_unary_plus_node.rb +8 -0
  190. data/test/test_unsigned_right_shift_node.rb +8 -0
  191. data/test/test_var_decl_node.rb +21 -0
  192. data/test/test_var_statement_node.rb +14 -0
  193. data/test/test_void_node.rb +8 -0
  194. data/test/test_while_node.rb +15 -0
  195. data/test/test_with_node.rb +8 -0
  196. metadata +385 -0
data/CHANGELOG.txt ADDED
@@ -0,0 +1,7 @@
1
+ = RKelly CHANGELOG
2
+
3
+ == 0.0.1
4
+
5
+ * Added dynamic method assignment
6
+ * Birthday!
7
+
data/Manifest.txt ADDED
@@ -0,0 +1,197 @@
1
+ CHANGELOG.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/parser.y
6
+ lib/rkelly.rb
7
+ lib/rkelly/constants.rb
8
+ lib/rkelly/generated_parser.rb
9
+ lib/rkelly/js.rb
10
+ lib/rkelly/js/array.rb
11
+ lib/rkelly/js/base.rb
12
+ lib/rkelly/js/boolean.rb
13
+ lib/rkelly/js/function.rb
14
+ lib/rkelly/js/function_prototype.rb
15
+ lib/rkelly/js/global_object.rb
16
+ lib/rkelly/js/math.rb
17
+ lib/rkelly/js/nan.rb
18
+ lib/rkelly/js/number.rb
19
+ lib/rkelly/js/object.rb
20
+ lib/rkelly/js/object_prototype.rb
21
+ lib/rkelly/js/property.rb
22
+ lib/rkelly/js/scope.rb
23
+ lib/rkelly/js/string.rb
24
+ lib/rkelly/lexeme.rb
25
+ lib/rkelly/nodes.rb
26
+ lib/rkelly/nodes/binary_node.rb
27
+ lib/rkelly/nodes/bracket_accessor_node.rb
28
+ lib/rkelly/nodes/case_clause_node.rb
29
+ lib/rkelly/nodes/comma_node.rb
30
+ lib/rkelly/nodes/conditional_node.rb
31
+ lib/rkelly/nodes/dot_accessor_node.rb
32
+ lib/rkelly/nodes/for_in_node.rb
33
+ lib/rkelly/nodes/for_node.rb
34
+ lib/rkelly/nodes/function_call_node.rb
35
+ lib/rkelly/nodes/function_decl_node.rb
36
+ lib/rkelly/nodes/function_expr_node.rb
37
+ lib/rkelly/nodes/if_node.rb
38
+ lib/rkelly/nodes/label_node.rb
39
+ lib/rkelly/nodes/new_expr_node.rb
40
+ lib/rkelly/nodes/node.rb
41
+ lib/rkelly/nodes/not_strict_equal_node.rb
42
+ lib/rkelly/nodes/op_equal_node.rb
43
+ lib/rkelly/nodes/postfix_node.rb
44
+ lib/rkelly/nodes/prefix_node.rb
45
+ lib/rkelly/nodes/property_node.rb
46
+ lib/rkelly/nodes/resolve_node.rb
47
+ lib/rkelly/nodes/strict_equal_node.rb
48
+ lib/rkelly/nodes/try_node.rb
49
+ lib/rkelly/nodes/var_decl_node.rb
50
+ lib/rkelly/parser.rb
51
+ lib/rkelly/runtime.rb
52
+ lib/rkelly/runtime/ruby_function.rb
53
+ lib/rkelly/runtime/scope_chain.rb
54
+ lib/rkelly/token.rb
55
+ lib/rkelly/tokenizer.rb
56
+ lib/rkelly/visitable.rb
57
+ lib/rkelly/visitors.rb
58
+ lib/rkelly/visitors/dot_visitor.rb
59
+ lib/rkelly/visitors/ecma_visitor.rb
60
+ lib/rkelly/visitors/enumerable_visitor.rb
61
+ lib/rkelly/visitors/evaluation_visitor.rb
62
+ lib/rkelly/visitors/function_visitor.rb
63
+ lib/rkelly/visitors/pointcut_visitor.rb
64
+ lib/rkelly/visitors/sexp_visitor.rb
65
+ lib/rkelly/visitors/visitor.rb
66
+ rkelly.gemspec
67
+ test/ecma_script_test_case.rb
68
+ test/execute_test_case.rb
69
+ test/execution_contexts/test_10_1_3-1.rb
70
+ test/expressions/test_11_3_1.rb
71
+ test/expressions/test_11_3_2.rb
72
+ test/expressions/test_11_4_2.rb
73
+ test/expressions/test_11_4_3.rb
74
+ test/expressions/test_11_4_4.rb
75
+ test/expressions/test_11_4_5.rb
76
+ test/expressions/test_11_4_6.rb
77
+ test/expressions/test_11_4_8.rb
78
+ test/expressions/test_11_4_9.rb
79
+ test/expressions/test_11_5_1.rb
80
+ test/expressions/test_11_5_2.rb
81
+ test/expressions/test_11_5_3.rb
82
+ test/expressions/test_11_6_1-1.rb
83
+ test/expressions/test_11_9_1.rb
84
+ test/function/test_15_3_1_1-1.rb
85
+ test/global_object/test_15_1_1_1.rb
86
+ test/global_object/test_15_1_1_2.rb
87
+ test/global_object/test_15_1_1_3.rb
88
+ test/helper.rb
89
+ test/node_test_case.rb
90
+ test/object/test_15_2_1_1.rb
91
+ test/object/test_15_2_1_2.rb
92
+ test/object/test_15_2_2_1.rb
93
+ test/statements/test_12_5-1.rb
94
+ test/test_add_node.rb
95
+ test/test_arguments_node.rb
96
+ test/test_array_node.rb
97
+ test/test_assign_expr_node.rb
98
+ test/test_automatic_semicolon_insertion.rb
99
+ test/test_bit_and_node.rb
100
+ test/test_bit_or_node.rb
101
+ test/test_bit_x_or_node.rb
102
+ test/test_bitwise_not_node.rb
103
+ test/test_block_node.rb
104
+ test/test_bracket_accessor_node.rb
105
+ test/test_break_node.rb
106
+ test/test_case_block_node.rb
107
+ test/test_case_clause_node.rb
108
+ test/test_comma_node.rb
109
+ test/test_comments.rb
110
+ test/test_conditional_node.rb
111
+ test/test_const_statement_node.rb
112
+ test/test_continue_node.rb
113
+ test/test_delete_node.rb
114
+ test/test_divide_node.rb
115
+ test/test_do_while_node.rb
116
+ test/test_dot_accessor_node.rb
117
+ test/test_ecma_visitor.rb
118
+ test/test_element_node.rb
119
+ test/test_empty_statement_node.rb
120
+ test/test_equal_node.rb
121
+ test/test_evaluation_visitor.rb
122
+ test/test_expression_statement_node.rb
123
+ test/test_false_node.rb
124
+ test/test_for_in_node.rb
125
+ test/test_for_node.rb
126
+ test/test_function_body_node.rb
127
+ test/test_function_call_node.rb
128
+ test/test_function_decl_node.rb
129
+ test/test_function_expr_node.rb
130
+ test/test_function_visitor.rb
131
+ test/test_getter_property_node.rb
132
+ test/test_global_object.rb
133
+ test/test_greater_node.rb
134
+ test/test_greater_or_equal_node.rb
135
+ test/test_if_node.rb
136
+ test/test_in_node.rb
137
+ test/test_instance_of_node.rb
138
+ test/test_label_node.rb
139
+ test/test_left_shift_node.rb
140
+ test/test_less_node.rb
141
+ test/test_less_or_equal_node.rb
142
+ test/test_line_number.rb
143
+ test/test_logical_and_node.rb
144
+ test/test_logical_not_node.rb
145
+ test/test_logical_or_node.rb
146
+ test/test_modulus_node.rb
147
+ test/test_multiply_node.rb
148
+ test/test_new_expr_node.rb
149
+ test/test_not_equal_node.rb
150
+ test/test_not_strict_equal_node.rb
151
+ test/test_null_node.rb
152
+ test/test_number_node.rb
153
+ test/test_object_literal_node.rb
154
+ test/test_op_and_equal_node.rb
155
+ test/test_op_divide_equal_node.rb
156
+ test/test_op_equal_node.rb
157
+ test/test_op_l_shift_equal_node.rb
158
+ test/test_op_minus_equal_node.rb
159
+ test/test_op_mod_equal_node.rb
160
+ test/test_op_multiply_equal_node.rb
161
+ test/test_op_or_equal_node.rb
162
+ test/test_op_plus_equal_node.rb
163
+ test/test_op_r_shift_equal_node.rb
164
+ test/test_op_u_r_shift_equal_node.rb
165
+ test/test_op_x_or_equal_node.rb
166
+ test/test_parameter_node.rb
167
+ test/test_parser.rb
168
+ test/test_pointcut_visitor.rb
169
+ test/test_postfix_node.rb
170
+ test/test_prefix_node.rb
171
+ test/test_property_node.rb
172
+ test/test_regexp_node.rb
173
+ test/test_resolve_node.rb
174
+ test/test_return_node.rb
175
+ test/test_right_shift_node.rb
176
+ test/test_runtime.rb
177
+ test/test_scope_chain.rb
178
+ test/test_setter_property_node.rb
179
+ test/test_source_elements.rb
180
+ test/test_strict_equal_node.rb
181
+ test/test_string_node.rb
182
+ test/test_subtract_node.rb
183
+ test/test_switch_node.rb
184
+ test/test_this_node.rb
185
+ test/test_throw_node.rb
186
+ test/test_tokenizer.rb
187
+ test/test_true_node.rb
188
+ test/test_try_node.rb
189
+ test/test_type_of_node.rb
190
+ test/test_unary_minus_node.rb
191
+ test/test_unary_plus_node.rb
192
+ test/test_unsigned_right_shift_node.rb
193
+ test/test_var_decl_node.rb
194
+ test/test_var_statement_node.rb
195
+ test/test_void_node.rb
196
+ test/test_while_node.rb
197
+ test/test_with_node.rb
data/README.txt ADDED
@@ -0,0 +1,49 @@
1
+ = RKelly
2
+
3
+ http://rkelly.rubyforge.org/
4
+
5
+ == DESCRIPTION
6
+
7
+ The RKelly library will parse JavaScript and return a parse tree.
8
+
9
+ == Example
10
+
11
+ require 'rkelly'
12
+
13
+ parser = RKelly::Parser.new
14
+ ast = parser.parse(
15
+ "for(var i = 0; i < 10; i++) { var x = 5 + 5; }"
16
+ )
17
+
18
+ == Acknowledgments
19
+
20
+ The original javascript parser was was taken from rbnarcissus written by
21
+ Paul Sowden. Thanks Paul!
22
+
23
+ http://idontsmoke.co.uk/2005/rbnarcissus/
24
+
25
+ The current parser was ported from WebKit. Thank you WebKit team!
26
+
27
+ == License
28
+
29
+ The MIT License
30
+
31
+ Copyright (c) 2007, 2008 Aaron Patterson, John Barnette
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining a copy
34
+ of this software and associated documentation files (the "Software"), to deal
35
+ in the Software without restriction, including without limitation the rights
36
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+ copies of the Software, and to permit persons to whom the Software is
38
+ furnished to do so, subject to the following conditions:
39
+
40
+ The above copyright notice and this permission notice shall be included in
41
+ all copies or substantial portions of the Software.
42
+
43
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
49
+ THE SOFTWARE
data/Rakefile ADDED
@@ -0,0 +1,85 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+
4
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "lib")
5
+
6
+ require 'rkelly/constants'
7
+
8
+ GENERATED_PARSER = "lib/rkelly/generated_parser.rb"
9
+
10
+ HOE = Hoe.new('rkelly', RKelly::VERSION) do |p|
11
+ p.rubyforge_name = 'rkelly'
12
+ p.author = 'Aaron Patterson'
13
+ p.email = 'aaronp@rubyforge.org'
14
+ p.summary = "RKelly parses JavaScript and returns a parse tree suitable for feeding to Ruby2Ruby."
15
+ p.description = p.paragraphs_of('README.txt', 3).join("\n\n")
16
+ p.url = p.paragraphs_of('README.txt', 1).first.strip
17
+ p.changes = p.paragraphs_of('CHANGELOG.txt', 0..2).join("\n\n")
18
+ p.clean_globs = [GENERATED_PARSER]
19
+ end
20
+
21
+ file GENERATED_PARSER => "lib/parser.y" do |t|
22
+ if ENV['DEBUG']
23
+ sh "racc -g -v -o #{t.name} #{t.prerequisites.first}"
24
+ else
25
+ sh "racc -o #{t.name} #{t.prerequisites.first}"
26
+ end
27
+ end
28
+
29
+ task :parser => GENERATED_PARSER
30
+
31
+ # make sure the parser's up-to-date when we test
32
+ Rake::Task[:test].prerequisites << :parser
33
+ Rake::Task[:check_manifest].prerequisites << :parser
34
+
35
+ desc "Create a new node"
36
+ task :new_node do
37
+ filename = ENV['NODE']
38
+ raise "invalid node name" if !filename
39
+
40
+ classname = nil
41
+ if filename =~ /[A-Z]/
42
+ classname = filename
43
+ filename = filename.gsub(/([A-Z])/) { |x| "_#{x.downcase}" }.gsub(/^_/, '')
44
+ end
45
+
46
+ full_file = "lib/rkelly/nodes/#{filename}.rb"
47
+ test_file = "test/test_#{filename}.rb"
48
+ puts "writing: #{full_file}"
49
+ File.open(full_file, 'wb') { |f|
50
+ f.write <<-END
51
+ module RKelly
52
+ module Nodes
53
+ class #{classname} < Node
54
+ end
55
+ end
56
+ end
57
+ END
58
+ }
59
+ puts "adding to nodes include"
60
+ File.open("lib/rkelly/nodes.rb", 'ab') { |f|
61
+ f.puts "require 'rkelly/nodes/#{filename}'"
62
+ }
63
+
64
+ puts "writing test case: #{test_file}"
65
+ File.open(test_file, 'wb') { |f|
66
+ f.write <<-END
67
+ require File.dirname(__FILE__) + "/helper"
68
+
69
+ class #{classname}Test < NodeTestCase
70
+ def test_failure
71
+ assert false
72
+ end
73
+ end
74
+ END
75
+ }
76
+ end
77
+
78
+ namespace :gem do
79
+ task :spec do
80
+ File.open("#{HOE.name}.gemspec", 'w') do |f|
81
+ HOE.spec.version = "#{HOE.version}.#{Time.now.strftime("%Y%m%d%H%M%S")}"
82
+ f.write(HOE.spec.to_ruby)
83
+ end
84
+ end
85
+ end
data/lib/parser.y ADDED
@@ -0,0 +1,870 @@
1
+ /* vim: set filetype=racc : */
2
+
3
+ class RKelly::GeneratedParser
4
+
5
+ /* Literals */
6
+ token NULL TRUE FALSE
7
+
8
+ /* keywords */
9
+ token BREAK CASE CATCH CONST CONTINUE DEBUGGER DEFAULT DELETE DO ELSE ENUM
10
+ token FINALLY FOR FUNCTION IF IN INSTANCEOF NEW RETURN SWITCH THIS THROW TRY
11
+ token TYPEOF VAR VOID WHILE WITH
12
+
13
+ /* punctuators */
14
+ token EQEQ NE /* == and != */
15
+ token STREQ STRNEQ /* === and !== */
16
+ token LE GE /* < and > */
17
+ token OR AND /* || and && */
18
+ token PLUSPLUS MINUSMINUS /* ++ and -- */
19
+ token LSHIFT /* << */
20
+ token RSHIFT URSHIFT /* >> and >>> */
21
+ token PLUSEQUAL MINUSEQUAL /* += and -= */
22
+ token MULTEQUAL DIVEQUAL /* *= and /= */
23
+ token LSHIFTEQUAL /* <<= */
24
+ token RSHIFTEQUAL URSHIFTEQUAL /* >>= and >>>= */
25
+ token ANDEQUAL MODEQUAL /* &= and %= */
26
+ token XOREQUAL OREQUAL /* ^= and |= */
27
+
28
+ /* Terminal types */
29
+ token REGEXP
30
+ token NUMBER
31
+ token STRING
32
+ token IDENT
33
+
34
+ token AUTOPLUSPLUS AUTOMINUSMINUS IF_WITHOUT_ELSE
35
+
36
+ prechigh
37
+ nonassoc ELSE
38
+ nonassoc IF_WITHOUT_ELSE
39
+ preclow
40
+
41
+ rule
42
+ SourceElements:
43
+ /* nothing */ { result = SourceElementsNode.new([]) }
44
+ | SourceElementList { result = SourceElementsNode.new([val].flatten) }
45
+
46
+ SourceElementList:
47
+ SourceElement
48
+ | SourceElementList SourceElement { result = val.flatten }
49
+ ;
50
+
51
+ SourceElement:
52
+ FunctionDeclaration
53
+ | Statement
54
+ ;
55
+
56
+ Statement:
57
+ Block
58
+ | VariableStatement
59
+ | ConstStatement
60
+ | EmptyStatement
61
+ | ExprStatement
62
+ | IfStatement
63
+ | IterationStatement
64
+ | ContinueStatement
65
+ | BreakStatement
66
+ | ReturnStatement
67
+ | WithStatement
68
+ | SwitchStatement
69
+ | LabelledStatement
70
+ | ThrowStatement
71
+ | TryStatement
72
+ | DebuggerStatement
73
+ ;
74
+
75
+ Literal:
76
+ NULL { result = NullNode.new(val.first) }
77
+ | TRUE { result = TrueNode.new(val.first) }
78
+ | FALSE { result = FalseNode.new(val.first) }
79
+ | NUMBER { result = NumberNode.new(val.first) }
80
+ | STRING { result = StringNode.new(val.first) }
81
+ | REGEXP { result = RegexpNode.new(val.first) }
82
+ ;
83
+
84
+ Property:
85
+ IDENT ':' AssignmentExpr {
86
+ result = PropertyNode.new(val[0], val[2])
87
+ }
88
+ | STRING ':' AssignmentExpr { result = PropertyNode.new(val.first, val.last) }
89
+ | NUMBER ':' AssignmentExpr { result = PropertyNode.new(val.first, val.last) }
90
+ | IDENT IDENT '(' ')' '{' FunctionBody '}' {
91
+ klass = property_class_for(val.first)
92
+ yyabort unless klass
93
+ result = klass.new(val[1], FunctionExprNode.new(nil, val[5]))
94
+ }
95
+ | IDENT IDENT '(' FormalParameterList ')' '{' FunctionBody '}' {
96
+ klass = property_class_for(val.first)
97
+ yyabort unless klass
98
+ result = klass.new(val[1], FunctionExprNode.new(nil, val[6], val[3]))
99
+ }
100
+ ;
101
+
102
+ PropertyList:
103
+ Property { result = val }
104
+ | PropertyList ',' Property { result = [val.first, val.last].flatten }
105
+ ;
106
+
107
+ PrimaryExpr:
108
+ PrimaryExprNoBrace
109
+ | '{' '}' { result = ObjectLiteralNode.new([]) }
110
+ | '{' PropertyList '}' { result = ObjectLiteralNode.new(val[1]) }
111
+ | '{' PropertyList ',' '}' { result = ObjectLiteralNode.new(val[1]) }
112
+ ;
113
+
114
+ PrimaryExprNoBrace:
115
+ THIS { result = ThisNode.new(val.first) }
116
+ | Literal
117
+ | ArrayLiteral
118
+ | IDENT { result = ResolveNode.new(val.first) }
119
+ | '(' Expr ')' { result = val[1] }
120
+ ;
121
+
122
+ ArrayLiteral:
123
+ '[' ElisionOpt ']' { result = ArrayNode.new([] + [nil] * val[1]) }
124
+ | '[' ElementList ']' { result = ArrayNode.new(val[1]) }
125
+ | '[' ElementList ',' ElisionOpt ']' {
126
+ result = ArrayNode.new(val[1] + [nil] * val[3])
127
+ }
128
+ ;
129
+
130
+ ElementList:
131
+ ElisionOpt AssignmentExpr {
132
+ result = [nil] * val[0] + [ElementNode.new(val[1])]
133
+ }
134
+ | ElementList ',' ElisionOpt AssignmentExpr {
135
+ result = [val[0], [nil] * val[2], ElementNode.new(val[3])].flatten
136
+ }
137
+ ;
138
+
139
+ ElisionOpt:
140
+ /* nothing */ { result = 0 }
141
+ | Elision
142
+ ;
143
+
144
+ Elision:
145
+ ',' { result = 1 }
146
+ | Elision ',' { result = val.first + 1 }
147
+ ;
148
+
149
+ MemberExpr:
150
+ PrimaryExpr
151
+ | FunctionExpr
152
+ | MemberExpr '[' Expr ']' { result = BracketAccessorNode.new(val[0], val[2]) }
153
+ | MemberExpr '.' IDENT { result = DotAccessorNode.new(val[0], val[2]) }
154
+ | NEW MemberExpr Arguments { result = NewExprNode.new(val[1], val[2]) }
155
+ ;
156
+
157
+ MemberExprNoBF:
158
+ PrimaryExprNoBrace
159
+ | MemberExprNoBF '[' Expr ']' {
160
+ result = BracketAccessorNode.new(val[0], val[2])
161
+ }
162
+ | MemberExprNoBF '.' IDENT { result = DotAccessorNode.new(val[0], val[2]) }
163
+ | NEW MemberExpr Arguments { result = NewExprNode.new(val[1], val[2]) }
164
+ ;
165
+
166
+ NewExpr:
167
+ MemberExpr
168
+ | NEW NewExpr { result = NewExprNode.new(val[1], ArgumentsNode.new([])) }
169
+ ;
170
+
171
+ NewExprNoBF:
172
+ MemberExprNoBF
173
+ | NEW NewExpr { result = NewExprNode.new(val[1], ArgumentsNode.new([])) }
174
+ ;
175
+
176
+ CallExpr:
177
+ MemberExpr Arguments { result = FunctionCallNode.new(val[0], val[1]) }
178
+ | CallExpr Arguments { result = FunctionCallNode.new(val[0], val[1]) }
179
+ | CallExpr '[' Expr ']' { result = BracketAccessorNode.new(val[0], val[2]) }
180
+ | CallExpr '.' IDENT { result = DotAccessorNode.new(val[0], val[2]) }
181
+ ;
182
+
183
+ CallExprNoBF:
184
+ MemberExprNoBF Arguments { result = FunctionCallNode.new(val[0], val[1]) }
185
+ | CallExprNoBF Arguments { result = FunctionCallNode.new(val[0], val[1]) }
186
+ | CallExprNoBF '[' Expr ']' { result = BracketAccessorNode.new(val[0], val[2]) }
187
+ | CallExprNoBF '.' IDENT { result = DotAccessorNode.new(val[0], val[2]) }
188
+ ;
189
+
190
+ Arguments:
191
+ '(' ')' { result = ArgumentsNode.new([]) }
192
+ | '(' ArgumentList ')' { result = ArgumentsNode.new(val[1]); }
193
+ ;
194
+
195
+ ArgumentList:
196
+ AssignmentExpr { result = val }
197
+ | ArgumentList ',' AssignmentExpr { result = [val[0], val[2]].flatten }
198
+ ;
199
+
200
+ LeftHandSideExpr:
201
+ NewExpr
202
+ | CallExpr
203
+ ;
204
+
205
+ LeftHandSideExprNoBF:
206
+ NewExprNoBF
207
+ | CallExprNoBF
208
+ ;
209
+
210
+ PostfixExpr:
211
+ LeftHandSideExpr
212
+ | LeftHandSideExpr PLUSPLUS { result = PostfixNode.new(val[0], '++') }
213
+ | LeftHandSideExpr MINUSMINUS { result = PostfixNode.new(val[0], '--') }
214
+ ;
215
+
216
+ PostfixExprNoBF:
217
+ LeftHandSideExprNoBF
218
+ | LeftHandSideExprNoBF PLUSPLUS { result = PostfixNode.new(val[0], '++') }
219
+ | LeftHandSideExprNoBF MINUSMINUS { result = PostfixNode.new(val[0], '--') }
220
+ ;
221
+
222
+ UnaryExprCommon:
223
+ DELETE UnaryExpr { result = DeleteNode.new(val[1]) }
224
+ | VOID UnaryExpr { result = VoidNode.new(val[1]) }
225
+ | TYPEOF UnaryExpr { result = TypeOfNode.new(val[1]) }
226
+ | PLUSPLUS UnaryExpr { result = PrefixNode.new(val[1], '++') }
227
+ /* FIXME: Not sure when this can ever happen
228
+ | AUTOPLUSPLUS UnaryExpr { result = makePrefixNode($2, OpPlusPlus); } */
229
+ | MINUSMINUS UnaryExpr { result = PrefixNode.new(val[1], '--') }
230
+ /* FIXME: Not sure when this can ever happen
231
+ | AUTOMINUSMINUS UnaryExpr { result = makePrefixNode($2, OpMinusMinus); } */
232
+ | '+' UnaryExpr { result = UnaryPlusNode.new(val[1]) }
233
+ | '-' UnaryExpr { result = UnaryMinusNode.new(val[1]) }
234
+ | '~' UnaryExpr { result = BitwiseNotNode.new(val[1]) }
235
+ | '!' UnaryExpr { result = LogicalNotNode.new(val[1]) }
236
+ ;
237
+
238
+ UnaryExpr:
239
+ PostfixExpr
240
+ | UnaryExprCommon
241
+ ;
242
+
243
+ UnaryExprNoBF:
244
+ PostfixExprNoBF
245
+ | UnaryExprCommon
246
+ ;
247
+
248
+ MultiplicativeExpr:
249
+ UnaryExpr
250
+ | MultiplicativeExpr '*' UnaryExpr { result = MultiplyNode.new(val[0],val[2])}
251
+ | MultiplicativeExpr '/' UnaryExpr { result = DivideNode.new(val[0], val[2]) }
252
+ | MultiplicativeExpr '%' UnaryExpr { result = ModulusNode.new(val[0], val[2])}
253
+ ;
254
+
255
+ MultiplicativeExprNoBF:
256
+ UnaryExprNoBF
257
+ | MultiplicativeExprNoBF '*' UnaryExpr { result = MultiplyNode.new(val[0], val[2]) }
258
+ | MultiplicativeExprNoBF '/' UnaryExpr { result = DivideNode.new(val[0],val[2]) }
259
+ | MultiplicativeExprNoBF '%' UnaryExpr { result = ModulusNode.new(val[0], val[2]) }
260
+ ;
261
+
262
+ AdditiveExpr:
263
+ MultiplicativeExpr
264
+ | AdditiveExpr '+' MultiplicativeExpr { result = AddNode.new(val[0], val[2]) }
265
+ | AdditiveExpr '-' MultiplicativeExpr { result = SubtractNode.new(val[0], val[2]) }
266
+ ;
267
+
268
+ AdditiveExprNoBF:
269
+ MultiplicativeExprNoBF
270
+ | AdditiveExprNoBF '+' MultiplicativeExpr { result = AddNode.new(val[0], val[2]) }
271
+ | AdditiveExprNoBF '-' MultiplicativeExpr { result = SubtractNode.new(val[0], val[2]) }
272
+ ;
273
+
274
+ ShiftExpr:
275
+ AdditiveExpr
276
+ | ShiftExpr LSHIFT AdditiveExpr { result = LeftShiftNode.new(val[0], val[2]) }
277
+ | ShiftExpr RSHIFT AdditiveExpr { result = RightShiftNode.new(val[0], val[2]) }
278
+ | ShiftExpr URSHIFT AdditiveExpr { result = UnsignedRightShiftNode.new(val[0], val[2]) }
279
+ ;
280
+
281
+ ShiftExprNoBF:
282
+ AdditiveExprNoBF
283
+ | ShiftExprNoBF LSHIFT AdditiveExpr { result = LeftShiftNode.new(val[0], val[2]) }
284
+ | ShiftExprNoBF RSHIFT AdditiveExpr { result = RightShiftNode.new(val[0], val[2]) }
285
+ | ShiftExprNoBF URSHIFT AdditiveExpr { result = UnsignedRightShiftNode.new(val[0], val[2]) }
286
+ ;
287
+
288
+ RelationalExpr:
289
+ ShiftExpr
290
+ | RelationalExpr '<' ShiftExpr { result = LessNode.new(val[0], val[2])}
291
+ | RelationalExpr '>' ShiftExpr { result = GreaterNode.new(val[0], val[2]) }
292
+ | RelationalExpr LE ShiftExpr { result = LessOrEqualNode.new(val[0], val[2]) }
293
+ | RelationalExpr GE ShiftExpr { result = GreaterOrEqualNode.new(val[0], val[2]) }
294
+ | RelationalExpr INSTANCEOF ShiftExpr { result = InstanceOfNode.new(val[0], val[2]) }
295
+ | RelationalExpr IN ShiftExpr { result = InNode.new(val[0], val[2]) }
296
+ ;
297
+
298
+ RelationalExprNoIn:
299
+ ShiftExpr
300
+ | RelationalExprNoIn '<' ShiftExpr { result = LessNode.new(val[0], val[2])}
301
+ | RelationalExprNoIn '>' ShiftExpr { result = GreaterNode.new(val[0], val[2]) }
302
+ | RelationalExprNoIn LE ShiftExpr { result = LessOrEqualNode.new(val[0], val[2]) }
303
+ | RelationalExprNoIn GE ShiftExpr { result = GreaterOrEqualNode.new(val[0], val[2]) }
304
+ | RelationalExprNoIn INSTANCEOF ShiftExpr
305
+ { result = InstanceOfNode.new(val[0], val[2]) }
306
+ ;
307
+
308
+ RelationalExprNoBF:
309
+ ShiftExprNoBF
310
+ | RelationalExprNoBF '<' ShiftExpr { result = LessNode.new(val[0], val[2]) }
311
+ | RelationalExprNoBF '>' ShiftExpr { result = GreaterNode.new(val[0], val[2]) }
312
+ | RelationalExprNoBF LE ShiftExpr { result = LessOrEqualNode.new(val[0], val[2]) }
313
+ | RelationalExprNoBF GE ShiftExpr { result = GreaterOrEqualNode.new(val[0], val[2]) }
314
+ | RelationalExprNoBF INSTANCEOF ShiftExpr
315
+ { result = InstanceOfNode.new(val[0], val[2]) }
316
+ | RelationalExprNoBF IN ShiftExpr { result = InNode.new(val[0], val[2]) }
317
+ ;
318
+
319
+ EqualityExpr:
320
+ RelationalExpr
321
+ | EqualityExpr EQEQ RelationalExpr { result = EqualNode.new(val[0], val[2]) }
322
+ | EqualityExpr NE RelationalExpr { result = NotEqualNode.new(val[0], val[2]) }
323
+ | EqualityExpr STREQ RelationalExpr { result = StrictEqualNode.new(val[0], val[2]) }
324
+ | EqualityExpr STRNEQ RelationalExpr { result = NotStrictEqualNode.new(val[0], val[2]) }
325
+ ;
326
+
327
+ EqualityExprNoIn:
328
+ RelationalExprNoIn
329
+ | EqualityExprNoIn EQEQ RelationalExprNoIn
330
+ { result = EqualNode.new(val[0], val[2]) }
331
+ | EqualityExprNoIn NE RelationalExprNoIn
332
+ { result = NotEqualNode.new(val[0], val[2]) }
333
+ | EqualityExprNoIn STREQ RelationalExprNoIn
334
+ { result = StrictEqualNode.new(val[0], val[2]) }
335
+ | EqualityExprNoIn STRNEQ RelationalExprNoIn
336
+ { result = NotStrictEqualNode.new(val[0], val[2]) }
337
+ ;
338
+
339
+ EqualityExprNoBF:
340
+ RelationalExprNoBF
341
+ | EqualityExprNoBF EQEQ RelationalExpr
342
+ { result = EqualNode.new(val[0], val[2]) }
343
+ | EqualityExprNoBF NE RelationalExpr { result = NotEqualNode.new(val[0], val[2]) }
344
+ | EqualityExprNoBF STREQ RelationalExpr
345
+ { result = StrictEqualNode.new(val[0], val[2]) }
346
+ | EqualityExprNoBF STRNEQ RelationalExpr
347
+ { result = NotStrictEqualNode.new(val[0], val[2]) }
348
+ ;
349
+
350
+ BitwiseANDExpr:
351
+ EqualityExpr
352
+ | BitwiseANDExpr '&' EqualityExpr { result = BitAndNode.new(val[0], val[2]) }
353
+ ;
354
+
355
+ BitwiseANDExprNoIn:
356
+ EqualityExprNoIn
357
+ | BitwiseANDExprNoIn '&' EqualityExprNoIn
358
+ { result = BitAndNode.new(val[0], val[2]) }
359
+ ;
360
+
361
+ BitwiseANDExprNoBF:
362
+ EqualityExprNoBF
363
+ | BitwiseANDExprNoBF '&' EqualityExpr { result = BitAndNode.new(val[0], val[2]) }
364
+ ;
365
+
366
+ BitwiseXORExpr:
367
+ BitwiseANDExpr
368
+ | BitwiseXORExpr '^' BitwiseANDExpr { result = BitXOrNode.new(val[0], val[2]) }
369
+ ;
370
+
371
+ BitwiseXORExprNoIn:
372
+ BitwiseANDExprNoIn
373
+ | BitwiseXORExprNoIn '^' BitwiseANDExprNoIn
374
+ { result = BitXOrNode.new(val[0], val[2]) }
375
+ ;
376
+
377
+ BitwiseXORExprNoBF:
378
+ BitwiseANDExprNoBF
379
+ | BitwiseXORExprNoBF '^' BitwiseANDExpr
380
+ { result = BitXOrNode.new(val[0], val[2]) }
381
+ ;
382
+
383
+ BitwiseORExpr:
384
+ BitwiseXORExpr
385
+ | BitwiseORExpr '|' BitwiseXORExpr { result = BitOrNode.new(val[0], val[2]) }
386
+ ;
387
+
388
+ BitwiseORExprNoIn:
389
+ BitwiseXORExprNoIn
390
+ | BitwiseORExprNoIn '|' BitwiseXORExprNoIn
391
+ { result = BitOrNode.new(val[0], val[2]) }
392
+ ;
393
+
394
+ BitwiseORExprNoBF:
395
+ BitwiseXORExprNoBF
396
+ | BitwiseORExprNoBF '|' BitwiseXORExpr
397
+ { result = BitOrNode.new(val[0], val[2]) }
398
+ ;
399
+
400
+ LogicalANDExpr:
401
+ BitwiseORExpr
402
+ | LogicalANDExpr AND BitwiseORExpr { result = LogicalAndNode.new(val[0], val[2]) }
403
+ ;
404
+
405
+ LogicalANDExprNoIn:
406
+ BitwiseORExprNoIn
407
+ | LogicalANDExprNoIn AND BitwiseORExprNoIn
408
+ { result = LogicalAndNode.new(val[0], val[2]) }
409
+ ;
410
+
411
+ LogicalANDExprNoBF:
412
+ BitwiseORExprNoBF
413
+ | LogicalANDExprNoBF AND BitwiseORExpr
414
+ { result = LogicalAndNode.new(val[0], val[2]) }
415
+ ;
416
+
417
+ LogicalORExpr:
418
+ LogicalANDExpr
419
+ | LogicalORExpr OR LogicalANDExpr { result = LogicalOrNode.new(val[0], val[2]) }
420
+ ;
421
+
422
+ LogicalORExprNoIn:
423
+ LogicalANDExprNoIn
424
+ | LogicalORExprNoIn OR LogicalANDExprNoIn
425
+ { result = LogicalOrNode.new(val[0], val[2]) }
426
+ ;
427
+
428
+ LogicalORExprNoBF:
429
+ LogicalANDExprNoBF
430
+ | LogicalORExprNoBF OR LogicalANDExpr { result = LogicalOrNode.new(val[0], val[2]) }
431
+ ;
432
+
433
+ ConditionalExpr:
434
+ LogicalORExpr
435
+ | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr {
436
+ result = ConditionalNode.new(val[0], val[2], val[4])
437
+ }
438
+ ;
439
+
440
+ ConditionalExprNoIn:
441
+ LogicalORExprNoIn
442
+ | LogicalORExprNoIn '?' AssignmentExprNoIn ':' AssignmentExprNoIn {
443
+ result = ConditionalNode.new(val[0], val[2], val[4])
444
+ }
445
+ ;
446
+
447
+ ConditionalExprNoBF:
448
+ LogicalORExprNoBF
449
+ | LogicalORExprNoBF '?' AssignmentExpr ':' AssignmentExpr {
450
+ result = ConditionalNode.new(val[0], val[2], val[4])
451
+ }
452
+ ;
453
+
454
+ AssignmentExpr:
455
+ ConditionalExpr
456
+ | LeftHandSideExpr AssignmentOperator AssignmentExpr {
457
+ result = val[1].new(val.first, val.last)
458
+ }
459
+ ;
460
+
461
+ AssignmentExprNoIn:
462
+ ConditionalExprNoIn
463
+ | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn {
464
+ result = val[1].new(val.first, val.last)
465
+ }
466
+ ;
467
+
468
+ AssignmentExprNoBF:
469
+ ConditionalExprNoBF
470
+ | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr {
471
+ result = val[1].new(val.first, val.last)
472
+ }
473
+ ;
474
+
475
+ AssignmentOperator:
476
+ '=' { result = OpEqualNode }
477
+ | PLUSEQUAL { result = OpPlusEqualNode }
478
+ | MINUSEQUAL { result = OpMinusEqualNode }
479
+ | MULTEQUAL { result = OpMultiplyEqualNode }
480
+ | DIVEQUAL { result = OpDivideEqualNode }
481
+ | LSHIFTEQUAL { result = OpLShiftEqualNode }
482
+ | RSHIFTEQUAL { result = OpRShiftEqualNode }
483
+ | URSHIFTEQUAL { result = OpURShiftEqualNode }
484
+ | ANDEQUAL { result = OpAndEqualNode }
485
+ | XOREQUAL { result = OpXOrEqualNode }
486
+ | OREQUAL { result = OpOrEqualNode }
487
+ | MODEQUAL { result = OpModEqualNode }
488
+ ;
489
+
490
+ Expr:
491
+ AssignmentExpr
492
+ | Expr ',' AssignmentExpr { result = CommaNode.new(val[0], val[2]) }
493
+ ;
494
+
495
+ ExprNoIn:
496
+ AssignmentExprNoIn
497
+ | ExprNoIn ',' AssignmentExprNoIn { result = CommaNode.new(val[0], val[2]) }
498
+ ;
499
+
500
+ ExprNoBF:
501
+ AssignmentExprNoBF
502
+ | ExprNoBF ',' AssignmentExpr { result = CommaNode.new(val[0], val[2]) }
503
+ ;
504
+
505
+
506
+ Block:
507
+ '{' SourceElements '}' {
508
+ result = BlockNode.new(val[1])
509
+ debug(result)
510
+ }
511
+ ;
512
+
513
+ VariableStatement:
514
+ VAR VariableDeclarationList ';' {
515
+ result = VarStatementNode.new(val[1])
516
+ debug(result)
517
+ }
518
+ | VAR VariableDeclarationList error {
519
+ result = VarStatementNode.new(val[1])
520
+ debug(result)
521
+ yyabort unless allow_auto_semi?(val.last)
522
+ }
523
+ ;
524
+
525
+ VariableDeclarationList:
526
+ VariableDeclaration { result = val }
527
+ | VariableDeclarationList ',' VariableDeclaration {
528
+ result = [val.first, val.last].flatten
529
+ }
530
+ ;
531
+
532
+ VariableDeclarationListNoIn:
533
+ VariableDeclarationNoIn { result = val }
534
+ | VariableDeclarationListNoIn ',' VariableDeclarationNoIn {
535
+ result = [val.first, val.last].flatten
536
+ }
537
+ ;
538
+
539
+ VariableDeclaration:
540
+ IDENT { result = VarDeclNode.new(val.first, nil) }
541
+ | IDENT Initializer { result = VarDeclNode.new(val.first, val[1]) }
542
+ ;
543
+
544
+ VariableDeclarationNoIn:
545
+ IDENT { result = VarDeclNode.new(val[0],nil) }
546
+ | IDENT InitializerNoIn { result = VarDeclNode.new(val[0], val[1]) }
547
+ ;
548
+
549
+ ConstStatement:
550
+ CONST ConstDeclarationList ';' {
551
+ result = ConstStatementNode.new(val[1])
552
+ debug(result)
553
+ }
554
+ | CONST ConstDeclarationList error {
555
+ result = ConstStatementNode.new(val[1])
556
+ debug(result)
557
+ yyerror unless allow_auto_semi?(val.last)
558
+ }
559
+ ;
560
+
561
+ ConstDeclarationList:
562
+ ConstDeclaration { result = val }
563
+ | ConstDeclarationList ',' ConstDeclaration {
564
+ result = [val.first, val.last].flatten
565
+ }
566
+ ;
567
+
568
+ ConstDeclaration:
569
+ IDENT { result = VarDeclNode.new(val[0], nil, true) }
570
+ | IDENT Initializer { result = VarDeclNode.new(val[0], val[1], true) }
571
+ ;
572
+
573
+ Initializer:
574
+ '=' AssignmentExpr { result = AssignExprNode.new(val[1]) }
575
+ ;
576
+
577
+ InitializerNoIn:
578
+ '=' AssignmentExprNoIn { result = AssignExprNode.new(val[1]) }
579
+ ;
580
+
581
+ EmptyStatement:
582
+ ';' { result = EmptyStatementNode.new(val[0]) }
583
+ ;
584
+
585
+ ExprStatement:
586
+ ExprNoBF ';' {
587
+ result = ExpressionStatementNode.new(val.first)
588
+ debug(result)
589
+ }
590
+ | ExprNoBF error {
591
+ result = ExpressionStatementNode.new(val.first)
592
+ debug(result)
593
+ yyabort unless allow_auto_semi?(val.last)
594
+ }
595
+ ;
596
+
597
+ IfStatement:
598
+ IF '(' Expr ')' Statement =IF_WITHOUT_ELSE {
599
+ result = IfNode.new(val[2], val[4])
600
+ debug(result)
601
+ }
602
+ | IF '(' Expr ')' Statement ELSE Statement {
603
+ result = IfNode.new(val[2], val[4], val[6])
604
+ debug(result)
605
+ }
606
+ ;
607
+
608
+ IterationStatement:
609
+ DO Statement WHILE '(' Expr ')' ';' {
610
+ result = DoWhileNode.new(val[1], val[4])
611
+ debug(result)
612
+ }
613
+ | DO Statement WHILE '(' Expr ')' error {
614
+ result = DoWhileNode.new(val[1], val[4])
615
+ debug(result)
616
+ } /* Always performs automatic semicolon insertion. */
617
+ | WHILE '(' Expr ')' Statement {
618
+ result = WhileNode.new(val[2], val[4])
619
+ debug(result)
620
+ }
621
+ | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement {
622
+ result = ForNode.new(val[2], val[4], val[6], val[8])
623
+ debug(result)
624
+ }
625
+ | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement
626
+ {
627
+ result = ForNode.new(VarStatementNode.new(val[3]), val[5], val[7], val[9])
628
+ debug(result)
629
+ }
630
+ | FOR '(' LeftHandSideExpr IN Expr ')' Statement {
631
+ #yyabort if (!n.isLocation())
632
+ result = ForInNode.new(val[2], val[4], val[6])
633
+ debug(result);
634
+ }
635
+ | FOR '(' VAR IDENT IN Expr ')' Statement {
636
+ result = ForInNode.new(
637
+ VarDeclNode.new(val[3], nil), val[5], val[7])
638
+ debug(result)
639
+ }
640
+ | FOR '(' VAR IDENT InitializerNoIn IN Expr ')' Statement {
641
+ result = ForInNode.new(
642
+ VarDeclNode.new(val[3], val[4]), val[6], val[8]
643
+ )
644
+ debug(result)
645
+ }
646
+ ;
647
+
648
+ ExprOpt:
649
+ /* nothing */ { result = nil }
650
+ | Expr
651
+ ;
652
+
653
+ ExprNoInOpt:
654
+ /* nothing */ { result = nil }
655
+ | ExprNoIn
656
+ ;
657
+
658
+ ContinueStatement:
659
+ CONTINUE ';' {
660
+ result = ContinueNode.new(nil)
661
+ debug(result)
662
+ }
663
+ | CONTINUE error {
664
+ result = ContinueNode.new(nil)
665
+ debug(result)
666
+ yyabort unless allow_auto_semi?(val[1])
667
+ }
668
+ | CONTINUE IDENT ';' {
669
+ result = ContinueNode.new(val[1])
670
+ debug(result)
671
+ }
672
+ | CONTINUE IDENT error {
673
+ result = ContinueNode.new(val[1])
674
+ debug(result)
675
+ yyabort unless allow_auto_semi?(val[2])
676
+ }
677
+ ;
678
+
679
+ BreakStatement:
680
+ BREAK ';' {
681
+ result = BreakNode.new(nil)
682
+ debug(result)
683
+ }
684
+ | BREAK error {
685
+ result = BreakNode.new(nil)
686
+ debug(result)
687
+ yyabort unless allow_auto_semi?(val[1])
688
+ }
689
+ | BREAK IDENT ';' {
690
+ result = BreakNode.new(val[1])
691
+ debug(result)
692
+ }
693
+ | BREAK IDENT error {
694
+ result = BreakNode.new(val[1])
695
+ debug(result)
696
+ yyabort unless allow_auto_semi?(val[2])
697
+ }
698
+ ;
699
+
700
+ ReturnStatement:
701
+ RETURN ';' {
702
+ result = ReturnNode.new(nil)
703
+ debug(result)
704
+ }
705
+ | RETURN error {
706
+ result = ReturnNode.new(nil)
707
+ debug(result)
708
+ yyabort unless allow_auto_semi?(val[1])
709
+ }
710
+ | RETURN Expr ';' {
711
+ result = ReturnNode.new(val[1])
712
+ debug(result)
713
+ }
714
+ | RETURN Expr error {
715
+ result = ReturnNode.new(val[1])
716
+ debug(result)
717
+ yyabort unless allow_auto_semi?(val[2])
718
+ }
719
+ ;
720
+
721
+ WithStatement:
722
+ WITH '(' Expr ')' Statement {
723
+ result = WithNode.new(val[2], val[4])
724
+ debug(result)
725
+ }
726
+ ;
727
+
728
+ SwitchStatement:
729
+ SWITCH '(' Expr ')' CaseBlock {
730
+ result = SwitchNode.new(val[2], val[4])
731
+ debug(result)
732
+ }
733
+ ;
734
+
735
+ CaseBlock:
736
+ '{' CaseClausesOpt '}' { result = CaseBlockNode.new(val[1]) }
737
+ | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}' {
738
+ result = CaseBlockNode.new([val[1], val[2], val[3]].flatten)
739
+ }
740
+ ;
741
+
742
+ CaseClausesOpt:
743
+ /* nothing */ { result = [] }
744
+ | CaseClauses
745
+ ;
746
+
747
+ CaseClauses:
748
+ CaseClause { result = val }
749
+ | CaseClauses CaseClause { result = val.flatten }
750
+ ;
751
+
752
+ CaseClause:
753
+ CASE Expr ':' SourceElements {
754
+ result = CaseClauseNode.new(val[1], val[3])
755
+ }
756
+ ;
757
+
758
+ DefaultClause:
759
+ DEFAULT ':' SourceElements {
760
+ result = CaseClauseNode.new(nil, val[2])
761
+ }
762
+ ;
763
+
764
+ LabelledStatement:
765
+ IDENT ':' Statement { result = LabelNode.new(val[0], val[2]) }
766
+ ;
767
+
768
+ ThrowStatement:
769
+ THROW Expr ';' {
770
+ result = ThrowNode.new(val[1])
771
+ debug(result)
772
+ }
773
+ | THROW Expr error {
774
+ result = ThrowNode.new(val[1])
775
+ debug(result)
776
+ yyabort unless allow_auto_semi?(val[2])
777
+ }
778
+ ;
779
+
780
+ TryStatement:
781
+ TRY Block FINALLY Block {
782
+ result = TryNode.new(val[1], nil, nil, val[3])
783
+ debug(result)
784
+ }
785
+ | TRY Block CATCH '(' IDENT ')' Block {
786
+ result = TryNode.new(val[1], val[4], val[6])
787
+ debug(result)
788
+ }
789
+ | TRY Block CATCH '(' IDENT ')' Block FINALLY Block {
790
+ result = TryNode.new(val[1], val[4], val[6], val[8])
791
+ debug(result)
792
+ }
793
+ ;
794
+
795
+ DebuggerStatement:
796
+ DEBUGGER ';' {
797
+ result = EmptyStatementNode.new(val[0])
798
+ debug(result)
799
+ }
800
+ | DEBUGGER error {
801
+ result = EmptyStatementNode.new(val[0])
802
+ debug(result)
803
+ yyabort unless allow_auto_semi?(val[1])
804
+ }
805
+ ;
806
+
807
+ FunctionDeclaration:
808
+ FUNCTION IDENT '(' ')' '{' FunctionBody '}' {
809
+ result = FunctionDeclNode.new(val[1], val[5])
810
+ debug(val[5])
811
+ }
812
+ | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}' {
813
+ result = FunctionDeclNode.new(val[1], val[6], val[3])
814
+ debug(val[6])
815
+ }
816
+ ;
817
+
818
+ FunctionExpr:
819
+ FUNCTION '(' ')' '{' FunctionBody '}' {
820
+ result = FunctionExprNode.new(val[0], val[4])
821
+ debug(val[4])
822
+ }
823
+ | FUNCTION '(' FormalParameterList ')' '{' FunctionBody '}' {
824
+ result = FunctionExprNode.new(val[0], val[5], val[2])
825
+ debug(val[5])
826
+ }
827
+ | FUNCTION IDENT '(' ')' '{' FunctionBody '}' {
828
+ result = FunctionExprNode.new(val[1], val[5])
829
+ debug(val[5])
830
+ }
831
+ | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}' {
832
+ result = FunctionExprNode.new(val[1], val[6], val[3])
833
+ debug(val[6])
834
+ }
835
+ ;
836
+
837
+ FormalParameterList:
838
+ IDENT { result = [ParameterNode.new(val[0])] }
839
+ | FormalParameterList ',' IDENT {
840
+ result = [val.first, ParameterNode.new(val.last)].flatten
841
+ }
842
+ ;
843
+
844
+ FunctionBody:
845
+ SourceElements { result = FunctionBodyNode.new(val[0]) }
846
+ ;
847
+ end
848
+
849
+ ---- header
850
+ require "rkelly/nodes"
851
+
852
+ ---- inner
853
+ include RKelly::Nodes
854
+
855
+ def allow_auto_semi?(error_token)
856
+ error_token == false || error_token == '}' || @terminator
857
+ end
858
+
859
+ def property_class_for(ident)
860
+ case ident
861
+ when 'get'
862
+ GetterPropertyNode
863
+ when 'set'
864
+ SetterPropertyNode
865
+ end
866
+ end
867
+
868
+ def debug(*args)
869
+ logger.debug(*args) if logger
870
+ end