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 作ってみれば良いのだとは思うんですが、具体的にどう、というのが微妙。