rkelly 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. data/CHANGELOG.txt +7 -0
  2. data/Manifest.txt +199 -0
  3. data/README.txt +58 -0
  4. data/Rakefile +85 -0
  5. data/lib/parser.y +870 -0
  6. data/lib/rkelly.rb +13 -0
  7. data/lib/rkelly/constants.rb +3 -0
  8. data/lib/rkelly/generated_parser.rb +3237 -0
  9. data/lib/rkelly/js.rb +14 -0
  10. data/lib/rkelly/js/array.rb +15 -0
  11. data/lib/rkelly/js/base.rb +91 -0
  12. data/lib/rkelly/js/boolean.rb +21 -0
  13. data/lib/rkelly/js/function.rb +39 -0
  14. data/lib/rkelly/js/function_prototype.rb +15 -0
  15. data/lib/rkelly/js/global_object.rb +52 -0
  16. data/lib/rkelly/js/math.rb +10 -0
  17. data/lib/rkelly/js/nan.rb +18 -0
  18. data/lib/rkelly/js/number.rb +22 -0
  19. data/lib/rkelly/js/object.rb +30 -0
  20. data/lib/rkelly/js/object_prototype.rb +14 -0
  21. data/lib/rkelly/js/property.rb +20 -0
  22. data/lib/rkelly/js/scope.rb +6 -0
  23. data/lib/rkelly/js/string.rb +21 -0
  24. data/lib/rkelly/lexeme.rb +18 -0
  25. data/lib/rkelly/nodes.rb +5 -0
  26. data/lib/rkelly/nodes/binary_node.rb +18 -0
  27. data/lib/rkelly/nodes/bracket_accessor_node.rb +11 -0
  28. data/lib/rkelly/nodes/case_clause_node.rb +11 -0
  29. data/lib/rkelly/nodes/comma_node.rb +11 -0
  30. data/lib/rkelly/nodes/conditional_node.rb +11 -0
  31. data/lib/rkelly/nodes/dot_accessor_node.rb +11 -0
  32. data/lib/rkelly/nodes/for_in_node.rb +12 -0
  33. data/lib/rkelly/nodes/for_node.rb +13 -0
  34. data/lib/rkelly/nodes/function_call_node.rb +16 -0
  35. data/lib/rkelly/nodes/function_decl_node.rb +6 -0
  36. data/lib/rkelly/nodes/function_expr_node.rb +12 -0
  37. data/lib/rkelly/nodes/if_node.rb +12 -0
  38. data/lib/rkelly/nodes/label_node.rb +11 -0
  39. data/lib/rkelly/nodes/new_expr_node.rb +11 -0
  40. data/lib/rkelly/nodes/node.rb +88 -0
  41. data/lib/rkelly/nodes/not_strict_equal_node.rb +6 -0
  42. data/lib/rkelly/nodes/op_equal_node.rb +16 -0
  43. data/lib/rkelly/nodes/postfix_node.rb +11 -0
  44. data/lib/rkelly/nodes/prefix_node.rb +6 -0
  45. data/lib/rkelly/nodes/property_node.rb +13 -0
  46. data/lib/rkelly/nodes/resolve_node.rb +19 -0
  47. data/lib/rkelly/nodes/strict_equal_node.rb +6 -0
  48. data/lib/rkelly/nodes/try_node.rb +13 -0
  49. data/lib/rkelly/nodes/var_decl_node.rb +15 -0
  50. data/lib/rkelly/parser.rb +100 -0
  51. data/lib/rkelly/runtime.rb +36 -0
  52. data/lib/rkelly/runtime/ruby_function.rb +13 -0
  53. data/lib/rkelly/runtime/scope_chain.rb +57 -0
  54. data/lib/rkelly/token.rb +15 -0
  55. data/lib/rkelly/tokenizer.rb +122 -0
  56. data/lib/rkelly/visitable.rb +16 -0
  57. data/lib/rkelly/visitors.rb +4 -0
  58. data/lib/rkelly/visitors/dot_visitor.rb +228 -0
  59. data/lib/rkelly/visitors/ecma_visitor.rb +314 -0
  60. data/lib/rkelly/visitors/enumerable_visitor.rb +18 -0
  61. data/lib/rkelly/visitors/evaluation_visitor.rb +419 -0
  62. data/lib/rkelly/visitors/function_visitor.rb +46 -0
  63. data/lib/rkelly/visitors/pointcut_visitor.rb +31 -0
  64. data/lib/rkelly/visitors/real_sexp_visitor.rb +16 -0
  65. data/lib/rkelly/visitors/sexp_visitor.rb +373 -0
  66. data/lib/rkelly/visitors/visitor.rb +136 -0
  67. data/rkelly.gemspec +33 -0
  68. data/test/ecma_script_test_case.rb +21 -0
  69. data/test/execute_test_case.rb +16 -0
  70. data/test/execution_contexts/test_10_1_3-1.rb +32 -0
  71. data/test/expressions/test_11_3_1.rb +64 -0
  72. data/test/expressions/test_11_3_2.rb +64 -0
  73. data/test/expressions/test_11_4_2.rb +13 -0
  74. data/test/expressions/test_11_4_3.rb +52 -0
  75. data/test/expressions/test_11_4_4.rb +68 -0
  76. data/test/expressions/test_11_4_5.rb +69 -0
  77. data/test/expressions/test_11_4_6.rb +88 -0
  78. data/test/expressions/test_11_4_8.rb +28 -0
  79. data/test/expressions/test_11_4_9.rb +103 -0
  80. data/test/expressions/test_11_5_1.rb +51 -0
  81. data/test/expressions/test_11_5_2.rb +80 -0
  82. data/test/expressions/test_11_5_3.rb +88 -0
  83. data/test/expressions/test_11_6_1-1.rb +19 -0
  84. data/test/expressions/test_11_9_1.rb +19 -0
  85. data/test/function/test_15_3_1_1-1.rb +34 -0
  86. data/test/global_object/test_15_1_1_1.rb +29 -0
  87. data/test/global_object/test_15_1_1_2.rb +17 -0
  88. data/test/global_object/test_15_1_1_3.rb +9 -0
  89. data/test/helper.rb +5 -0
  90. data/test/node_test_case.rb +11 -0
  91. data/test/object/test_15_2_1_1.rb +257 -0
  92. data/test/object/test_15_2_1_2.rb +21 -0
  93. data/test/object/test_15_2_2_1.rb +52 -0
  94. data/test/statements/test_12_5-1.rb +27 -0
  95. data/test/test_add_node.rb +8 -0
  96. data/test/test_arguments_node.rb +8 -0
  97. data/test/test_array_node.rb +9 -0
  98. data/test/test_assign_expr_node.rb +8 -0
  99. data/test/test_automatic_semicolon_insertion.rb +137 -0
  100. data/test/test_bit_and_node.rb +8 -0
  101. data/test/test_bit_or_node.rb +8 -0
  102. data/test/test_bit_x_or_node.rb +8 -0
  103. data/test/test_bitwise_not_node.rb +8 -0
  104. data/test/test_block_node.rb +14 -0
  105. data/test/test_bracket_accessor_node.rb +16 -0
  106. data/test/test_break_node.rb +11 -0
  107. data/test/test_case_block_node.rb +11 -0
  108. data/test/test_case_clause_node.rb +15 -0
  109. data/test/test_comma_node.rb +13 -0
  110. data/test/test_comments.rb +44 -0
  111. data/test/test_conditional_node.rb +17 -0
  112. data/test/test_const_statement_node.rb +14 -0
  113. data/test/test_continue_node.rb +11 -0
  114. data/test/test_delete_node.rb +8 -0
  115. data/test/test_divide_node.rb +8 -0
  116. data/test/test_do_while_node.rb +13 -0
  117. data/test/test_dot_accessor_node.rb +9 -0
  118. data/test/test_ecma_visitor.rb +192 -0
  119. data/test/test_element_node.rb +8 -0
  120. data/test/test_empty_statement_node.rb +8 -0
  121. data/test/test_equal_node.rb +8 -0
  122. data/test/test_evaluation_visitor.rb +66 -0
  123. data/test/test_expression_statement_node.rb +10 -0
  124. data/test/test_false_node.rb +8 -0
  125. data/test/test_for_in_node.rb +17 -0
  126. data/test/test_for_node.rb +24 -0
  127. data/test/test_function_body_node.rb +8 -0
  128. data/test/test_function_call_node.rb +10 -0
  129. data/test/test_function_decl_node.rb +16 -0
  130. data/test/test_function_expr_node.rb +16 -0
  131. data/test/test_function_visitor.rb +26 -0
  132. data/test/test_getter_property_node.rb +10 -0
  133. data/test/test_global_object.rb +49 -0
  134. data/test/test_greater_node.rb +8 -0
  135. data/test/test_greater_or_equal_node.rb +8 -0
  136. data/test/test_if_node.rb +17 -0
  137. data/test/test_in_node.rb +8 -0
  138. data/test/test_instance_of_node.rb +8 -0
  139. data/test/test_label_node.rb +13 -0
  140. data/test/test_left_shift_node.rb +8 -0
  141. data/test/test_less_node.rb +8 -0
  142. data/test/test_less_or_equal_node.rb +8 -0
  143. data/test/test_line_number.rb +23 -0
  144. data/test/test_logical_and_node.rb +8 -0
  145. data/test/test_logical_not_node.rb +8 -0
  146. data/test/test_logical_or_node.rb +8 -0
  147. data/test/test_modulus_node.rb +8 -0
  148. data/test/test_multiply_node.rb +8 -0
  149. data/test/test_new_expr_node.rb +9 -0
  150. data/test/test_not_equal_node.rb +8 -0
  151. data/test/test_not_strict_equal_node.rb +8 -0
  152. data/test/test_null_node.rb +8 -0
  153. data/test/test_number_node.rb +8 -0
  154. data/test/test_object_literal_node.rb +9 -0
  155. data/test/test_op_and_equal_node.rb +10 -0
  156. data/test/test_op_divide_equal_node.rb +10 -0
  157. data/test/test_op_equal_node.rb +10 -0
  158. data/test/test_op_l_shift_equal_node.rb +10 -0
  159. data/test/test_op_minus_equal_node.rb +10 -0
  160. data/test/test_op_mod_equal_node.rb +10 -0
  161. data/test/test_op_multiply_equal_node.rb +10 -0
  162. data/test/test_op_or_equal_node.rb +10 -0
  163. data/test/test_op_plus_equal_node.rb +10 -0
  164. data/test/test_op_r_shift_equal_node.rb +10 -0
  165. data/test/test_op_u_r_shift_equal_node.rb +10 -0
  166. data/test/test_op_x_or_equal_node.rb +10 -0
  167. data/test/test_parameter_node.rb +8 -0
  168. data/test/test_parser.rb +1355 -0
  169. data/test/test_pointcut_visitor.rb +34 -0
  170. data/test/test_postfix_node.rb +8 -0
  171. data/test/test_prefix_node.rb +8 -0
  172. data/test/test_property_node.rb +8 -0
  173. data/test/test_regexp_node.rb +8 -0
  174. data/test/test_resolve_node.rb +22 -0
  175. data/test/test_return_node.rb +11 -0
  176. data/test/test_right_shift_node.rb +8 -0
  177. data/test/test_rkelly.rb +19 -0
  178. data/test/test_runtime.rb +12 -0
  179. data/test/test_scope_chain.rb +50 -0
  180. data/test/test_setter_property_node.rb +10 -0
  181. data/test/test_source_elements.rb +9 -0
  182. data/test/test_strict_equal_node.rb +8 -0
  183. data/test/test_string_node.rb +8 -0
  184. data/test/test_subtract_node.rb +8 -0
  185. data/test/test_switch_node.rb +12 -0
  186. data/test/test_this_node.rb +8 -0
  187. data/test/test_throw_node.rb +7 -0
  188. data/test/test_tokenizer.rb +143 -0
  189. data/test/test_true_node.rb +8 -0
  190. data/test/test_try_node.rb +59 -0
  191. data/test/test_type_of_node.rb +8 -0
  192. data/test/test_unary_minus_node.rb +8 -0
  193. data/test/test_unary_plus_node.rb +8 -0
  194. data/test/test_unsigned_right_shift_node.rb +8 -0
  195. data/test/test_var_decl_node.rb +21 -0
  196. data/test/test_var_statement_node.rb +14 -0
  197. data/test/test_void_node.rb +8 -0
  198. data/test/test_while_node.rb +15 -0
  199. data/test/test_with_node.rb +8 -0
  200. metadata +390 -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,199 @@
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/real_sexp_visitor.rb
65
+ lib/rkelly/visitors/sexp_visitor.rb
66
+ lib/rkelly/visitors/visitor.rb
67
+ rkelly.gemspec
68
+ test/ecma_script_test_case.rb
69
+ test/execute_test_case.rb
70
+ test/execution_contexts/test_10_1_3-1.rb
71
+ test/expressions/test_11_3_1.rb
72
+ test/expressions/test_11_3_2.rb
73
+ test/expressions/test_11_4_2.rb
74
+ test/expressions/test_11_4_3.rb
75
+ test/expressions/test_11_4_4.rb
76
+ test/expressions/test_11_4_5.rb
77
+ test/expressions/test_11_4_6.rb
78
+ test/expressions/test_11_4_8.rb
79
+ test/expressions/test_11_4_9.rb
80
+ test/expressions/test_11_5_1.rb
81
+ test/expressions/test_11_5_2.rb
82
+ test/expressions/test_11_5_3.rb
83
+ test/expressions/test_11_6_1-1.rb
84
+ test/expressions/test_11_9_1.rb
85
+ test/function/test_15_3_1_1-1.rb
86
+ test/global_object/test_15_1_1_1.rb
87
+ test/global_object/test_15_1_1_2.rb
88
+ test/global_object/test_15_1_1_3.rb
89
+ test/helper.rb
90
+ test/node_test_case.rb
91
+ test/object/test_15_2_1_1.rb
92
+ test/object/test_15_2_1_2.rb
93
+ test/object/test_15_2_2_1.rb
94
+ test/statements/test_12_5-1.rb
95
+ test/test_add_node.rb
96
+ test/test_arguments_node.rb
97
+ test/test_array_node.rb
98
+ test/test_assign_expr_node.rb
99
+ test/test_automatic_semicolon_insertion.rb
100
+ test/test_bit_and_node.rb
101
+ test/test_bit_or_node.rb
102
+ test/test_bit_x_or_node.rb
103
+ test/test_bitwise_not_node.rb
104
+ test/test_block_node.rb
105
+ test/test_bracket_accessor_node.rb
106
+ test/test_break_node.rb
107
+ test/test_case_block_node.rb
108
+ test/test_case_clause_node.rb
109
+ test/test_comma_node.rb
110
+ test/test_comments.rb
111
+ test/test_conditional_node.rb
112
+ test/test_const_statement_node.rb
113
+ test/test_continue_node.rb
114
+ test/test_delete_node.rb
115
+ test/test_divide_node.rb
116
+ test/test_do_while_node.rb
117
+ test/test_dot_accessor_node.rb
118
+ test/test_ecma_visitor.rb
119
+ test/test_element_node.rb
120
+ test/test_empty_statement_node.rb
121
+ test/test_equal_node.rb
122
+ test/test_evaluation_visitor.rb
123
+ test/test_expression_statement_node.rb
124
+ test/test_false_node.rb
125
+ test/test_for_in_node.rb
126
+ test/test_for_node.rb
127
+ test/test_function_body_node.rb
128
+ test/test_function_call_node.rb
129
+ test/test_function_decl_node.rb
130
+ test/test_function_expr_node.rb
131
+ test/test_function_visitor.rb
132
+ test/test_getter_property_node.rb
133
+ test/test_global_object.rb
134
+ test/test_greater_node.rb
135
+ test/test_greater_or_equal_node.rb
136
+ test/test_if_node.rb
137
+ test/test_in_node.rb
138
+ test/test_instance_of_node.rb
139
+ test/test_label_node.rb
140
+ test/test_left_shift_node.rb
141
+ test/test_less_node.rb
142
+ test/test_less_or_equal_node.rb
143
+ test/test_line_number.rb
144
+ test/test_logical_and_node.rb
145
+ test/test_logical_not_node.rb
146
+ test/test_logical_or_node.rb
147
+ test/test_modulus_node.rb
148
+ test/test_multiply_node.rb
149
+ test/test_new_expr_node.rb
150
+ test/test_not_equal_node.rb
151
+ test/test_not_strict_equal_node.rb
152
+ test/test_null_node.rb
153
+ test/test_number_node.rb
154
+ test/test_object_literal_node.rb
155
+ test/test_op_and_equal_node.rb
156
+ test/test_op_divide_equal_node.rb
157
+ test/test_op_equal_node.rb
158
+ test/test_op_l_shift_equal_node.rb
159
+ test/test_op_minus_equal_node.rb
160
+ test/test_op_mod_equal_node.rb
161
+ test/test_op_multiply_equal_node.rb
162
+ test/test_op_or_equal_node.rb
163
+ test/test_op_plus_equal_node.rb
164
+ test/test_op_r_shift_equal_node.rb
165
+ test/test_op_u_r_shift_equal_node.rb
166
+ test/test_op_x_or_equal_node.rb
167
+ test/test_parameter_node.rb
168
+ test/test_parser.rb
169
+ test/test_pointcut_visitor.rb
170
+ test/test_postfix_node.rb
171
+ test/test_prefix_node.rb
172
+ test/test_property_node.rb
173
+ test/test_regexp_node.rb
174
+ test/test_resolve_node.rb
175
+ test/test_return_node.rb
176
+ test/test_right_shift_node.rb
177
+ test/test_rkelly.rb
178
+ test/test_runtime.rb
179
+ test/test_scope_chain.rb
180
+ test/test_setter_property_node.rb
181
+ test/test_source_elements.rb
182
+ test/test_strict_equal_node.rb
183
+ test/test_string_node.rb
184
+ test/test_subtract_node.rb
185
+ test/test_switch_node.rb
186
+ test/test_this_node.rb
187
+ test/test_throw_node.rb
188
+ test/test_tokenizer.rb
189
+ test/test_true_node.rb
190
+ test/test_try_node.rb
191
+ test/test_type_of_node.rb
192
+ test/test_unary_minus_node.rb
193
+ test/test_unary_plus_node.rb
194
+ test/test_unsigned_right_shift_node.rb
195
+ test/test_var_decl_node.rb
196
+ test/test_var_statement_node.rb
197
+ test/test_void_node.rb
198
+ test/test_while_node.rb
199
+ test/test_with_node.rb
data/README.txt ADDED
@@ -0,0 +1,58 @@
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
+ ##
12
+ # Iterate over and modify a JavaScript AST. Then print the modified
13
+ # AST as JavaScript.
14
+ require 'rkelly'
15
+
16
+ parser = RKelly::Parser.new
17
+ ast = parser.parse(
18
+ "for(var i = 0; i < 10; i++) { var x = 5 + 5; }"
19
+ )
20
+
21
+ ast.each do |node|
22
+ node.value = 'hello' if node.value == 'i'
23
+ node.name = 'hello' if node.respond_to?(:name) && node.name == 'i'
24
+ end
25
+ puts ast.to_ecma # => awesome javascript
26
+
27
+ == Acknowledgments
28
+
29
+ The original javascript parser was was taken from rbnarcissus written by
30
+ Paul Sowden. Thanks Paul!
31
+
32
+ http://idontsmoke.co.uk/2005/rbnarcissus/
33
+
34
+ The current parser was ported from WebKit. Thank you WebKit team!
35
+
36
+ == License
37
+
38
+ The MIT License
39
+
40
+ Copyright (c) 2007, 2008, 2009 Aaron Patterson, John Barnette
41
+
42
+ Permission is hereby granted, free of charge, to any person obtaining a copy
43
+ of this software and associated documentation files (the "Software"), to deal
44
+ in the Software without restriction, including without limitation the rights
45
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+ copies of the Software, and to permit persons to whom the Software is
47
+ furnished to do so, subject to the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be included in
50
+ all copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ 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