rkelly 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,11 @@
1
+ module RKelly
2
+ module Nodes
3
+ class BracketAccessorNode < Node
4
+ attr_reader :accessor
5
+ def initialize(resolve, accessor)
6
+ super(resolve)
7
+ @accessor = accessor
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'rkelly/nodes/binary_node'
2
+
3
+ module RKelly
4
+ module Nodes
5
+ class CaseClauseNode < BinaryNode
6
+ def initialize(left, src = SourceElementsNode.new([]))
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module RKelly
2
+ module Nodes
3
+ class CommaNode < Node
4
+ attr_reader :left
5
+ def initialize(left, right)
6
+ super(right)
7
+ @left = left
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'rkelly/nodes/if_node'
2
+
3
+ module RKelly
4
+ module Nodes
5
+ class ConditionalNode < IfNode
6
+ def initialize(test, true_block, else_block)
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module RKelly
2
+ module Nodes
3
+ class DotAccessorNode < Node
4
+ attr_reader :accessor
5
+ def initialize(resolve, accessor)
6
+ super(resolve)
7
+ @accessor = accessor
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module RKelly
2
+ module Nodes
3
+ class ForInNode < Node
4
+ attr_reader :left, :right
5
+ def initialize(left, right, block)
6
+ super(block)
7
+ @left = left
8
+ @right = right
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module RKelly
2
+ module Nodes
3
+ class ForNode < Node
4
+ attr_reader :init, :test, :counter
5
+ def initialize(init, test, counter, body)
6
+ super(body)
7
+ @init = init
8
+ @test = test
9
+ @counter = counter
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module RKelly
2
+ module Nodes
3
+ class FunctionCallNode < Node
4
+ attr_reader :arguments
5
+ def initialize(value, arguments)
6
+ super(value)
7
+ @arguments = arguments
8
+ end
9
+
10
+ def ==(other)
11
+ super && @arguments == other.arguments
12
+ end
13
+ alias :=~ :==
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ module RKelly
2
+ module Nodes
3
+ class FunctionDeclNode < FunctionExprNode
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+ module RKelly
2
+ module Nodes
3
+ class FunctionExprNode < Node
4
+ attr_reader :function_body, :arguments
5
+ def initialize(name, body, args = [])
6
+ super(name)
7
+ @function_body = body
8
+ @arguments = args
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module RKelly
2
+ module Nodes
3
+ class IfNode < Node
4
+ attr_reader :conditions, :else
5
+ def initialize(conditions, value, else_stmt = nil)
6
+ super(value)
7
+ @conditions = conditions
8
+ @else = else_stmt
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module RKelly
2
+ module Nodes
3
+ class LabelNode < Node
4
+ attr_reader :name
5
+ def initialize(name, value)
6
+ super(value)
7
+ @name = name
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module RKelly
2
+ module Nodes
3
+ class NewExprNode < Node
4
+ attr_reader :arguments
5
+ def initialize(value, args)
6
+ super(value)
7
+ @arguments = args
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,88 @@
1
+ module RKelly
2
+ module Nodes
3
+ class Node
4
+ include RKelly::Visitable
5
+ include RKelly::Visitors
6
+ include Enumerable
7
+
8
+ attr_accessor :value, :comments, :line, :filename
9
+ def initialize(value)
10
+ @value = value
11
+ @comments = []
12
+ @filename = @line = nil
13
+ end
14
+
15
+ def ==(other)
16
+ other.is_a?(self.class) && @value == other.value
17
+ end
18
+ alias :=~ :==
19
+
20
+ def ===(other)
21
+ other.is_a?(self.class) && @value === other.value
22
+ end
23
+
24
+ def pointcut(pattern)
25
+ case pattern
26
+ when String
27
+ ast = RKelly::Parser.new.parse(pattern)
28
+ # Only take the first statement
29
+ finder = ast.value.first.class.to_s =~ /StatementNode$/ ?
30
+ ast.value.first.value : ast.value.first
31
+ visitor = PointcutVisitor.new(finder)
32
+ else
33
+ visitor = PointcutVisitor.new(pattern)
34
+ end
35
+
36
+ visitor.accept(self)
37
+ visitor
38
+ end
39
+ alias :/ :pointcut
40
+
41
+ def to_sexp
42
+ SexpVisitor.new.accept(self)
43
+ end
44
+
45
+ def to_ecma
46
+ ECMAVisitor.new.accept(self)
47
+ end
48
+
49
+ def to_dots
50
+ visitor = DotVisitor.new
51
+ visitor.accept(self)
52
+ header = <<-END
53
+ digraph g {
54
+ graph [ rankdir = "TB" ];
55
+ node [
56
+ fontsize = "16"
57
+ shape = "ellipse"
58
+ ];
59
+ edge [ ];
60
+ END
61
+ nodes = visitor.nodes.map { |x| x.to_s }.join("\n")
62
+ counter = 0
63
+ arrows = visitor.arrows.map { |x|
64
+ s = "#{x} [\nid = #{counter}\n];"
65
+ counter += 1
66
+ s
67
+ }.join("\n")
68
+ "#{header}\n#{nodes}\n#{arrows}\n}"
69
+ end
70
+
71
+ def each(&block)
72
+ EnumerableVisitor.new(block).accept(self)
73
+ end
74
+
75
+ def to_real_sexp
76
+ RealSexpVisitor.new.accept(self)
77
+ end
78
+ end
79
+
80
+ %w[EmptyStatement ExpressionStatement True Delete Return TypeOf
81
+ SourceElements Number LogicalNot AssignExpr FunctionBody
82
+ ObjectLiteral UnaryMinus Throw This BitwiseNot Element String
83
+ Array CaseBlock Null Break Parameter Block False Void Regexp
84
+ Arguments Attr Continue ConstStatement UnaryPlus VarStatement].each do |node|
85
+ eval "class #{node}Node < Node; end"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,6 @@
1
+ module RKelly
2
+ module Nodes
3
+ class NotStrictEqualNode < BinaryNode
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ module RKelly
2
+ module Nodes
3
+ class OpEqualNode < Node
4
+ attr_reader :left
5
+ def initialize(left, right)
6
+ super(right)
7
+ @left = left
8
+ end
9
+ end
10
+
11
+ %w[Multiply Divide LShift Minus Plus Mod XOr RShift And URShift Or].each do |node|
12
+ eval "class Op#{node}EqualNode < OpEqualNode; end"
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module RKelly
2
+ module Nodes
3
+ class PostfixNode < Node
4
+ attr_reader :operand
5
+ def initialize(operand, operator)
6
+ super(operator)
7
+ @operand = operand
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module RKelly
2
+ module Nodes
3
+ class PrefixNode < PostfixNode
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module RKelly
2
+ module Nodes
3
+ class PropertyNode < Node
4
+ attr_reader :name
5
+ def initialize(name, value)
6
+ super(value)
7
+ @name = name
8
+ end
9
+ end
10
+
11
+ %w[Getter Setter].each {|node| eval "class #{node}PropertyNode < PropertyNode; end"}
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module RKelly
2
+ module Nodes
3
+ class ResolveNode < Node
4
+ def ==(other)
5
+ return true if super
6
+ if @value =~ /^[A-Z]/
7
+ place = [Object, Module, RKelly::Nodes].find { |x|
8
+ x.const_defined?(@value.to_sym)
9
+ }
10
+ return false unless place
11
+ klass = place.const_get(@value.to_sym)
12
+ return true if klass && other.is_a?(klass) || other.value.is_a?(klass)
13
+ end
14
+ false
15
+ end
16
+ alias :=~ :==
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ module RKelly
2
+ module Nodes
3
+ class StrictEqualNode < BinaryNode
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module RKelly
2
+ module Nodes
3
+ class TryNode < Node
4
+ attr_reader :catch_var, :catch_block, :finally_block
5
+ def initialize(value, catch_var, catch_block, finally_block = nil)
6
+ super(value)
7
+ @catch_var = catch_var
8
+ @catch_block = catch_block
9
+ @finally_block = finally_block
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module RKelly
2
+ module Nodes
3
+ class VarDeclNode < Node
4
+ attr_accessor :name, :type
5
+ def initialize(name, value, constant = false)
6
+ super(value)
7
+ @name = name
8
+ @constant = constant
9
+ end
10
+
11
+ def constant?; @constant; end
12
+ def variable?; !@constant; end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,100 @@
1
+ require 'rkelly/tokenizer'
2
+ require 'rkelly/generated_parser'
3
+
4
+
5
+ module RKelly
6
+ class Parser < RKelly::GeneratedParser
7
+ TOKENIZER = Tokenizer.new
8
+
9
+ RKelly::GeneratedParser.instance_methods.each do |im|
10
+ next unless im.to_s =~ /^_reduce_\d+$/
11
+ eval(<<-eoawesomehack)
12
+ def #{im}(val, _values, result)
13
+ r = super(val.map { |v|
14
+ v.is_a?(Token) ? v.to_racc_token[1] : v
15
+ }, _values, result)
16
+ if token = val.find { |v| v.is_a?(Token) }
17
+ r.line = token.line if r.respond_to?(:line)
18
+ r.filename = @filename if r.respond_to?(:filename)
19
+ end
20
+ r
21
+ end
22
+ eoawesomehack
23
+ end
24
+
25
+ attr_accessor :logger
26
+ def initialize
27
+ @tokens = []
28
+ @logger = nil
29
+ @terminator = false
30
+ @prev_token = nil
31
+ @comments = []
32
+ end
33
+
34
+ # Parse +javascript+ and return an AST
35
+ def parse(javascript, filename = nil)
36
+ @tokens = TOKENIZER.raw_tokens(javascript)
37
+ @position = 0
38
+ @filename = filename
39
+ ast = do_parse
40
+ apply_comments(ast)
41
+ end
42
+
43
+ private
44
+ def apply_comments(ast)
45
+ ast_hash = Hash.new { |h,k| h[k] = [] }
46
+ (ast || []).each { |n|
47
+ next unless n.line
48
+ ast_hash[n.line] << n
49
+ }
50
+ max = ast_hash.keys.sort.last
51
+ @comments.each do |comment|
52
+ node = nil
53
+ comment.line.upto(max) do |line|
54
+ if ast_hash.key?(line)
55
+ node = ast_hash[line].first
56
+ break
57
+ end
58
+ end
59
+ node.comments << comment if node
60
+ end if max
61
+ ast
62
+ end
63
+
64
+ def on_error(error_token_id, error_value, value_stack)
65
+ if logger
66
+ logger.error(token_to_str(error_token_id))
67
+ logger.error("error value: #{error_value}")
68
+ logger.error("error stack: #{value_stack}")
69
+ end
70
+ end
71
+
72
+ def next_token
73
+ @terminator = false
74
+ begin
75
+ return [false, false] if @position >= @tokens.length
76
+ n_token = @tokens[@position]
77
+ @position += 1
78
+ case @tokens[@position - 1].name
79
+ when :COMMENT
80
+ @comments << n_token
81
+ @terminator = true if n_token.value =~ /^\/\//
82
+ when :S
83
+ @terminator = true if n_token.value =~ /[\r\n]/
84
+ end
85
+ end while([:COMMENT, :S].include?(n_token.name))
86
+
87
+ if @terminator &&
88
+ ((@prev_token && %w[continue break return throw].include?(@prev_token.value)) ||
89
+ (n_token && %w[++ --].include?(n_token.value)))
90
+ @position -= 1
91
+ return (@prev_token = RKelly::Token.new(';', ';')).to_racc_token
92
+ end
93
+
94
+ @prev_token = n_token
95
+ v = n_token.to_racc_token
96
+ v[1] = n_token
97
+ v
98
+ end
99
+ end
100
+ end