ライブラリ互換レイヤの制作 - Gauche/R7RS stub library
Gaucheとchibi-schemeではR7RS形式のライブラリを使用する。もともとR7RS対応を念頭にデザインしているシステムなので、大きな問題は無く対応できる。
生成されるstub libraryは:
(define-library (yuni base shorten) (export ^) (import (scheme base) (yuni-runtime r7rs)) (include "lib/yuni/base/shorten.sls"))
ランタイムは、
(define-library (yuni-runtime r7rs) (export library) (import (scheme base)) (begin (define-syntax library (syntax-rules () ((_ libname (export ...) (import ...) body ...) (begin body ...))))))
のようになる。つまり、library構文を、R6RS-light形式ライブラリのbody形式を取り出すためだけのsyntaxとして定義している。これが、yuniのライブラリ中でlibraryというシンボルをexportできない理由となっている。
(将来は、load-hookを実装するためこのlibraryがライブラリコードのentry pointとして機能するように変更される。)
キーワードオブジェクトの処理
Gauche(と、Sagittarius)には、Common-lisp風のキーワードオブジェクトのサポートが有り、コロンで始まるidentifierが(エスケープを行わないかぎり)持てない。
yuniでは、コロンで始まるシンボルを補助構文要素以外には使用しないため、Gauche向けのstub libraryでは、
- export中にコロンで始まるシンボルが有った場合は削除する
- コロン始まりのaux syntaxを取るsyntax-rulesには専用のvariantを用意し、そちらを使う
という方法で対処することにした。
; ~: generic, recursive ref/set syntax. (define-syntax ~ (syntax-rules/keywords () (:=) ((_ target slot := obj) (refset! target slot obj)) ((_ target slot) (ref target slot)) ((_ target slot next-slot ...) (~ (ref target slot) next-slot ...))))
syntax-rules/keywordsはリテラルリストを2つ取り、後者のリテラルリストはGaucheでは無視される。
Gaucheとchibi-schemeの挙動差
R7RSはフロントエンドの細かい挙動までは規定しないため、Gaucheとchibi-schemeでは微妙な挙動差がある。
Chibi-schemeはライブラリの拡張子は*.sldとする必要があるが、Gaucheでは*.scmを使用する。
Chibi-schemeでは*.scmはライブラリとして認識されないため、stub libraryは両者のために別々のライブラリを生成する。
include(や、include-library-definition)によってソースコードをincludeする場合に検索されるパスも異なる。Gaucheの場合は、指定しているライブラリパスがそのまま使用される。Chibi-schemeでは、includeを記述した.sldからの相対パスが使用される。