Converting JavaScript to Ruby with RKelly 4

Posted by Aaron Patterson on April 15, 2007

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()
Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. Eric Hodel Mon, 16 Apr 2007 14:45:02 PDT

    No rkelly.to_ruby?

  2. Aaron Patterson Mon, 16 Apr 2007 16:18:18 PDT

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

  3. jax Wed, 18 Apr 2007 18:56:59 PDT

    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.

  4. topfunky Thu, 19 Apr 2007 15:39:08 PDT

    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.

Comments

Check Spelling
Activate Spell Check while Typing