gauche.cgen 確認

モジュールもクラスも今まで完全スルーだったので色々確認しながら、にならざるを得ないので微妙にもどかしくはありますが、最初は我慢が必要。

gauche.cgen

とりあえず gauche.cgen.unit と gauche.cgen.literal を継承している模様。gencomp で使われてるソレも見つつ掘ってみます。

gauche.cgen.unit

とりあえず cgen-decl を確認してみます。以下なカンジ。

(define (cgen-decl . code)
  (cgen-add! (make <cgen-raw-decl> :code code)))

なオブジェクトを作って cgen-add! している模様。 の定義は以下。

(define-class <cgen-raw-decl> (<cgen-node>)
  ((code  :init-keyword :code :init-value "")))
(define-method cgen-emit-decl ((node <cgen-raw-decl>))
  (emit-raw [@ node'code]))

まず、 クラスは を継承してて code という属性 (slot?) がナニ。クラス定義あたりは 7.3.1 クラス定義 のあたりとか。
cgen-emit-decl というナニも若干微妙。中身は置いといて以下なコマンド実行。

rms@debian:~/Gauche-0.8.11/lib/gauche$ find |xargs grep 'cgen-emit-decl'
./cgen/literal.scm:       (define-method cgen-emit-decl ((self class)) . ?body)
./cgen/unit.scm:          cgen-emit-xtrn cgen-emit-decl cgen-emit-body cgen-emit-init
./cgen/unit.scm:(define-method cgen-emit-decl ((node <cgen-node>)) #f)
./cgen/unit.scm:    ((decl)   (with-cpp-condition cgen-emit-decl))
./cgen/unit.scm:(define-method cgen-emit-decl ((node <cgen-raw-decl>))
./cgen/unit.scm:(define-method cgen-emit-decl ((node <cgen-include>))
rms@debian:~/Gauche-0.8.11/lib/gauche$ 

上記出力から以下な記述を発見。

(define-method cgen-emit ((node <cgen-node>) part)
  ;; A kludge for emitting cpp-condition only when necessary.
  (define (method-overridden? gf)
    (and-let* ((meths (compute-applicable-methods gf (list node)))
               ( (not (null? meths)) ))
      (match [@ (car meths)'specializers]
        (((? (cut eq? <> <cgen-node>))) #f)
        (_ #t))))
  (define (with-cpp-condition gf)
    (cond ([@ node'cpp-condition]
           => (lambda (cppc)
                (cond ((method-overridden? gf)
                       (print "#if "cppc)
                       (gf node)
                       (print "#endif /* "cppc" */"))
                      (else (gf node)))))
          (else (gf node))))
  (case part
    ((extern) (with-cpp-condition cgen-emit-xtrn))
    ((decl)   (with-cpp-condition cgen-emit-decl))
    ((body)   (with-cpp-condition cgen-emit-body))
    ((init)   (with-cpp-condition cgen-emit-init))))

これ、cgen-emit なる総称関数の定義と振り分けなソレの定義でしょうか。違うカンジ。

むむ

ちょっと最初は俯瞰できるようになるまで時間かかりそげ。ちょっと掘り方ばらばらで微妙なので再度トライ。
まず、cgen-decl の定義。

(define (cgen-decl . code)
  (cgen-add! (make <cgen-raw-decl> :code code)))

cgen-add! 手続きは?

(define (cgen-add! node)
  (and-let* ((unit (cgen-current-unit)))
    (slot-push! unit 'toplevels node))
  node)

cgen-current-unit って何でしょ。

(define cgen-current-unit (make-parameter #f))

うーん。ちょっと頭をヒヤす。

cgen-decl を呼び出してるナニとして gencomp の中の do-it が以下なナニ。

(define (do-it src base)
  (parameterize ((cgen-current-unit (get-unit src base))
                 (compile-module    (make-module #f))
                 (compile-file-basename base)
                 (vm-eval-situation SCM_VM_COMPILING))
    ;; Set up initial environment
    (eval '(define-macro (current-module)
             `(find-module ',(with-module user (compile-module-name))))
          (compile-module))
    ;; Static stuff
    (cgen-decl "#include <gauche/code.h>")

;; (以下略

上記 cgen-add! の cgen-current-module が何を束縛しているのか、が微妙。export してる、ってコトは上記 do-it でナニしてる部分で上書きなんスか?
がしかし、試験の方法をナニするリキが既に足りてません。(弱