Staging the interpreter for commands proceeds in a similar manner:
(* interpret2 : Com -> index -> <unit M> *) fun interpret2 stmt index = case stmt of Assign(name,e) => let val loc = position name index in <Do mswo { n <- ~(eval2 e index) ; write ~(lift loc) n }> end | Seq(s1,s2) => <Do mswo { x <- ~(interpret2 s1 index); y <- ~(interpret2 s2 index); Return mswo () }> | Cond(e,s1,s2) => <Do mswo { x <- ~(eval2 e index); if x=1 then ~(interpret2 s1 index) else ~(interpret2 s2 index)}> | While(e,b) => <let fun loop () = Do mswo { v <- ~(eval2 e index); if v=0 then Return mswo () else Do mswo { q <- ~(interpret2 b index); loop ()} } in loop () end> | Declare(nm,e,stmt) => <Do mswo { x <- ~(eval2 e index) ; push x ; ~(interpret2 stmt (nm::index)) ; pop }> | Print e => <Do mswo { x <- ~(eval2 e index) ; output x }>;