ライブラリ互換レイヤの制作 - 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では微妙な挙動差がある。

  • ライブラリの拡張子: Gauche(*.scm), chibi-scheme(*.sld)

Chibi-schemeはライブラリの拡張子は*.sldとする必要があるが、Gaucheでは*.scmを使用する。
Chibi-schemeでは*.scmはライブラリとして認識されないため、stub libraryは両者のために別々のライブラリを生成する。

  • includeの検索先: Gauche(ライブラリパス), chibi-scheme(インクルード元相対)

include(や、include-library-definition)によってソースコードをincludeする場合に検索されるパスも異なる。Gaucheの場合は、指定しているライブラリパスがそのまま使用される。Chibi-schemeでは、includeを記述した.sldからの相対パスが使用される。