中間コードを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)))
上記のように VM はC言語用に変換されたコードを実行する。
変換コードを 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))))))))