# Gauche VM の instruction を眺める - Scheme VM を書く

Gauche の src/vminsn.scm に定義されている instruction を見ていく。
instruction の粒度が分かって勉強になる。

inlined operators はすぐにでもまねしよう。

```;; Some immediate constants
(define-insn CONSTI 1 none)             ; constant small integer
(define-insn CONSTN 0 none)             ; constant ()
(define-insn CONSTF 0 none)             ; constant #f
(define-insn CONSTU 0 none)             ; constant #<undef>

;; BF <else-offset>          ; branch if VAL0 is false
;; BT <else-offset>          ; branch if VAL0 is true
;; BNNULL <else-offset>      ; branch if VAL0 is not null
;; BNEQ <else-offset>        ; branch if VAL0 is not eq? to (POP)
;; BNEQV <else-offset>       ; branch if VAL0 is not eqv? to (POP)
;; BNUMNE  <else-offset>     ; branch if (VAL0 != (POP))
;; BNLT  <else-offset>     ; branch if !((POP) < VAL0)
;; BNLE  <else-offset>     ; branch if !((POP) <= VAL0)
;; BNGT  <else-offset>     ; branch if !((POP) > VAL0)
;; BNGE  <else-offset>     ; branch if !((POP) >= VAL0)
;;   Conditional branches.

;;  Primitive operation for receive and call-with-values.
;;  Turn the value(s) into an environment.
;;  Like LET, this pushes the continuation frame to resume the
;;  operation from CONT-OFFSET.
;;

;; PROMISE
;;  Delay syntax emits this instruction.  Wrap a procedure into a promise
;;  object.
;;
(define-insn PROMISE     0 none)

;; Inlined operators
;;  They work the same as corresponding Scheme primitives, but they are
;;  directly interpreted by VM, skipping argument processing part.
;;  Compiler may insert these in order to fulfill the operation (e.g.
;;  `case' needs MEMV).  If the optimization level is high, global
;;  reference of those primitive calls in the user code are replaced
;;  as well.
;;
(define-insn CONS        0 none)
(define-insn CONS-PUSH   0 none   (CONS PUSH))
(define-insn CAR         0 none)
(define-insn CAR-PUSH    0 none   (CAR PUSH))
(define-insn CDR         0 none)
(define-insn CDR-PUSH    0 none   (CDR PUSH))

(define-insn LIST        1 none)
(define-insn LIST-STAR   1 none)        ; list*
(define-insn LENGTH      0 none)        ; length
(define-insn MEMQ        0 none)
(define-insn MEMV        0 none)

(define-insn NUMEQ2      0 none)        ; =
(define-insn NUMLT2      0 none)        ; <
(define-insn NUMLE2      0 none)        ; <=