ikra 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ast/builder.rb +225 -77
- data/lib/ast/host_section_builder.rb +38 -0
- data/lib/ast/interpreter.rb +67 -0
- data/lib/ast/lexical_variables_enumerator.rb +3 -2
- data/lib/ast/nodes.rb +521 -31
- data/lib/ast/printer.rb +116 -18
- data/lib/ast/ssa_generator.rb +192 -0
- data/lib/ast/visitor.rb +235 -21
- data/lib/config/configuration.rb +28 -3
- data/lib/config/os_configuration.rb +62 -9
- data/lib/cpu/cpu_implementation.rb +39 -0
- data/lib/ikra.rb +13 -3
- data/lib/resources/cuda/allocate_device_memory.cpp +5 -0
- data/lib/resources/cuda/allocate_host_memory.cpp +1 -0
- data/lib/resources/cuda/allocate_memcpy_environment_to_device.cpp +11 -0
- data/lib/resources/cuda/ast/assignment.cpp +1 -0
- data/lib/resources/cuda/block_function_head.cpp +7 -1
- data/lib/resources/cuda/entry_point.cpp +47 -0
- data/lib/resources/cuda/env_builder_copy_array.cpp +8 -2
- data/lib/resources/cuda/free_device_memory.cpp +3 -0
- data/lib/resources/cuda/free_memory_for_command.cpp +24 -0
- data/lib/resources/cuda/header.cpp +23 -9
- data/lib/resources/cuda/header_structs.cpp +92 -0
- data/lib/resources/cuda/host_section_block_function_head.cpp +12 -0
- data/lib/resources/cuda/host_section_entry_point.cpp +55 -0
- data/lib/resources/cuda/host_section_free_device_memory.cpp +18 -0
- data/lib/resources/cuda/host_section_launch_parallel_section.cpp +14 -0
- data/lib/resources/cuda/host_section_malloc_memcpy_device_to_host.cpp +10 -0
- data/lib/resources/cuda/kernel.cpp +9 -2
- data/lib/resources/cuda/launch_kernel.cpp +5 -0
- data/lib/resources/cuda/memcpy_device_to_host.cpp +3 -0
- data/lib/resources/cuda/memcpy_device_to_host_expr.cpp +10 -0
- data/lib/resources/cuda/reduce_body.cpp +88 -0
- data/lib/resources/cuda/stencil_array_reconstruction.cpp +2 -0
- data/lib/resources/cuda/stencil_body.cpp +16 -0
- data/lib/resources/cuda/struct_definition.cpp +4 -0
- data/lib/ruby_core/array.rb +34 -0
- data/lib/ruby_core/array_command.rb +313 -0
- data/lib/ruby_core/core.rb +103 -0
- data/lib/ruby_core/interpreter.rb +16 -0
- data/lib/ruby_core/math.rb +32 -0
- data/lib/ruby_core/ruby_integration.rb +256 -0
- data/lib/symbolic/host_section.rb +115 -0
- data/lib/symbolic/input.rb +87 -0
- data/lib/symbolic/input_visitor.rb +68 -0
- data/lib/symbolic/symbolic.rb +793 -117
- data/lib/symbolic/visitor.rb +70 -8
- data/lib/translator/array_command_struct_builder.rb +163 -0
- data/lib/translator/ast_translator.rb +572 -0
- data/lib/translator/block_translator.rb +104 -48
- data/lib/translator/commands/array_combine_command.rb +41 -0
- data/lib/translator/commands/array_identity_command.rb +28 -0
- data/lib/translator/commands/array_index_command.rb +52 -0
- data/lib/translator/commands/array_reduce_command.rb +135 -0
- data/lib/translator/commands/array_stencil_command.rb +129 -0
- data/lib/translator/commands/array_zip_command.rb +30 -0
- data/lib/translator/commands/command_translator.rb +264 -0
- data/lib/translator/cuda_errors.rb +32 -0
- data/lib/translator/environment_builder.rb +263 -0
- data/lib/translator/host_section/array_host_section_command.rb +150 -0
- data/lib/translator/host_section/array_in_host_section_command.rb +41 -0
- data/lib/translator/host_section/ast_translator.rb +14 -0
- data/lib/translator/host_section/parallel_section_invocation_visitor.rb +20 -0
- data/lib/translator/host_section/program_builder.rb +89 -0
- data/lib/translator/input_translator.rb +226 -0
- data/lib/translator/kernel_builder.rb +137 -0
- data/lib/translator/kernel_launcher/for_loop_kernel_launcher.rb +40 -0
- data/lib/translator/kernel_launcher/kernel_launcher.rb +259 -0
- data/lib/translator/kernel_launcher/while_loop_kernel_launcher.rb +38 -0
- data/lib/translator/last_returns_visitor.rb +19 -10
- data/lib/translator/program_builder.rb +197 -0
- data/lib/translator/program_launcher.rb +273 -0
- data/lib/translator/struct_type.rb +55 -0
- data/lib/translator/translator.rb +34 -11
- data/lib/translator/variable_classifier_visitor.rb +56 -0
- data/lib/types/inference/ast_inference.rb +586 -0
- data/lib/types/inference/clear_types_visitor.rb +11 -0
- data/lib/types/inference/command_inference.rb +101 -0
- data/lib/types/inference/input_inference.rb +62 -0
- data/lib/types/{object_tracer.rb → inference/object_tracer.rb} +5 -6
- data/lib/types/inference/ruby_extension.rb +35 -0
- data/lib/types/inference/symbol_table.rb +131 -0
- data/lib/types/types.rb +14 -0
- data/lib/types/types/array_command_type.rb +123 -0
- data/lib/types/types/array_type.rb +137 -0
- data/lib/types/{class_type.rb → types/class_type.rb} +42 -18
- data/lib/types/{primitive_type.rb → types/primitive_type.rb} +20 -7
- data/lib/types/types/ruby_type.rb +88 -0
- data/lib/types/types/struct_type.rb +179 -0
- data/lib/types/types/union_type.rb +239 -0
- metadata +160 -18
- data/lib/ast/method_definition.rb +0 -37
- data/lib/ast/translator.rb +0 -264
- data/lib/resources/cuda/kernel_launcher.cpp +0 -28
- data/lib/scope.rb +0 -166
- data/lib/translator/command_translator.rb +0 -421
- data/lib/translator/local_variables_enumerator.rb +0 -35
- data/lib/translator/method_translator.rb +0 -24
- data/lib/types/array_type.rb +0 -51
- data/lib/types/ruby_extension.rb +0 -67
- data/lib/types/ruby_type.rb +0 -45
- data/lib/types/type_inference.rb +0 -382
- data/lib/types/union_type.rb +0 -155
data/lib/ast/printer.rb
CHANGED
@@ -2,81 +2,179 @@ module Ikra
|
|
2
2
|
module AST
|
3
3
|
class Node
|
4
4
|
def to_s
|
5
|
-
"[Node]"
|
5
|
+
return "[Node]"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class ProgramNode
|
10
|
+
def to_s
|
11
|
+
return "[ProgramNode: #{blocks.to_s}; #{classes.to_s}]"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ClassDefNode
|
16
|
+
def to_s
|
17
|
+
return "[ClassDefNode: #{name}; #{instance_variables.to_s}; #{instance_methods.to_s}]"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class VarDefNode
|
22
|
+
def to_s
|
23
|
+
return "[VarDefNode: #{name}, read = #{read}, written = #{written}]"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class MethDefNode
|
28
|
+
def to_s
|
29
|
+
return "[MethDefNode: #{name} #{body.to_s}]"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class BlockDefNode
|
34
|
+
def to_s
|
35
|
+
return "[BlockDefNode: #{body.to_s}]"
|
6
36
|
end
|
7
37
|
end
|
8
38
|
|
9
39
|
class RootNode
|
10
40
|
def to_s
|
11
|
-
"[RootNode: #{
|
41
|
+
return "[RootNode: #{single_child.to_s}]"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class ArrayNode
|
46
|
+
def to_s
|
47
|
+
return "[ArrayNode: [#{(values.map do |v| v.to_s end).join(', ')}]]"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class SourceCodeExprNode
|
52
|
+
def to_s
|
53
|
+
return "[SourceCodeExprNode: #{code}]"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class HashNode
|
58
|
+
def to_s
|
59
|
+
return "[HashNode: {" + hash.map do |key, value|
|
60
|
+
"#{key.to_s} => #{value.to_s}"
|
61
|
+
end.join(", ") + "}]"
|
12
62
|
end
|
13
63
|
end
|
14
64
|
|
15
65
|
class ConstNode
|
16
66
|
def to_s
|
17
|
-
"[ConstNode: #{identifier.to_s}]"
|
67
|
+
return "[ConstNode: #{identifier.to_s}]"
|
18
68
|
end
|
19
69
|
end
|
20
70
|
|
21
71
|
class LVarReadNode
|
22
72
|
def to_s
|
23
|
-
"[LVarReadNode: #{identifier.to_s}]"
|
73
|
+
return "[LVarReadNode: #{identifier.to_s}]"
|
24
74
|
end
|
25
75
|
end
|
26
76
|
|
27
77
|
class LVarWriteNode
|
28
78
|
def to_s
|
29
|
-
"[LVarWriteNode: #{identifier.to_s} := #{value.to_s}]"
|
79
|
+
return "[LVarWriteNode: #{identifier.to_s} := #{value.to_s}]"
|
30
80
|
end
|
31
81
|
end
|
32
82
|
|
33
|
-
class
|
83
|
+
class IntLiteralNode
|
34
84
|
def to_s
|
35
|
-
"<#{value.to_s}>"
|
85
|
+
return "<#{value.to_s}>"
|
36
86
|
end
|
37
87
|
end
|
38
88
|
|
39
|
-
class
|
89
|
+
class FloatLiteralNode
|
40
90
|
def to_s
|
41
|
-
"<#{value.to_s}>"
|
91
|
+
return "<#{value.to_s}>"
|
42
92
|
end
|
43
93
|
end
|
44
94
|
|
45
|
-
class
|
95
|
+
class BoolLiteralNode
|
46
96
|
def to_s
|
47
|
-
"<#{value.to_s}>"
|
97
|
+
return "<#{value.to_s}>"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class NilLiteralNode
|
102
|
+
def to_s
|
103
|
+
return "<nil>"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class SymbolLiteralNode
|
108
|
+
def to_s
|
109
|
+
return "<:#{value.to_s}>"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class StringLiteralNode
|
114
|
+
def to_s
|
115
|
+
return "<#{value.to_s}>"
|
48
116
|
end
|
49
117
|
end
|
50
118
|
|
51
119
|
class ForNode
|
52
120
|
def to_s
|
53
|
-
"[ForNode: #{iterator_identifier.to_s} := #{range_from.to_s}...#{range_to.to_s}, #{body_stmts.to_s}]"
|
121
|
+
return "[ForNode: #{iterator_identifier.to_s} := #{range_from.to_s}...#{range_to.to_s}, #{body_stmts.to_s}]"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class WhileNode
|
126
|
+
def to_s
|
127
|
+
return "[WhileNode: #{condition.to_s}, #{body_stmts.to_s}]"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class WhilePostNode
|
132
|
+
def to_s
|
133
|
+
return "[WhilePostNode: #{condition.to_s}, #{body_stmts.to_s}]"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class UntilNode
|
138
|
+
def to_s
|
139
|
+
return "[UntilNode: #{condition.to_s}, #{body_stmts.to_s}]"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class UntilPostNode
|
144
|
+
def to_s
|
145
|
+
return "[UntilPostNode: #{condition.to_s}, #{body_stmts.to_s}]"
|
54
146
|
end
|
55
147
|
end
|
56
148
|
|
57
149
|
class BreakNode
|
58
150
|
def to_s
|
59
|
-
"[BreakNode]"
|
151
|
+
return "[BreakNode]"
|
60
152
|
end
|
61
153
|
end
|
62
154
|
|
63
155
|
class IfNode
|
64
156
|
def to_s
|
65
157
|
if false_body_stmts != nil
|
66
|
-
"[IfNode: #{condition.to_s}, #{true_body_stmts.to_s}, #{false_body_stmts.to_s}]"
|
158
|
+
return "[IfNode: #{condition.to_s}, #{true_body_stmts.to_s}, #{false_body_stmts.to_s}]"
|
67
159
|
else
|
68
|
-
"[IfNode: #{condition.to_s}, #{true_body_stmts.to_s}]"
|
160
|
+
return "[IfNode: #{condition.to_s}, #{true_body_stmts.to_s}]"
|
69
161
|
end
|
70
162
|
end
|
71
163
|
end
|
72
164
|
|
165
|
+
class TernaryNode
|
166
|
+
def to_s
|
167
|
+
return "[TernaryNode: #{condition.to_s}, #{true_val.to_s}, #{false_val.to_s}]"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
73
171
|
class BeginNode
|
74
172
|
def to_s
|
75
173
|
stmts = body_stmts.map do |stmt|
|
76
174
|
stmt.to_s
|
77
175
|
end.join(";\n")
|
78
176
|
|
79
|
-
"[BeginNode: {#{stmts}}]"
|
177
|
+
return "[BeginNode: {#{stmts}}]"
|
80
178
|
end
|
81
179
|
end
|
82
180
|
|
@@ -86,13 +184,13 @@ module Ikra
|
|
86
184
|
arg.to_s
|
87
185
|
end.join("; ")
|
88
186
|
|
89
|
-
"[SendNode: #{receiver.to_s}.#{selector.to_s}(#{args})]"
|
187
|
+
return "[SendNode: #{receiver.to_s}.#{selector.to_s}(#{args})]"
|
90
188
|
end
|
91
189
|
end
|
92
190
|
|
93
191
|
class ReturnNode
|
94
192
|
def to_s
|
95
|
-
"[ReturnNode: #{value.to_s}]"
|
193
|
+
return "[ReturnNode: #{value.to_s}]"
|
96
194
|
end
|
97
195
|
end
|
98
196
|
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module Ikra
|
4
|
+
module AST
|
5
|
+
# Converts an AST to single static assignment form (SSA).
|
6
|
+
# TODO: Make SSA form minimal, i.e., remove unnecessary assignments (Phi node artifacts).
|
7
|
+
class SSAGenerator < Visitor
|
8
|
+
def self.transform_to_ssa!(node)
|
9
|
+
node.accept(self.new)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@aliases = {}
|
14
|
+
@ssa_id = 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def new_ssa_var_name(old_name = nil)
|
18
|
+
@ssa_id = @ssa_id + 1
|
19
|
+
|
20
|
+
if old_name == nil
|
21
|
+
return "_ssa_var_#{@ssa_id}"
|
22
|
+
else
|
23
|
+
return "_ssa_var_#{old_name}_#{@ssa_id}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def visit_lvar_read_node(node)
|
28
|
+
super
|
29
|
+
|
30
|
+
if @aliases.include?(node.identifier)
|
31
|
+
# This variable was renamed
|
32
|
+
node.replace(LVarReadNode.new(identifier: @aliases[node.identifier]))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def visit_lvar_write_node(node)
|
37
|
+
super
|
38
|
+
|
39
|
+
# Give the variable a new name
|
40
|
+
new_name = new_ssa_var_name(node.identifier)
|
41
|
+
@aliases[node.identifier] = new_name
|
42
|
+
|
43
|
+
node.replace(LVarWriteNode.new(
|
44
|
+
identifier: new_name,
|
45
|
+
value: node.value))
|
46
|
+
end
|
47
|
+
|
48
|
+
# Merges all "alias" hash maps given by `branch_aliases`. If a conflict is detected,
|
49
|
+
# i.e., a variable is renamed to different names in at least to branches, `block` is
|
50
|
+
# executed with the original variable name as argument. The block should return the
|
51
|
+
# new resolved variable name.
|
52
|
+
def merge_aliases(*branch_aliases, &block)
|
53
|
+
result = {}
|
54
|
+
|
55
|
+
orig_names = Set.new(branch_aliases.map do |aliases|
|
56
|
+
aliases.keys
|
57
|
+
end.flatten)
|
58
|
+
|
59
|
+
for orig_name in orig_names
|
60
|
+
new_names = Set.new(branch_aliases.map do |aliases|
|
61
|
+
aliases[orig_name]
|
62
|
+
end)
|
63
|
+
|
64
|
+
if new_names.size > 1
|
65
|
+
# Renamed to different values
|
66
|
+
result[orig_name] = yield(orig_name)
|
67
|
+
else
|
68
|
+
result[orig_name] = new_names.first
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
return result
|
73
|
+
end
|
74
|
+
|
75
|
+
def visit_if_node(node)
|
76
|
+
node.condition.accept(self)
|
77
|
+
|
78
|
+
branch1_aliases = @aliases.dup
|
79
|
+
branch2_aliases = @aliases.dup
|
80
|
+
|
81
|
+
@aliases = branch1_aliases
|
82
|
+
node.true_body_stmts.accept(self)
|
83
|
+
branch1_aliases = @aliases
|
84
|
+
|
85
|
+
@aliases = branch2_aliases
|
86
|
+
node.false_body_stmts.accept(self)
|
87
|
+
branch2_aliases = @aliases
|
88
|
+
|
89
|
+
@aliases = merge_aliases(branch1_aliases, branch2_aliases) do |orig_var|
|
90
|
+
# Conflict found: `orig_var` renamed in both branches
|
91
|
+
name1 = branch1_aliases[orig_var]
|
92
|
+
name2 = branch2_aliases[orig_var]
|
93
|
+
|
94
|
+
resolved_name = new_ssa_var_name(orig_var)
|
95
|
+
|
96
|
+
if not node.true_body_stmts.is_a?(BeginNode)
|
97
|
+
raise AssertionError.new("Expected a BeginNode")
|
98
|
+
end
|
99
|
+
|
100
|
+
if not node.false_body_stmts.is_a?(BeginNode)
|
101
|
+
raise AssertionError.new("Expected a BeginNode")
|
102
|
+
end
|
103
|
+
|
104
|
+
# TODO: Should check liveness of variables
|
105
|
+
node.true_body_stmts.add_statement(LVarWriteNode.new(
|
106
|
+
identifier: resolved_name, value: LVarReadNode.new(identifier: name1)))
|
107
|
+
node.false_body_stmts.add_statement(LVarWriteNode.new(
|
108
|
+
identifier: resolved_name, value: LVarReadNode.new(identifier: name2)))
|
109
|
+
|
110
|
+
resolved_name
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# TODO: Handle `TernaryNode`
|
115
|
+
|
116
|
+
def visit_for_node(node)
|
117
|
+
node.range_from.accept(self)
|
118
|
+
node.range_to.accept(self)
|
119
|
+
|
120
|
+
before_loop_aliases = @aliases.dup
|
121
|
+
|
122
|
+
node.body_stmts.accept(self)
|
123
|
+
loop_body_aliases = @aliases.dup
|
124
|
+
|
125
|
+
# Insert merge statements at the end of the loop body
|
126
|
+
@aliases = merge_aliases(before_loop_aliases, loop_body_aliases) do |orig_var|
|
127
|
+
# Conflict found
|
128
|
+
name_before = before_loop_aliases[orig_var]
|
129
|
+
name_inside = loop_body_aliases[orig_var]
|
130
|
+
|
131
|
+
if name_before != nil
|
132
|
+
resolved_name = name_before
|
133
|
+
|
134
|
+
node.body_stmts.add_statement(LVarWriteNode.new(
|
135
|
+
identifier: name_before,
|
136
|
+
value: LVarReadNode.new(identifier: name_inside)))
|
137
|
+
else
|
138
|
+
resolved_name = name_inside
|
139
|
+
end
|
140
|
+
|
141
|
+
# Resolved name is `name_before`
|
142
|
+
resolved_name
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def process_while_until_node(node)
|
147
|
+
node.condition.accept(self)
|
148
|
+
|
149
|
+
before_loop_aliases = @aliases.dup
|
150
|
+
|
151
|
+
node.body_stmts.accept(self)
|
152
|
+
loop_body_aliases = @aliases.dup
|
153
|
+
|
154
|
+
# Insert merge statements at the end of the loop body
|
155
|
+
@aliases = merge_aliases(before_loop_aliases, loop_body_aliases) do |orig_var|
|
156
|
+
# Conflict found
|
157
|
+
name_before = before_loop_aliases[orig_var]
|
158
|
+
name_inside = loop_body_aliases[orig_var]
|
159
|
+
|
160
|
+
if name_before != nil
|
161
|
+
resolved_name = name_before
|
162
|
+
|
163
|
+
node.body_stmts.add_statement(LVarWriteNode.new(
|
164
|
+
identifier: name_before,
|
165
|
+
value: LVarReadNode.new(identifier: name_inside)))
|
166
|
+
else
|
167
|
+
resolved_name = name_inside
|
168
|
+
end
|
169
|
+
|
170
|
+
# Resolved name is `name_before`
|
171
|
+
resolved_name
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def visit_while_node(node)
|
176
|
+
process_while_until_node(node)
|
177
|
+
end
|
178
|
+
|
179
|
+
def visit_until_node(node)
|
180
|
+
process_while_until_node(node)
|
181
|
+
end
|
182
|
+
|
183
|
+
def visit_while_post_node(node)
|
184
|
+
process_while_until_node(node)
|
185
|
+
end
|
186
|
+
|
187
|
+
def visit_until_post_node(node)
|
188
|
+
process_while_until_node(node)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
data/lib/ast/visitor.rb
CHANGED
@@ -4,13 +4,39 @@ module Ikra
|
|
4
4
|
module AST
|
5
5
|
class Node
|
6
6
|
def accept(visitor)
|
7
|
-
visitor.visit_node(self)
|
7
|
+
return visitor.visit_node(self)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
class
|
11
|
+
class ProgramNode
|
12
12
|
def accept(visitor)
|
13
|
-
visitor
|
13
|
+
def accept(visitor)
|
14
|
+
return visitor.visit_program_node(self)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ClassDefNode
|
20
|
+
def accept(visitor)
|
21
|
+
return visitor.visit_class_def_node(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class VarDefNode
|
26
|
+
def accept(visitor)
|
27
|
+
return visitor.visit_var_def_node(self)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class MethDefNode
|
32
|
+
def accept(visitor)
|
33
|
+
return visitor.visit_meth_def_node(self)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class BlockDefNode
|
38
|
+
def accept(visitor)
|
39
|
+
return visitor.visit_block_def_node(self)
|
14
40
|
end
|
15
41
|
end
|
16
42
|
|
@@ -20,6 +46,30 @@ module Ikra
|
|
20
46
|
end
|
21
47
|
end
|
22
48
|
|
49
|
+
class ArrayNode
|
50
|
+
def accept(visitor)
|
51
|
+
visitor.visit_array_node(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class SourceCodeExprNode
|
56
|
+
def accept(visitor)
|
57
|
+
visitor.visit_source_code_expr_node(self)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class HashNode
|
62
|
+
def accept(visitor)
|
63
|
+
visitor.visit_hash_node(self)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class ConstNode
|
68
|
+
def accept(visitor)
|
69
|
+
visitor.visit_const_node(self)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
23
73
|
class LVarReadNode
|
24
74
|
def accept(visitor)
|
25
75
|
visitor.visit_lvar_read_node(self)
|
@@ -38,57 +88,105 @@ module Ikra
|
|
38
88
|
end
|
39
89
|
end
|
40
90
|
|
41
|
-
class
|
91
|
+
class IntLiteralNode
|
42
92
|
def accept(visitor)
|
43
93
|
visitor.visit_int_node(self)
|
44
94
|
end
|
45
95
|
end
|
46
96
|
|
47
|
-
class
|
97
|
+
class FloatLiteralNode
|
48
98
|
def accept(visitor)
|
49
99
|
visitor.visit_float_node(self)
|
50
100
|
end
|
51
101
|
end
|
52
102
|
|
53
|
-
class
|
103
|
+
class BoolLiteralNode
|
54
104
|
def accept(visitor)
|
55
105
|
visitor.visit_bool_node(self)
|
56
106
|
end
|
57
107
|
end
|
58
108
|
|
109
|
+
class NilLiteralNode
|
110
|
+
def accept(visitor)
|
111
|
+
visitor.visit_nil_node(self)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class SymbolLiteralNode
|
116
|
+
def accept(visitor)
|
117
|
+
visitor.visit_symbol_node(self)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class StringLiteralNode
|
122
|
+
def accept(visitor)
|
123
|
+
visitor.visit_string_node(self)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
59
127
|
class ForNode
|
60
128
|
def accept(visitor)
|
61
129
|
visitor.visit_for_node(self)
|
62
130
|
end
|
63
131
|
end
|
64
132
|
|
133
|
+
class WhileNode
|
134
|
+
def accept(visitor)
|
135
|
+
return visitor.visit_while_node(self)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class WhilePostNode
|
140
|
+
def accept(visitor)
|
141
|
+
return visitor.visit_while_post_node(self)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class UntilNode
|
146
|
+
def accept(visitor)
|
147
|
+
return visitor.visit_until_node(self)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class UntilPostNode
|
152
|
+
def accept(visitor)
|
153
|
+
return visitor.visit_until_post_node(self)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
65
157
|
class BreakNode
|
66
158
|
def accept(visitor)
|
67
|
-
visitor.visit_break_node(self)
|
159
|
+
return visitor.visit_break_node(self)
|
68
160
|
end
|
69
161
|
end
|
70
162
|
|
71
163
|
class IfNode
|
72
164
|
def accept(visitor)
|
73
|
-
visitor.visit_if_node(self)
|
165
|
+
return visitor.visit_if_node(self)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class TernaryNode
|
170
|
+
def accept(visitor)
|
171
|
+
return visitor.visit_ternary_node(self)
|
74
172
|
end
|
75
173
|
end
|
76
174
|
|
77
175
|
class BeginNode
|
78
176
|
def accept(visitor)
|
79
|
-
visitor.visit_begin_node(self)
|
177
|
+
return visitor.visit_begin_node(self)
|
80
178
|
end
|
81
179
|
end
|
82
180
|
|
83
181
|
class SendNode
|
84
182
|
def accept(visitor)
|
85
|
-
visitor.visit_send_node(self)
|
183
|
+
return visitor.visit_send_node(self)
|
86
184
|
end
|
87
185
|
end
|
88
186
|
|
89
187
|
class ReturnNode
|
90
188
|
def accept(visitor)
|
91
|
-
visitor.visit_return_node(self)
|
189
|
+
return visitor.visit_return_node(self)
|
92
190
|
end
|
93
191
|
end
|
94
192
|
|
@@ -97,64 +195,179 @@ module Ikra
|
|
97
195
|
|
98
196
|
end
|
99
197
|
|
100
|
-
def
|
198
|
+
def visit_program_node(node)
|
199
|
+
visit_node(node)
|
200
|
+
|
201
|
+
node.classes.each do |c|
|
202
|
+
c.accept(self)
|
203
|
+
end
|
101
204
|
|
205
|
+
node.blocks.each do |b|
|
206
|
+
b.accept(self)
|
207
|
+
end
|
102
208
|
end
|
103
|
-
|
209
|
+
|
210
|
+
def visit_class_def_node(node)
|
211
|
+
visit_node(node)
|
212
|
+
|
213
|
+
node.instance_variables.each do |iv|
|
214
|
+
iv.accept(self)
|
215
|
+
end
|
216
|
+
|
217
|
+
node.instance_methods.each do |im|
|
218
|
+
im.accept(self)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
104
222
|
def visit_root_node(node)
|
105
|
-
node
|
223
|
+
visit_node(node)
|
224
|
+
node.single_child.accept(self)
|
225
|
+
end
|
226
|
+
|
227
|
+
def visit_array_node(node)
|
228
|
+
visit_node(node)
|
229
|
+
|
230
|
+
for value in node.values
|
231
|
+
value.accept(self)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def visit_source_code_expr_node(node)
|
236
|
+
visit_node(node)
|
237
|
+
end
|
238
|
+
|
239
|
+
def visit_hash_node(node)
|
240
|
+
visit_node(node)
|
241
|
+
|
242
|
+
node.hash.each do |key, value|
|
243
|
+
key.accept(self)
|
244
|
+
value.accept(self)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def visit_var_def_node(node)
|
249
|
+
visit_node(node)
|
250
|
+
end
|
251
|
+
|
252
|
+
def visit_meth_def_node(node)
|
253
|
+
visit_node(node)
|
254
|
+
node.body.accept(self)
|
255
|
+
end
|
256
|
+
|
257
|
+
def visit_block_def_node(node)
|
258
|
+
visit_node(node)
|
259
|
+
node.body.accept(self)
|
260
|
+
end
|
261
|
+
|
262
|
+
def visit_const_node(node)
|
263
|
+
visit_node(node)
|
106
264
|
end
|
107
265
|
|
108
266
|
def visit_lvar_read_node(node)
|
109
|
-
|
267
|
+
visit_node(node)
|
110
268
|
end
|
111
269
|
|
112
270
|
def visit_lvar_write_node(node)
|
271
|
+
visit_node(node)
|
113
272
|
node.value.accept(self)
|
114
273
|
end
|
115
274
|
|
116
275
|
def visit_ivar_read_node(node)
|
117
|
-
|
276
|
+
visit_node(node)
|
118
277
|
end
|
119
278
|
|
120
279
|
def visit_int_node(node)
|
121
|
-
|
280
|
+
visit_node(node)
|
122
281
|
end
|
123
282
|
|
124
283
|
def visit_float_node(node)
|
284
|
+
visit_node(node)
|
125
285
|
|
126
286
|
end
|
127
287
|
|
128
288
|
def visit_bool_node(node)
|
289
|
+
visit_node(node)
|
290
|
+
end
|
129
291
|
|
292
|
+
def visit_nil_node(node)
|
293
|
+
visit_node(node)
|
130
294
|
end
|
131
295
|
|
296
|
+
def visit_symbol_node(node)
|
297
|
+
visit_node(node)
|
298
|
+
end
|
299
|
+
|
300
|
+
def visit_string_node(node)
|
301
|
+
visit_node(node)
|
302
|
+
end
|
303
|
+
|
132
304
|
def visit_for_node(node)
|
305
|
+
visit_node(node)
|
306
|
+
|
133
307
|
node.range_from.accept(self)
|
134
308
|
node.range_to.accept(self)
|
135
309
|
node.body_stmts.accept(self)
|
136
310
|
end
|
137
311
|
|
138
|
-
def
|
312
|
+
def visit_while_node(node)
|
313
|
+
visit_node(node)
|
314
|
+
|
315
|
+
node.condition.accept(self)
|
316
|
+
node.body_stmts.accept(self)
|
317
|
+
end
|
318
|
+
|
319
|
+
def visit_while_post_node(node)
|
320
|
+
visit_node(node)
|
321
|
+
|
322
|
+
node.condition.accept(self)
|
323
|
+
node.body_stmts.accept(self)
|
324
|
+
end
|
325
|
+
|
326
|
+
def visit_until_node(node)
|
327
|
+
visit_node(node)
|
328
|
+
|
329
|
+
node.condition.accept(self)
|
330
|
+
node.body_stmts.accept(self)
|
331
|
+
end
|
139
332
|
|
333
|
+
def visit_until_post_node(node)
|
334
|
+
visit_node(node)
|
335
|
+
|
336
|
+
node.condition.accept(self)
|
337
|
+
node.body_stmts.accept(self)
|
338
|
+
end
|
339
|
+
|
340
|
+
def visit_break_node(node)
|
341
|
+
visit_node(node)
|
140
342
|
end
|
141
343
|
|
142
344
|
def visit_if_node(node)
|
345
|
+
visit_node(node)
|
346
|
+
|
143
347
|
node.condition.accept(self)
|
144
348
|
node.true_body_stmts.accept(self)
|
349
|
+
node.false_body_stmts.accept(self)
|
350
|
+
end
|
351
|
+
|
352
|
+
def visit_ternary_node(node)
|
353
|
+
visit_node(node)
|
145
354
|
|
146
|
-
|
147
|
-
|
148
|
-
|
355
|
+
node.condition.accept(self)
|
356
|
+
node.true_val.accept(self)
|
357
|
+
node.false_val.accept(self)
|
149
358
|
end
|
150
359
|
|
151
360
|
def visit_begin_node(node)
|
361
|
+
visit_node(node)
|
362
|
+
|
152
363
|
node.body_stmts.each do |stmt|
|
153
364
|
stmt.accept(self)
|
154
365
|
end
|
155
366
|
end
|
156
367
|
|
157
368
|
def visit_send_node(node)
|
369
|
+
visit_node(node)
|
370
|
+
|
158
371
|
# Receiver might be nil for self sends
|
159
372
|
if node.receiver != nil
|
160
373
|
node.receiver.accept(self)
|
@@ -166,6 +379,7 @@ module Ikra
|
|
166
379
|
end
|
167
380
|
|
168
381
|
def visit_return_node(node)
|
382
|
+
visit_node(node)
|
169
383
|
node.value.accept(self)
|
170
384
|
end
|
171
385
|
end
|