gencomp 確認 (13)
昨晩の続きで色々確認したんですが、へろへろだし次の日になるしで微妙。
(let-args-internal (cdr args) () () ((keep-private-macro "keep-private-macro=s" #f) (ext-module "ext-module=s" #f) (output-base "o|output=s" #f) . args) body)
だとして Normal case だと以下?
(let-args-internal (cdr args) ((keep-private-macro #f) . ()) (() ("keep-private-macro=s" => (lambda x (set! keep-private-macro (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x)))))) ((ext-module "ext-module=s" #f) (output-base "o|output=s" #f) . args) body)
opts が微妙。これは最終的にこうなる?
(let-args-internal (cdr args) ((output-base #f) (ext-module #f) (keep-private-macro #f) . ()) (() ("keep-private-macro=s" => (lambda x (set! keep-private-macro (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))) ("ext-module=s" => (lambda x (set! ext-module (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))) ("o|output=s" => (lambda x (set! output-base (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x)))))) args body)
これはパターン的には以下が適用?
((_ args binds opts rest body) (let binds (let ((rest (parse-options args opts))) (let () . body))))
として
(let ((output-base #f) (ext-module #f) (keep-private-macro #f)) (let ((args (parse-options (cdr args) (() ("keep-private-macro=s" => (lambda x (set! keep-private-macro (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))) ("ext-module=s" => (lambda x (set! ext-module (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))) ("o|output=s" => (lambda x (set! output-base (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))))))) (let () . body)))
うーん。ここまで置き換えると意味が分かるような気が。現時点で微妙なのは parse-options ですが、幸いなコトに lib/gauche/parseopt.scm にて定義されているらしい。
(define-syntax make-option-parser (syntax-rules () ((_ clauses) (make-option-parser-int clauses ())))) (define-syntax make-option-parser-int (syntax-rules (else =>) ((_ () specs) (build-option-parser (list . specs) (lambda (option args looper) (error "unrecognized option:" option)))) ((_ ((else args . body)) specs) (build-option-parser (list . specs) (lambda args . body))) ((_ ((else => proc)) specs) (build-option-parser (list . specs) proc)) ((_ ((optspec => proc) . clause) (spec ...)) (make-option-parser-int clause (spec ... (list optspec proc)))) ((_ ((optspec vars . body) . clause) (spec ...)) (make-option-parser-int clause (spec ... (list optspec (lambda vars . body))))) ((_ (other . clause) specs) (syntax-error "make-option-parser: malformed clause:" other)) )) (define-syntax parse-options (syntax-rules () ((_ args clauses) ((make-option-parser clauses) args))))
上記によれば以下?
((make-option-parser (() ("keep-private-macro=s" => (lambda x (set! keep-private-macro (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))) ("ext-module=s" => (lambda x (set! ext-module (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))) ("o|output=s" => (lambda x (set! output-base (cond ((null? x) #t) ((null? (cdr x)) (car x)) (else x))))))) (cdr args))
うーん。なんか違う。
以下のパターン的に
(opts ... (spec1 => (lambda x
opts が '() な場合どうなるんでしょ。ソレ次第で上記のアウトプットは変わるな。
追記
うーん。
Normal case の
((_ args binds (opts ...) ((var1 spec1 default1) . varspecs) body) (let-args-internal args ((var1 default1) . binds) (opts ... (spec1 => (lambda x
な opts が '() だった場合、どう展開されるのか。同じような define-syntax 作ってみれば良いのだとは思うんですが、具体的にどう、というのが微妙。