psyntax 最新版への道 1


psyntax の最新ブランチを利用できないか四苦八苦するの巻き。
IronScheme の作者が管理している psyntax のブランチ。定期的に Ikarus における最新の変更をマージしてくれている。


公式の psyntax のリリースを rev0 とすると rev1 〜 rev10 がブランチに存在する。
いきなり最新の rev10 を使いたいところだがそれは難しい。
なぜならば

  • ブートストラップに必要な psyntax.pp が IronScheme 用で Mosh/Gauche で動かない
  • 最低限ではあるものの IronScheme 依存となるコードが含まれている

から。

特に前者は非常に難しい問題で psyntax.pp には psyntax.pp が必要。
なので出発点で安定した psyntax.pp が存在する rev0 から rev1 用の psyntax.pp を作るみたいな感じで段階をふんでいきたい。

目的

この作業の目的は

  • R6RS の機能を楽して実装するために psyntax の最新版を移植する
  • 将来的に psyntax に手を入れることになることが予想されるので学ぶ

の2つ。
作業は複雑でヒューリスティックなものになると思うので作業ログをとりながら進める。

checkout

for i in `seq 1 10`; \
do  (mkdir rev$i; cd rev$i; \
bzr branch lp:~leppie/r6rs-libraries/ironscheme.dev -r$i psyntax); \
done

rev1

まずは rev0 と diff を

diff -ur ~/mosh/tools/psyntax-r6rs/psyntax rev1/psyntax |jed

あまりに変わりすぎていて絶望した。


まずは Gauche で rev1のpsyntax.pp を rev1 の psyntax.pp 自身で更新できるかトライする。

% cp ~/mosh/tools/psyntax-r6rs/gosh.r6rs.ss rev1
% cd rev1
% cp psyntax/psyntax.pp .
% gosh gosh.r6rs.ss psyntax/psyntax-buildscript.ss
*** ERROR: symbol not defined: #<identifier user#g$g$symbol-hash$13447$13479>

ふむ。user#g$g$symbol-hash$13447$13479 ってなんだろう?
psyntax.pp を覗いてみよう。

(set! g$g$symbol-hash$13447$13479 g$symbol-hash$13447)

なるほど。define していないシンボルに set! しているのね。
処理系によってはこれを許してくれるのだけど Gauche は許してくれないからエラーと。
psyntax 的には config.ss で (define-option if-wants-global-defines #f) と指定されてこの psyntax.pp が作られたことが分かる。


ふーむ。どうしようかな。まだくじけるわけにはいけない。
define を全て用意してあげよう。
Emacs で繰り返し自動検出マクロをうまく利用して set! を抜き出して define を作った。

もう一度トライしてみよう。

% gosh gosh.r6rs.ss psyntax/psyntax-buildscript.ss
*** ERROR: unbound variable: clr-new-internal

CLR ってこどは IronScheme 由来のシンボルっぽい。
gosh.r6rs で以下のように定義して様子を見よう。

(define (clr-new-internal . args) `(clr-new-internal ,@args))

clr-call-internal が必要と言われたよ。

(define (clr-call-internal . args) `(clr-call-internal ,@args))


さて今度こそ。

% gosh gosh.r6rs.ss psyntax/psyntax-buildscript.ss
*** ERROR: #f "cannot find library" (ironscheme reader)

それっぽくなってきた。
とりあえず ironscheme/reader.ss をダミーで作ってみよう。

(library (ironscheme reader)
  (export)
  (import))
% gosh gosh.r6rs.ss psyntax/psyntax-buildscript.ss
*** ERROR: expander "invalid expression" define


ふーむ。これはどういうことだ?
expander.ss の chi-expr で起きていることは分かる。
どこに書かれた "define" が invalid なのだろうか。

psyntax.pp で invalid expression となっている部分のオブジェクトを表示させてみる。

#(g$14619 define (top) (#(g$14586 #(define define-syntax b

これは何だ?。
だめだ分からない。頭を冷やすために違う角度から攻めよう。
まず psyntax.pp を保存しておこう psyntax.pp.damepo とリネーム。


次に rev0 の psyntax.pp を持ってくる。

% cp ~/mosh/tools/psyntax-r6rs/psyntax.pp .
% gosh gosh.r6rs.ss psyntax/psyntax-buildscript.ss
r6rs psyntax ready
*** ERROR: expander "cannot export unbound identifier" annotation-stripped

お。annotation-stripped はさっき diff で見た気がする。

  ;;; this is reverse engineered from psyntax.ss
  ;;; (define-struct annotation (expression source stripped))
  ;;; - source is a pair of file-name x char-position
  ;;; - stripped is an s-expression with no annotations
  ;;; - expression is a list/vector/id/whathaveyou that 
  ;;;   may contain further annotations.
  
  #|
  (define read-annotated read)
  (define (annotation? x) #f)
  (define annotation-expression #f)
  (define annotation-source #f)
  (define annotation-stripped #f)
  |#

んー。なるほど。read時の annotation がつけられると。
今回は #f などにしておこう。

% gosh gosh.r6rs.ss psyntax/psyntax-buildscript.ss
r6rs psyntax ready
*** ERROR: expander "unbound identifier" &condition-rcd

とりあえず compat.ss に (define &condition-rcd #f) とごまかす。export にも追加。
だめだな。落ち着け落ち着け。