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
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class OpRShiftEqualNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ resolve = ResolveNode.new('foo')
6
+ number = NumberNode.new(10)
7
+ node = OpRShiftEqualNode.new(resolve, number)
8
+ assert_sexp([:op_rshift_equal, [:resolve, 'foo'], [:lit, 10]], node)
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class OpURShiftEqualNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ resolve = ResolveNode.new('foo')
6
+ number = NumberNode.new(10)
7
+ node = OpURShiftEqualNode.new(resolve, number)
8
+ assert_sexp([:op_urshift_equal, [:resolve, 'foo'], [:lit, 10]], node)
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class OpXOrEqualNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ resolve = ResolveNode.new('foo')
6
+ number = NumberNode.new(10)
7
+ node = OpXOrEqualNode.new(resolve, number)
8
+ assert_sexp([:op_xor_equal, [:resolve, 'foo'], [:lit, 10]], node)
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class ParameterNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = ParameterNode.new('a')
6
+ assert_sexp([:param, 'a'], node)
7
+ end
8
+ end
@@ -0,0 +1,1355 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class ParserTest < Test::Unit::TestCase
4
+ def setup
5
+ @parser = RKelly::Parser.new
6
+ end
7
+
8
+ def test_array_access
9
+ assert_sexp(
10
+ [
11
+ [:var,
12
+ [[:var_decl, :a,
13
+ [:assign, [:bracket_access, [:resolve, "foo"], [:lit, 10]]],
14
+ ]]
15
+ ]
16
+ ],
17
+ @parser.parse('var a = foo[10];'))
18
+ end
19
+
20
+ def test_function_expr_anon_no_args
21
+ assert_sexp(
22
+ [[:var,
23
+ [[:var_decl, :foo, [:assign,
24
+ [:func_expr, "function", [], [:func_body, []]]
25
+ ]]]
26
+ ]],
27
+ @parser.parse("var foo = function() { }"))
28
+ end
29
+
30
+ def test_function_body_expr_anon_no_args
31
+ assert_sexp(
32
+ [[:var,
33
+ [[:var_decl, :foo, [:assign,
34
+ [:func_expr, "function", [],
35
+ [:func_body,
36
+ [[:var, [[:var_decl, :a, [:assign, [:lit, 10]]]]]]
37
+ ]
38
+ ]
39
+ ]]]
40
+ ]],
41
+ @parser.parse("var foo = function() { var a = 10; }"))
42
+ end
43
+
44
+ def test_function_expr_anon_single_arg
45
+ assert_sexp(
46
+ [[:var,
47
+ [[:var_decl, :foo, [:assign,
48
+ [:func_expr, "function", [[:param, "a"]], [:func_body, []]]
49
+ ]]]
50
+ ]],
51
+ @parser.parse("var foo = function(a) { }"))
52
+ end
53
+
54
+ def test_function_expr_anon
55
+ assert_sexp(
56
+ [[:var,
57
+ [[:var_decl, :foo, [:assign,
58
+ [:func_expr, "function", [[:param, "a"], [:param, 'b']], [:func_body, []]]
59
+ ]]]
60
+ ]],
61
+ @parser.parse("var foo = function(a,b) { }"))
62
+ end
63
+
64
+ def test_function_expr_no_args
65
+ assert_sexp(
66
+ [[:var,
67
+ [[:var_decl, :foo, [:assign,
68
+ [:func_expr, 'aaron', [], [:func_body, []]]
69
+ ]]]
70
+ ]],
71
+ @parser.parse("var foo = function aaron() { }"))
72
+ end
73
+
74
+ def test_function_expr_with_args
75
+ assert_sexp(
76
+ [[:var,
77
+ [[:var_decl, :foo, [:assign,
78
+ [:func_expr, 'aaron', [[:param, 'a'], [:param, 'b']], [:func_body, []]]
79
+ ]]]
80
+ ]],
81
+ @parser.parse("var foo = function aaron(a, b) { }"))
82
+ end
83
+
84
+ def test_labelled_statement
85
+ assert_sexp([[:label, :foo, [:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]],
86
+ @parser.parse('foo: var x = 10;'))
87
+ assert_sexp([[:label, :foo, [:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]],
88
+ @parser.parse('foo: var x = 10'))
89
+ end
90
+
91
+ def test_throw_statement
92
+ assert_sexp([[:throw, [:lit, 10]]], @parser.parse('throw 10;'))
93
+ assert_sexp([[:throw, [:lit, 10]]], @parser.parse('throw 10'))
94
+ end
95
+
96
+ def test_object_literal
97
+ assert_sexp(
98
+ [[:var,
99
+ [[:var_decl, :foo, [:assign,
100
+ [:object, [[:property, :bar, [:lit, 10]]]]
101
+ ]]]
102
+ ]],
103
+ @parser.parse('var foo = { bar: 10 }'))
104
+ assert_sexp(
105
+ [[:var,
106
+ [[:var_decl, :foo, [:assign,
107
+ [:object, []]
108
+ ]]]
109
+ ]],
110
+ @parser.parse('var foo = { }'))
111
+ assert_sexp(
112
+ [[:var,
113
+ [[:var_decl, :foo, [:assign,
114
+ [:object, [[:property, '"bar"'.to_sym, [:lit, 10]]]]
115
+ ]]]
116
+ ]],
117
+ @parser.parse('var foo = { "bar": 10 }'))
118
+ assert_sexp(
119
+ [[:var,
120
+ [[:var_decl, :foo, [:assign,
121
+ [:object, [[:property, :"5", [:lit, 10]]]]
122
+ ]]]
123
+ ]],
124
+ @parser.parse('var foo = { 5: 10 }'))
125
+ end
126
+
127
+ def test_object_literal_getter
128
+ assert_sexp(
129
+ [[:var,
130
+ [[:var_decl, :foo, [:assign,
131
+ [:object, [[:getter, :a, [:func_expr, nil, [], [:func_body, []]]]]]
132
+ ]]]
133
+ ]],
134
+ @parser.parse('var foo = { get a() { } }'))
135
+ end
136
+
137
+ def test_object_literal_setter
138
+ assert_sexp(
139
+ [[:var,
140
+ [[:var_decl, :foo, [:assign,
141
+ [:object, [[:setter, :a,
142
+ [:func_expr, nil, [[:param, 'foo']], [:func_body, []]]
143
+ ]]]
144
+ ]]]
145
+ ]],
146
+ @parser.parse('var foo = { set a(foo) { } }'))
147
+ end
148
+
149
+ def test_object_literal_multi
150
+ assert_sexp(
151
+ [[:var,
152
+ [[:var_decl, :foo, [:assign,
153
+ [:object, [
154
+ [:property, :bar, [:lit, 10]],
155
+ [:property, :baz, [:lit, 1]]
156
+ ]]
157
+ ]]]
158
+ ]],
159
+ @parser.parse('var foo = { bar: 10, baz: 1 }'))
160
+ assert_sexp(
161
+ [[:var,
162
+ [[:var_decl, :foo, [:assign,
163
+ [:object, [
164
+ [:property, :bar, [:lit, 10]],
165
+ [:property, :baz, [:lit, 1]]
166
+ ]]
167
+ ]]]
168
+ ]],
169
+ @parser.parse('var foo = { bar: 10, baz: 1, }'))
170
+ end
171
+
172
+ def test_this
173
+ assert_sexp(
174
+ [[:var, [[:var_decl, :foo, [:assign, [:this]]]]]],
175
+ @parser.parse('var foo = this;')
176
+ )
177
+ end
178
+
179
+ def test_array_literal
180
+ assert_sexp(
181
+ [[:var, [[:var_decl, :foo, [:assign,
182
+ [:array, [[:element, [:lit, 1]]]]
183
+ ]]]]],
184
+ @parser.parse('var foo = [1];')
185
+ )
186
+ assert_sexp(
187
+ [[:var, [[:var_decl, :foo, [:assign,
188
+ [:array, [
189
+ nil,
190
+ nil,
191
+ [:element, [:lit, 1]]
192
+ ]]
193
+ ]]]]],
194
+ @parser.parse('var foo = [,,1];')
195
+ )
196
+ assert_sexp(
197
+ [[:var, [[:var_decl, :foo, [:assign,
198
+ [:array, [
199
+ [:element, [:lit, 1]],
200
+ nil,
201
+ nil,
202
+ [:element, [:lit, 2]]
203
+ ]]
204
+ ]]]]],
205
+ @parser.parse('var foo = [1,,,2];')
206
+ )
207
+ assert_sexp(
208
+ [[:var, [[:var_decl, :foo, [:assign,
209
+ [:array, [
210
+ [:element, [:lit, 1]],
211
+ nil,
212
+ nil,
213
+ ]]
214
+ ]]]]],
215
+ @parser.parse('var foo = [1,,,];')
216
+ )
217
+ assert_sexp(
218
+ [[:var, [[:var_decl, :foo, [:assign,
219
+ [:array, [
220
+ ]]
221
+ ]]]]],
222
+ @parser.parse('var foo = [];')
223
+ )
224
+ assert_sexp(
225
+ [[:var, [[:var_decl, :foo, [:assign,
226
+ [:array, [
227
+ nil, nil
228
+ ]]
229
+ ]]]]],
230
+ @parser.parse('var foo = [,,];')
231
+ )
232
+ end
233
+
234
+ def test_primary_expr_paren
235
+ assert_sexp(
236
+ [[:var,
237
+ [[:var_decl, :a, [:assign, [:lit, 10]]]]
238
+ ]],
239
+ @parser.parse('var a = (10);'))
240
+ end
241
+
242
+ def test_expression_statement
243
+ assert_sexp(
244
+ [[:expression, [:dot_access, [:resolve, "foo"], "bar"]]],
245
+ @parser.parse('foo.bar;')
246
+ )
247
+ assert_sexp(
248
+ [[:expression, [:dot_access, [:resolve, "foo"], "bar"]]],
249
+ @parser.parse('foo.bar')
250
+ )
251
+ end
252
+
253
+ def test_expr_comma
254
+ assert_sexp([[:expression, [:comma,
255
+ [:op_equal, [:resolve, 'i'], [:lit, 10]],
256
+ [:op_equal, [:resolve, 'j'], [:lit, 11]]]]],
257
+ @parser.parse('i = 10, j = 11;')
258
+ )
259
+ end
260
+
261
+ def test_op_plus_equal
262
+ assert_sexp([[:expression, [:op_plus_equal, [:resolve, 'i'], [:lit, 10]]]],
263
+ @parser.parse('i += 10'))
264
+ end
265
+
266
+ def test_op_minus_equal
267
+ assert_sexp([[:expression, [:op_minus_equal, [:resolve, 'i'], [:lit, 10]]]],
268
+ @parser.parse('i -= 10'))
269
+ end
270
+
271
+ def test_op_multiply_equal
272
+ assert_sexp([[:expression, [:op_multiply_equal, [:resolve, 'i'], [:lit, 10]]]],
273
+ @parser.parse('i *= 10'))
274
+ end
275
+
276
+ def test_op_divide_equal
277
+ assert_sexp([[:expression, [:op_divide_equal, [:resolve, 'i'], [:lit, 10]]]],
278
+ @parser.parse('i /= 10'))
279
+ end
280
+
281
+ def test_op_lshift_equal
282
+ assert_sexp([[:expression, [:op_lshift_equal, [:resolve, 'i'], [:lit, 10]]]],
283
+ @parser.parse('i <<= 10'))
284
+ end
285
+
286
+ def test_op_rshift_equal
287
+ assert_sexp([[:expression, [:op_rshift_equal, [:resolve, 'i'], [:lit, 10]]]],
288
+ @parser.parse('i >>= 10'))
289
+ end
290
+
291
+ def test_op_urshift_equal
292
+ assert_sexp([[:expression, [:op_urshift_equal, [:resolve, 'i'], [:lit, 10]]]],
293
+ @parser.parse('i >>>= 10'))
294
+ end
295
+
296
+ def test_op_and_equal
297
+ assert_sexp([[:expression, [:op_and_equal, [:resolve, 'i'], [:lit, 10]]]],
298
+ @parser.parse('i &= 10'))
299
+ end
300
+
301
+ def test_op_xor_equal
302
+ assert_sexp([[:expression, [:op_xor_equal, [:resolve, 'i'], [:lit, 10]]]],
303
+ @parser.parse('i ^= 10'))
304
+ end
305
+
306
+ def test_op_or_equal
307
+ assert_sexp([[:expression, [:op_or_equal, [:resolve, 'i'], [:lit, 10]]]],
308
+ @parser.parse('i |= 10'))
309
+ end
310
+
311
+ def test_op_mod_equal
312
+ assert_sexp([[:expression, [:op_mod_equal, [:resolve, 'i'], [:lit, 10]]]],
313
+ @parser.parse('i %= 10'))
314
+ end
315
+
316
+ def test_bracket_access_no_bf
317
+ assert_sexp(
318
+ [[:expression,
319
+ [:bracket_access, [:resolve, "foo"], [:lit, 10]],
320
+ ]],
321
+ @parser.parse('foo[10];'))
322
+ end
323
+
324
+ def test_new_member_expr_no_bf
325
+ assert_sexp(
326
+ [[:expression,
327
+ [:new_expr, [:resolve, "foo"], [:args, []]],
328
+ ]],
329
+ @parser.parse('new foo();'))
330
+ end
331
+
332
+ def test_resolve_function_call
333
+ assert_sexp([[:var,
334
+ [[:var_decl,
335
+ :x,
336
+ [:assign, [:function_call, [:resolve, "bar"], [:args, []]]]
337
+ ]]
338
+ ]],
339
+ @parser.parse('var x = bar();'))
340
+ assert_sexp([[:var,
341
+ [[:var_decl,
342
+ :x,
343
+ [:assign, [:function_call, [:resolve, "bar"], [:args, [[:lit, 10]]]]]
344
+ ]]
345
+ ]],
346
+ @parser.parse('var x = bar(10);'))
347
+ assert_sexp([[:var,
348
+ [[:var_decl,
349
+ :x,
350
+ [:assign, [:function_call, [:resolve, "bar"], [:args, [
351
+ [:resolve, 'a'],
352
+ [:lit, 10]
353
+ ]]]]
354
+ ]]
355
+ ]],
356
+ @parser.parse('var x = bar(a,10);'))
357
+ end
358
+
359
+ def test_function_no_bf
360
+ assert_sexp([[:expression,
361
+ [:function_call, [:resolve, "bar"], [:args, []]]
362
+ ]],
363
+ @parser.parse('bar();'))
364
+ end
365
+
366
+ def test_function_on_function_no_bf
367
+ assert_sexp([[:expression,
368
+ [:function_call,
369
+ [:function_call, [:resolve, "bar"], [:args, []]],
370
+ [:args, []]
371
+ ]
372
+ ]],
373
+ @parser.parse('bar()();'))
374
+ end
375
+
376
+ def test_bracket_on_function_no_bf
377
+ assert_sexp([[:expression,
378
+ [:bracket_access,
379
+ [:function_call, [:resolve, "bar"], [:args, []]],
380
+ [:lit, 1],
381
+ ]
382
+ ]],
383
+ @parser.parse('bar()[1];'))
384
+ end
385
+
386
+ def test_dot_on_function_no_bf
387
+ assert_sexp([[:expression,
388
+ [:dot_access,
389
+ [:function_call, [:resolve, "bar"], [:args, []]],
390
+ 'baz',
391
+ ]
392
+ ]],
393
+ @parser.parse('bar().baz;'))
394
+ end
395
+
396
+ def test_new_expr_no_bf
397
+ assert_sexp([[:expression, [:new_expr, [:resolve, 'foo'], [:args, []]]]],
398
+ @parser.parse('new foo;'))
399
+ end
400
+
401
+ def test_new_expr
402
+ assert_sexp([[:var, [[:var_decl, :a, [:assign, [:new_expr, [:resolve, 'foo'], [:args, []]]]]]]],
403
+ @parser.parse('var a = new foo;'))
404
+ end
405
+
406
+ def test_postfix_expr
407
+ assert_sexp([[:var,
408
+ [[:var_decl,
409
+ :x,
410
+ [:assign, [:postfix, [:lit, 10], '++']]]]]],
411
+ @parser.parse('var x = 10++;'))
412
+ assert_sexp([[:var,
413
+ [[:var_decl,
414
+ :x,
415
+ [:assign, [:postfix, [:lit, 10], '--']]]]]],
416
+ @parser.parse('var x = 10--;'))
417
+ end
418
+
419
+ def test_postfix_expr_no_bf
420
+ assert_sexp([[:expression,
421
+ [:postfix, [:lit, 10], '++']]],
422
+ @parser.parse('10++;'))
423
+ assert_sexp([[:expression,
424
+ [:postfix, [:lit, 10], '--']]],
425
+ @parser.parse('10--;'))
426
+ end
427
+
428
+ def test_unary_delete
429
+ assert_sexp([[:expression, [:delete, [:resolve, 'foo']]]],
430
+ @parser.parse('delete foo;'))
431
+ end
432
+
433
+ def test_unary_void
434
+ assert_sexp([[:expression, [:void, [:resolve, 'foo']]]],
435
+ @parser.parse('void foo;'))
436
+ end
437
+
438
+ def test_unary_typeof
439
+ assert_sexp([[:expression, [:typeof, [:resolve, 'foo']]]],
440
+ @parser.parse('typeof foo;'))
441
+ end
442
+
443
+ def test_unary_prefix
444
+ assert_sexp([[:expression, [:prefix, [:lit, 10], '++']]],
445
+ @parser.parse('++10;'))
446
+ assert_sexp([[:expression, [:prefix, [:lit, 10], '--']]],
447
+ @parser.parse('--10;'))
448
+ end
449
+
450
+ def test_unary_plus
451
+ assert_sexp([[:expression, [:u_plus, [:lit, 10]]]],
452
+ @parser.parse('+10;'))
453
+ end
454
+
455
+ def test_unary_minus
456
+ assert_sexp([[:expression, [:u_minus, [:lit, 10]]]],
457
+ @parser.parse('-10;'))
458
+ end
459
+
460
+ def test_unary_bitwise_not
461
+ assert_sexp([[:expression, [:bitwise_not, [:lit, 10]]]],
462
+ @parser.parse('~10;'))
463
+ end
464
+
465
+ def test_unary_logical_not
466
+ assert_sexp([[:expression, [:not, [:lit, 10]]]],
467
+ @parser.parse('!10;'))
468
+ end
469
+
470
+ def test_multiply
471
+ assert_sexp([[:var,
472
+ [[:var_decl,
473
+ :x,
474
+ [:assign, [:multiply, [:lit, 5], [:lit, 10]]]
475
+ ]]
476
+ ]],
477
+ @parser.parse('var x = 5 * 10;'))
478
+ end
479
+
480
+ def test_multiply_no_bf
481
+ assert_sexp([[:expression, [:multiply, [:lit, 5], [:lit, 10]] ]],
482
+ @parser.parse('5 * 10;'))
483
+ end
484
+
485
+ def test_divide
486
+ assert_sexp([[:var,
487
+ [[:var_decl,
488
+ :x,
489
+ [:assign, [:divide, [:lit, 5], [:lit, 10]]]
490
+ ]]
491
+ ]],
492
+ @parser.parse('var x = 5 / 10;'))
493
+ end
494
+
495
+ def test_divide_no_bf
496
+ assert_sexp([[:expression, [:divide, [:lit, 5], [:lit, 10]] ]],
497
+ @parser.parse('5 / 10;'))
498
+ end
499
+
500
+ def test_modulus
501
+ assert_sexp([[:var,
502
+ [[:var_decl,
503
+ :x,
504
+ [:assign, [:modulus, [:lit, 5], [:lit, 10]]]
505
+ ]]
506
+ ]],
507
+ @parser.parse('var x = 5 % 10;'))
508
+ end
509
+
510
+ def test_modulus_no_bf
511
+ assert_sexp([[:expression, [:modulus, [:lit, 5], [:lit, 10]] ]],
512
+ @parser.parse('5 % 10;'))
513
+ end
514
+
515
+ def test_add
516
+ assert_sexp([[:var,
517
+ [[:var_decl,
518
+ :x,
519
+ [:assign, [:add, [:lit, 5], [:lit, 10]]]
520
+ ]]
521
+ ]],
522
+ @parser.parse('var x = 5 + 10;'))
523
+ end
524
+
525
+ def test_add_no_bf
526
+ assert_sexp([[:expression, [:add, [:lit, 5], [:lit, 10]] ]],
527
+ @parser.parse('5 + 10;'))
528
+ end
529
+
530
+ def test_subtract
531
+ assert_sexp([[:var,
532
+ [[:var_decl,
533
+ :x,
534
+ [:assign, [:subtract, [:lit, 5], [:lit, 10]]]
535
+ ]]
536
+ ]],
537
+ @parser.parse('var x = 5 - 10;'))
538
+ end
539
+
540
+ def test_subtract_no_bf
541
+ assert_sexp([[:expression, [:subtract, [:lit, 5], [:lit, 10]] ]],
542
+ @parser.parse('5 - 10;'))
543
+ end
544
+
545
+ def test_lshift
546
+ assert_sexp([[:var,
547
+ [[:var_decl,
548
+ :x,
549
+ [:assign, [:lshift, [:lit, 5], [:lit, 10]]]
550
+ ]]
551
+ ]],
552
+ @parser.parse('var x = 5 << 10;'))
553
+ end
554
+
555
+ def test_lshift_no_bf
556
+ assert_sexp([[:expression, [:lshift, [:lit, 5], [:lit, 10]] ]],
557
+ @parser.parse('5 << 10;'))
558
+ end
559
+
560
+ def test_rshift
561
+ assert_sexp([[:var,
562
+ [[:var_decl,
563
+ :x,
564
+ [:assign, [:rshift, [:lit, 5], [:lit, 10]]]
565
+ ]]
566
+ ]],
567
+ @parser.parse('var x = 5 >> 10;'))
568
+ end
569
+
570
+ def test_rshift_no_bf
571
+ assert_sexp([[:expression, [:rshift, [:lit, 5], [:lit, 10]] ]],
572
+ @parser.parse('5 >> 10;'))
573
+ end
574
+
575
+ def test_urshift
576
+ assert_sexp([[:var,
577
+ [[:var_decl,
578
+ :x,
579
+ [:assign, [:urshift, [:lit, 5], [:lit, 10]]]
580
+ ]]
581
+ ]],
582
+ @parser.parse('var x = 5 >>> 10;'))
583
+ end
584
+
585
+ def test_urshift_no_bf
586
+ assert_sexp([[:expression, [:urshift, [:lit, 5], [:lit, 10]] ]],
587
+ @parser.parse('5 >>> 10;'))
588
+ end
589
+
590
+ def test_less
591
+ assert_sexp([[:var,
592
+ [[:var_decl,
593
+ :x,
594
+ [:assign, [:less, [:lit, 5], [:lit, 10]]]
595
+ ]]
596
+ ]],
597
+ @parser.parse('var x = 5 < 10;'))
598
+ end
599
+
600
+ def test_less_no_bf
601
+ assert_sexp([[:expression, [:less, [:lit, 5], [:lit, 10]] ]],
602
+ @parser.parse('5 < 10;'))
603
+ end
604
+
605
+ def test_less_no_in
606
+ assert_sexp(
607
+ for_loop_sexp([:less, [:resolve, 'foo'], [:lit, 10]]),
608
+ @parser.parse('for(foo < 10; foo < 10; foo++) { var x = 10; }')
609
+ )
610
+ end
611
+
612
+ def test_greater
613
+ assert_sexp([[:var,
614
+ [[:var_decl,
615
+ :x,
616
+ [:assign, [:greater, [:lit, 5], [:lit, 10]]]
617
+ ]]
618
+ ]],
619
+ @parser.parse('var x = 5 > 10;'))
620
+ end
621
+
622
+ def test_greater_no_bf
623
+ assert_sexp([[:expression, [:greater, [:lit, 5], [:lit, 10]] ]],
624
+ @parser.parse('5 > 10;'))
625
+ end
626
+
627
+ def test_greater_no_in
628
+ assert_sexp(
629
+ for_loop_sexp([:greater, [:resolve, 'foo'], [:lit, 10]]),
630
+ @parser.parse('for(foo > 10; foo < 10; foo++) { var x = 10; }')
631
+ )
632
+ end
633
+
634
+ def test_less_or_equal
635
+ assert_sexp([[:var,
636
+ [[:var_decl,
637
+ :x,
638
+ [:assign, [:less_or_equal, [:lit, 5], [:lit, 10]]]
639
+ ]]
640
+ ]],
641
+ @parser.parse('var x = 5 <= 10;'))
642
+ end
643
+
644
+ def test_less_or_equal_no_bf
645
+ assert_sexp([[:expression, [:less_or_equal, [:lit, 5], [:lit, 10]] ]],
646
+ @parser.parse('5 <= 10;'))
647
+ end
648
+
649
+ def test_less_or_equal_no_in
650
+ assert_sexp(
651
+ for_loop_sexp([:less_or_equal, [:resolve, 'foo'], [:lit, 10]]),
652
+ @parser.parse('for(foo <= 10; foo < 10; foo++) { var x = 10; }')
653
+ )
654
+ end
655
+
656
+ def test_greater_or_equal
657
+ assert_sexp([[:var,
658
+ [[:var_decl,
659
+ :x,
660
+ [:assign, [:greater_or_equal, [:lit, 5], [:lit, 10]]]
661
+ ]]
662
+ ]],
663
+ @parser.parse('var x = 5 >= 10;'))
664
+ end
665
+
666
+ def test_greater_or_equal_no_bf
667
+ assert_sexp([[:expression, [:greater_or_equal, [:lit, 5], [:lit, 10]] ]],
668
+ @parser.parse('5 >= 10;'))
669
+ end
670
+
671
+ def test_greater_or_equal_no_in
672
+ assert_sexp(
673
+ for_loop_sexp([:greater_or_equal, [:resolve, 'foo'], [:lit, 10]]),
674
+ @parser.parse('for(foo >= 10; foo < 10; foo++) { var x = 10; }')
675
+ )
676
+ end
677
+
678
+ def test_instance_of
679
+ assert_sexp([[:var,
680
+ [[:var_decl,
681
+ :x,
682
+ [:assign, [:instance_of, [:lit, 5], [:lit, 10]]]
683
+ ]]
684
+ ]],
685
+ @parser.parse('var x = 5 instanceof 10;'))
686
+ end
687
+
688
+ def test_instanceof_no_bf
689
+ assert_sexp([[:expression, [:instance_of, [:lit, 5], [:lit, 10]] ]],
690
+ @parser.parse('5 instanceof 10;'))
691
+ end
692
+
693
+ def test_instanceof_no_in
694
+ assert_sexp(for_loop_sexp([:instance_of, [:resolve, 'foo'], [:lit, 10]]),
695
+ @parser.parse('for(foo instanceof 10; foo < 10; foo++) { var x = 10; }'))
696
+ end
697
+
698
+ def test_equal_equal
699
+ assert_sexp([[:var,
700
+ [[:var_decl,
701
+ :x,
702
+ [:assign, [:equal, [:lit, 5], [:lit, 10]]]
703
+ ]]
704
+ ]],
705
+ @parser.parse('var x = 5 == 10;'))
706
+ end
707
+
708
+ def test_equal_equal_no_bf
709
+ assert_sexp([[:expression, [:equal, [:lit, 5], [:lit, 10]] ]],
710
+ @parser.parse('5 == 10;'))
711
+ end
712
+
713
+ def test_equal_equal_no_in
714
+ assert_sexp(
715
+ for_loop_sexp([:equal, [:resolve, 'foo'], [:lit, 10]]),
716
+ @parser.parse('for(foo == 10; foo < 10; foo++) { var x = 10; }')
717
+ )
718
+ end
719
+
720
+ def test_not_equal
721
+ assert_sexp([[:var,
722
+ [[:var_decl,
723
+ :x,
724
+ [:assign, [:not_equal, [:lit, 5], [:lit, 10]]]
725
+ ]]
726
+ ]],
727
+ @parser.parse('var x = 5 != 10;'))
728
+ end
729
+
730
+ def test_not_equal_no_bf
731
+ assert_sexp([[:expression, [:not_equal, [:lit, 5], [:lit, 10]] ]],
732
+ @parser.parse('5 != 10;'))
733
+ end
734
+
735
+ def test_not_equal_no_in
736
+ assert_sexp(
737
+ for_loop_sexp([:not_equal, [:resolve, 'foo'], [:lit, 10]]),
738
+ @parser.parse('for(foo != 10; foo < 10; foo++) { var x = 10; }')
739
+ )
740
+ end
741
+
742
+ def test_strict_equal
743
+ assert_sexp([[:var,
744
+ [[:var_decl,
745
+ :x,
746
+ [:assign, [:strict_equal, [:lit, 5], [:lit, 10]]]
747
+ ]]
748
+ ]],
749
+ @parser.parse('var x = 5 === 10;'))
750
+ end
751
+
752
+ def test_strict_equal_no_bf
753
+ assert_sexp([[:expression, [:strict_equal, [:lit, 5], [:lit, 10]] ]],
754
+ @parser.parse('5 === 10;'))
755
+ end
756
+
757
+ def test_strict_equal_no_in
758
+ assert_sexp(
759
+ for_loop_sexp([:strict_equal, [:resolve, 'foo'], [:lit, 10]]),
760
+ @parser.parse('for(foo === 10; foo < 10; foo++) { var x = 10; }')
761
+ )
762
+ end
763
+
764
+ def test_not_strict_equal
765
+ assert_sexp([[:var,
766
+ [[:var_decl,
767
+ :x,
768
+ [:assign, [:not_strict_equal, [:lit, 5], [:lit, 10]]]
769
+ ]]
770
+ ]],
771
+ @parser.parse('var x = 5 !== 10;'))
772
+ end
773
+
774
+ def test_not_strict_equal_no_bf
775
+ assert_sexp([[:expression, [:not_strict_equal, [:lit, 5], [:lit, 10]] ]],
776
+ @parser.parse('5 !== 10;'))
777
+ end
778
+
779
+ def test_not_strict_equal_no_in
780
+ assert_sexp(
781
+ for_loop_sexp([:not_strict_equal, [:resolve, 'foo'], [:lit, 10]]),
782
+ @parser.parse('for(foo !== 10; foo < 10; foo++) { var x = 10; }')
783
+ )
784
+ end
785
+
786
+ def test_bit_and
787
+ assert_sexp([[:var,
788
+ [[:var_decl,
789
+ :x,
790
+ [:assign, [:bit_and, [:lit, 5], [:lit, 10]]]
791
+ ]]
792
+ ]],
793
+ @parser.parse('var x = 5 & 10;'))
794
+ end
795
+
796
+ def test_bit_and_no_bf
797
+ assert_sexp([[:expression, [:bit_and, [:lit, 5], [:lit, 10]] ]],
798
+ @parser.parse('5 & 10;'))
799
+ end
800
+
801
+ def test_bit_and_no_in
802
+ assert_sexp(
803
+ for_loop_sexp([:bit_and, [:resolve, 'foo'], [:lit, 10]]),
804
+ @parser.parse('for(foo & 10; foo < 10; foo++) { var x = 10; }')
805
+ )
806
+ end
807
+
808
+ def test_bit_xor
809
+ assert_sexp([[:var,
810
+ [[:var_decl,
811
+ :x,
812
+ [:assign, [:bit_xor, [:lit, 5], [:lit, 10]]]
813
+ ]]
814
+ ]],
815
+ @parser.parse('var x = 5 ^ 10;'))
816
+ end
817
+
818
+ def test_bit_xor_no_bf
819
+ assert_sexp([[:expression, [:bit_xor, [:lit, 5], [:lit, 10]] ]],
820
+ @parser.parse('5 ^ 10;'))
821
+ end
822
+
823
+ def test_bit_xor_no_in
824
+ assert_sexp(
825
+ for_loop_sexp([:bit_xor, [:resolve, 'foo'], [:lit, 10]]),
826
+ @parser.parse('for(foo ^ 10; foo < 10; foo++) { var x = 10; }')
827
+ )
828
+ end
829
+
830
+ def test_bit_or
831
+ assert_sexp([[:var,
832
+ [[:var_decl,
833
+ :x,
834
+ [:assign, [:bit_or, [:lit, 5], [:lit, 10]]]
835
+ ]]
836
+ ]],
837
+ @parser.parse('var x = 5 | 10;'))
838
+ end
839
+
840
+ def test_bit_or_no_bf
841
+ assert_sexp([[:expression, [:bit_or, [:lit, 5], [:lit, 10]] ]],
842
+ @parser.parse('5 | 10;'))
843
+ end
844
+
845
+ def test_bit_or_no_in
846
+ assert_sexp(
847
+ for_loop_sexp([:bit_or, [:resolve, 'foo'], [:lit, 10]]),
848
+ @parser.parse('for(foo | 10; foo < 10; foo++) { var x = 10; }')
849
+ )
850
+ end
851
+
852
+ def test_and
853
+ assert_sexp([[:var,
854
+ [[:var_decl,
855
+ :x,
856
+ [:assign, [:and, [:lit, 5], [:lit, 10]]]
857
+ ]]
858
+ ]],
859
+ @parser.parse('var x = 5 && 10;'))
860
+ end
861
+
862
+ def test_and_no_bf
863
+ assert_sexp([[:expression, [:and, [:lit, 5], [:lit, 10]] ]],
864
+ @parser.parse('5 && 10;'))
865
+ end
866
+
867
+ def test_and_no_in
868
+ assert_sexp(
869
+ for_loop_sexp([:and, [:resolve, 'foo'], [:lit, 10]]),
870
+ @parser.parse('for(foo && 10; foo < 10; foo++) { var x = 10; }')
871
+ )
872
+ end
873
+
874
+ def test_or
875
+ assert_sexp([[:var,
876
+ [[:var_decl,
877
+ :x,
878
+ [:assign, [:or, [:lit, 5], [:lit, 10]]]
879
+ ]]
880
+ ]],
881
+ @parser.parse('var x = 5 || 10;'))
882
+ end
883
+
884
+ def test_or_no_bf
885
+ assert_sexp([[:expression, [:or, [:lit, 5], [:lit, 10]] ]],
886
+ @parser.parse('5 || 10;'))
887
+ end
888
+
889
+ def test_or_no_in
890
+ assert_sexp(
891
+ for_loop_sexp([:or, [:resolve, 'foo'], [:lit, 10]]),
892
+ @parser.parse('for(foo || 10; foo < 10; foo++) { var x = 10; }')
893
+ )
894
+ end
895
+
896
+ def test_conditional_expr
897
+ assert_sexp([
898
+ var_sexp('x', [:conditional, [:less, [:lit, 5], [:lit, 10]], [:lit, 20], [:lit, 30]])
899
+ ],
900
+ @parser.parse('var x = 5 < 10 ? 20 : 30;')
901
+ )
902
+ end
903
+
904
+ def test_conditional_expr_no_bf
905
+ assert_sexp([[:expression,
906
+ [:conditional, [:less, [:lit, 5], [:lit, 10]], [:lit, 20], [:lit, 30]]
907
+ ]],
908
+ @parser.parse('5 < 10 ? 20 : 30;')
909
+ )
910
+ end
911
+
912
+ def test_for_expr_comma
913
+ @parser.parse('for(y = 20, x = 10; foo < 10; foo++) {}')
914
+ assert_sexp(
915
+ for_loop_sexp([:comma,
916
+ [:op_equal, [:resolve, 'y'], [:lit, 20]],
917
+ [:op_equal, [:resolve, 'x'], [:lit, 10]]]
918
+ ),
919
+ @parser.parse('for(y = 20, x = 10; foo < 10; foo++) { var x = 10; }')
920
+ )
921
+ end
922
+
923
+ def test_conditional_expr_no_in
924
+ assert_sexp(
925
+ for_loop_sexp([:conditional, [:less, [:lit, 5], [:lit, 10]], [:lit, 20], [:lit, 30]]),
926
+ @parser.parse('for(5 < 10 ? 20 : 30; foo < 10; foo++) { var x = 10; }')
927
+ )
928
+ end
929
+
930
+ def test_block_node
931
+ assert_sexp([[:block, []]], @parser.parse('{ }'))
932
+ assert_sexp([[:block, [[:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]]]]],
933
+ @parser.parse('{ var foo = 10; }'))
934
+
935
+ assert_sexp([
936
+ [:block, [[:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]]]],
937
+ [:var, [[:var_decl, :bax, [:assign, [:lit, 20]]]]],
938
+ ],
939
+ @parser.parse('{ var foo = 10 } var bax = 20;'))
940
+ end
941
+
942
+ def test_if_no_else
943
+ assert_sexp([[:if,
944
+ [:and, [:lit, 5], [:lit, 10]],
945
+ [:var, [[:var_decl, :foo, [:assign, [:lit, 20]]]]],
946
+ ]], @parser.parse('if(5 && 10) var foo = 20;'))
947
+ end
948
+
949
+ def test_if_else
950
+ assert_sexp([[:if,
951
+ [:and, [:lit, 5], [:lit, 10]],
952
+ [:var, [[:var_decl, :foo, [:assign, [:lit, 20]]]]],
953
+ [:var, [[:var_decl, :bar, [:assign, [:lit, 5]]]]],
954
+ ]], @parser.parse(' if(5 && 10) var foo = 20; else var bar = 5; '))
955
+ end
956
+
957
+ def test_if_comma
958
+ assert_sexp(
959
+ [[:if,
960
+ [:comma,
961
+ [:op_equal, [:resolve, "i"], [:lit, 10]],
962
+ [:op_equal, [:resolve, "j"], [:lit, 11]]],
963
+ [:block, []]]],
964
+ @parser.parse('if(i = 10, j = 11) { }')
965
+ )
966
+ end
967
+
968
+ def test_in
969
+ assert_sexp([[:var,
970
+ [[:var_decl, :x, [:assign,
971
+ [:in, [:lit, 0], [:resolve, "foo"]]
972
+ ]]]
973
+ ]],
974
+ @parser.parse('var x = 0 in foo;'))
975
+ end
976
+
977
+ def test_in_no_bf
978
+ assert_sexp([[:expression, [:in, [:lit, 0], [:resolve, "foo"]]]],
979
+ @parser.parse('0 in foo;'))
980
+ end
981
+
982
+ def test_do_while
983
+ assert_sexp([[:do_while, [:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]],
984
+ [:true]]],
985
+ @parser.parse('do var x = 10; while(true);'))
986
+ assert_sexp([[:do_while, [:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]],
987
+ [:true]]],
988
+ @parser.parse('do var x = 10; while(true)'))
989
+ end
990
+
991
+ def test_while
992
+ assert_sexp([[:while,
993
+ [:true],
994
+ [:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]],
995
+ ]],
996
+ @parser.parse('while(true) var x = 10;'))
997
+ end
998
+
999
+ def test_for_with_semi
1000
+ assert_sexp([[:for, nil, nil, nil,
1001
+ [:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]],
1002
+ ]], @parser.parse('for( ; ; ) var x = 10;'))
1003
+
1004
+ assert_sexp([[:for,
1005
+ [:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]],
1006
+ [:less, [:resolve, 'foo'], [:lit, 10]],
1007
+ [:postfix, [:resolve, 'foo'], '++'],
1008
+ [:block, [[:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]]]
1009
+ ], @parser.parse('for(var foo = 10; foo < 10; foo++) { var x = 10; }'))
1010
+ assert_sexp([[:for,
1011
+ [:op_equal, [:resolve, 'foo'], [:lit, 10]],
1012
+ [:less, [:resolve, 'foo'], [:lit, 10]],
1013
+ [:postfix, [:resolve, 'foo'], '++'],
1014
+ [:block, [[:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]]]
1015
+ ], @parser.parse('for(foo = 10; foo < 10; foo++) { var x = 10; }'))
1016
+
1017
+ assert_sexp(for_loop_sexp([:var, [[:var_decl, :x, [:assign, [:lit, 10]]],
1018
+ [:var_decl, :y, [:assign, [:lit, 20]]]]]),
1019
+ @parser.parse('for(var x = 10, y = 20; foo < 10; foo++) { var x = 10; }'))
1020
+
1021
+ assert_sexp(for_loop_sexp([:var, [[:var_decl, :foo, nil]]]),
1022
+ @parser.parse('for(var foo; foo < 10; foo++) { var x = 10; }'))
1023
+ end
1024
+
1025
+ def test_for_expr_in_expr
1026
+ assert_sexp(
1027
+ for_in_sexp([:resolve, 'foo'], [:resolve, 'bar']),
1028
+ @parser.parse('for(foo in bar) { var x = 10; }')
1029
+ )
1030
+ end
1031
+
1032
+ def test_for_var_ident_in_expr
1033
+ assert_sexp(
1034
+ for_in_sexp([:var_decl, :foo, nil], [:resolve, 'bar']),
1035
+ @parser.parse('for(var foo in bar) { var x = 10; }')
1036
+ )
1037
+ end
1038
+
1039
+ def test_for_var_ident_init_in_expr
1040
+ assert_sexp(
1041
+ for_in_sexp([:var_decl, :foo, [:assign,[:lit, 10]]], [:resolve, 'bar']),
1042
+ @parser.parse('for(var foo = 10 in bar) { var x = 10; }')
1043
+ )
1044
+ end
1045
+
1046
+ def test_try_finally
1047
+ assert_sexp([[ :try,
1048
+ [:block,
1049
+ [[:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]
1050
+ ],
1051
+ nil,
1052
+ nil,
1053
+ [:block,
1054
+ [[:var, [[:var_decl, :x, [:assign, [:lit, 20]]]]]]
1055
+ ]
1056
+ ]],
1057
+ @parser.parse('try { var x = 10; } finally { var x = 20; }'))
1058
+ end
1059
+
1060
+ def test_try_catch
1061
+ assert_sexp([[ :try,
1062
+ [:block,
1063
+ [[:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]
1064
+ ],
1065
+ 'a',
1066
+ [:block,
1067
+ [[:var, [[:var_decl, :x, [:assign, [:lit, 20]]]]]]
1068
+ ],
1069
+ nil,
1070
+ ]],
1071
+ @parser.parse('try { var x = 10; } catch(a) { var x = 20; }'))
1072
+ end
1073
+
1074
+ def test_try_catch_finally
1075
+ assert_sexp([[ :try,
1076
+ [:block,
1077
+ [[:var, [[:var_decl, :baz, [:assign, [:lit, 69]]]]]]
1078
+ ],
1079
+ 'a',
1080
+ [:block,
1081
+ [[:var, [[:var_decl, :bar, [:assign, [:lit, 20]]]]]]
1082
+ ],
1083
+ [:block,
1084
+ [[:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]]]
1085
+ ]
1086
+ ]],
1087
+ @parser.parse('try { var baz = 69; } catch(a) { var bar = 20; } finally { var foo = 10; }'))
1088
+ end
1089
+
1090
+ def test_with
1091
+ assert_sexp([[:with, [:resolve, 'o'], [:expression, [:resolve, 'x']]]],
1092
+ @parser.parse('with (o) x;')
1093
+ )
1094
+ end
1095
+
1096
+ def test_switch_no_case
1097
+ assert_sexp([[:switch, [:resolve, 'o'], [:case_block, []]]],
1098
+ @parser.parse('switch(o) { }')
1099
+ )
1100
+ end
1101
+
1102
+ def test_switch_case_no_statement
1103
+ assert_sexp([[:switch, [:resolve, 'o'], [:case_block, [[:case, [:resolve, 'j'], []]]]]],
1104
+ @parser.parse('switch(o) { case j: }')
1105
+ )
1106
+ end
1107
+
1108
+ def test_switch_case
1109
+ assert_sexp([[:switch, [:resolve, 'o'],
1110
+ [:case_block,
1111
+ [[:case, [:resolve, 'j'], [[:expression, [:resolve, 'foo']]]]]
1112
+ ]
1113
+ ]],
1114
+ @parser.parse('switch(o) { case j: foo; }')
1115
+ )
1116
+ end
1117
+
1118
+ def test_switch_case_case
1119
+ assert_sexp([[:switch, [:resolve, 'o'],
1120
+ [:case_block,[
1121
+ [:case, [:resolve, 'j'], [[:expression, [:resolve, 'foo']]]],
1122
+ [:case, [:resolve, 'k'], [[:expression, [:resolve, 'bar']]]],
1123
+ ]]
1124
+ ]],
1125
+ @parser.parse('switch(o) { case j: foo; case k: bar; }')
1126
+ )
1127
+ end
1128
+
1129
+ def test_switch_default
1130
+ assert_sexp([[:switch, [:resolve, 'o'],
1131
+ [:case_block,[
1132
+ [:case, nil, [[:expression, [:resolve, 'bar']]]],
1133
+ ]]
1134
+ ]],
1135
+ @parser.parse('switch(o) { default: bar; }')
1136
+ )
1137
+ end
1138
+
1139
+ def test_switch_default_no_expr
1140
+ assert_sexp([[:switch, [:resolve, 'o'],
1141
+ [:case_block,[
1142
+ [:case, nil, []],
1143
+ ]]
1144
+ ]],
1145
+ @parser.parse('switch(o) { default: }')
1146
+ )
1147
+ end
1148
+
1149
+ def test_function_call_on_function
1150
+ assert_sexp([[:var,
1151
+ [[:var_decl,
1152
+ :x,
1153
+ [:assign, [:function_call,
1154
+ [:function_call, [:resolve, "bar"], [:args, []]],
1155
+ [:args, []]]]
1156
+ ]]
1157
+ ]],
1158
+ @parser.parse('var x = bar()();'))
1159
+ end
1160
+
1161
+ def test_bracket_on_function
1162
+ assert_sexp([[:var,
1163
+ [[:var_decl,
1164
+ :x,
1165
+ [:assign, [:bracket_access,
1166
+ [:function_call, [:resolve, "bar"], [:args, []]],
1167
+ [:lit, 1]
1168
+ ]]
1169
+ ]]
1170
+ ]],
1171
+ @parser.parse('var x = bar()[1];'))
1172
+ end
1173
+
1174
+ def test_dot_on_function
1175
+ assert_sexp([[:var,
1176
+ [[:var_decl,
1177
+ :x,
1178
+ [:assign, [:dot_access,
1179
+ [:function_call, [:resolve, "bar"], [:args, []]],
1180
+ 'baz'
1181
+ ]]
1182
+ ]]
1183
+ ]],
1184
+ @parser.parse('var x = bar().baz;'))
1185
+ end
1186
+
1187
+ def test_dot_access
1188
+ assert_sexp(
1189
+ [[:var,
1190
+ [[:var_decl, :a, [:assign, [:dot_access, [:resolve, "foo"], "bar"]]]]
1191
+ ]],
1192
+ @parser.parse('var a = foo.bar;'))
1193
+ end
1194
+
1195
+ def test_new_member_expr
1196
+ assert_sexp(
1197
+ [[:var,
1198
+ [[:var_decl, :a,
1199
+ [:assign, [:new_expr, [:resolve, "foo"], [:args, []]]]
1200
+ ]]
1201
+ ]],
1202
+ @parser.parse('var a = new foo();'))
1203
+ end
1204
+
1205
+ def test_empty_statement
1206
+ assert_sexp(
1207
+ [
1208
+ [:const, [[:const_decl, :foo, [:assign, [:lit, 10]]]]],
1209
+ [:empty]
1210
+ ],
1211
+ @parser.parse('const foo = 10; ;')
1212
+ )
1213
+ end
1214
+
1215
+ def test_debugger_statement
1216
+ assert_sexp(
1217
+ [ [:empty] ],
1218
+ @parser.parse('debugger;')
1219
+ )
1220
+ assert_sexp(
1221
+ [ [:empty] ],
1222
+ @parser.parse('debugger')
1223
+ )
1224
+ end
1225
+
1226
+ def test_function_decl
1227
+ assert_sexp([[:func_decl, 'foo', [], [:func_body, []]]],
1228
+ @parser.parse('function foo() { }'))
1229
+ end
1230
+
1231
+ def test_function_decl_params
1232
+ assert_sexp([[:func_decl, 'foo', [[:param, 'a']], [:func_body, []]]],
1233
+ @parser.parse('function foo(a) { }'))
1234
+ end
1235
+
1236
+ def test_const_statement
1237
+ assert_sexp(
1238
+ [[:const, [[:const_decl, :foo, [:assign, [:lit, 10]]]]]],
1239
+ @parser.parse('const foo = 10;')
1240
+ )
1241
+ end
1242
+
1243
+ def test_const_decl_list
1244
+ assert_sexp(
1245
+ [[:const,
1246
+ [
1247
+ [:const_decl, :foo, [:assign, [:lit, 10]]],
1248
+ [:const_decl, :bar, [:assign, [:lit, 1]]],
1249
+ ]]],
1250
+ @parser.parse('const foo = 10, bar = 1;')
1251
+ )
1252
+ end
1253
+
1254
+ def test_const_decl_no_init
1255
+ assert_sexp(
1256
+ [[:const, [[:const_decl, :foo, nil]]]],
1257
+ @parser.parse('const foo;')
1258
+ )
1259
+ end
1260
+
1261
+ def test_const_statement_error
1262
+ assert_sexp(
1263
+ [[:const, [[:const_decl, :foo, [:assign, [:lit, 10]]]]]],
1264
+ @parser.parse('const foo = 10')
1265
+ )
1266
+ end
1267
+
1268
+ def test_variable_statement
1269
+ assert_sexp(
1270
+ [[:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]]],
1271
+ @parser.parse('var foo = 10;')
1272
+ )
1273
+ end
1274
+
1275
+ def test_variable_declaration_no_init
1276
+ assert_sexp(
1277
+ [[:var, [[:var_decl, :foo, nil]]]],
1278
+ @parser.parse('var foo;')
1279
+ )
1280
+ end
1281
+
1282
+ def test_variable_declaration_nil_init
1283
+ assert_sexp(
1284
+ [[:var, [[:var_decl, :foo, [:assign, [:nil]]]]]],
1285
+ @parser.parse('var foo = null;')
1286
+ )
1287
+ end
1288
+
1289
+ def test_variable_statement_no_semi
1290
+ assert_sexp(
1291
+ [[:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]]],
1292
+ @parser.parse('var foo = 10')
1293
+ )
1294
+ end
1295
+
1296
+ def test_return_statement
1297
+ assert_sexp(
1298
+ [[:return]],
1299
+ @parser.parse('return;')
1300
+ )
1301
+ assert_sexp(
1302
+ [[:return]],
1303
+ @parser.parse('return')
1304
+ )
1305
+ assert_sexp(
1306
+ [[:return, [:lit, 10]]],
1307
+ @parser.parse('return 10;')
1308
+ )
1309
+ assert_sexp(
1310
+ [[:return, [:lit, 10]]],
1311
+ @parser.parse('return 10')
1312
+ )
1313
+ end
1314
+
1315
+ def test_break_statement
1316
+ assert_sexp([[:break]], @parser.parse('break;'))
1317
+ assert_sexp([[:break]], @parser.parse('break'))
1318
+ assert_sexp([[:break, 'foo']], @parser.parse('break foo;'))
1319
+ assert_sexp([[:break, 'foo']], @parser.parse('break foo'))
1320
+ end
1321
+
1322
+ def test_continue_statement
1323
+ assert_sexp([[:continue]], @parser.parse('continue;'))
1324
+ assert_sexp([[:continue]], @parser.parse('continue'))
1325
+ assert_sexp([[:continue, 'foo']], @parser.parse('continue foo;'))
1326
+ assert_sexp([[:continue, 'foo']], @parser.parse('continue foo'))
1327
+ end
1328
+
1329
+ def test_variable_declaration_list
1330
+ assert_sexp(
1331
+ [[:var,
1332
+ [
1333
+ [:var_decl, :foo, [:assign, [:lit, 10]]],
1334
+ [:var_decl, :bar, [:assign, [:lit, 1]]],
1335
+ ]]],
1336
+ @parser.parse('var foo = 10, bar = 1;')
1337
+ )
1338
+ end
1339
+
1340
+ def assert_sexp(expected, node)
1341
+ assert_equal(expected, node.to_sexp)
1342
+ end
1343
+
1344
+ def var_sexp(variable_name, val = [:lit, 10])
1345
+ [:var, [[:var_decl, variable_name.to_sym, [:assign, val]]]]
1346
+ end
1347
+
1348
+ def for_in_sexp(variable, list)
1349
+ [[:for_in, variable, list, [:block, [[:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]]]]
1350
+ end
1351
+
1352
+ def for_loop_sexp(init, test = [:less, [:resolve, 'foo'], [:lit, 10]], exec = [:postfix, [:resolve, 'foo'], '++'])
1353
+ [[:for, init, test, exec, [:block, [[:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]]]]
1354
+ end
1355
+ end