modulr 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.
- data/LICENSE +22 -0
- data/README.markdown +62 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/assets/modulr.js +58 -0
- data/bin/modulrize +39 -0
- data/example/foo/bar.js +1 -0
- data/example/foo/foo.js +3 -0
- data/example/increment.js +6 -0
- data/example/inspect.js +3 -0
- data/example/math.js +7 -0
- data/example/program.js +9 -0
- data/lib/modulr/collector.rb +60 -0
- data/lib/modulr/js_module.rb +88 -0
- data/lib/modulr/version.rb +6 -0
- data/lib/modulr.rb +21 -0
- data/vendor/rkelly/CHANGELOG.rdoc +13 -0
- data/vendor/rkelly/Manifest.txt +198 -0
- data/vendor/rkelly/README.rdoc +58 -0
- data/vendor/rkelly/Rakefile +39 -0
- data/vendor/rkelly/lib/parser.y +870 -0
- data/vendor/rkelly/lib/rkelly/constants.rb +3 -0
- data/vendor/rkelly/lib/rkelly/generated_parser.rb +3237 -0
- data/vendor/rkelly/lib/rkelly/js/array.rb +15 -0
- data/vendor/rkelly/lib/rkelly/js/base.rb +91 -0
- data/vendor/rkelly/lib/rkelly/js/boolean.rb +21 -0
- data/vendor/rkelly/lib/rkelly/js/function.rb +39 -0
- data/vendor/rkelly/lib/rkelly/js/function_prototype.rb +15 -0
- data/vendor/rkelly/lib/rkelly/js/global_object.rb +52 -0
- data/vendor/rkelly/lib/rkelly/js/math.rb +10 -0
- data/vendor/rkelly/lib/rkelly/js/nan.rb +18 -0
- data/vendor/rkelly/lib/rkelly/js/number.rb +22 -0
- data/vendor/rkelly/lib/rkelly/js/object.rb +30 -0
- data/vendor/rkelly/lib/rkelly/js/object_prototype.rb +14 -0
- data/vendor/rkelly/lib/rkelly/js/property.rb +20 -0
- data/vendor/rkelly/lib/rkelly/js/scope.rb +6 -0
- data/vendor/rkelly/lib/rkelly/js/string.rb +21 -0
- data/vendor/rkelly/lib/rkelly/js.rb +14 -0
- data/vendor/rkelly/lib/rkelly/lexeme.rb +18 -0
- data/vendor/rkelly/lib/rkelly/nodes/binary_node.rb +18 -0
- data/vendor/rkelly/lib/rkelly/nodes/bracket_accessor_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/case_clause_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/comma_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/conditional_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/dot_accessor_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/for_in_node.rb +12 -0
- data/vendor/rkelly/lib/rkelly/nodes/for_node.rb +13 -0
- data/vendor/rkelly/lib/rkelly/nodes/function_call_node.rb +16 -0
- data/vendor/rkelly/lib/rkelly/nodes/function_decl_node.rb +6 -0
- data/vendor/rkelly/lib/rkelly/nodes/function_expr_node.rb +12 -0
- data/vendor/rkelly/lib/rkelly/nodes/if_node.rb +12 -0
- data/vendor/rkelly/lib/rkelly/nodes/label_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/new_expr_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/node.rb +88 -0
- data/vendor/rkelly/lib/rkelly/nodes/not_strict_equal_node.rb +6 -0
- data/vendor/rkelly/lib/rkelly/nodes/op_equal_node.rb +16 -0
- data/vendor/rkelly/lib/rkelly/nodes/postfix_node.rb +11 -0
- data/vendor/rkelly/lib/rkelly/nodes/prefix_node.rb +6 -0
- data/vendor/rkelly/lib/rkelly/nodes/property_node.rb +13 -0
- data/vendor/rkelly/lib/rkelly/nodes/resolve_node.rb +19 -0
- data/vendor/rkelly/lib/rkelly/nodes/strict_equal_node.rb +6 -0
- data/vendor/rkelly/lib/rkelly/nodes/try_node.rb +13 -0
- data/vendor/rkelly/lib/rkelly/nodes/var_decl_node.rb +15 -0
- data/vendor/rkelly/lib/rkelly/nodes.rb +25 -0
- data/vendor/rkelly/lib/rkelly/parser.rb +104 -0
- data/vendor/rkelly/lib/rkelly/runtime/ruby_function.rb +13 -0
- data/vendor/rkelly/lib/rkelly/runtime/scope_chain.rb +57 -0
- data/vendor/rkelly/lib/rkelly/runtime.rb +36 -0
- data/vendor/rkelly/lib/rkelly/syntax_error.rb +4 -0
- data/vendor/rkelly/lib/rkelly/token.rb +15 -0
- data/vendor/rkelly/lib/rkelly/tokenizer.rb +122 -0
- data/vendor/rkelly/lib/rkelly/visitable.rb +16 -0
- data/vendor/rkelly/lib/rkelly/visitors/dot_visitor.rb +228 -0
- data/vendor/rkelly/lib/rkelly/visitors/ecma_visitor.rb +314 -0
- data/vendor/rkelly/lib/rkelly/visitors/enumerable_visitor.rb +18 -0
- data/vendor/rkelly/lib/rkelly/visitors/evaluation_visitor.rb +419 -0
- data/vendor/rkelly/lib/rkelly/visitors/function_visitor.rb +46 -0
- data/vendor/rkelly/lib/rkelly/visitors/pointcut_visitor.rb +31 -0
- data/vendor/rkelly/lib/rkelly/visitors/real_sexp_visitor.rb +16 -0
- data/vendor/rkelly/lib/rkelly/visitors/sexp_visitor.rb +373 -0
- data/vendor/rkelly/lib/rkelly/visitors/visitor.rb +136 -0
- data/vendor/rkelly/lib/rkelly/visitors.rb +4 -0
- data/vendor/rkelly/lib/rkelly.rb +14 -0
- data/vendor/rkelly/rkelly.gemspec +34 -0
- data/vendor/rkelly/test/ecma_script_test_case.rb +21 -0
- data/vendor/rkelly/test/execute_test_case.rb +16 -0
- data/vendor/rkelly/test/execution_contexts/test_10_1_3-1.rb +32 -0
- data/vendor/rkelly/test/expressions/test_11_3_1.rb +64 -0
- data/vendor/rkelly/test/expressions/test_11_3_2.rb +64 -0
- data/vendor/rkelly/test/expressions/test_11_4_2.rb +13 -0
- data/vendor/rkelly/test/expressions/test_11_4_3.rb +52 -0
- data/vendor/rkelly/test/expressions/test_11_4_4.rb +68 -0
- data/vendor/rkelly/test/expressions/test_11_4_5.rb +69 -0
- data/vendor/rkelly/test/expressions/test_11_4_6.rb +88 -0
- data/vendor/rkelly/test/expressions/test_11_4_8.rb +28 -0
- data/vendor/rkelly/test/expressions/test_11_4_9.rb +103 -0
- data/vendor/rkelly/test/expressions/test_11_5_1.rb +51 -0
- data/vendor/rkelly/test/expressions/test_11_5_2.rb +80 -0
- data/vendor/rkelly/test/expressions/test_11_5_3.rb +88 -0
- data/vendor/rkelly/test/expressions/test_11_6_1-1.rb +19 -0
- data/vendor/rkelly/test/expressions/test_11_9_1.rb +19 -0
- data/vendor/rkelly/test/function/test_15_3_1_1-1.rb +34 -0
- data/vendor/rkelly/test/global_object/test_15_1_1_1.rb +29 -0
- data/vendor/rkelly/test/global_object/test_15_1_1_2.rb +17 -0
- data/vendor/rkelly/test/global_object/test_15_1_1_3.rb +9 -0
- data/vendor/rkelly/test/helper.rb +5 -0
- data/vendor/rkelly/test/node_test_case.rb +11 -0
- data/vendor/rkelly/test/object/test_15_2_1_1.rb +257 -0
- data/vendor/rkelly/test/object/test_15_2_1_2.rb +21 -0
- data/vendor/rkelly/test/object/test_15_2_2_1.rb +52 -0
- data/vendor/rkelly/test/statements/test_12_5-1.rb +27 -0
- data/vendor/rkelly/test/test_add_node.rb +8 -0
- data/vendor/rkelly/test/test_arguments_node.rb +8 -0
- data/vendor/rkelly/test/test_array_node.rb +9 -0
- data/vendor/rkelly/test/test_assign_expr_node.rb +8 -0
- data/vendor/rkelly/test/test_automatic_semicolon_insertion.rb +137 -0
- data/vendor/rkelly/test/test_bit_and_node.rb +8 -0
- data/vendor/rkelly/test/test_bit_or_node.rb +8 -0
- data/vendor/rkelly/test/test_bit_x_or_node.rb +8 -0
- data/vendor/rkelly/test/test_bitwise_not_node.rb +8 -0
- data/vendor/rkelly/test/test_block_node.rb +14 -0
- data/vendor/rkelly/test/test_bracket_accessor_node.rb +16 -0
- data/vendor/rkelly/test/test_break_node.rb +11 -0
- data/vendor/rkelly/test/test_case_block_node.rb +11 -0
- data/vendor/rkelly/test/test_case_clause_node.rb +15 -0
- data/vendor/rkelly/test/test_comma_node.rb +13 -0
- data/vendor/rkelly/test/test_comments.rb +44 -0
- data/vendor/rkelly/test/test_conditional_node.rb +17 -0
- data/vendor/rkelly/test/test_const_statement_node.rb +14 -0
- data/vendor/rkelly/test/test_continue_node.rb +11 -0
- data/vendor/rkelly/test/test_delete_node.rb +8 -0
- data/vendor/rkelly/test/test_divide_node.rb +8 -0
- data/vendor/rkelly/test/test_do_while_node.rb +13 -0
- data/vendor/rkelly/test/test_dot_accessor_node.rb +9 -0
- data/vendor/rkelly/test/test_ecma_visitor.rb +192 -0
- data/vendor/rkelly/test/test_element_node.rb +8 -0
- data/vendor/rkelly/test/test_empty_statement_node.rb +8 -0
- data/vendor/rkelly/test/test_equal_node.rb +8 -0
- data/vendor/rkelly/test/test_evaluation_visitor.rb +66 -0
- data/vendor/rkelly/test/test_expression_statement_node.rb +10 -0
- data/vendor/rkelly/test/test_false_node.rb +8 -0
- data/vendor/rkelly/test/test_for_in_node.rb +17 -0
- data/vendor/rkelly/test/test_for_node.rb +24 -0
- data/vendor/rkelly/test/test_function_body_node.rb +8 -0
- data/vendor/rkelly/test/test_function_call_node.rb +10 -0
- data/vendor/rkelly/test/test_function_decl_node.rb +16 -0
- data/vendor/rkelly/test/test_function_expr_node.rb +16 -0
- data/vendor/rkelly/test/test_function_visitor.rb +26 -0
- data/vendor/rkelly/test/test_getter_property_node.rb +10 -0
- data/vendor/rkelly/test/test_global_object.rb +49 -0
- data/vendor/rkelly/test/test_greater_node.rb +8 -0
- data/vendor/rkelly/test/test_greater_or_equal_node.rb +8 -0
- data/vendor/rkelly/test/test_if_node.rb +17 -0
- data/vendor/rkelly/test/test_in_node.rb +8 -0
- data/vendor/rkelly/test/test_instance_of_node.rb +8 -0
- data/vendor/rkelly/test/test_label_node.rb +13 -0
- data/vendor/rkelly/test/test_left_shift_node.rb +8 -0
- data/vendor/rkelly/test/test_less_node.rb +8 -0
- data/vendor/rkelly/test/test_less_or_equal_node.rb +8 -0
- data/vendor/rkelly/test/test_line_number.rb +23 -0
- data/vendor/rkelly/test/test_logical_and_node.rb +8 -0
- data/vendor/rkelly/test/test_logical_not_node.rb +8 -0
- data/vendor/rkelly/test/test_logical_or_node.rb +8 -0
- data/vendor/rkelly/test/test_modulus_node.rb +8 -0
- data/vendor/rkelly/test/test_multiply_node.rb +8 -0
- data/vendor/rkelly/test/test_new_expr_node.rb +9 -0
- data/vendor/rkelly/test/test_not_equal_node.rb +8 -0
- data/vendor/rkelly/test/test_not_strict_equal_node.rb +8 -0
- data/vendor/rkelly/test/test_null_node.rb +8 -0
- data/vendor/rkelly/test/test_number_node.rb +8 -0
- data/vendor/rkelly/test/test_object_literal_node.rb +9 -0
- data/vendor/rkelly/test/test_op_and_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_divide_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_l_shift_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_minus_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_mod_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_multiply_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_or_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_plus_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_r_shift_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_u_r_shift_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_op_x_or_equal_node.rb +10 -0
- data/vendor/rkelly/test/test_parameter_node.rb +8 -0
- data/vendor/rkelly/test/test_parser.rb +1361 -0
- data/vendor/rkelly/test/test_pointcut_visitor.rb +34 -0
- data/vendor/rkelly/test/test_postfix_node.rb +8 -0
- data/vendor/rkelly/test/test_prefix_node.rb +8 -0
- data/vendor/rkelly/test/test_property_node.rb +8 -0
- data/vendor/rkelly/test/test_regexp_node.rb +8 -0
- data/vendor/rkelly/test/test_resolve_node.rb +22 -0
- data/vendor/rkelly/test/test_return_node.rb +11 -0
- data/vendor/rkelly/test/test_right_shift_node.rb +8 -0
- data/vendor/rkelly/test/test_rkelly.rb +19 -0
- data/vendor/rkelly/test/test_runtime.rb +12 -0
- data/vendor/rkelly/test/test_scope_chain.rb +50 -0
- data/vendor/rkelly/test/test_setter_property_node.rb +10 -0
- data/vendor/rkelly/test/test_source_elements.rb +9 -0
- data/vendor/rkelly/test/test_strict_equal_node.rb +8 -0
- data/vendor/rkelly/test/test_string_node.rb +8 -0
- data/vendor/rkelly/test/test_subtract_node.rb +8 -0
- data/vendor/rkelly/test/test_switch_node.rb +12 -0
- data/vendor/rkelly/test/test_this_node.rb +8 -0
- data/vendor/rkelly/test/test_throw_node.rb +7 -0
- data/vendor/rkelly/test/test_tokenizer.rb +148 -0
- data/vendor/rkelly/test/test_true_node.rb +8 -0
- data/vendor/rkelly/test/test_try_node.rb +59 -0
- data/vendor/rkelly/test/test_type_of_node.rb +8 -0
- data/vendor/rkelly/test/test_unary_minus_node.rb +8 -0
- data/vendor/rkelly/test/test_unary_plus_node.rb +8 -0
- data/vendor/rkelly/test/test_unsigned_right_shift_node.rb +8 -0
- data/vendor/rkelly/test/test_var_decl_node.rb +21 -0
- data/vendor/rkelly/test/test_var_statement_node.rb +14 -0
- data/vendor/rkelly/test/test_void_node.rb +8 -0
- data/vendor/rkelly/test/test_while_node.rb +15 -0
- data/vendor/rkelly/test/test_with_node.rb +8 -0
- metadata +271 -0
@@ -0,0 +1,228 @@
|
|
1
|
+
module RKelly
|
2
|
+
module Visitors
|
3
|
+
class DotVisitor < Visitor
|
4
|
+
class Node < Struct.new(:node_id, :fields)
|
5
|
+
ESCAPE = /([<>"\\])/
|
6
|
+
def to_s
|
7
|
+
counter = 0
|
8
|
+
label = fields.map { |f|
|
9
|
+
s = "<f#{counter}> #{f.to_s.gsub(ESCAPE, '\\\\\1').gsub(/[\r\n]/,' ')}"
|
10
|
+
counter += 1
|
11
|
+
s
|
12
|
+
}.join('|')
|
13
|
+
"\"#{node_id}\" [\nlabel = \"#{label}\"\nshape = \"record\"\n];"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Arrow < Struct.new(:from, :to, :label)
|
18
|
+
def to_s
|
19
|
+
"\"#{from.node_id}\":f0 -> \"#{to.node_id}\":f0"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :nodes, :arrows
|
24
|
+
def initialize
|
25
|
+
@stack = []
|
26
|
+
@node_index = 0
|
27
|
+
@nodes = []
|
28
|
+
@arrows = []
|
29
|
+
end
|
30
|
+
|
31
|
+
## Terminal nodes
|
32
|
+
%w{
|
33
|
+
BreakNode ContinueNode EmptyStatementNode FalseNode
|
34
|
+
NullNode NumberNode ParameterNode RegexpNode ResolveNode StringNode
|
35
|
+
ThisNode TrueNode
|
36
|
+
}.each do |type|
|
37
|
+
define_method(:"visit_#{type}") do |o|
|
38
|
+
node = Node.new(@node_index += 1, [type, o.value].compact)
|
39
|
+
add_arrow_for(node)
|
40
|
+
@nodes << node
|
41
|
+
end
|
42
|
+
end
|
43
|
+
## End Terminal nodes
|
44
|
+
|
45
|
+
# Single value nodes
|
46
|
+
%w{
|
47
|
+
AssignExprNode BitwiseNotNode BlockNode DeleteNode ElementNode
|
48
|
+
ExpressionStatementNode FunctionBodyNode LogicalNotNode ReturnNode
|
49
|
+
ThrowNode TypeOfNode UnaryMinusNode UnaryPlusNode VoidNode
|
50
|
+
}.each do |type|
|
51
|
+
define_method(:"visit_#{type}") do |o|
|
52
|
+
node = Node.new(@node_index += 1, [type])
|
53
|
+
add_arrow_for(node)
|
54
|
+
@nodes << node
|
55
|
+
@stack.push(node)
|
56
|
+
o.value && o.value.accept(self)
|
57
|
+
@stack.pop
|
58
|
+
end
|
59
|
+
end
|
60
|
+
# End Single value nodes
|
61
|
+
|
62
|
+
# Binary nodes
|
63
|
+
%w{
|
64
|
+
AddNode BitAndNode BitOrNode BitXOrNode CaseClauseNode CommaNode
|
65
|
+
DivideNode DoWhileNode EqualNode GreaterNode GreaterOrEqualNode InNode
|
66
|
+
InstanceOfNode LeftShiftNode LessNode LessOrEqualNode LogicalAndNode
|
67
|
+
LogicalOrNode ModulusNode MultiplyNode NotEqualNode NotStrictEqualNode
|
68
|
+
OpAndEqualNode OpDivideEqualNode OpEqualNode OpLShiftEqualNode
|
69
|
+
OpMinusEqualNode OpModEqualNode OpMultiplyEqualNode OpOrEqualNode
|
70
|
+
OpPlusEqualNode OpRShiftEqualNode OpURShiftEqualNode OpXOrEqualNode
|
71
|
+
RightShiftNode StrictEqualNode SubtractNode SwitchNode
|
72
|
+
UnsignedRightShiftNode WhileNode WithNode
|
73
|
+
}.each do |type|
|
74
|
+
define_method(:"visit_#{type}") do |o|
|
75
|
+
node = Node.new(@node_index += 1, [type])
|
76
|
+
add_arrow_for(node)
|
77
|
+
@nodes << node
|
78
|
+
@stack.push(node)
|
79
|
+
o.left && o.left.accept(self)
|
80
|
+
o.value && o.value.accept(self)
|
81
|
+
@stack.pop
|
82
|
+
end
|
83
|
+
end
|
84
|
+
# End Binary nodes
|
85
|
+
|
86
|
+
# Array Value Nodes
|
87
|
+
%w{
|
88
|
+
ArgumentsNode ArrayNode CaseBlockNode ConstStatementNode
|
89
|
+
ObjectLiteralNode SourceElementsNode VarStatementNode
|
90
|
+
}.each do |type|
|
91
|
+
define_method(:"visit_#{type}") do |o|
|
92
|
+
node = Node.new(@node_index += 1, [type])
|
93
|
+
add_arrow_for(node)
|
94
|
+
@nodes << node
|
95
|
+
@stack.push(node)
|
96
|
+
o.value && o.value.each { |v| v && v.accept(self) }
|
97
|
+
@stack.pop
|
98
|
+
end
|
99
|
+
end
|
100
|
+
# END Array Value Nodes
|
101
|
+
|
102
|
+
# Name and Value Nodes
|
103
|
+
%w{
|
104
|
+
LabelNode PropertyNode GetterPropertyNode SetterPropertyNode VarDeclNode
|
105
|
+
}.each do |type|
|
106
|
+
define_method(:"visit_#{type}") do |o|
|
107
|
+
node = Node.new(@node_index += 1, [type, o.name || 'NULL'])
|
108
|
+
add_arrow_for(node)
|
109
|
+
@nodes << node
|
110
|
+
@stack.push(node)
|
111
|
+
o.value && o.value.accept(self)
|
112
|
+
@stack.pop
|
113
|
+
end
|
114
|
+
end
|
115
|
+
# END Name and Value Nodes
|
116
|
+
|
117
|
+
%w{ PostfixNode PrefixNode }.each do |type|
|
118
|
+
define_method(:"visit_#{type}") do |o|
|
119
|
+
node = Node.new(@node_index += 1, [type, o.value])
|
120
|
+
add_arrow_for(node)
|
121
|
+
@nodes << node
|
122
|
+
@stack.push(node)
|
123
|
+
o.operand && o.operand.accept(self)
|
124
|
+
@stack.pop
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def visit_ForNode(o)
|
129
|
+
node = Node.new(@node_index += 1, ['ForNode'])
|
130
|
+
add_arrow_for(node)
|
131
|
+
@nodes << node
|
132
|
+
@stack.push(node)
|
133
|
+
[:init, :test, :counter, :value].each do |method|
|
134
|
+
o.send(method) && o.send(method).accept(self)
|
135
|
+
end
|
136
|
+
@stack.pop
|
137
|
+
end
|
138
|
+
|
139
|
+
%w{ IfNode ConditionalNode }.each do |type|
|
140
|
+
define_method(:"visit_#{type}") do |o|
|
141
|
+
node = Node.new(@node_index += 1, [type])
|
142
|
+
add_arrow_for(node)
|
143
|
+
@nodes << node
|
144
|
+
@stack.push(node)
|
145
|
+
[:conditions, :value, :else].each do |method|
|
146
|
+
o.send(method) && o.send(method).accept(self)
|
147
|
+
end
|
148
|
+
@stack.pop
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def visit_ForInNode(o)
|
153
|
+
node = Node.new(@node_index += 1, ['ForInNode'])
|
154
|
+
add_arrow_for(node)
|
155
|
+
@nodes << node
|
156
|
+
@stack.push(node)
|
157
|
+
[:left, :right, :value].each do |method|
|
158
|
+
o.send(method) && o.send(method).accept(self)
|
159
|
+
end
|
160
|
+
@stack.pop
|
161
|
+
end
|
162
|
+
|
163
|
+
def visit_TryNode(o)
|
164
|
+
node = Node.new(@node_index += 1, ['TryNode', o.catch_var || 'NULL'])
|
165
|
+
add_arrow_for(node)
|
166
|
+
@nodes << node
|
167
|
+
@stack.push(node)
|
168
|
+
[:value, :catch_block, :finally_block].each do |method|
|
169
|
+
o.send(method) && o.send(method).accept(self)
|
170
|
+
end
|
171
|
+
@stack.pop
|
172
|
+
end
|
173
|
+
|
174
|
+
def visit_BracketAccessorNode(o)
|
175
|
+
node = Node.new(@node_index += 1, ['BracketAccessorNode'])
|
176
|
+
add_arrow_for(node)
|
177
|
+
@nodes << node
|
178
|
+
@stack.push(node)
|
179
|
+
[:value, :accessor].each do |method|
|
180
|
+
o.send(method) && o.send(method).accept(self)
|
181
|
+
end
|
182
|
+
@stack.pop
|
183
|
+
end
|
184
|
+
|
185
|
+
%w{ NewExprNode FunctionCallNode }.each do |type|
|
186
|
+
define_method(:"visit_#{type}") do |o|
|
187
|
+
node = Node.new(@node_index += 1, [type])
|
188
|
+
add_arrow_for(node)
|
189
|
+
@nodes << node
|
190
|
+
@stack.push(node)
|
191
|
+
[:value, :arguments].each do |method|
|
192
|
+
o.send(method) && o.send(method).accept(self)
|
193
|
+
end
|
194
|
+
@stack.pop
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
%w{ FunctionExprNode FunctionDeclNode }.each do |type|
|
199
|
+
define_method(:"visit_#{type}") do |o|
|
200
|
+
node = Node.new(@node_index += 1, [type, o.value || 'NULL'])
|
201
|
+
add_arrow_for(node)
|
202
|
+
@nodes << node
|
203
|
+
@stack.push(node)
|
204
|
+
o.arguments.each { |a| a && a.accept(self) }
|
205
|
+
o.function_body && o.function_body.accept(self)
|
206
|
+
@stack.pop
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def visit_DotAccessorNode(o)
|
211
|
+
node = Node.new(@node_index += 1, ['DotAccessorNode', o.accessor])
|
212
|
+
add_arrow_for(node)
|
213
|
+
@nodes << node
|
214
|
+
@stack.push(node)
|
215
|
+
[:value].each do |method|
|
216
|
+
o.send(method) && o.send(method).accept(self)
|
217
|
+
end
|
218
|
+
@stack.pop
|
219
|
+
end
|
220
|
+
|
221
|
+
private
|
222
|
+
def add_arrow_for(node, label = nil)
|
223
|
+
@arrows << Arrow.new(@stack.last, node, label) if @stack.length > 0
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,314 @@
|
|
1
|
+
module RKelly
|
2
|
+
module Visitors
|
3
|
+
class ECMAVisitor < Visitor
|
4
|
+
def initialize
|
5
|
+
@indent = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def visit_SourceElementsNode(o)
|
9
|
+
o.value.map { |x| "#{indent}#{x.accept(self)}" }.join("\n")
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit_VarStatementNode(o)
|
13
|
+
"var #{o.value.map { |x| x.accept(self) }.join(', ')};"
|
14
|
+
end
|
15
|
+
|
16
|
+
def visit_ConstStatementNode(o)
|
17
|
+
"const #{o.value.map { |x| x.accept(self) }.join(', ')};"
|
18
|
+
end
|
19
|
+
|
20
|
+
def visit_VarDeclNode(o)
|
21
|
+
"#{o.name}#{o.value ? o.value.accept(self) : nil}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def visit_AssignExprNode(o)
|
25
|
+
" = #{o.value.accept(self)}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def visit_NumberNode(o)
|
29
|
+
o.value.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def visit_ForNode(o)
|
33
|
+
init = o.init ? o.init.accept(self) : ';'
|
34
|
+
test = o.test ? o.test.accept(self) : ''
|
35
|
+
counter = o.counter ? o.counter.accept(self) : ''
|
36
|
+
"for(#{init} #{test}; #{counter}) #{o.value.accept(self)}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def visit_LessNode(o)
|
40
|
+
"#{o.left.accept(self)} < #{o.value.accept(self)}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def visit_ResolveNode(o)
|
44
|
+
o.value
|
45
|
+
end
|
46
|
+
|
47
|
+
def visit_PostfixNode(o)
|
48
|
+
"#{o.operand.accept(self)}#{o.value}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def visit_PrefixNode(o)
|
52
|
+
"#{o.value}#{o.operand.accept(self)}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def visit_BlockNode(o)
|
56
|
+
@indent += 1
|
57
|
+
"{\n#{o.value.accept(self)}\n#{@indent -=1; indent}}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def visit_ExpressionStatementNode(o)
|
61
|
+
"#{o.value.accept(self)};"
|
62
|
+
end
|
63
|
+
|
64
|
+
def visit_OpEqualNode(o)
|
65
|
+
"#{o.left.accept(self)} = #{o.value.accept(self)}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def visit_FunctionCallNode(o)
|
69
|
+
"#{o.value.accept(self)}(#{o.arguments.accept(self)})"
|
70
|
+
end
|
71
|
+
|
72
|
+
def visit_ArgumentsNode(o)
|
73
|
+
o.value.map { |x| x.accept(self) }.join(', ')
|
74
|
+
end
|
75
|
+
|
76
|
+
def visit_StringNode(o)
|
77
|
+
o.value
|
78
|
+
end
|
79
|
+
|
80
|
+
def visit_NullNode(o)
|
81
|
+
"null"
|
82
|
+
end
|
83
|
+
|
84
|
+
def visit_FunctionDeclNode(o)
|
85
|
+
"#{indent}function #{o.value}(" +
|
86
|
+
"#{o.arguments.map { |x| x.accept(self) }.join(', ')})" +
|
87
|
+
"#{o.function_body.accept(self)}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def visit_ParameterNode(o)
|
91
|
+
o.value
|
92
|
+
end
|
93
|
+
|
94
|
+
def visit_FunctionBodyNode(o)
|
95
|
+
@indent += 1
|
96
|
+
"{\n#{o.value.accept(self)}\n#{@indent -=1; indent}}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def visit_BreakNode(o)
|
100
|
+
"break" + (o.value ? " #{o.value}" : '') + ';'
|
101
|
+
end
|
102
|
+
|
103
|
+
def visit_ContinueNode(o)
|
104
|
+
"continue" + (o.value ? " #{o.value}" : '') + ';'
|
105
|
+
end
|
106
|
+
|
107
|
+
def visit_TrueNode(o)
|
108
|
+
"true"
|
109
|
+
end
|
110
|
+
|
111
|
+
def visit_FalseNode(o)
|
112
|
+
"false"
|
113
|
+
end
|
114
|
+
|
115
|
+
def visit_EmptyStatementNode(o)
|
116
|
+
';'
|
117
|
+
end
|
118
|
+
|
119
|
+
def visit_RegexpNode(o)
|
120
|
+
o.value
|
121
|
+
end
|
122
|
+
|
123
|
+
def visit_DotAccessorNode(o)
|
124
|
+
"#{o.value.accept(self)}.#{o.accessor}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def visit_ThisNode(o)
|
128
|
+
"this"
|
129
|
+
end
|
130
|
+
|
131
|
+
def visit_BitwiseNotNode(o)
|
132
|
+
"~#{o.value.accept(self)}"
|
133
|
+
end
|
134
|
+
|
135
|
+
def visit_DeleteNode(o)
|
136
|
+
"delete #{o.value.accept(self)}"
|
137
|
+
end
|
138
|
+
|
139
|
+
def visit_ArrayNode(o)
|
140
|
+
"[#{o.value.map { |x| x ? x.accept(self) : '' }.join(', ')}]"
|
141
|
+
end
|
142
|
+
|
143
|
+
def visit_ElementNode(o)
|
144
|
+
o.value.accept(self)
|
145
|
+
end
|
146
|
+
|
147
|
+
def visit_LogicalNotNode(o)
|
148
|
+
"!#{o.value.accept(self)}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def visit_UnaryMinusNode(o)
|
152
|
+
"-#{o.value.accept(self)}"
|
153
|
+
end
|
154
|
+
|
155
|
+
def visit_UnaryPlusNode(o)
|
156
|
+
"+#{o.value.accept(self)}"
|
157
|
+
end
|
158
|
+
|
159
|
+
def visit_ReturnNode(o)
|
160
|
+
"return" + (o.value ? " #{o.value.accept(self)}" : '') + ';'
|
161
|
+
end
|
162
|
+
|
163
|
+
def visit_ThrowNode(o)
|
164
|
+
"throw #{o.value.accept(self)};"
|
165
|
+
end
|
166
|
+
|
167
|
+
def visit_TypeOfNode(o)
|
168
|
+
"typeof #{o.value.accept(self)}"
|
169
|
+
end
|
170
|
+
|
171
|
+
def visit_VoidNode(o)
|
172
|
+
"void(#{o.value.accept(self)})"
|
173
|
+
end
|
174
|
+
|
175
|
+
[
|
176
|
+
[:Add, '+'],
|
177
|
+
[:BitAnd, '&'],
|
178
|
+
[:BitOr, '|'],
|
179
|
+
[:BitXOr, '^'],
|
180
|
+
[:Divide, '/'],
|
181
|
+
[:Equal, '=='],
|
182
|
+
[:Greater, '>'],
|
183
|
+
[:Greater, '>'],
|
184
|
+
[:GreaterOrEqual, '>='],
|
185
|
+
[:GreaterOrEqual, '>='],
|
186
|
+
[:In, 'in'],
|
187
|
+
[:InstanceOf, 'instanceof'],
|
188
|
+
[:LeftShift, '<<'],
|
189
|
+
[:LessOrEqual, '<='],
|
190
|
+
[:LogicalAnd, '&&'],
|
191
|
+
[:LogicalOr, '||'],
|
192
|
+
[:Modulus, '%'],
|
193
|
+
[:Multiply, '*'],
|
194
|
+
[:NotEqual, '!='],
|
195
|
+
[:NotStrictEqual, '!=='],
|
196
|
+
[:OpAndEqual, '&='],
|
197
|
+
[:OpDivideEqual, '/='],
|
198
|
+
[:OpLShiftEqual, '<<='],
|
199
|
+
[:OpMinusEqual, '-='],
|
200
|
+
[:OpModEqual, '%='],
|
201
|
+
[:OpMultiplyEqual, '*='],
|
202
|
+
[:OpOrEqual, '|='],
|
203
|
+
[:OpPlusEqual, '+='],
|
204
|
+
[:OpRShiftEqual, '>>='],
|
205
|
+
[:OpURShiftEqual, '>>>='],
|
206
|
+
[:OpXOrEqual, '^='],
|
207
|
+
[:RightShift, '>>'],
|
208
|
+
[:StrictEqual, '==='],
|
209
|
+
[:Subtract, '-'],
|
210
|
+
[:UnsignedRightShift, '>>>'],
|
211
|
+
].each do |name,op|
|
212
|
+
define_method(:"visit_#{name}Node") do |o|
|
213
|
+
"#{o.left.accept(self)} #{op} #{o.value.accept(self)}"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def visit_WhileNode(o)
|
218
|
+
"while(#{o.left.accept(self)}) #{o.value.accept(self)}"
|
219
|
+
end
|
220
|
+
|
221
|
+
def visit_SwitchNode(o)
|
222
|
+
"switch(#{o.left.accept(self)}) #{o.value.accept(self)}"
|
223
|
+
end
|
224
|
+
|
225
|
+
def visit_CaseBlockNode(o)
|
226
|
+
@indent += 1
|
227
|
+
"{\n" + (o.value ? o.value.map { |x| x.accept(self) }.join('') : '') +
|
228
|
+
"#{@indent -=1; indent}}"
|
229
|
+
end
|
230
|
+
|
231
|
+
def visit_CaseClauseNode(o)
|
232
|
+
case_code = "#{indent}case #{o.left ? o.left.accept(self) : nil}:\n"
|
233
|
+
@indent += 1
|
234
|
+
case_code += "#{o.value.accept(self)}\n"
|
235
|
+
@indent -= 1
|
236
|
+
case_code
|
237
|
+
end
|
238
|
+
|
239
|
+
def visit_DoWhileNode(o)
|
240
|
+
"do #{o.left.accept(self)} while(#{o.value.accept(self)});"
|
241
|
+
end
|
242
|
+
|
243
|
+
def visit_WithNode(o)
|
244
|
+
"with(#{o.left.accept(self)}) #{o.value.accept(self)}"
|
245
|
+
end
|
246
|
+
|
247
|
+
def visit_LabelNode(o)
|
248
|
+
"#{o.name}: #{o.value.accept(self)}"
|
249
|
+
end
|
250
|
+
|
251
|
+
def visit_ObjectLiteralNode(o)
|
252
|
+
@indent += 1
|
253
|
+
lit = "{" + (o.value.length > 0 ? "\n" : ' ') +
|
254
|
+
o.value.map { |x| "#{indent}#{x.accept(self)}" }.join(",\n") +
|
255
|
+
(o.value.length > 0 ? "\n" : '') + '}'
|
256
|
+
@indent -= 1
|
257
|
+
lit
|
258
|
+
end
|
259
|
+
|
260
|
+
def visit_PropertyNode(o)
|
261
|
+
"#{o.name}: #{o.value.accept(self)}"
|
262
|
+
end
|
263
|
+
|
264
|
+
def visit_GetterPropertyNode(o)
|
265
|
+
"get #{o.name}#{o.value.accept(self)}"
|
266
|
+
end
|
267
|
+
|
268
|
+
def visit_SetterPropertyNode(o)
|
269
|
+
"set #{o.name}#{o.value.accept(self)}"
|
270
|
+
end
|
271
|
+
|
272
|
+
def visit_FunctionExprNode(o)
|
273
|
+
"#{o.value}(#{o.arguments.map { |x| x.accept(self) }.join(', ')}) " +
|
274
|
+
"#{o.function_body.accept(self)}"
|
275
|
+
end
|
276
|
+
|
277
|
+
def visit_CommaNode(o)
|
278
|
+
"#{o.left.accept(self)}, #{o.value.accept(self)}"
|
279
|
+
end
|
280
|
+
|
281
|
+
def visit_IfNode(o)
|
282
|
+
"if(#{o.conditions.accept(self)}) #{o.value.accept(self)}" +
|
283
|
+
(o.else ? " else #{o.else.accept(self)}" : '')
|
284
|
+
end
|
285
|
+
|
286
|
+
def visit_ConditionalNode(o)
|
287
|
+
"#{o.conditions.accept(self)} ? #{o.value.accept(self)} : " +
|
288
|
+
"#{o.else.accept(self)}"
|
289
|
+
end
|
290
|
+
|
291
|
+
def visit_ForInNode(o)
|
292
|
+
"for(#{o.left.accept(self)} in #{o.right.accept(self)}) " +
|
293
|
+
"#{o.value.accept(self)}"
|
294
|
+
end
|
295
|
+
|
296
|
+
def visit_TryNode(o)
|
297
|
+
"try #{o.value.accept(self)}" +
|
298
|
+
(o.catch_block ? " catch(#{o.catch_var}) #{o.catch_block.accept(self)}" : '') +
|
299
|
+
(o.finally_block ? " finally #{o.finally_block.accept(self)}" : '')
|
300
|
+
end
|
301
|
+
|
302
|
+
def visit_BracketAccessorNode(o)
|
303
|
+
"#{o.value.accept(self)}[#{o.accessor.accept(self)}]"
|
304
|
+
end
|
305
|
+
|
306
|
+
def visit_NewExprNode(o)
|
307
|
+
"new #{o.value.accept(self)}(#{o.arguments.accept(self)})"
|
308
|
+
end
|
309
|
+
|
310
|
+
private
|
311
|
+
def indent; ' ' * @indent * 2; end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RKelly
|
2
|
+
module Visitors
|
3
|
+
class EnumerableVisitor < Visitor
|
4
|
+
def initialize(block)
|
5
|
+
@block = block
|
6
|
+
end
|
7
|
+
|
8
|
+
ALL_NODES.each do |type|
|
9
|
+
eval <<-RUBY
|
10
|
+
def visit_#{type}Node(o)
|
11
|
+
@block[o]
|
12
|
+
super
|
13
|
+
end
|
14
|
+
RUBY
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|