モジュールシステム

頭がこんがらがりつつ思考停止していた。

何に?

ええと、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-decl 手続きは

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

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

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

ここが思考停止のナニ。cgen-current-unit は unit.scm の中でも定義されてて以下。

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

昨晩からワケワカ状態で起床後も同じところを行ったりきたり。プログラミング Gauche をぼさっとめくってると_モジュールシステム_の項に名前の衝突を防ぐ云々が目的、とある。
cgen-current-unit がモジュールの外から隠蔽されているのだとすると永遠に #f が格納された parameter だという事は昨晩判明してるので、まさかと言いつつ unit.scm の先頭部分 (というか define-module してるソレ) を見ると

  (export <cgen-unit> cgen-current-unit

てーコトは cgen-current-unit は public なのね、という理解で良いのでしょうか。

しかも

試しに動かして云々、という部分も微妙だったりして駄目。

って

よく見たら do-it 側で parameterize 使ってます。

(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))

あ、成程。gosh 上で

gosh> (use gauche.cgen)
#<undef>
gosh> (use text.tr)
#<undef>
gosh> (define (get-unit src base)
  (make <cgen-unit>
    :name base
    :preamble `(,(format "/* Generated automatically from ~a.  DO NOT EDIT */"
                         src))
    :pre-decl '("#define LIBGAUCHE_BODY")
    :init-prologue (format "void Scm_Init_~a() { ScmModule *mod;"
                           (string-tr (sys-basename base) "-+" "__"))
    ))
get-unit
gosh> (define x (get-unit "xxx.scm" "xxx"))
x
gosh>

みたいなコトしてて

gosh> (cgen-decl "#include <gauche/code.h>")
#<<cgen-raw-node> 0x829c088>
gosh> (set! cgen-current-unit x)
#<<cgen-unit> 0x829c2e0>
gosh> (cgen-decl "#include <gauche/code.h>")
*** ERROR: invalid application: (#<<cgen-unit> 0x829c2e0>)
Stack Trace:
_______________________________________
  0  (cgen-current-unit)
        At line 179 of "/usr/share/gauche/0.8.7/lib/gauche/cgen.scm"
gosh> 

上記だと cgen-current-unit は parameter になってないので駄目なのか。

ぼちぼち

続きを確認予定。

追記

昨晩のエントリのケツで export には行きついていたのを今更発見。parameterize の知識不足が敗因だった模様。