proglog

主にプログラミングに関する断片的メモ

マクロ:回数制限つきループ

マクロの練習も兼ねて、C言語系のforループに回数制限を付けたものを書いてみる。

例えば、"numloop"をその名前とし、20回を制限として、下記のような感じで使えるもの。

(define lst '(1 2 3 4 5 6 7 7 7 8 8 8 4 3 22 14 34 1 2 1 () 1 3))
(numloop 20 (items lst) (null? (car items)) (cdr items)
		 (display (car items))
		 (newline))

制限回数になったら終了条件を満たさなくても、強制終了し、例外を投げる。
終了判定が甘い可能性がある時に、安全弁として働くように。

R5RSのマクロを使う。

(define-syntax numloop
  (syntax-rules ()
    ((numloop NUM INIT-C TEST-C NEXT-C BODY ...)
     (let loop ((count 0 ) INIT-C)
       (cond ((= count NUM) (error "out of count" count))
	     (TEST-C #t)
	     (else
	      BODY ...
	      (loop (+ count 1) NEXT-C)))))))

イメージとしては、3行目の<パターン>部が正規表現の括弧で括ったもの。
パターン変数というらしい。
ここでは、大文字で書いてある。

実際に使われたソースで、そこにマッチしたものを、4行目以降のマクロ展開<テンプレート>部が後方参照してる、という感じか。

マッチするとは言っても、単に位置関係だけっぽい。

このsyntax-rulesの次の括弧の中になんか書いとくと、それがリテラルとして、構文中の付属的なキーワード的に扱われるらしい。
cond文でのelseとかそんな感じか。

あ、このマクロはGaucheerrorを使ってる。