Inductive cont': Type :=
  | Kseq: statement -> cont'       (**r [Kseq s2 k] = after [s1] in [s1;s2] *)
  | Kloop1: statement -> statement -> cont'
  | Kloop2: statement -> statement  -> cont'
  | Kswitch: cont'       (**r catches [break] statements arising out of [switch] *)
  | Kcall: forall (l: option ident),                  (**r where to store result *)
           function ->                      (**r called (not calling!) function *)
           env ->                           (**r local env of calling function *)
           temp_env ->                      (**r temporary env of calling function *)
           cont'.Inductive cont': Type :=
  | Kseq: statement -> cont'       (**r [Kseq s2 k] = after [s1] in [s1;s2] *)
  | Kloop1: statement -> statement -> cont'
  | Kloop2: statement -> statement  -> cont'
  | Kswitch: cont'       (**r catches [break] statements arising out of [switch] *)
  | Kcall: forall (l: option ident),                  (**r where to store result *)
           function ->                      (**r called (not calling!) function *)
           env ->                           (**r local env of calling function *)
           temp_env ->                      (**r temporary env of calling function *)
           cont'.Inductive cont': Type :=
  | Kseq: statement -> cont'       (**r [Kseq s2 k] = after [s1] in [s1;s2] *)
  | Kloop1: statement -> statement -> cont'
  | Kloop2: statement -> statement  -> cont'
  | Kswitch: cont'       (**r catches [break] statements arising out of [switch] *)
  | Kcall: forall (l: option ident),                  (**r where to store result *)
           function ->                      (**r called (not calling!) function *)
           env ->                           (**r local env of calling function *)
           temp_env ->                      (**r temporary env of calling function *)
           cont'.Inductive cont': Type :=
  | Kseq: statement -> cont'       (**r [Kseq s2 k] = after [s1] in [s1;s2] *)
  | Kloop1: statement -> statement -> cont'
  | Kloop2: statement -> statement  -> cont'
  | Kswitch: cont'       (**r catches [break] statements arising out of [switch] *)
  | Kcall: forall (l: option ident),                  (**r where to store result *)
           function ->                      (**r called (not calling!) function *)
           env ->                           (**r local env of calling function *)
           temp_env ->                      (**r temporary env of calling function *)
           cont'.Inductive cont': Type :=
  | Kseq: statement -> cont'       (**r [Kseq s2 k] = after [s1] in [s1;s2] *)
  | Kloop1: statement -> statement -> cont'
  | Kloop2: statement -> statement  -> cont'
  | Kswitch: cont'       (**r catches [break] statements arising out of [switch] *)
  | Kcall: forall (l: option ident),                  (**r where to store result *)
           function ->                      (**r called (not calling!) function *)
           env ->                           (**r local env of calling function *)
           temp_env ->                      (**r temporary env of calling function *)
           cont'.Inductive cont': Type :=
  | Kseq: statement -> cont'       (**r [Kseq s2 k] = after [s1] in [s1;s2] *)
  | Kloop1: statement -> statement -> cont'
  | Kloop2: statement -> statement  -> cont'
  | Kswitch: cont'       (**r catches [break] statements arising out of [switch] *)
  | Kcall: forall (l: option ident),                  (**r where to store result *)
           function ->                      (**r called (not calling!) function *)
           env ->                           (**r local env of calling function *)
           temp_env ->                      (**r temporary env of calling function *)
           cont'.Definition cont := list cont'.(** Pop continuation until a call or stop *)

Fixpoint call_cont (k: cont) : cont :=
  match k with
  | Kseq s :: k => call_cont k
  | Kloop1 _ _ :: k => call_cont k
  | Kloop2 _ _ :: k => call_cont k
  | Kswitch :: k => call_cont k
  | _ => k
  end.Fixpoint current_function (k: cont) : option function :=
 match k with
  | Kseq s :: k => current_function k
  | Kloop1 _ _ :: k => current_function k
  | Kloop2 _ _:: k =>current_function k
  | Kswitch :: k => current_function k
  | Kcall _ f _ _ :: _ => Some f
  | _ => None
  end.Fixpoint continue_cont (k: cont) : cont :=
  match k with
  | Kseq s :: k' => continue_cont k'
  | Kloop1 s1 s2 :: k' => Kseq s2 :: Kloop2 s1 s2 :: k'
  | Kswitch :: k' => continue_cont k'
  | _ => nil (* stuck *)
  end.

(* Specifications: *)
Lemma call_cont_nonnil: forall k f, current_function k = Some f -> call_cont k <> nil.
Lemma call_cont_nonnil: forall k f, current_function k = Some f -> call_cont k <> nil.