中間コードをC言語用に変換 - Scheme VM を書く

コンパイラScheme で書いたものを当分使用し、VMの開発から始める。

1234
=> コンパイル
(constant 1234 (halt))
=> C言語用に変換
SCM_CONS(SCM_MAKE_INT(VM::CONSTANT), SCM_CONS(SCM_MAKE_INT(1234), SCM_CONS(SCM_CONS(SCM_MAKE_INT(VM::HALT), SCM_NIL), SCM_NIL)))

上記のように VMC言語用に変換されたコードを実行する。
変換コードを Gauche で書いてしばらくはこれでテストを繰り返そう。

(define *opcodes*
  '((constant . "SCM_MAKE_INT(VM::CONSTANT)")
    (halt     . "SCM_MAKE_INT(VM::HALT)")
))

(define (scheme2c obj)
  (cond ((number? obj) (format "SCM_MAKE_INT(~d)" obj))
        ((pair? obj) (format "SCM_CONS(~a, ~a)" (scheme2c (car obj)) (scheme2c (cdr obj))))
        ((null? obj) "SCM_NIL")
        ((symbol? obj)
         (if (assoc obj *opcodes*)
             (assoc-ref *opcodes* obj)
             obj))))

(define (main args)
  (call-with-input-string (cadr args)
     (lambda (port)
       (let loop ((obj (read port)))
         (if (eof-object? obj)
             '()
             (begin
               (print (scheme2c obj))
               (loop (read port))))))))