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")

うごご。これはつらい。どうすりゃいいんだ。
(続く)