rkelly-turbo 0.1.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.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +38 -0
- data/Manifest.txt +203 -0
- data/README.rdoc +135 -0
- data/Rakefile +41 -0
- data/lib/parser.y +883 -0
- data/lib/rkelly.rb +14 -0
- data/lib/rkelly/char_pos.rb +39 -0
- data/lib/rkelly/char_range.rb +33 -0
- data/lib/rkelly/constants.rb +3 -0
- data/lib/rkelly/generated_parser.rb +3380 -0
- data/lib/rkelly/js.rb +14 -0
- data/lib/rkelly/js/array.rb +15 -0
- data/lib/rkelly/js/base.rb +91 -0
- data/lib/rkelly/js/boolean.rb +21 -0
- data/lib/rkelly/js/function.rb +39 -0
- data/lib/rkelly/js/function_prototype.rb +15 -0
- data/lib/rkelly/js/global_object.rb +52 -0
- data/lib/rkelly/js/math.rb +10 -0
- data/lib/rkelly/js/nan.rb +18 -0
- data/lib/rkelly/js/number.rb +22 -0
- data/lib/rkelly/js/object.rb +30 -0
- data/lib/rkelly/js/object_prototype.rb +14 -0
- data/lib/rkelly/js/property.rb +20 -0
- data/lib/rkelly/js/scope.rb +6 -0
- data/lib/rkelly/js/string.rb +21 -0
- data/lib/rkelly/lexeme.rb +18 -0
- data/lib/rkelly/nodes.rb +25 -0
- data/lib/rkelly/nodes/binary_node.rb +18 -0
- data/lib/rkelly/nodes/bracket_accessor_node.rb +11 -0
- data/lib/rkelly/nodes/case_clause_node.rb +11 -0
- data/lib/rkelly/nodes/comma_node.rb +11 -0
- data/lib/rkelly/nodes/conditional_node.rb +11 -0
- data/lib/rkelly/nodes/dot_accessor_node.rb +11 -0
- data/lib/rkelly/nodes/for_in_node.rb +12 -0
- data/lib/rkelly/nodes/for_node.rb +13 -0
- data/lib/rkelly/nodes/function_call_node.rb +16 -0
- data/lib/rkelly/nodes/function_decl_node.rb +6 -0
- data/lib/rkelly/nodes/function_expr_node.rb +12 -0
- data/lib/rkelly/nodes/if_node.rb +12 -0
- data/lib/rkelly/nodes/label_node.rb +11 -0
- data/lib/rkelly/nodes/new_expr_node.rb +11 -0
- data/lib/rkelly/nodes/node.rb +116 -0
- data/lib/rkelly/nodes/not_strict_equal_node.rb +6 -0
- data/lib/rkelly/nodes/op_equal_node.rb +16 -0
- data/lib/rkelly/nodes/postfix_node.rb +11 -0
- data/lib/rkelly/nodes/prefix_node.rb +6 -0
- data/lib/rkelly/nodes/property_node.rb +13 -0
- data/lib/rkelly/nodes/resolve_node.rb +19 -0
- data/lib/rkelly/nodes/strict_equal_node.rb +6 -0
- data/lib/rkelly/nodes/try_node.rb +13 -0
- data/lib/rkelly/nodes/var_decl_node.rb +15 -0
- data/lib/rkelly/parser.rb +106 -0
- data/lib/rkelly/runtime.rb +36 -0
- data/lib/rkelly/runtime/ruby_function.rb +13 -0
- data/lib/rkelly/runtime/scope_chain.rb +57 -0
- data/lib/rkelly/syntax_error.rb +4 -0
- data/lib/rkelly/token.rb +27 -0
- data/lib/rkelly/tokenizer.rb +255 -0
- data/lib/rkelly/visitable.rb +31 -0
- data/lib/rkelly/visitors.rb +4 -0
- data/lib/rkelly/visitors/dot_visitor.rb +228 -0
- data/lib/rkelly/visitors/ecma_visitor.rb +328 -0
- data/lib/rkelly/visitors/enumerable_visitor.rb +18 -0
- data/lib/rkelly/visitors/evaluation_visitor.rb +419 -0
- data/lib/rkelly/visitors/function_visitor.rb +46 -0
- data/lib/rkelly/visitors/pointcut_visitor.rb +31 -0
- data/lib/rkelly/visitors/real_sexp_visitor.rb +16 -0
- data/lib/rkelly/visitors/sexp_visitor.rb +373 -0
- data/lib/rkelly/visitors/visitor.rb +149 -0
- data/test/ecma_script_test_case.rb +21 -0
- data/test/execute_test_case.rb +16 -0
- data/test/execution_contexts/test_10_1_3-1.rb +32 -0
- data/test/expressions/test_11_3_1.rb +64 -0
- data/test/expressions/test_11_3_2.rb +64 -0
- data/test/expressions/test_11_4_2.rb +13 -0
- data/test/expressions/test_11_4_3.rb +52 -0
- data/test/expressions/test_11_4_4.rb +68 -0
- data/test/expressions/test_11_4_5.rb +69 -0
- data/test/expressions/test_11_4_6.rb +94 -0
- data/test/expressions/test_11_4_8.rb +28 -0
- data/test/expressions/test_11_4_9.rb +103 -0
- data/test/expressions/test_11_5_1.rb +51 -0
- data/test/expressions/test_11_5_2.rb +80 -0
- data/test/expressions/test_11_5_3.rb +88 -0
- data/test/expressions/test_11_6_1-1.rb +19 -0
- data/test/expressions/test_11_9_1.rb +19 -0
- data/test/function/test_15_3_1_1-1.rb +34 -0
- data/test/global_object/test_15_1_1_1.rb +29 -0
- data/test/global_object/test_15_1_1_2.rb +17 -0
- data/test/global_object/test_15_1_1_3.rb +9 -0
- data/test/helper.rb +5 -0
- data/test/node_test_case.rb +11 -0
- data/test/object/test_15_2_1_1.rb +257 -0
- data/test/object/test_15_2_1_2.rb +21 -0
- data/test/object/test_15_2_2_1.rb +52 -0
- data/test/statements/test_12_5-1.rb +27 -0
- data/test/test_add_node.rb +8 -0
- data/test/test_arguments_node.rb +8 -0
- data/test/test_array_node.rb +9 -0
- data/test/test_assign_expr_node.rb +8 -0
- data/test/test_automatic_semicolon_insertion.rb +137 -0
- data/test/test_bit_and_node.rb +8 -0
- data/test/test_bit_or_node.rb +8 -0
- data/test/test_bit_x_or_node.rb +8 -0
- data/test/test_bitwise_not_node.rb +8 -0
- data/test/test_block_node.rb +14 -0
- data/test/test_bracket_accessor_node.rb +16 -0
- data/test/test_break_node.rb +11 -0
- data/test/test_case_block_node.rb +11 -0
- data/test/test_case_clause_node.rb +15 -0
- data/test/test_char_pos.rb +39 -0
- data/test/test_char_range.rb +29 -0
- data/test/test_comma_node.rb +13 -0
- data/test/test_comments.rb +45 -0
- data/test/test_conditional_node.rb +17 -0
- data/test/test_const_statement_node.rb +14 -0
- data/test/test_continue_node.rb +11 -0
- data/test/test_delete_node.rb +8 -0
- data/test/test_divide_node.rb +8 -0
- data/test/test_do_while_node.rb +13 -0
- data/test/test_dot_accessor_node.rb +9 -0
- data/test/test_ecma_visitor.rb +213 -0
- data/test/test_element_node.rb +8 -0
- data/test/test_empty_statement_node.rb +8 -0
- data/test/test_equal_node.rb +8 -0
- data/test/test_evaluation_visitor.rb +66 -0
- data/test/test_expression_statement_node.rb +10 -0
- data/test/test_false_node.rb +8 -0
- data/test/test_for_in_node.rb +17 -0
- data/test/test_for_node.rb +24 -0
- data/test/test_function_body_node.rb +8 -0
- data/test/test_function_call_node.rb +10 -0
- data/test/test_function_decl_node.rb +16 -0
- data/test/test_function_expr_node.rb +16 -0
- data/test/test_function_visitor.rb +26 -0
- data/test/test_getter_property_node.rb +10 -0
- data/test/test_global_object.rb +49 -0
- data/test/test_greater_node.rb +8 -0
- data/test/test_greater_or_equal_node.rb +8 -0
- data/test/test_if_node.rb +17 -0
- data/test/test_in_node.rb +8 -0
- data/test/test_instance_of_node.rb +8 -0
- data/test/test_label_node.rb +13 -0
- data/test/test_left_shift_node.rb +8 -0
- data/test/test_less_node.rb +8 -0
- data/test/test_less_or_equal_node.rb +8 -0
- data/test/test_line_number.rb +81 -0
- data/test/test_logical_and_node.rb +8 -0
- data/test/test_logical_not_node.rb +8 -0
- data/test/test_logical_or_node.rb +8 -0
- data/test/test_modulus_node.rb +8 -0
- data/test/test_multiply_node.rb +8 -0
- data/test/test_new_expr_node.rb +9 -0
- data/test/test_not_equal_node.rb +8 -0
- data/test/test_not_strict_equal_node.rb +8 -0
- data/test/test_null_node.rb +8 -0
- data/test/test_number_node.rb +8 -0
- data/test/test_object_literal_node.rb +9 -0
- data/test/test_op_and_equal_node.rb +10 -0
- data/test/test_op_divide_equal_node.rb +10 -0
- data/test/test_op_equal_node.rb +10 -0
- data/test/test_op_l_shift_equal_node.rb +10 -0
- data/test/test_op_minus_equal_node.rb +10 -0
- data/test/test_op_mod_equal_node.rb +10 -0
- data/test/test_op_multiply_equal_node.rb +10 -0
- data/test/test_op_or_equal_node.rb +10 -0
- data/test/test_op_plus_equal_node.rb +10 -0
- data/test/test_op_r_shift_equal_node.rb +10 -0
- data/test/test_op_u_r_shift_equal_node.rb +10 -0
- data/test/test_op_x_or_equal_node.rb +10 -0
- data/test/test_parameter_node.rb +8 -0
- data/test/test_parser.rb +1434 -0
- data/test/test_pointcut_visitor.rb +34 -0
- data/test/test_postfix_node.rb +8 -0
- data/test/test_prefix_node.rb +8 -0
- data/test/test_property_node.rb +8 -0
- data/test/test_regexp_node.rb +8 -0
- data/test/test_resolve_node.rb +22 -0
- data/test/test_return_node.rb +11 -0
- data/test/test_right_shift_node.rb +8 -0
- data/test/test_rkelly.rb +19 -0
- data/test/test_runtime.rb +12 -0
- data/test/test_scope_chain.rb +50 -0
- data/test/test_setter_property_node.rb +10 -0
- data/test/test_source_elements.rb +9 -0
- data/test/test_strict_equal_node.rb +8 -0
- data/test/test_string_node.rb +8 -0
- data/test/test_subtract_node.rb +8 -0
- data/test/test_switch_node.rb +12 -0
- data/test/test_this_node.rb +8 -0
- data/test/test_throw_node.rb +7 -0
- data/test/test_tokenizer.rb +285 -0
- data/test/test_true_node.rb +8 -0
- data/test/test_try_node.rb +59 -0
- data/test/test_type_of_node.rb +8 -0
- data/test/test_unary_minus_node.rb +8 -0
- data/test/test_unary_plus_node.rb +8 -0
- data/test/test_unsigned_right_shift_node.rb +8 -0
- data/test/test_var_decl_node.rb +21 -0
- data/test/test_var_statement_node.rb +14 -0
- data/test/test_void_node.rb +8 -0
- data/test/test_while_node.rb +15 -0
- data/test/test_with_node.rb +8 -0
- metadata +293 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
module RKelly
|
2
|
+
module Nodes
|
3
|
+
class BinaryNode < Node
|
4
|
+
attr_reader :left
|
5
|
+
def initialize(left, right)
|
6
|
+
super(right)
|
7
|
+
@left = left
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
%w[Subtract LessOrEqual GreaterOrEqual Add Multiply NotEqual
|
12
|
+
DoWhile Switch LogicalAnd UnsignedRightShift Modulus While
|
13
|
+
NotStrictEqual Less With In Greater BitOr StrictEqual LogicalOr
|
14
|
+
BitXOr LeftShift Equal BitAnd InstanceOf Divide RightShift].each do |node|
|
15
|
+
const_set "#{node}Node", Class.new(BinaryNode)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
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,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RKelly
|
4
|
+
module Nodes
|
5
|
+
class Node
|
6
|
+
include RKelly::Visitable
|
7
|
+
include RKelly::Visitors
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
attr_accessor :value, :comments, :range, :filename
|
11
|
+
def initialize(value)
|
12
|
+
@value = value
|
13
|
+
@range = CharRange::EMPTY
|
14
|
+
end
|
15
|
+
|
16
|
+
def comments; @comments || []; end
|
17
|
+
|
18
|
+
# For backwards compatibility
|
19
|
+
def line
|
20
|
+
@range.from.line
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
other.is_a?(self.class) && @value == other.value
|
25
|
+
end
|
26
|
+
alias :=~ :==
|
27
|
+
|
28
|
+
def ===(other)
|
29
|
+
other.is_a?(self.class) && @value === other.value
|
30
|
+
end
|
31
|
+
|
32
|
+
# Matches nodes with the given pattern (usually a class name of
|
33
|
+
# the node) and returns an instance of PointcutVisitor on which
|
34
|
+
# #matches can be invoked to get the list of AST nodes that
|
35
|
+
# matched.
|
36
|
+
#
|
37
|
+
# ast.pointcut(RKelly::Nodes::IfNode).matches --> array of nodes
|
38
|
+
#
|
39
|
+
def pointcut(pattern)
|
40
|
+
case pattern
|
41
|
+
when String
|
42
|
+
ast = RKelly::Parser.new.parse(pattern)
|
43
|
+
# Only take the first statement
|
44
|
+
finder = ast.value.first.class.name.end_with?("StatementNode") ?
|
45
|
+
ast.value.first.value : ast.value.first
|
46
|
+
visitor = PointcutVisitor.new(finder)
|
47
|
+
else
|
48
|
+
visitor = PointcutVisitor.new(pattern)
|
49
|
+
end
|
50
|
+
|
51
|
+
visitor.accept(self)
|
52
|
+
visitor
|
53
|
+
end
|
54
|
+
alias :/ :pointcut
|
55
|
+
|
56
|
+
# Generates an s-expression data structure like so:
|
57
|
+
#
|
58
|
+
# "var x = 10;" --> [:var, [[:var_decl, :x, [:assign, [:lit, 10]]]]]]
|
59
|
+
#
|
60
|
+
def to_sexp
|
61
|
+
SexpVisitor.new.accept(self)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Generates formatted and intented JavaScript source code.
|
65
|
+
def to_ecma
|
66
|
+
ECMAVisitor.new.accept(self)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Generates a graph description in DOT language. This can be
|
70
|
+
# fed into the dot program to generate a graph of the AST:
|
71
|
+
#
|
72
|
+
# $ dot -Tpng generated-graph.dot -o graph.png
|
73
|
+
#
|
74
|
+
def to_dots
|
75
|
+
visitor = DotVisitor.new
|
76
|
+
visitor.accept(self)
|
77
|
+
header = <<-END
|
78
|
+
digraph g {
|
79
|
+
graph [ rankdir = "TB" ];
|
80
|
+
node [
|
81
|
+
fontsize = "16"
|
82
|
+
shape = "ellipse"
|
83
|
+
];
|
84
|
+
edge [ ];
|
85
|
+
END
|
86
|
+
nodes = visitor.nodes.map { |x| x.to_s }.join("\n")
|
87
|
+
counter = 0
|
88
|
+
arrows = visitor.arrows.map { |x|
|
89
|
+
s = "#{x} [\nid = #{counter}\n];"
|
90
|
+
counter += 1
|
91
|
+
s
|
92
|
+
}.join("\n")
|
93
|
+
"#{header}\n#{nodes}\n#{arrows}\n}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# Loops through all the syntax nodes.
|
97
|
+
def each(&block)
|
98
|
+
EnumerableVisitor.new(block).accept(self)
|
99
|
+
end
|
100
|
+
|
101
|
+
# This CRASHES!
|
102
|
+
# It calls method #s which is nowhere to be found.
|
103
|
+
def to_real_sexp
|
104
|
+
RealSexpVisitor.new.accept(self)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
%w[EmptyStatement Parenthetical ExpressionStatement True Delete Return TypeOf
|
109
|
+
SourceElements Number LogicalNot AssignExpr FunctionBody
|
110
|
+
ObjectLiteral UnaryMinus Throw This BitwiseNot Element String
|
111
|
+
Array CaseBlock Null Break Parameter Block False Void Regexp
|
112
|
+
Arguments Attr Continue ConstStatement UnaryPlus VarStatement].each do |node|
|
113
|
+
eval "class #{node}Node < Node; end"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
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,19 @@
|
|
1
|
+
module RKelly
|
2
|
+
module Nodes
|
3
|
+
class ResolveNode < Node
|
4
|
+
def ==(other)
|
5
|
+
return true if super
|
6
|
+
if ('A'..'Z').include? @value[0]
|
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,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,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rkelly/tokenizer'
|
4
|
+
require 'rkelly/generated_parser'
|
5
|
+
|
6
|
+
|
7
|
+
module RKelly
|
8
|
+
class Parser < RKelly::GeneratedParser
|
9
|
+
TOKENIZER = Tokenizer.new
|
10
|
+
|
11
|
+
RKelly::GeneratedParser.instance_methods.each do |im|
|
12
|
+
next unless im.to_s =~ /^_reduce_\d+$/
|
13
|
+
define_method im do |val, _values, result|
|
14
|
+
r = super(val.map { |v|
|
15
|
+
v.is_a?(Token) ? v.to_racc_token[1] : v
|
16
|
+
}, _values, result)
|
17
|
+
|
18
|
+
if r.respond_to? :range
|
19
|
+
suitable_values = val.flatten.find_all {|v| v.is_a? Token or v.is_a? Node }
|
20
|
+
first = suitable_values.first
|
21
|
+
if first
|
22
|
+
r.range = CharRange.new(first.range.from, suitable_values.last.range.to)
|
23
|
+
r.filename = @filename if @filename
|
24
|
+
end
|
25
|
+
end
|
26
|
+
r
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :logger
|
31
|
+
def initialize
|
32
|
+
@tokens = []
|
33
|
+
@logger = nil
|
34
|
+
@terminator = false
|
35
|
+
@prev_token = nil
|
36
|
+
@comments = []
|
37
|
+
end
|
38
|
+
|
39
|
+
# Parse +javascript+ and return an AST
|
40
|
+
def parse(javascript, filename = nil)
|
41
|
+
@tokens = TOKENIZER.raw_tokens(javascript)
|
42
|
+
@position = 0
|
43
|
+
@filename = filename
|
44
|
+
ast = do_parse
|
45
|
+
ast.comments = @comments if ast
|
46
|
+
ast
|
47
|
+
end
|
48
|
+
|
49
|
+
def yyabort
|
50
|
+
raise "something bad happened, please report a bug with sample JavaScript"
|
51
|
+
end
|
52
|
+
|
53
|
+
# When parsing finishes without all tokens being parsed, returns
|
54
|
+
# the token at which the parsing stopped. Returns nil when parser
|
55
|
+
# reached to the very last token (but possibly still failed as it
|
56
|
+
# expeced more tokens).
|
57
|
+
#
|
58
|
+
# Useful for pin-pointing the position of a syntax error.
|
59
|
+
def stopped_at
|
60
|
+
if @position < @tokens.length
|
61
|
+
@tokens[@position-1]
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def on_error(error_token_id, error_value, value_stack)
|
69
|
+
if logger
|
70
|
+
logger.error(token_to_str(error_token_id))
|
71
|
+
logger.error("error value: #{error_value}")
|
72
|
+
logger.error("error stack: #{value_stack}")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
SEMICOLON_TOKEN = RKelly::Token.new(';', ';').freeze
|
77
|
+
|
78
|
+
def next_token
|
79
|
+
@terminator = false
|
80
|
+
begin
|
81
|
+
return [false, false] if @position >= @tokens.length
|
82
|
+
n_token = @tokens[@position]
|
83
|
+
@position += 1
|
84
|
+
case @tokens[@position - 1].name
|
85
|
+
when :COMMENT
|
86
|
+
@comments << n_token
|
87
|
+
@terminator = true if n_token.value.start_with? "//"
|
88
|
+
when :S
|
89
|
+
@terminator = true if n_token.value =~ /[\r\n]/
|
90
|
+
end
|
91
|
+
end while([:COMMENT, :S].include?(n_token.name))
|
92
|
+
|
93
|
+
if @terminator &&
|
94
|
+
((@prev_token && %w[continue break return throw].include?(@prev_token.value)) ||
|
95
|
+
(n_token && %w[++ --].include?(n_token.value)))
|
96
|
+
@position -= 1
|
97
|
+
return (@prev_token = SEMICOLON_TOKEN.dup).to_racc_token
|
98
|
+
end
|
99
|
+
|
100
|
+
@prev_token = n_token
|
101
|
+
v = n_token.to_racc_token
|
102
|
+
v[1] = n_token
|
103
|
+
v
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|