module Heist
  class Runtime
    
    # The +Continuation+ class encapsulates the first-class continuations as
    # generated by the Scheme <tt>(call/cc)</tt> procedure. It inherits from
    # +Function+ so as to be recognised as a callable object by the +Stack+
    # execution model. Each +Continuation+ contains a snapshot of the state of
    # the +Stack+ at the moment it was created, and this state is restored,
    # overriding whatever state is then in effect, when the +Continuation+ is
    # called.
    class Continuation < Function

      # A +Continuation+ is initialized with a +Stack+ object, which it saves a
      # snapshot of. The topmost frame on the stack will typically be a call to
      # <tt>(call/cc)</tt> or some other +Continuation+-generating function, and
      # is thus discarded as this call site marks the hole that should be filled
      # when the +Continuation+ is called and the saved stack is resumed.
      def initialize(stack)
        @stack  = stack.copy(false)
        @target = stack.last.target
      end
      
      # Calls the +Continuation+ with the current +Scope+ and a +Cons+ list of
      # parameters to the continuation. Returns a copy of the saved +Stack+ with
      # the innermost hole filled with the value of the parameter to the
      # continuation call. The currently running +Stack+ will see this return
      # value as an instruction to throw out the current state of the stack and
      # replace it with the stack returned by this method before continuing
      # execution.
      def call(scope, cells)
        apply(cells.to_a)
      end
      
      # TODO support call-with-values
      def apply(params)
        stack = @stack.copy
        stack.fill!(@target, Value.new(params.first))
        stack
      end
      
      # Returns a string representation of the +Continuation+ for console output.
      def to_s
        "#<continuation>"
      end
      alias :inspect :to_s
    end
    
  end
end

