Class: SyntaxTree::YARV::Compiler::RubyVisitor
Overview
This visitor is responsible for converting Syntax Tree nodes into their corresponding Ruby structures. This is used to convert the operands of some instructions like putobject that push a Ruby object directly onto the stack. It is only used when the entire structure can be represented at compile-time, as opposed to constructed at run-time.
Defined Under Namespace
Classes: CompilationError
Class Method Summary
collapse
Instance Method Summary
collapse
#visit, #visit_all, #visit_child_nodes, visit_method, visit_methods
Class Method Details
.compile(node) ⇒ Object
This will attempt to compile the given node. If it’s possible, then it will return the compiled object. Otherwise it will return nil.
122
123
124
125
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 122
def self.compile(node)
node.accept(new)
rescue CompilationError
end
|
Instance Method Details
#visit_array(node) ⇒ Object
127
128
129
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 127
def visit_array(node)
node.contents ? visit_all(node.contents.parts) : []
end
|
#visit_bare_assoc_hash(node) ⇒ Object
Also known as:
visit_hash
131
132
133
134
135
136
137
138
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 131
def visit_bare_assoc_hash(node)
node.assocs.to_h do |assoc|
raise CompilationError unless assoc.is_a?(Assoc)
[visit(assoc.key), visit(assoc.value)]
end
end
|
#visit_float(node) ⇒ Object
140
141
142
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 140
def visit_float(node)
node.value.to_f
end
|
#visit_imaginary(node) ⇒ Object
146
147
148
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 146
def visit_imaginary(node)
node.value.to_c
end
|
#visit_int(node) ⇒ Object
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 150
def visit_int(node)
case (value = node.value)
when /^0b/
value[2..].to_i(2)
when /^0o/
value[2..].to_i(8)
when /^0d/
value[2..].to_i
when /^0x/
value[2..].to_i(16)
else
value.to_i
end
end
|
#visit_label(node) ⇒ Object
165
166
167
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 165
def visit_label(node)
node.value.chomp(":").to_sym
end
|
#visit_mrhs(node) ⇒ Object
169
170
171
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 169
def visit_mrhs(node)
visit_all(node.parts)
end
|
#visit_qsymbols(node) ⇒ Object
173
174
175
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 173
def visit_qsymbols(node)
node.elements.map { |element| visit(element).to_sym }
end
|
#visit_qwords(node) ⇒ Object
177
178
179
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 177
def visit_qwords(node)
visit_all(node.elements)
end
|
#visit_range(node) ⇒ Object
181
182
183
184
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 181
def visit_range(node)
left, right = [visit(node.left), visit(node.right)]
node.operator.value === ".." ? left..right : left...right
end
|
#visit_rational(node) ⇒ Object
186
187
188
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 186
def visit_rational(node)
node.value.to_r
end
|
#visit_regexp_literal(node) ⇒ Object
190
191
192
193
194
195
196
197
198
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 190
def visit_regexp_literal(node)
if node.parts.length == 1 && node.parts.first.is_a?(TStringContent)
Regexp.new(node.parts.first.value, visit_regexp_literal_flags(node))
else
raise CompilationError
end
end
|
#visit_regexp_literal_flags(node) ⇒ Object
This isn’t actually a visit method, though maybe it should be. It is responsible for converting the set of string options on a regular expression into its equivalent integer.
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 203
def visit_regexp_literal_flags(node)
node
.options
.chars
.inject(0) do |accum, option|
accum |
case option
when "i"
Regexp::IGNORECASE
when "x"
Regexp::EXTENDED
when "m"
Regexp::MULTILINE
else
raise "Unknown regexp option: #{option}"
end
end
end
|
#visit_symbol_literal(node) ⇒ Object
222
223
224
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 222
def visit_symbol_literal(node)
node.value.value.to_sym
end
|
#visit_symbols(node) ⇒ Object
226
227
228
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 226
def visit_symbols(node)
node.elements.map { |element| visit(element).to_sym }
end
|
#visit_tstring_content(node) ⇒ Object
230
231
232
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 230
def visit_tstring_content(node)
node.value
end
|
#visit_unsupported(_node) ⇒ Object
263
264
265
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 263
def visit_unsupported(_node)
raise CompilationError
end
|
#visit_var_ref(node) ⇒ Object
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 234
def visit_var_ref(node)
raise CompilationError unless node.value.is_a?(Kw)
case node.value.value
when "nil"
nil
when "true"
true
when "false"
false
else
raise CompilationError
end
end
|
#visit_word(node) ⇒ Object
249
250
251
252
253
254
255
256
257
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 249
def visit_word(node)
if node.parts.length == 1 && node.parts.first.is_a?(TStringContent)
node.parts.first.value
else
raise CompilationError
end
end
|
#visit_words(node) ⇒ Object
259
260
261
|
# File 'lib/syntax_tree/yarv/compiler.rb', line 259
def visit_words(node)
visit_all(node.elements)
end
|