Let's start Scheme

2011-12-29

リーダーマクロが動いた

まだ、あまりテストしていないが、簡単なリーダーマクロが動いた。
とりあえず当初の目的の通り正規表現を#/regex/と書ける様にしてみた。こんな感じ。
#<(sagittarius regex)
(import (sagittarius regex))
(define rx #/\w+/)
(print (regex-replace-all rx "abcdef@abcdef" "**$0**"))
もちろん#/regex/ixumsのようにも書ける。
汚いなぁと思うのは#<(ライブラリ)のように書かないとリーダーマクロがインポートされない部分。上記のようなプログラムなら(import)がやっても一緒なのだが、ライブラリが問題になってくるので、こんな風にした。
また、loadしたファイルの影響を受けると意味が分からなくなるので影響範囲はファイル単位になっている。

括弧ゴルフに勝つるツールが手に入った(違
ついでにそれっぽいライブラリも作った。
使い方は以下のようになる。
(library (test)
    (export :export-reader-macro)
    (import (rnrs) (sagittarius reader) 
     (sagittarius)
     (sagittarius vm)
     (pp))
  (define-reader-macro @-reader #\@
    (lambda (port c)
      (let loop ((c (get-char port)))
 (cond ((eof-object? c) #f)
       ((char=? c #\newline) #f)
       (else (loop (get-char port)))))))

  (define-dispatch-macro !^-reader #\! #\^
    (lambda (port c param)
      (let loop ((c (get-char port)))
 (cond ((eof-object? c) #f)
       ((char=? c #\newline) #f)
       (else (loop (get-char port)))))))
  )


#<(test)
@(print hogehoge)))))
(print 'ok)
!^***** hogehoge
(print 'ok)
これは@を一行コメント、!^を一行コメントにするだけのものだが、普通に動く。今のところ問題になるというか、ドキュメントに明示しないといけないなぁと思っているのは、ライブラリ内で定義を書く場合は上記のdefine-reader-macroもしくはdefine-dispatch-macroを必ず使う必要があること。
また、ライブラリ外で何か定義したい場合は別の組み込み関数を使う必要があること。実装上の都合でこんな風になっている。
今のところ、括弧ゴルフか正規表現(実装済み)にしか使う予定はないので問題はないのだが、ちょっと面倒かもしれない。

No comments:

Post a Comment