ikra 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ast/builder.rb +225 -77
  3. data/lib/ast/host_section_builder.rb +38 -0
  4. data/lib/ast/interpreter.rb +67 -0
  5. data/lib/ast/lexical_variables_enumerator.rb +3 -2
  6. data/lib/ast/nodes.rb +521 -31
  7. data/lib/ast/printer.rb +116 -18
  8. data/lib/ast/ssa_generator.rb +192 -0
  9. data/lib/ast/visitor.rb +235 -21
  10. data/lib/config/configuration.rb +28 -3
  11. data/lib/config/os_configuration.rb +62 -9
  12. data/lib/cpu/cpu_implementation.rb +39 -0
  13. data/lib/ikra.rb +13 -3
  14. data/lib/resources/cuda/allocate_device_memory.cpp +5 -0
  15. data/lib/resources/cuda/allocate_host_memory.cpp +1 -0
  16. data/lib/resources/cuda/allocate_memcpy_environment_to_device.cpp +11 -0
  17. data/lib/resources/cuda/ast/assignment.cpp +1 -0
  18. data/lib/resources/cuda/block_function_head.cpp +7 -1
  19. data/lib/resources/cuda/entry_point.cpp +47 -0
  20. data/lib/resources/cuda/env_builder_copy_array.cpp +8 -2
  21. data/lib/resources/cuda/free_device_memory.cpp +3 -0
  22. data/lib/resources/cuda/free_memory_for_command.cpp +24 -0
  23. data/lib/resources/cuda/header.cpp +23 -9
  24. data/lib/resources/cuda/header_structs.cpp +92 -0
  25. data/lib/resources/cuda/host_section_block_function_head.cpp +12 -0
  26. data/lib/resources/cuda/host_section_entry_point.cpp +55 -0
  27. data/lib/resources/cuda/host_section_free_device_memory.cpp +18 -0
  28. data/lib/resources/cuda/host_section_launch_parallel_section.cpp +14 -0
  29. data/lib/resources/cuda/host_section_malloc_memcpy_device_to_host.cpp +10 -0
  30. data/lib/resources/cuda/kernel.cpp +9 -2
  31. data/lib/resources/cuda/launch_kernel.cpp +5 -0
  32. data/lib/resources/cuda/memcpy_device_to_host.cpp +3 -0
  33. data/lib/resources/cuda/memcpy_device_to_host_expr.cpp +10 -0
  34. data/lib/resources/cuda/reduce_body.cpp +88 -0
  35. data/lib/resources/cuda/stencil_array_reconstruction.cpp +2 -0
  36. data/lib/resources/cuda/stencil_body.cpp +16 -0
  37. data/lib/resources/cuda/struct_definition.cpp +4 -0
  38. data/lib/ruby_core/array.rb +34 -0
  39. data/lib/ruby_core/array_command.rb +313 -0
  40. data/lib/ruby_core/core.rb +103 -0
  41. data/lib/ruby_core/interpreter.rb +16 -0
  42. data/lib/ruby_core/math.rb +32 -0
  43. data/lib/ruby_core/ruby_integration.rb +256 -0
  44. data/lib/symbolic/host_section.rb +115 -0
  45. data/lib/symbolic/input.rb +87 -0
  46. data/lib/symbolic/input_visitor.rb +68 -0
  47. data/lib/symbolic/symbolic.rb +793 -117
  48. data/lib/symbolic/visitor.rb +70 -8
  49. data/lib/translator/array_command_struct_builder.rb +163 -0
  50. data/lib/translator/ast_translator.rb +572 -0
  51. data/lib/translator/block_translator.rb +104 -48
  52. data/lib/translator/commands/array_combine_command.rb +41 -0
  53. data/lib/translator/commands/array_identity_command.rb +28 -0
  54. data/lib/translator/commands/array_index_command.rb +52 -0
  55. data/lib/translator/commands/array_reduce_command.rb +135 -0
  56. data/lib/translator/commands/array_stencil_command.rb +129 -0
  57. data/lib/translator/commands/array_zip_command.rb +30 -0
  58. data/lib/translator/commands/command_translator.rb +264 -0
  59. data/lib/translator/cuda_errors.rb +32 -0
  60. data/lib/translator/environment_builder.rb +263 -0
  61. data/lib/translator/host_section/array_host_section_command.rb +150 -0
  62. data/lib/translator/host_section/array_in_host_section_command.rb +41 -0
  63. data/lib/translator/host_section/ast_translator.rb +14 -0
  64. data/lib/translator/host_section/parallel_section_invocation_visitor.rb +20 -0
  65. data/lib/translator/host_section/program_builder.rb +89 -0
  66. data/lib/translator/input_translator.rb +226 -0
  67. data/lib/translator/kernel_builder.rb +137 -0
  68. data/lib/translator/kernel_launcher/for_loop_kernel_launcher.rb +40 -0
  69. data/lib/translator/kernel_launcher/kernel_launcher.rb +259 -0
  70. data/lib/translator/kernel_launcher/while_loop_kernel_launcher.rb +38 -0
  71. data/lib/translator/last_returns_visitor.rb +19 -10
  72. data/lib/translator/program_builder.rb +197 -0
  73. data/lib/translator/program_launcher.rb +273 -0
  74. data/lib/translator/struct_type.rb +55 -0
  75. data/lib/translator/translator.rb +34 -11
  76. data/lib/translator/variable_classifier_visitor.rb +56 -0
  77. data/lib/types/inference/ast_inference.rb +586 -0
  78. data/lib/types/inference/clear_types_visitor.rb +11 -0
  79. data/lib/types/inference/command_inference.rb +101 -0
  80. data/lib/types/inference/input_inference.rb +62 -0
  81. data/lib/types/{object_tracer.rb → inference/object_tracer.rb} +5 -6
  82. data/lib/types/inference/ruby_extension.rb +35 -0
  83. data/lib/types/inference/symbol_table.rb +131 -0
  84. data/lib/types/types.rb +14 -0
  85. data/lib/types/types/array_command_type.rb +123 -0
  86. data/lib/types/types/array_type.rb +137 -0
  87. data/lib/types/{class_type.rb → types/class_type.rb} +42 -18
  88. data/lib/types/{primitive_type.rb → types/primitive_type.rb} +20 -7
  89. data/lib/types/types/ruby_type.rb +88 -0
  90. data/lib/types/types/struct_type.rb +179 -0
  91. data/lib/types/types/union_type.rb +239 -0
  92. metadata +160 -18
  93. data/lib/ast/method_definition.rb +0 -37
  94. data/lib/ast/translator.rb +0 -264
  95. data/lib/resources/cuda/kernel_launcher.cpp +0 -28
  96. data/lib/scope.rb +0 -166
  97. data/lib/translator/command_translator.rb +0 -421
  98. data/lib/translator/local_variables_enumerator.rb +0 -35
  99. data/lib/translator/method_translator.rb +0 -24
  100. data/lib/types/array_type.rb +0 -51
  101. data/lib/types/ruby_extension.rb +0 -67
  102. data/lib/types/ruby_type.rb +0 -45
  103. data/lib/types/type_inference.rb +0 -382
  104. data/lib/types/union_type.rb +0 -155
@@ -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: #{child.to_s}]"
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 IntNode
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 FloatNode
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 BoolNode
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
@@ -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 ConstNode
11
+ class ProgramNode
12
12
  def accept(visitor)
13
- visitor.visit_const_node(self)
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 IntNode
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 FloatNode
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 BoolNode
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 visit_const_node(node)
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.child.accept(self)
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 visit_break_node(node)
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
- if node.false_body_stmts != nil
147
- node.false_body_stmts.accept(self)
148
- end
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