ikra 0.0.1 → 0.0.2
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 +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
|