       ;; (:VM_VSET ~(make-sym var))
       ;; (:VM_VREF ~(make-sym var))
       (:VM_VINC ~(make-sym var))
-      (:VM_PUSH)
       (:VM_IVAL ~(make-num num))
       (:VM_LE)
       (:VM_BIF ~end-label)
-      (:VM_POP)
       (:VM_JMP ~retry-label)
       ~end-label
       (:VM_POP)
       (:VM_UNBIND 1))))
+
+(defn compile-while [pred body]
+  (let [retry-label (gensym),
+        end-label (gensym)
+        pred (fold-constant pred)]
+    (if (kondoval-t? pred)
+      `(~retry-label
+        ~@(apply concat (map compile-pass1 body))
+        (:VM_JMP ~retry-label))
+      `((:VM_IVAL ~(make-nil))
+        ~retry-label
+        (:VM_PUSH)
+        ~@(compile-pass1 pred)
+        (:VM_BIFN ~end-label)
+        (:VM_POP)
+        ~@(apply concat (map compile-pass1 body))
+        (:VM_JMP ~retry-label)
+        ~end-label
+        (:VM_POP)))))
 
 (defn builtin-fun-id [fname]
   (index (fn [pair] (= (first pair) fname))


(declare compile-pass1)

(defn compile-quote [exp]
  (cond
   (or (and (coll? exp)

            `(~@insts
              ~end-label))
          ;;
	  ('while pred & body)	(compile-while pred body)
	  ;;
	  ('dotimes (var num) & body)
          (compile-dotimes var num body)
