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.
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