Require compcert.common.Globalenvs.
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.
Fixpoint precontinue_cont (k: cont) : cont :=
match k with
| Kseq s :: k' => precontinue_cont k'
| Kloop1 _ _ :: _ => k
| Kswitch :: k' => precontinue_cont k'
| _ => nil (* stuck *)
end.