blog/content/post/2010/05/22/2010-05-22-00001364.md

128 lines
6.1 KiB
Markdown
Raw Normal View History

2019-03-31 11:00:21 +00:00
---
title: define-syntax で遊んでみた
author: kazu634
date: 2010-05-22
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:5261;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- gauche
- Lisp
---
<div class="section">
<p>
これぞまさしく for を使いたい場面が出てきたのだけれど、 Gauche には for がないので作ってみました。基本的にはこんな感じで使うイメージです:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>for <span class="synSpecial">(</span>i <span class="synConstant">1</span> <span class="synConstant">10</span><span class="synSpecial">)</span> <span class="synSpecial">(</span><span class="synStatement">print</span> i<span class="synSpecial">))</span>
</pre>
<p>
条件が成立している場合にだけ、「(print i)」を評価したいから、こういう場合はマクロを使うんだよね。たしか。
</p>
<p>
作成に当たっては、「<a href="http://eclipse.cspc.jp/perma/000139/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://eclipse.cspc.jp/perma/000139/', 'define-syntax | METAMATE');" target="_blank">define-syntax | METAMATE</a>」を参考にしたよ:
</p>
<blockquote title="define-syntax | METAMATE" cite="http://eclipse.cspc.jp/perma/000139/">
<p>
マクロ定義はdefine-syntaxで行う。
</p>
<p>
GaucheではCommon Lispのdefmacroのようなマクロ定義構文として、
</p>
<p>
define-macroもある。がこっちはR5RS範囲外。
</p>
<p>
</p>
<p>
マクロの書き方は次のかたち。
</p>
<p>
パターンの中で&#8221;_&#8221;が出てきたらマクロ名、
</p>
<p>
&#8220;&#8230;&#8221;は可変数の式として解釈します。
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>define-syntax マクロ名
<span class="synSpecial">(</span>syntax-rules <span class="synSpecial">(</span>キーワードリスト<span class="synSpecial">)</span>
<span class="synSpecial">((</span>パターン1<span class="synSpecial">)</span> <span class="synSpecial">(</span>マクロ展開後の式<span class="synSpecial">))</span>
<span class="synSpecial">((</span>パターン2<span class="synSpecial">)</span> <span class="synSpecial">(</span>マクロ展開後の式<span class="synSpecial">))</span>
...<span class="synSpecial">))</span>
</pre>
<p>
<cite><a href="http://eclipse.cspc.jp/perma/000139/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://eclipse.cspc.jp/perma/000139/', 'define-syntax | METAMATE');" target="_blank">define-syntax | METAMATE</a></cite>
</p>
</blockquote>
<h4>
ソース
</h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>define-syntax for
<span class="synSpecial">(</span>syntax-rules <span class="synSpecial">(</span>by<span class="synSpecial">)</span>
[<span class="synSpecial">(</span>for <span class="synSpecial">(</span>i init limit by <span class="synStatement">step</span><span class="synSpecial">)</span> expr ...<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">do</span> <span class="synSpecial">((</span>tlimit limit<span class="synSpecial">)</span>
<span class="synSpecial">(</span>i init <span class="synSpecial">(</span><span class="synStatement">+</span> i <span class="synStatement">step</span><span class="synSpecial">)))</span>
<span class="synSpecial">((</span><span class="synStatement">&#62;</span> i tlimit<span class="synSpecial">))</span>
expr ...<span class="synSpecial">)</span>]
[<span class="synSpecial">(</span>for <span class="synSpecial">(</span>i init limit<span class="synSpecial">)</span> expr ...<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">do</span> <span class="synSpecial">((</span>tlimit limit<span class="synSpecial">)</span>
<span class="synSpecial">(</span>i init <span class="synSpecial">(</span><span class="synStatement">+</span> i <span class="synConstant">1</span><span class="synSpecial">)))</span>
<span class="synSpecial">((</span><span class="synStatement">&#62;</span> i tlimit<span class="synSpecial">))</span>
expr ...<span class="synSpecial">)</span>]<span class="synSpecial">))</span>
</pre>
<p>
「syntax-rules (by)」とすることで「by」が特別扱いされる…ようだ。
</p>
<h4>
実行例
</h4>
<pre class="syntax-highlight">
gosh&#62; <span class="synSpecial">(</span>for <span class="synSpecial">(</span>i <span class="synConstant">1</span> <span class="synConstant">10</span><span class="synSpecial">)</span> <span class="synSpecial">(</span><span class="synStatement">print</span> <span class="synConstant">&#34;foo&#34;</span><span class="synSpecial">))</span>
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
#<span class="synStatement">t</span>
gosh&#62; <span class="synSpecial">(</span>for <span class="synSpecial">(</span>i <span class="synConstant">1</span> <span class="synConstant">10</span><span class="synSpecial">)</span> <span class="synSpecial">(</span><span class="synStatement">print</span> i<span class="synSpecial">))</span>
<span class="synConstant">1</span>
<span class="synConstant">2</span>
<span class="synConstant">3</span>
<span class="synConstant">4</span>
<span class="synConstant">5</span>
<span class="synConstant">6</span>
<span class="synConstant">7</span>
<span class="synConstant">8</span>
<span class="synConstant">9</span>
<span class="synConstant">10</span>
#<span class="synStatement">t</span>
gosh&#62; <span class="synSpecial">(</span>for <span class="synSpecial">(</span>i <span class="synConstant">1</span> <span class="synConstant">10</span> by <span class="synConstant">5</span><span class="synSpecial">)</span> <span class="synSpecial">(</span><span class="synStatement">print</span> i<span class="synSpecial">))</span>
<span class="synConstant">1</span>
<span class="synConstant">6</span>
#<span class="synStatement">t</span>
</pre>
</div>