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

MUST_BE_CURLY

Public Instance Methods

__var(name) click to toggle source
# File lib/ruby2ruby.rb, line 377
def __var name
  case context[1]
  when /_pat$/ then
    "^#{name}"
  when :in then
    "^#{name}"
  else
    name.to_s
  end
end
cond_loop(exp, name) click to toggle source

Generate a post-or-pre conditional loop.

# File lib/ruby2ruby.rb, line 1313
def cond_loop(exp, name)
  _, cond, body, head_controlled = exp

  cond = process cond
  body = process body

  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 1338
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
indent(s) click to toggle source

Indent all lines of s to the current indent level.

# File lib/ruby2ruby.rb, line 1355
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 1362
def parenthesize exp
  case context[1]
  when nil, :defn, :defs, :class, :sclass, :if, :iter, :resbody, :when, :while then
    exp
  else
    "(#{exp})"
  end
end
process_forward_args(exp) click to toggle source
# File lib/ruby2ruby.rb, line 547
def process_forward_args exp
  "..."
end
process_kwsplat(exp) click to toggle source
# File lib/ruby2ruby.rb, line 796
def process_kwsplat(exp)
  _, kw = exp
  "**#{process kw}"
end
re_opt(options) click to toggle source

Return the appropriate regexp flags for a given numeric code.

# File lib/ruby2ruby.rb, line 1374
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 1383
def splat(sym)
  :"*#{sym}"
end
util_dthing(type, exp) click to toggle source

Utility method to generate something interpolated.

# File lib/ruby2ruby.rb, line 1390
def util_dthing(type, exp)
  _, str, *rest = exp

  # first item in sexp is a string literal
  str = dthing_escape(type, str)

  rest = rest.map { |pt|
    case pt.sexp_type
    when :str then
      dthing_escape(type, pt.last)
    when :evstr then
      '#{%s}' % [process(pt)]
    else
      raise "unknown type: #{pt.inspect}"
    end
  }

  [str, rest].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 1413
def util_module_or_class exp, is_class = false
  result = []

  _, name, *body = exp
  superk = body.shift if is_class

  name = process name if Sexp === name

  result << name

  if superk then
    superk = process superk
    result << " < #{superk}" if superk
  end

  result << "\n"

  body = body.map { |sexp|
    process(sexp).chomp
  }

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

  result << body
  result << "end"

  result.join
end