tenderlove-rkelly 0.0.0.20080909095845
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.txt +7 -0
- data/Manifest.txt +197 -0
- data/README.txt +49 -0
- data/Rakefile +85 -0
- data/lib/parser.y +870 -0
- data/lib/rkelly.rb +8 -0
- data/lib/rkelly/constants.rb +3 -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 +5 -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 +80 -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 +98 -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/token.rb +15 -0
- data/lib/rkelly/tokenizer.rb +122 -0
- data/lib/rkelly/visitable.rb +16 -0
- data/lib/rkelly/visitors.rb +4 -0
- data/lib/rkelly/visitors/dot_visitor.rb +228 -0
- data/lib/rkelly/visitors/ecma_visitor.rb +314 -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 +18 -0
- data/lib/rkelly/visitors/sexp_visitor.rb +374 -0
- data/lib/rkelly/visitors/visitor.rb +136 -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 +88 -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_comma_node.rb +13 -0
- data/test/test_comments.rb +44 -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 +192 -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 +23 -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 +1355 -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_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 +143 -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 +385 -0
data/lib/rkelly/nodes.rb
ADDED
@@ -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 While 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
|
+
eval "class #{node}Node < BinaryNode; end"
|
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,80 @@
|
|
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
|
9
|
+
def initialize(value)
|
10
|
+
@value = value
|
11
|
+
@comments = []
|
12
|
+
@line = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
other.is_a?(self.class) && @value === other.value
|
17
|
+
end
|
18
|
+
alias :=~ :==
|
19
|
+
alias :=== :==
|
20
|
+
|
21
|
+
def pointcut(pattern)
|
22
|
+
case pattern
|
23
|
+
when String
|
24
|
+
ast = RKelly::Parser.new.parse(pattern)
|
25
|
+
# Only take the first statement
|
26
|
+
finder = ast.value.first.class.to_s =~ /StatementNode$/ ?
|
27
|
+
ast.value.first.value : ast.value.first
|
28
|
+
visitor = PointcutVisitor.new(finder)
|
29
|
+
else
|
30
|
+
visitor = PointcutVisitor.new(pattern)
|
31
|
+
end
|
32
|
+
|
33
|
+
visitor.accept(self)
|
34
|
+
visitor
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_sexp
|
38
|
+
SexpVisitor.new.accept(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_ecma
|
42
|
+
ECMAVisitor.new.accept(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_dots
|
46
|
+
visitor = DotVisitor.new
|
47
|
+
visitor.accept(self)
|
48
|
+
header = <<-END
|
49
|
+
digraph g {
|
50
|
+
graph [ rankdir = "TB" ];
|
51
|
+
node [
|
52
|
+
fontsize = "16"
|
53
|
+
shape = "ellipse"
|
54
|
+
];
|
55
|
+
edge [ ];
|
56
|
+
END
|
57
|
+
nodes = visitor.nodes.map { |x| x.to_s }.join("\n")
|
58
|
+
counter = 0
|
59
|
+
arrows = visitor.arrows.map { |x|
|
60
|
+
s = "#{x} [\nid = #{counter}\n];"
|
61
|
+
counter += 1
|
62
|
+
s
|
63
|
+
}.join("\n")
|
64
|
+
"#{header}\n#{nodes}\n#{arrows}\n}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def each(&block)
|
68
|
+
EnumerableVisitor.new(block).accept(self)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
%w[EmptyStatement ExpressionStatement True Delete Return TypeOf
|
73
|
+
SourceElements Number LogicalNot AssignExpr FunctionBody
|
74
|
+
ObjectLiteral UnaryMinus Throw This BitwiseNot Element String
|
75
|
+
Array CaseBlock Null Break Parameter Block False Void Regexp
|
76
|
+
Arguments Attr Continue ConstStatement UnaryPlus VarStatement].each do |node|
|
77
|
+
eval "class #{node}Node < Node; end"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
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 @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,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,98 @@
|
|
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
|
+
end
|
19
|
+
r
|
20
|
+
end
|
21
|
+
eoawesomehack
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :logger
|
25
|
+
def initialize
|
26
|
+
@tokens = []
|
27
|
+
@logger = nil
|
28
|
+
@terminator = false
|
29
|
+
@prev_token = nil
|
30
|
+
@comments = []
|
31
|
+
end
|
32
|
+
|
33
|
+
# Parse +javascript+ and return an AST
|
34
|
+
def parse(javascript)
|
35
|
+
@tokens = TOKENIZER.raw_tokens(javascript)
|
36
|
+
@position = 0
|
37
|
+
ast = do_parse
|
38
|
+
apply_comments(ast)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def apply_comments(ast)
|
43
|
+
ast_hash = Hash.new { |h,k| h[k] = [] }
|
44
|
+
(ast || []).each { |n|
|
45
|
+
next unless n.line
|
46
|
+
ast_hash[n.line] << n
|
47
|
+
}
|
48
|
+
max = ast_hash.keys.sort.last
|
49
|
+
@comments.each do |comment|
|
50
|
+
node = nil
|
51
|
+
comment.line.upto(max) do |line|
|
52
|
+
if ast_hash.key?(line)
|
53
|
+
node = ast_hash[line].first
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
node.comments << comment if node
|
58
|
+
end
|
59
|
+
ast
|
60
|
+
end
|
61
|
+
|
62
|
+
def on_error(error_token_id, error_value, value_stack)
|
63
|
+
if logger
|
64
|
+
logger.error(token_to_str(error_token_id))
|
65
|
+
logger.error("error value: #{error_value}")
|
66
|
+
logger.error("error stack: #{value_stack}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def next_token
|
71
|
+
@terminator = false
|
72
|
+
begin
|
73
|
+
return [false, false] if @position >= @tokens.length
|
74
|
+
n_token = @tokens[@position]
|
75
|
+
@position += 1
|
76
|
+
case @tokens[@position - 1].name
|
77
|
+
when :COMMENT
|
78
|
+
@comments << n_token
|
79
|
+
@terminator = true if n_token.value =~ /^\/\//
|
80
|
+
when :S
|
81
|
+
@terminator = true if n_token.value =~ /[\r\n]/
|
82
|
+
end
|
83
|
+
end while([:COMMENT, :S].include?(n_token.name))
|
84
|
+
|
85
|
+
if @terminator &&
|
86
|
+
((@prev_token && %w[continue break return throw].include?(@prev_token.value)) ||
|
87
|
+
(n_token && %w[++ --].include?(n_token.value)))
|
88
|
+
@position -= 1
|
89
|
+
return (@prev_token = RKelly::Token.new(';', ';')).to_racc_token
|
90
|
+
end
|
91
|
+
|
92
|
+
@prev_token = n_token
|
93
|
+
v = n_token.to_racc_token
|
94
|
+
v[1] = n_token
|
95
|
+
v
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|