psyntax 最新版への道 2
前回までの問題
Mosh で psyntax(rev 10) の展開を行うときに library-manager.ss の define-record library で定義済みであるはずの make-library が psyntax の中で Unbound variable になる。
そこでもっと簡単なケースで試したが
の psyntax(rev0) で同様の症状が見られる。
逆に psyntax (rev 10) を利用している IronScheme ではこの現象は起きないことが分かった。
現時点での仮結論は、「この問題は rev 10 に上げれば解決する」。
続き
さて仮結論はいいとして、この問題をどう切り抜けるか。
今コードを見ていて気づいたのだが
- rev 0 では define-record は vector に展開
- rev 10 では define-record は define-record-type に展開
と違いがある。
rev 0 の define-record を持ってこよう。
Condition components: 1. &error 2. &who: expander 3. &message: "cannot redefine" 4. &irritants: (library?)
先に進んだね。library-manager.ss の以下をコメントアウトしてみる。
(define (library? x) #f)
Condition components: 1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((stx? sym))
expander.ss で ((stx? sym) (gen-lexical (id->sym sym))) がエラーに。
stx? だね。これも define-record stx だ。rev 0 から持って来ようと思ったが構造が違うね。
自前で展開するか。expander.ss に書いた。
(define stx-rtd (make-record-type-descriptor 'stx #f #f #f #f '#((mutable mark*) (mutable subst*) (mutable ae*)))) (define stx-rcd (make-record-constructor-descriptor stx-rtd #f #f)) (define make-stx (record-constructor stx-rcd)) (define stx? (record-predicate stx-rtd)) (define stx-mark* (record-accessor stx-rtd 0)) (define stx-mark*-set! (record-mutator stx-rtd 0)) (define stx-subst* (record-accessor stx-rtd 1)) (define stx-subst*-set! (record-mutator stx-rtd 1)) (define stx-ae* (record-accessor stx-rtd 2)) (define stx-ae*-set! (record-mutator stx-rtd 2))
さてどうかな?
Condition components: 1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((id->sym sym))
後方参照できないのかな。id->sym を前に持ってこよう。うまくいった。
次
Condition components: 1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((annotation? expr))
これは分かるよ。rev 10 から導入されたソースに annotation のやつ。とりあえず #f 返しておこう。
(define (annotation-stripped x) x) (define (annotation? x) #f)
Condition components: 1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((stx-expr x))
んん。やべ。stx-expr 定義するの忘れてた。
次
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((same-marks? mark* (car mark**)))
same-marks? の定義をコードの先頭に移動。
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((set-interaction-env-locs! env (cons (cons label loc) locs)))
また define-record だ。展開。
(define interaction-env-rtd (make-record-type-descriptor 'interaction-env #f #f #f #f '#((mutable rib) (mutable r) (mutable locs)))) (define interaction-env-rcd (make-record-constructor-descriptor interaction-env-rtd #f #f)) (define make-interaction-env (record-constructor interaction-env-rcd)) (define interaction-env? (record-predicate interaction-env-rtd)) (define interaction-env-rib (record-accessor interaction-env-rtd 0)) (define set-interaction-env-rib! (record-mutator interaction-env-rtd 0)) (define interaction-env-r (record-accessor interaction-env-rtd 1)) (define set-interaction-env-r! (record-mutator interaction-env-rtd 1)) (define interaction-env-locs (record-accessor interaction-env-rtd 2)) (define set-interaction-env-locs! (record-mutator interaction-env-rtd 2))
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((top-level-context))
例のごとく先頭へ定義を移動。
2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((stx-error id "cannot redefine"))
(define-syntax stx-error をコードの先頭に持ってきた。
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((syntax-violation #f "cannot redefine" id))
ふむ。これでしのごう。
(define (syntax-violation who msg irr) (assertion-violation who msg irr))
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: (idx)
これは #;(define (increment-rib-frequency! rib idx) のコメントアウトがおかしいのが原因だな。
全てコメントアウトした。
1. &error 2. &who: expander 3. &message: "cannot redefine" 4. &irritants: (read-annotated)
expander で以下をコメントアウト。compat.ss にも同じものがある
; (define read-annotated read)
1. &error 2. &who: expander 3. &message: "cannot redefine" 4. &irritants: (syntax-violation)
あれれ。ああ。そうかよく見れば syntax-violation はすでに expander.ss に定義されているのか、さっきのを消してこれをファイルの先頭に持ってくる。
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((annotation-expression x))
annotation-expression は何を返すべきだろうか?よく分からないが annotation? が #t の時にのみ評価されるようだから identity で良いか。
(define (annotation-expression x) x)
エラーは続くよ。どこまでも♪。
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((x old* new*))
これはかの有名な let*-values 問題と見た。psyntax rev0 では let*-values はサポートされない。
(let*-values ([(y old* new*) (rename x old* new*)] [(y* old* new*) (rename* x* old* new*)])
ここでコミットしておこう。(rev 469)
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((annotation-source x))
annotation-source は pair? じゃないものを返せば良さそう。
(define (annotation-source x) '())
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((compile-core (expanded->core invoke-code)))
compile-core は pre-compile-r6rs-top-level っで使われる。処理系が提供するものっぽい。
今は深追いせず。
;; temporary (define (compile-core expr) (error 'compile-core "compile-core is not implemented"))
1. &error 2. &message: "cannot find library" 3. &irritants: ((ironscheme))
(let ([lib (find-library-by-name '(ironscheme))]
これか。とりあえず '(rnrs) にしておこう。と思ったらここじゃないみたい。早とちりはいけない。
ironscheme-buildscript.ss の (only (ironscheme) time-it) だね。コメントアウトした。
1. &error 2. &who: expander 3. &message: "unbound identifier" 4. &irritants: ((time-it "the entire bootstrap process" (l
ふむ。これは分かりやすい流れだ。
ironscheme-buildscript.ss と expander.ss に追加。
(define (time-it message expr) (expr))
1. &assertion 2. &who: open-file-input-port 3. &message: "can't open file" 4. &irritants: ("ironscheme/base.ss")
お。だいぶ進んだね。
(define scheme-library-files '( "ironscheme/base.ss" "ironscheme/hashtables.ss" "ironscheme/files.ss"
このあたりをコメントアウト。
1. &assertion 2. &who: eval 3. &message: "unbound variable" 4. &irritants: ("bytevector?")
あれ。bytevector? 定義してなかったっけ。やべ。
定義した。
expanding psyntax/compat.ss Condition components: 1. &assertion 2. &who: eval 3. &message: "unbound variable" 4. &irritants: ("G8740")
うごご。これはつらい。どうすりゃいいんだ。
(続く)