class Ruby2Ruby

Generate ruby code from a sexp.

Constants

ASSIGN_NODES

Nodes that represent assignment and probably need () around them.

TODO: this should be replaced with full precedence support :/

BINARY

binary operation messages

HASH_VAL_NO_PAREN

Some sexp types are OK without parens when appearing as hash values. This list can include `:call`s because they're always printed with parens around their arguments. For example:

{ :foo => (bar("baz")) } # The outer parens are unnecessary
{ :foo => bar("baz") }   # This is the normal code style
LINE_LENGTH

cutoff for one-liners

Public Instance Methods

cond_loop(exp, name) click to toggle source

Generate a post-or-pre conditional loop.

# File lib/ruby2ruby.rb, line 1050
def cond_loop(exp, name)
  cond = process(exp.shift)
  body = process(exp.shift)
  head_controlled = exp.shift

  body = indent(body).chomp if body

  code = []
  if head_controlled then
    code << "#{name} #{cond} do"
    code << body if body
    code << "end"
  else
    code << "begin"
    code << body if body
    code << "end #{name} #{cond}"
  end
  code.join("\n")
end
dthing_escape(type, lit) click to toggle source

Utility method to escape something interpolated.

# File lib/ruby2ruby.rb, line 1073
def dthing_escape type, lit
  # TODO: this needs more testing
  case type
  when :dregx then
    lit.gsub(/(\A|[^\])\//, '\1\/')
  when :dstr, :dsym then
    lit.dump[1..-2]
  when :dxstr then
    lit.gsub(/`/, '\`')
  else
    raise "unsupported type #{type.inspect}"
  end
end
finish(exp) click to toggle source

Process all the remaining stuff in exp and return the results sans-nils.

# File lib/ruby2ruby.rb, line 1091
def finish exp # REFACTOR: work this out of the rest of the processors
  body = []
  until exp.empty? do
    body << process(exp.shift)
  end
  body.compact
end
indent(s) click to toggle source

Indent all lines of s to the current indent level.

# File lib/ruby2ruby.rb, line 1102
def indent(s)
  s.to_s.split(/\n/).map{|line| @indent + line}.join("\n")
end
parenthesize(exp) click to toggle source

Wrap appropriate expressions in matching parens.

# File lib/ruby2ruby.rb, line 1109
def parenthesize exp
  case self.context[1]
  when nil, :defn, :defs, :class, :sclass, :if, :iter, :resbody, :when, :while then
    exp
  else
    "(#{exp})"
  end
end
process_kwsplat(exp) click to toggle source
# File lib/ruby2ruby.rb, line 630
def process_kwsplat(exp)
  "**#{process exp.shift}"
end
re_opt(options) click to toggle source

Return the appropriate regexp flags for a given numeric code.

# File lib/ruby2ruby.rb, line 1121
def re_opt options
  bits = (0..8).map { |n| options[n] * 2**n }
  bits.delete 0
  bits.map { |n| Regexp::CODES[n] }.join
end
splat(sym) click to toggle source

Return a splatted symbol for sym.

# File lib/ruby2ruby.rb, line 1130
def splat(sym)
  :"*#{sym}"
end
util_dthing(type, exp) click to toggle source

Utility method to generate something interpolated.

# File lib/ruby2ruby.rb, line 1137
def util_dthing(type, exp)
  s = []

  # first item in sexp is a string literal
  s << dthing_escape(type, exp.shift)

  until exp.empty?
    pt = exp.shift
    case pt
    when Sexp then
      case pt.first
      when :str then
        s << dthing_escape(type, pt.last)
      when :evstr then
        s << '#{' << process(pt) << '}' # do not use interpolation here
      else
        raise "unknown type: #{pt.inspect}"
      end
    else
      raise "unhandled value in d-thing: #{pt.inspect}"
    end
  end

  s.join
end
util_module_or_class(exp, is_class=false) click to toggle source

Utility method to generate ether a module or class.

# File lib/ruby2ruby.rb, line 1166
def util_module_or_class(exp, is_class=false)
  result = []

  name = exp.shift
  name = process name if Sexp === name

  result << name

  if is_class then
    superk = process(exp.shift)
    result << " < #{superk}" if superk
  end

  result << "\n"

  body = []
  begin
    code = process(exp.shift) unless exp.empty?
    body << code.chomp unless code.nil? or code.chomp.empty?
  end until exp.empty?

  unless body.empty? then
    body = indent(body.join("\n\n")) + "\n"
  else
    body = ""
  end
  result << body
  result << "end"

  result.join
end