Converting JavaScript to Ruby with RKelly

I've been working on a yet-to-be-released project called RKelly, which will parse JavaScript and return a parse tree suitable for passing to Ruby2Ruby. Ruby2Ruby will then give you back ruby code that you can eval.

I thought I would share a few examples of what I have working so far, and also write a bit about where I want to go.

I have most simple looping working. For example, a for loop:

require 'rkelly'
require 'ruby2ruby'

rkelly = RKelly.new
puts RubyToRuby.new().process(rkelly.process(DATA.read))
__END__
for(var i = 0; i < 10; i++) {
  alert('hello world');
}

Will produce:

begin
  i = 0
  while (i < 10) do
    alert("hello world")
    [i, i = (i + 1)].first
  end

end

You can even calculate the Fibonacci sequence:

require 'rkelly'
require 'ruby2ruby'

rkelly = RKelly.new
puts RubyToRuby.new().process(rkelly.process(DATA.read))
__END__
function fib(n) {
  var s = 0;
  if(n == 0) return(s);
  if(n == 1) {
    s += 1;
    return(s);
  } else {
    return(fib(n - 1) + fib(n - 2));
  }
}

Which produces:

def fib(n)
  s = 0
  return s if (n == 0)
  if (n == 1) then
    s = (s + 1)
    return s
  else
    return (fib((n - 1)) + fib((n - 2)))
  end
end

Why am I torturing myself like this? I want to add JavaScript support to Mechanize, and I think I can do that with RKelly. So far I have been able to use RKelly for simple DOM manipulation with a slightly modified copy of Mechanize. If you would like to see that in action, just find me at one of the Seattle Ruby Brigade meetings.

I've also added some simple object support, which you can see after the jump.

Here is an example of simple object support:

require 'rkelly'
require 'ruby2ruby'

class OpenStruct
  def alert(s)
    puts s
  end
end

rkelly = RKelly.new
puts RubyToRuby.new().process(rkelly.process(DATA.read))
__END__
function foo() {
  alert('I am awesome!');
}

function bar() {
  this.blah = foo;
}

var baz = new bar;
baz.blah();

Which will produce the following code:

class Bar < OpenStruct
  def initialize
    super()
    bar()
  end
 
  def bar
    class << self
      def blah()
      alert("I am awesome!")
      end
    end
  end
end
def foo
  alert("I am awesome!")
end
def bar
  class << self
    def blah()
    alert("I am awesome!")
    end
  end
end
baz = Bar.new
baz.blah()

Posted by Aaron PattersonPermalinkLeave your Comment »

4 Comments for “Converting JavaScript to Ruby with RKelly”

  1. Eric Hodel says:

    No rkelly.to_ruby?

    Monday, 16 April 2007 @ 2:45pm

  2. Aaron Patterson says:

    Not yet. I’ll add that! :-)

    Monday, 16 April 2007 @ 4:18pm

  3. jax says:

    Oh my God! I was just bra shopping and thinking how I needed simple object support, but opted to manipulate a slightly modified copy of a former bra. Baby got back rub-y. Genius.

    Wednesday, 18 April 2007 @ 6:56pm

  4. topfunky says:

    I once saw a comic that described a horrific future where we would program servers in Javascript.

    I would be careful, Aaron, because I’m sure some Terminator will be sent from the future to stop this from becoming a reality.

    Thursday, 19 April 2007 @ 3:39pm

Leave your Respond

Check Spelling
Activate Spell Check while Typing

RSS Feed for this EntryTrackBack URL