Corner case 地獄その2
…と思ったけど (もっと大きな test の一部だったので)、どうもただの gauche の…バグ? でもないのか。
やっぱりバグと判断したので Wiliki に移動。固定 link 機能が欲しいな。
jun@debian /dvl/gauche/current $ gosh gosh> (let-syntax ((macro (syntax-rules () ((_ . _) 'mismatch)))) (list (macro 0 1 2 . 3))) *** ERROR: Compile Error: proper list required for function application: (macro 0 1 2 . 3) "(stdin)":1:(let-syntax ((macro (syntax-rules () ... Stack Trace: _______________________________________
R5RS には (
しかし guile, STklos, Scheme48 は普通に展開してくれる。うーむ。大体 R5RS の synopsis てちょこちょこボロがあるしな…
とか思ってたがやっぱりバグらしい。(list ) をとると普通に受け付けるようになる。
gosh> (let-syntax ((macro (syntax-rules () ((_ . _) 'mismatch)))) (macro 0 1 2 . 3)) mismatch
そんで patch (おお、今回は瞬殺だ)。
--- compile.scm 2005-12-24 18:20:50.000000000 -0800 +++ compile.scm.mutilated 2006-01-20 19:20:34.000000000 -0800 @@ -1401,21 +1401,23 @@ ;; main body of pass1 (cond ((pair? program) ; (op . args) - (unless (list? program) - (error "proper list required for function application:" program)) - (if (variable? (car program)) - (let1 head (cenv-lookup cenv (car program) SYNTAX) - (cond - ((identifier? head) - (pass1/global-call head)) - ((lvar? head) - (pass1/call program ($lref head) (cdr program) cenv)) - ((macro? head) ;; local macro - (pass1 (call-macro-expander head program (cenv-frames cenv)) cenv)) - (else - (error "[internal] unknown resolution of head:" head)))) - (pass1/call program (pass1 (car program) (cenv-sans-name cenv)) - (cdr program) cenv))) + (let1 head (if (variable? (car program)) + (cenv-lookup cenv (car program) SYNTAX) + #f) + (cond + ((macro? head) ;; local macro + (pass1 (call-macro-expander head program (cenv-frames cenv)) cenv)) + ((not (list? program)) + (error "proper list required for function application:" program)) + ((identifier? head) + (pass1/global-call head)) + ((lvar? head) + (pass1/call program ($lref head) (cdr program) cenv)) + ((not head) + (pass1/call program (pass1 (car program) (cenv-sans-name cenv)) + (cdr program) cenv)) + (else + (error "[internal] unknown resolution of head:" head))))) ((variable? program) ; variable reference (let1 r (cenv-lookup cenv program LEXICAL) (cond ((lvar? r) ($lref r))
#f とかちょっと苦しい。あと多分 compile time 増加。