6.2 KiB
6.2 KiB
title | author | date | url | wordtwit_post_info | categories | |||
---|---|---|---|---|---|---|---|---|
define-syntax で遊んでみた | kazu634 | 2010-05-22 | /2010/05/22/_1528/ |
|
|
これぞまさしく for を使いたい場面が出てきたのだけれど、 Gauche には for がないので作ってみました。基本的にはこんな感じで使うイメージです:
(for (i 1 10) (print i))
条件が成立している場合にだけ、「(print i)」を評価したいから、こういう場合はマクロを使うんだよね。たしか。
作成に当たっては、「define-syntax | METAMATE」を参考にしたよ:
マクロ定義はdefine-syntaxで行う。
GaucheではCommon Lispのdefmacroのようなマクロ定義構文として、
define-macroもある。がこっちはR5RS範囲外。
マクロの書き方は次のかたち。
パターンの中で”_”が出てきたらマクロ名、
“…”は可変数の式として解釈します。
(define-syntax マクロ名 (syntax-rules (キーワードリスト) ((パターン1) (マクロ展開後の式)) ((パターン2) (マクロ展開後の式)) ...))
ソース
(define-syntax for (syntax-rules (by) [(for (i init limit by step) expr ...) (do ((tlimit limit) (i init (+ i step))) ((> i tlimit)) expr ...)] [(for (i init limit) expr ...) (do ((tlimit limit) (i init (+ i 1))) ((> i tlimit)) expr ...)]))
「syntax-rules (by)」とすることで「by」が特別扱いされる…ようだ。
実行例
gosh> (for (i 1 10) (print "foo")) foo foo foo foo foo foo foo foo foo foo #t gosh> (for (i 1 10) (print i)) 1 2 3 4 5 6 7 8 9 10 #t gosh> (for (i 1 10 by 5) (print i)) 1 6 #t