Skip to content

Instantly share code, notes, and snippets.

@hosiawak
Created June 30, 2011 18:48
Show Gist options
  • Save hosiawak/1056900 to your computer and use it in GitHub Desktop.
Save hosiawak/1056900 to your computer and use it in GitHub Desktop.
def factorial(n, product)
if n == 0
product
else
recur(n - 1, n * product)
end
end
puts factorial(10_000)
module Rubinius
module AST
class BeginningLabel < Rubinius::Generator::Label
def initialize(generator)
super
@position = calc_start_pos(generator)
@basic_block = generator.new_basic_block
@generator.current_block.left = @basic_block
@generator.current_block.close
@generator.current_block = @basic_block
@basic_block.open
end
def calc_start_pos(g)
diff = g.total_args - g.required_args
# some arguments are default
# move the position pointer
diff * 8
end
end
class Recur < Node
def initialize(line, arguments)
@line = line
@arguments = arguments
end
def bytecode(g)
# insert label at the beginning of the method
@arguments.body.each_with_index do |arg,idx|
# push each argument result to the stack
g.execute(arg)
end
# pop the values and rebind to vars in reverse order
(@arguments.body.size-1).downto(0) do |idx|
g.set_local idx
g.pop
end
g.goto BeginningLabel.new(g)
end
end
end
end
module Macros
module Recur
def process_fcall(line, name, arguments)
if name == :recur
Rubinius::AST::Recur.new(line, arguments)
else
super
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment