class SyntaxTree::YARV::Compiler::RubyVisitor

at compile-time, as opposed to constructed at run-time.
the stack. It is only used when the entire structure can be represented
some instructions like putobject that push a Ruby object directly onto
corresponding Ruby structures. This is used to convert the operands of
This visitor is responsible for converting Syntax Tree nodes into their

def self.compile(node)

it will return the compiled object. Otherwise it will return nil.
This will attempt to compile the given node. If it's possible, then
def self.compile(node)
  node.accept(new)
rescue CompilationError
end

def visit_array(node)

def visit_array(node)
  node.contents ? visit_all(node.contents.parts) : []
end

def visit_bare_assoc_hash(node)

def visit_bare_assoc_hash(node)
  node.assocs.to_h do |assoc|
    # We can only convert regular key-value pairs. A double splat **
    # operator means it has to be converted at run-time.
    raise CompilationError unless assoc.is_a?(Assoc)
    [visit(assoc.key), visit(assoc.value)]
  end
end

def visit_float(node)

def visit_float(node)
  node.value.to_f
end

def visit_imaginary(node)

def visit_imaginary(node)
  node.value.to_c
end

def visit_int(node)

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

def visit_label(node)

def visit_label(node)
  node.value.chomp(":").to_sym
end

def visit_mrhs(node)

def visit_mrhs(node)
  visit_all(node.parts)
end

def visit_qsymbols(node)

def visit_qsymbols(node)
  node.elements.map { |element| visit(element).to_sym }
end

def visit_qwords(node)

def visit_qwords(node)
  visit_all(node.elements)
end

def visit_range(node)

def visit_range(node)
  left, right = [visit(node.left), visit(node.right)]
  node.operator.value === ".." ? left..right : left...right
end

def visit_rational(node)

def visit_rational(node)
  node.value.to_r
end

def visit_regexp_literal(node)

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
    # Any interpolation of expressions or variables will result in the
    # regular expression being constructed at run-time.
    raise CompilationError
  end
end

def visit_regexp_literal_flags(node)

expression into its equivalent integer.
responsible for converting the set of string options on a regular
This isn't actually a visit method, though maybe it should be. It is
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

def visit_symbol_literal(node)

def visit_symbol_literal(node)
  node.value.value.to_sym
end

def visit_symbols(node)

def visit_symbols(node)
  node.elements.map { |element| visit(element).to_sym }
end

def visit_tstring_content(node)

def visit_tstring_content(node)
  node.value
end

def visit_unsupported(_node)

def visit_unsupported(_node)
  raise CompilationError
end

def visit_var_ref(node)

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

def visit_word(node)

def visit_word(node)
  if node.parts.length == 1 && node.parts.first.is_a?(TStringContent)
    node.parts.first.value
  else
    # Any interpolation of expressions or variables will result in the
    # string being constructed at run-time.
    raise CompilationError
  end
end

def visit_words(node)

def visit_words(node)
  visit_all(node.elements)
end