いくつか確認とか

とりあえず dynamic-wind と macroexpand 並行で。

macro の動作確認

マクロのナニで現実トウヒ

手順が以下。

  • parseopt.scm をコピィ
$ cp /usr/share/gauche/0.8.7/lib/gauche/parseopt.scm .
  • parseopt.scm の中身修正
    • モジュール名を parseopt のみに
(define-module parseopt

(select-module parseopt)
  • let-args-internal とかを export する
  • コピィ先のディレクトリで gosh 起動
  • *load-path*の修正
gosh> (set! *loat-path* (cons "." *load-path*))
("." "/usr/share/gauche/site/lib" "/usr/share/gauche/0.8.7/lib")
gosh>
  • use する
gosh> (use parseopt)
#<undef>
gosh>

で、試験してみました。let-args-internal まで掘れました。が

  • その先が見たい
  • 0.8.7 (でびあん etch のバージョン)

という微妙なナニがあるんで、とりあえず 0.8.11 な parseopt.scm 使ってみる事に。

gosh> (set! *load-path* (cons "." *load-path*))
("." "/usr/share/gauche/site/lib" "/usr/share/gauche/0.8.7/lib")
gosh> (use parseopt)
#<undef>
gosh> (macroexpand-1 '(let-args args varspecs . body))
(#<identifier parseopt#let-args-internal> args () () varspecs body)
gosh> (macroexpand-1 '(let-args-internal args () () varspecs body))
(let-args-internal args () () varspecs body)
gosh> (reload 'parseopt)
#<undef>
gosh> (macroexpand-1 '(let-args-internal args () () varspecs body))
(#0=#<identifier parseopt#let> () (#0# ((varspecs (#<identifier parseopt#parse-options> args ()))) (#0# () . body)))
gosh> 

途中で reload してるのは let-args-internal が export されてないから、です。で、make-option-parser-int 手続きも export して、以下を試験してみる事に。

(let-args ("output=x" "y")
    ((output-base "o|output=s" #f)
     . args)
  (match args
    ((scmfile)
     (format #t "args = ~s\n" args)))
  0)

さ、どうなるか。(出力を適宜修正

gosh> (macroexpand-1 '(let-args ("output=x" "y")
    ((output-base "o|output=s" #f)
     . args)
  (match args
    ((scmfile)
     (format #t "args = ~s\n" args)))
  0)
)
(#<identifier parseopt#let-args-internal> 
  ("output=x" "y") 
  () 
  () 
  ((output-base "o|output=s" #f) . args) 
  ((match args ((scmfile) (format #t "args = ~s\n" args))) 0))
>||
このあたりはまだ良いのですが、次のステップでワケワカ。
>||
gosh> (macroexpand-1 '(let-args-internal ("output=x" "y") () () 
                        ((output-base "o|output=s" #f) . args) 
                        ((match args ((scmfile) (format #t "args = ~s\n" args)))
                        0)))
;;; 出力略

むーん。ちょっと見易い形に整形してみます。

(let-args-internal
  ("output=x" "y")
  ((output-base #f)) 
  (("o|output=s" = (lambda x (set! output-base 
                                   (cond ((null? x) #t) 
                                         ((null? (cdr x)) (car x)) 
                                         (else x)))))) 
  args 
  ((match args ((scmfile) (format #t "args = ~s\n" args))) 0))

これを macroexpand-1 に渡したらどうなるんだろ。

gosh> (macroexpand-1 '(let-args-internal
  ("output=x" "y")
  ((output-base #f)) 
  (("o|output=s" = (lambda x (set! output-base 
                                   (cond ((null? x) #t) 
                                         ((null? (cdr x)) (car x)) 
                                         (else x)))))) 
  args 
  ((match args ((scmfile) (format #t "args = ~s\n" args))) 0)))
;;; 出力略

これも出力を整形してみます。

(let ((output-base #f))
     (let ((args (parse-options ("output=x" "y")
                                (("o|output=s" = (lambda x (set! output-base
                                                                 (cond ((null? x) #t)
                                                                       ((nul? (cdr x)) (car x))
                                                                       (else x)))))))))
        (let () (match args ((scmfile) (format #t "args = ~s\n" args))) 0)))

見難い。しかも漫然と macroexpand するだけではなくて、マクロの定義を確認する必要あり。とりあえず置換が動作しているのが確認できたのでこちらはとりあえず OK とゆーコトで。

dynamic-wind

もう 2330 過ぎそう。限界かも。えーとケツから見てきます。このあたり

  (set! call-with-current-continuation call/cc)
  (set! dynamic-wind     
    (lambda (in body out)
      (in)
      (set! winders (cons (cons in out) winders))
      (let ((ans (body)))
        (set! winders (cdr winders))
        (out)  
        ans))))

はなんとなくイメージできる。body の中でどっかに jmp しなければ winders が巻き戻ってナニ。そうでなければ out が呼び出されて body の戻りを返却。

うーん

確か 1 年くらい前に gauche 本の 19 章を精査してエントリ投入してるはず、なのでソレを確認した方が良さげ。弱ければもっかい確認してメモ取った方が良いかも。
早く帰ってもなかなか割り込みが止まりません。ぼちぼちヤります。