#!/usr/bin/ruby
# generator using continuations

class Generator
  def initialize
    do_generation
  end

  def next
    callcc { |here|
      @main_context = here;
      @generator_context.call
    }
  end

  private

  def do_generation
    callcc { |context|
      @generator_context = context;
      return
    }
    generating_loop
  end

  def generate(value)
    callcc { |context|
      @generator_context = context;
      @main_context.call(value)    
    }
  end
end

class FibGenerator < Generator
  def generating_loop
    generate(1)
    a, b = 1, 1
    loop do
      generate(b)
      a, b = b, a+b
    end
  end
end

fib = FibGenerator.new

puts fib.next # => 1
puts fib.next # => 1
puts fib.next # => 2
puts fib.next # => 3
puts fib.next # => 5
puts fib.next # => 8
