# At first, our table of futures is just an empty table.
$futures = ({})

# Let's give the user some instructions.
puts "Type `hello' to get your number, just like at the post office."
puts "Except you say `hello' instead of pressing a button."
puts "--------------------------------------------------------------"

# This function gets an unused ID.
def get_an_id
  # We can get a unique ID by just checking the size of $futures.
  $futures.size
end

def get_line_from(id)
  callcc { |future|
    $futures[id] = future
    throw :suspended
  }
end

while true
  print "Yes? "
  line = gets
  if line == "hello\n"
    # This user is new.  Give him an ID, and set up his future.
    id = get_an_id

    catch :suspended do
      puts "OK, I'll be calling you #{id}.  I want your name."
      puts "When you're ready, give it to me by typing `#{id}: John Doe'."
      name = get_line_from id
      puts "Thanks, #{id}."
      puts "Now, I'd like your address, too.  Give it to me in the same way."
      address = get_line_from id
      puts "Thanks again, #{id}."
      puts "I'll be sending a hitman to #{name} at #{address}."
      while true
        get_line_from id
        puts "I'm done with you.  Get out of here."
      end
    end

  elsif line =~ /^(.*?): (.*)$/
    # The user gave us something that looks like a response.
    id = $1.to_i
    response = $2
    if $futures.has_key? id
      # The ID the user gave has a future.  Go to that future.
      $futures[id].call response
    else
      # The ID doesn't have a future.  Confused user!
      puts "Huh?  Say hello first."
    end

  else
    # The user said something that doesn't make sense.
    puts "Eh?"
  end
end