Check-in [203e4cb208]
Not logged in
Overview
SHA1 Hash:203e4cb208bbc9d4da4052d12d8656c368af24c0
Date: 2010-11-27 20:46:26
User: kinaba
Comment:fixed automatic memoization bug (whole part of the contexts are now used as the memo key)
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified doc/_common.html from [b9095bf676f7ac7c] to [99ddb75ae65a2432].

22 22 23 The list of modules globaly used inside Polemy.<br><br> 23 The list of modules globaly used inside Polemy.<br><br> 24 24 25 </td></tr> 25 </td></tr> 26 <tr><td id="docfooter"> 26 <tr><td id="docfooter"> 27 Page was generated with 27 Page was generated with 28 <img src="candydoc/img/candydoc.gif" style="vertical-ali 28 <img src="candydoc/img/candydoc.gif" style="vertical-ali 29 on Fri Nov 26 16:41:43 2010 | 29 on Sat Nov 27 01:17:56 2010 30 30 31 </td></tr> 31 </td></tr> 32 </table> 32 </table> 33 </div> 33 </div> 34 <script> 34 <script> 35 explorer.packageExplorer.addModule("index"); 35 explorer.packageExplorer.addModule("index"); 36 explorer.packageExplorer.addModule("main"); 36 explorer.packageExplorer.addModule("main");

Modified doc/ast.html from [7559b28d1aa75ece] to [30cfc60d3ceb137f].

590 <script>explorer.outline.decSymbolLevel();</script> 590 <script>explorer.outline.decSymbolLevel();</script> 591 591 592 592 593 </td></tr> 593 </td></tr> 594 <tr><td id="docfooter"> 594 <tr><td id="docfooter"> 595 Page was generated with 595 Page was generated with 596 <img src="candydoc/img/candydoc.gif" style="vertical-ali 596 <img src="candydoc/img/candydoc.gif" style="vertical-ali 597 on Fri Nov 26 16:41:44 2010 | 597 on Sat Nov 27 01:17:56 2010 598 598 599 </td></tr> 599 </td></tr> 600 </table> 600 </table> 601 </div> 601 </div> 602 <script> 602 <script> 603 explorer.packageExplorer.addModule("index"); 603 explorer.packageExplorer.addModule("index"); 604 explorer.packageExplorer.addModule("main"); 604 explorer.packageExplorer.addModule("main");

Modified doc/eval.html from [2f7c4dc496477f14] to [8d466c06bd23cd95].

36 36 37 37 38 <dd>Objects for maitaining global environment and evaluation of expression on it 38 <dd>Objects for maitaining global environment and evaluation of expression on it 39 39 40 40 41 <script>explorer.outline.incSymbolLevel();</script> 41 <script>explorer.outline.incSymbolLevel();</script> 42 <dl> 42 <dl> 43 <script>explorer.outline.writeEnabled = true;</script> < 44 <dt><span class="decl">this(); < 45 </span></dt> < 46 <script>explorer.outline.writeEnabled = false;</script> < 47 < 48 < 49 <dd>Initialize evaluator with empty context<br><br> < 50 < 51 </dd> < 52 < 53 <script>explorer.outline.writeEnabled = true;</script> 43 <script>explorer.outline.writeEnabled = true;</script> 54 <dt><span class="decl">Value 44 <dt><span class="decl">Value 55 <span class="currsymbol">evalAST</span> 45 <span class="currsymbol">evalAST</span> 56 <script>explorer.outline.addDecl('evalAST');</script> 46 <script>explorer.outline.addDecl('evalAST');</script> 57 47 58 (AST <span class="funcparam">e</span>); 48 (AST <span class="funcparam">e</span>); 59 </span></dt> 49 </span></dt> ................................................................................................................................................................................ 101 </span></dt> 91 </span></dt> 102 <script>explorer.outline.writeEnabled = false;</script> 92 <script>explorer.outline.writeEnabled = false;</script> 103 93 104 94 105 <dd>Get the global context<br><br> 95 <dd>Get the global context<br><br> 106 96 107 </dd> 97 </dd> > 98 > 99 <script>explorer.outline.writeEnabled = true;</script> > 100 <dt><span class="decl">this(); > 101 </span></dt> > 102 <script>explorer.outline.writeEnabled = false;</script> > 103 > 104 > 105 <dd>Initialize evaluator with empty context<br><br> > 106 > 107 </dd> 108 108 109 <script>explorer.outline.writeEnabled = true;</script> 109 <script>explorer.outline.writeEnabled = true;</script> 110 <dt><span class="decl">void 110 <dt><span class="decl">void 111 <span class="currsymbol">addPrimitive</span> 111 <span class="currsymbol">addPrimitive</span> 112 <script>explorer.outline.addDecl('addPrimitive');</script> 112 <script>explorer.outline.addDecl('addPrimitive');</script> 113 113 114 (R, T...)(string <span class="funcparam">name</span>, Layer <span class="funcpar 114 (R, T...)(string <span class="funcparam">name</span>, Layer <span class="funcpar ................................................................................................................................................................................ 128 <script>explorer.outline.decSymbolLevel();</script> 128 <script>explorer.outline.decSymbolLevel();</script> 129 129 130 130 131 </td></tr> 131 </td></tr> 132 <tr><td id="docfooter"> 132 <tr><td id="docfooter"> 133 Page was generated with 133 Page was generated with 134 <img src="candydoc/img/candydoc.gif" style="vertical-ali 134 <img src="candydoc/img/candydoc.gif" style="vertical-ali 135 on Fri Nov 26 16:41:45 2010 | 135 on Sat Nov 27 01:17:57 2010 136 136 137 </td></tr> 137 </td></tr> 138 </table> 138 </table> 139 </div> 139 </div> 140 <script> 140 <script> 141 explorer.packageExplorer.addModule("index"); 141 explorer.packageExplorer.addModule("index"); 142 explorer.packageExplorer.addModule("main"); 142 explorer.packageExplorer.addModule("main");

Modified doc/failure.html from [73b33ccfe21436b6] to [1a82c4c6591961ce].

178 <script>explorer.outline.decSymbolLevel();</script> 178 <script>explorer.outline.decSymbolLevel();</script> 179 179 180 180 181 </td></tr> 181 </td></tr> 182 <tr><td id="docfooter"> 182 <tr><td id="docfooter"> 183 Page was generated with 183 Page was generated with 184 <img src="candydoc/img/candydoc.gif" style="vertical-ali 184 <img src="candydoc/img/candydoc.gif" style="vertical-ali 185 on Fri Nov 26 16:41:45 2010 | 185 on Sat Nov 27 01:17:58 2010 186 186 187 </td></tr> 187 </td></tr> 188 </table> 188 </table> 189 </div> 189 </div> 190 <script> 190 <script> 191 explorer.packageExplorer.addModule("index"); 191 explorer.packageExplorer.addModule("index"); 192 explorer.packageExplorer.addModule("main"); 192 explorer.packageExplorer.addModule("main");

Modified doc/fresh.html from [9043a131c52ae01a] to [dd1d4442ef129d46].

46 <script>explorer.outline.decSymbolLevel();</script> 46 <script>explorer.outline.decSymbolLevel();</script> 47 47 48 48 49 </td></tr> 49 </td></tr> 50 <tr><td id="docfooter"> 50 <tr><td id="docfooter"> 51 Page was generated with 51 Page was generated with 52 <img src="candydoc/img/candydoc.gif" style="vertical-ali 52 <img src="candydoc/img/candydoc.gif" style="vertical-ali 53 on Fri Nov 26 16:41:46 2010 | 53 on Sat Nov 27 01:17:58 2010 54 54 55 </td></tr> 55 </td></tr> 56 </table> 56 </table> 57 </div> 57 </div> 58 <script> 58 <script> 59 explorer.packageExplorer.addModule("index"); 59 explorer.packageExplorer.addModule("index"); 60 explorer.packageExplorer.addModule("main"); 60 explorer.packageExplorer.addModule("main");

Modified doc/index.html from [dc242393e80db0b7] to [a076bfb1003e4c62].

16 16 17 <b>Authors:</b><br> 17 <b>Authors:</b><br> 18 k.inaba<br><br> 18 k.inaba<br><br> 19 <b>License:</b><br> 19 <b>License:</b><br> 20 NYSL 0.9982 (http://www.kmonos.net/nysl/)<br><br> 20 NYSL 0.9982 (http://www.kmonos.net/nysl/)<br><br> 21 21 22 <p> 22 <p> 23 このファイルは、言語仕様などの簡単な説明です。 | 23 左のサイドバーの "Package" タブをクリックすると実装のソースのドキュメントが読めます。 24 </p> 24 </p> 25 <p> 25 <p> 26 とついでに、左イドバーの "Package" タブをクリックすると実装のソースのドキュメントが読めます。 | 26 のファイルは、言語仕様などやや辞書的な説明です。<br /> > 27 もっとざっくりとした、言語デザインの方向性の魂的なもについては、 > 28 「メタプログラミングの会」の発表スライドをご覧下さい > 29 </p> > 30 <p> > 31 あと、 やたらとマクロの章が長くなっていますが、 この部分は、 > 32 レイヤ機能を入れたら自動的にすごく自然にマクロが入るーと思って、 > 33 おまけで実装してみた程度のものです。 > 34 あんまり重要ではないので、適当にスルーして下さいませ > 35 単に、適当に入れたら適当で微妙な部分が多く残ってしまたので注意書きが増えているだけで…。 27 </p> 36 </p> 28 37 29 38 30 <script>explorer.outline.incSymbolLevel();</script> 39 <script>explorer.outline.incSymbolLevel();</script> 31 <dl> 40 <dl> 32 <script>explorer.outline.writeEnabled = true;</script> 41 <script>explorer.outline.writeEnabled = true;</script> 33 <dt><span class="decl"> 42 <dt><span class="decl"> ................................................................................................................................................................................ 236 </pre> 245 </pre> 237 <p> 246 <p> 238 let-in を縦にチェインしたときだけ、同名変数を破壊的に上書きします 247 let-in を縦にチェインしたときだけ、同名変数を破壊的に上書きします 239 (再帰関数の定義が"うまく"いっているのはこの上書きのためです)。 248 (再帰関数の定義が"うまく"いっているのはこの上書きのためです)。 240 なんでこんなことになっているかというと、 249 なんでこんなことになっているかというと、 241 後で説明する「レイヤ」を使ったときに 250 後で説明する「レイヤ」を使ったときに 242 <tt>let foo = ... in @lay foo = ... in ...</tt> 251 <tt>let foo = ... in @lay foo = ... in ...</tt> 243 で他レイヤに重ね書きするためあります。 | 252 で他レイヤに重ね書きするためのつもりです。詳しくは後で 244 </p> 253 </p> 245 </dd> 254 </dd> 246 </dl> 255 </dl> 247 <script>explorer.outline.decSymbolLevel();</script> 256 <script>explorer.outline.decSymbolLevel();</script> 248 257 249 258 250 </dd> 259 </dd> ................................................................................................................................................................................ 288 以下のデータ型があります。 297 以下のデータ型があります。 289 </p> 298 </p> 290 <ul> 299 <ul> 291 <li>整数: <tt>0</tt>, <tt>123</tt>, <tt>456666666666666666666666666666666666 300 <li>整数: <tt>0</tt>, <tt>123</tt>, <tt>456666666666666666666666666666666666 292 <li>文字列: <tt>"hello, world!"</tt>, ...</li> 301 <li>文字列: <tt>"hello, world!"</tt>, ...</li> 293 <li>関数: <tt>fun(x){x+1}</tt></li> 302 <li>関数: <tt>fun(x){x+1}</tt></li> 294 <li>テーブル: <tt>{car: 1, cdr: {car: 2, cdr: {}}}</tt></li> 303 <li>テーブル: <tt>{car: 1, cdr: {car: 2, cdr: {}}}</tt></li> 295 <li>未定義値: (特殊なケースで作られます。「レイヤ」の説明参照のこと。)</li> | 304 <li>ボトム: (特殊なケースで作られます。「レイヤ」の説明参照のこと。)</li> 296 </ul> 305 </ul> 297 <p> 306 <p> 298 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 307 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 299 テーブルはいわゆるプロトタイプチェーンを持っていて、 308 テーブルはいわゆるプロトタイプチェーンを持っていて、 300 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 309 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 301 フィールドの書き換えがないので、これは特に意味ないかもしれない…。 310 フィールドの書き換えがないので、これは特に意味ないかもしれない…。 302 </p> 311 </p> ................................................................................................................................................................................ 556 </pre> 565 </pre> 557 <p> 566 <p> 558 動きとしてはこうです。 567 動きとしてはこうです。 559 </p> 568 </p> 560 <ol> 569 <ol> 561 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 570 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 562 まず、<code>@macro</code> レイヤでコードを実行。</li> 571 まず、<code>@macro</code> レイヤでコードを実行。</li> 563 <li>返ってきた構文木を、<code>@value</code> レイヤ、 < 564 またはその関数を呼び出したときのレイヤで実行。</li> | 572 <li>返ってきた構文木を、その関数を呼び出したときのレイヤで実行。</li> 565 </ol> 573 </ol> 566 <p> 574 <p> 567 <code>@macro</code> レイヤも所詮ただのレイヤですので、 575 <code>@macro</code> レイヤも所詮ただのレイヤですので、 568 上で説明した方法で <code>@macro</code> レイヤに関数などを登録しておくことで、 576 上で説明した方法で <code>@macro</code> レイヤに関数などを登録しておくことで、 569 構文木の生成をいじることが可能です。まさにマクロ。 577 構文木の生成をいじることが可能です。まさにマクロ。 570 </p> 578 </p> 571 579 ................................................................................................................................................................................ 655 )}; 663 )}; 656 print( reverseArgs(1-2) ); <font color=green># 2-1 == 1</font> 664 print( reverseArgs(1-2) ); <font color=green># 2-1 == 1</font> 657 </pre> 665 </pre> 658 <p> 666 <p> 659 <tt>reverseArgs</tt> は、関数呼び出しの構文木の、引数の順番を逆転する関数です。 667 <tt>reverseArgs</tt> は、関数呼び出しの構文木の、引数の順番を逆転する関数です。 660 <tt>@macro(e)</tt> によってマクロレイヤにセットされている構文木引数を取り出し、 668 <tt>@macro(e)</tt> によってマクロレイヤにセットされている構文木引数を取り出し、 661 それを <tt>@value</tt> レイヤによる普通の計算プログラムで操作しています。 669 それを <tt>@value</tt> レイヤによる普通の計算プログラムで操作しています。 662 要は、<tt>@macro(...)</tt> はいわゆる「準クオート (quasiquote)」、 | 670 <tt>@macro(...)</tt> はいわゆる「準クオート (quasiquote)」、 663 <tt>@value(...)</tt> は「逆クオート (unquote)」に近い働きをします。 | 671 <tt>@value(...)</tt> は「逆クオート (unquote)」にちょっと近いかもしれません 664 </p> 672 </p> 665 <p> 673 <p> 666 <tt>@layer(...)</tt> だけでなく、関数のレイヤ指定引数なども同様に使うことができるので、 674 <tt>@layer(...)</tt> だけでなく、関数のレイヤ指定引数なども同様に使うことができるので、 667 一部の引数は <tt>@macro</tt>、一部の引数は <tt>@value</tt> レイヤで受け取る関数を書くなど、 675 一部の引数は <tt>@macro</tt>、一部の引数は <tt>@value</tt> レイヤで受け取る関数を書くなど、 668 さらに色々面白いことが可能です。 676 さらに色々面白いことが可能です。 669 </p> 677 </p> 670 </dd> 678 </dd> ................................................................................................................................................................................ 696 配列メンバは cons リストになって入ってきます。 704 配列メンバは cons リストになって入ってきます。 697 自分で構文木を作る時は、<tt>pos</tt> フィールドだけは省略しても構いません。 705 自分で構文木を作る時は、<tt>pos</tt> フィールドだけは省略しても構いません。 698 </p> 706 </p> 699 </dd> 707 </dd> 700 708 701 <script>explorer.outline.writeEnabled = true;</script> 709 <script>explorer.outline.writeEnabled = true;</script> 702 <dt><span class="decl"> 710 <dt><span class="decl"> 703 <span class="currsymbol">微妙なところ</span> | 711 <span class="currsymbol">微妙なところ</span> 704 <script>explorer.outline.addDecl('微妙なところ');</script> | 712 <script>explorer.outline.addDecl('微妙なところ');</script> 705 713 706 </span></dt> 714 </span></dt> 707 <script>explorer.outline.writeEnabled = false;</script> 715 <script>explorer.outline.writeEnabled = false;</script> 708 716 709 <dd><p> 717 <dd><p> 710 ここまで、<tt>@macro</tt> が本当にただの1レイヤあるかのように説明してきましたが、 | 718 ここまで、<tt>@macro</tt> が本当にただの1レイヤ説明してきましたが、 711 実はちょっと幾つかのトリックが潜んでいます。 | 719 実はちょっとトリックが潜んでいます。 712 </p> 720 </p> 713 <pre> 721 <pre> 714 &gt;&gt; @macro twice(x) {x; x} in twice(<b>@value</b>(print("Hello"))) 722 &gt;&gt; @macro twice(x) {x; x} in twice(<b>@value</b>(print("Hello"))) 715 Hello 723 Hello 716 Hello 724 Hello 717 Hello 725 Hello 718 </pre> 726 </pre> 719 <p> 727 <p> 720 先ほどの例に <tt>@value</tt> を増やしたものですが、これでもやはり、Hello 728 先ほどの例に <tt>@value</tt> を増やしたものですが、これでもやはり、Hello 721 が2回 print されるようになります。 | 729 が2回 print されるようになります。これは本来はおかしな話で、<tt>print("Hello")</tt> > 730 は <tt>@value</tt> レイヤで実行されて値に落ちるはずなので、1回しか print されないはず。 > 731 </p> > 732 <p> > 733 実は、Polemy の中では、<tt>@macro</tt> レイヤと <tt>(rawmacro)</tt> > 734 レイヤという二つの異なるマクロ用レイヤが動いています > 735 </p> > 736 <ul> > 737 <li><tt>(rawmacro)</tt> も <tt>@macro</tt> も、コードを動かすとそ構文木を返す意味論。</li> > 738 <li>ただし、<tt>(rawmacro)</tt> も <tt>@macro</tt> も、 > 739 <tt>@macro</tt> レイヤに値のセットされた変数をみつけたとは、 > 740 その変数という構文木を作るのではなく、変数の内容を展開。</li> > 741 <li>また <tt>@macro</tt> は、 > 742 レイヤ指定式を見ると実行レイヤを切り替て、構文木生成モードをやめてしまう。</li> > 743 <li><tt>(rawmacro)</tt> は、 > 744 レイヤ指定式を見ても実行レイヤを切り替えないで構文木にする。</li> > 745 </ul> > 746 <p> > 747 ユーザーから直接 <tt>(rawmacro)</tt> は呼べませんが、 > 748 「関数やトップレベル実行開始前のマクロ処理は <tt>(rawmacro)</tt> で実行開始」 > 749 「<tt>@macro</tt> レイヤ以外で呼び出した関数の仮引数に <tt>@macro</tt> がついていたら、 > 750 その実引数は <tt>(rawmacro)</tt> で実行」 > 751 という2つのタイミングで <tt>(rawmacro)</tt> が動き出します > 752 <tt>(rawmacro)</tt> が <tt>@macro</tt> レイヤから変数を見つけてマロし始める時に、 > 753 そこで <tt>@macro</tt> に動作が移ります。 > 754 </p> > 755 <p> > 756 こうなっているのは、全部がレイヤ指定式に反応する <tt>@macro</tt> の動作だと、 > 757 レイヤを使ったプログラムが全て <tt>@value</tt> 実行時ではなく、 > 758 マクロ展開の時点で動き始めてしまって、おかしなことにるためです。 > 759 色々考えた結果、とりあえずこの中途半端な混合が具合がいのではないかということになりました。 > 760 </p> > 761 </dd> > 762 > 763 <script>explorer.outline.writeEnabled = true;</script> > 764 <dt><span class="decl"> > 765 <span class="currsymbol">微妙なところ2</span> > 766 <script>explorer.outline.addDecl('微妙なところ2');</script> > 767 > 768 </span></dt> > 769 <script>explorer.outline.writeEnabled = false;</script> > 770 > 771 <dd><p> > 772 「関数実行開始時に、まずマクロレイヤを実行」と書きまたが、この時、関数内関数まで辿りにいくので、 > 773 何重にもネストした関数を使っていると、内側の関数は、重にもマクロ展開が走ってしまいます。 > 774 これはなにかおかしい気がしますね。Scheme などはどうなっいるのか調べないと…。 > 775 </p> > 776 </dd> > 777 > 778 <script>explorer.outline.writeEnabled = true;</script> > 779 <dt><span class="decl"> > 780 <span class="currsymbol">微妙なところ3</span> > 781 <script>explorer.outline.addDecl('微妙なところ3');</script> > 782 > 783 </span></dt> > 784 <script>explorer.outline.writeEnabled = false;</script> > 785 > 786 <dd><p> > 787 これはエラーになります。 722 </p> 788 </p> 723 <pre> 789 <pre> 724 <tt>@macro</tt> レイヤと <tt>(rawmacro)</tt> レイヤという二つが協調して動作しています。 | 790 &gt;&gt; let _ = (@macro twice(x) {x;x} in twice(print("Hello"))) 725 (rawmacro) レイヤの話 | 791 polemy.failure.RuntimeException@C:\Develop\Projects\Polemy\polemy\value.d(10 726 < 727 [[limitations]] < 728 < 729 This @macro layer is a very primitive one, and not a perfect macro language. < 730 Two major limitations are seen in the following "it" example. < 731 < 732 &gt;&gt; @macro LetItBe(x, y) { let it = x in y }; < 733 < 734 The variable name is not hygenic, and so without any effort, the syntax tree < 735 can access the outer variable "it". < 736 < 737 &gt;&gt; def foo() { LetItBe( 1+2+3, it*it ) } < 738 &gt;&gt; foo() < 739 36 < 740 < 741 Of course, this is not just a limitation; it can sometimes allow us to write < 742 many interesting macros. < 743 < 744 The other problem is that the macro expansion is only done at function startu < 745 So < 746 < 747 &gt;&gt; LetItBe( 1+2+3, it*it ) < 748 ...\value.d(173): [<REPL>:24:1] variable LetItBe is not set in layer @value < 749 < 750 you cannot directly use the macro in the same scope as the definition. < 751 You need to wrap it up in a function (like the foo() in the above example). < > 792 [<REPL>:2:35] 'twice' is not set in @value layer 752 </pre> 793 </pre> > 794 <p> > 795 どういうことかというと、<tt>@macro</tt> で定義したマクロはつから使えるようになるかという話で、 > 796 この <tt>@macro twice(x) {x;x} in ...</tt> の部分は <tt>@value</tt> レイヤの式なので、 > 797 まずこの式全体のマクロ展開が終わったあとにしか実行さないのです。<tt>twice</tt> > 798 がマクロと見なされはじめるのは、<tt>@macro</tt> 実行が終わた後。 > 799 なので、 > 800 例えば <tt>twice(print("Hello"))</tt> の部分を無名関数にラップしてやれば、 > 801 マクロ展開を遅らせられて、 ちゃんと実行ができます。 > 802 </p> > 803 <p> > 804 これだと余りにも不便なので、関数のトップレベルの変数言式の列についてだけは、 > 805 <tt>@macro</tt> と <tt>@value</tt> の評価を交互にインターリーブるようにしました。 > 806 「関数やREPLのトップレベルの最初に宣言したマクロだけはその関数内で即座に使える」わけです。 > 807 これも Scheme の let-syntax などなどの動きを調べて勉強しないと…。 > 808 </p> 753 </dd> 809 </dd> 754 </dl> 810 </dl> 755 <script>explorer.outline.decSymbolLevel();</script> 811 <script>explorer.outline.decSymbolLevel();</script> 756 812 757 813 758 </dd> 814 </dd> 759 815 ................................................................................................................................................................................ 877 <script>explorer.outline.decSymbolLevel();</script> 933 <script>explorer.outline.decSymbolLevel();</script> 878 934 879 935 880 </td></tr> 936 </td></tr> 881 <tr><td id="docfooter"> 937 <tr><td id="docfooter"> 882 Page was generated with 938 Page was generated with 883 <img src="candydoc/img/candydoc.gif" style="vertical-ali 939 <img src="candydoc/img/candydoc.gif" style="vertical-ali 884 on Fri Nov 26 16:41:52 2010 | 940 on Sat Nov 27 01:54:49 2010 885 941 886 </td></tr> 942 </td></tr> 887 </table> 943 </table> 888 </div> 944 </div> 889 <script> 945 <script> 890 explorer.packageExplorer.addModule("index"); 946 explorer.packageExplorer.addModule("index"); 891 explorer.packageExplorer.addModule("main"); 947 explorer.packageExplorer.addModule("main");

Modified doc/layer.html from [a4f78e6e3d8c715a] to [136da3cf5e90765a].

163 <script>explorer.outline.decSymbolLevel();</script> 163 <script>explorer.outline.decSymbolLevel();</script> 164 164 165 165 166 </td></tr> 166 </td></tr> 167 <tr><td id="docfooter"> 167 <tr><td id="docfooter"> 168 Page was generated with 168 Page was generated with 169 <img src="candydoc/img/candydoc.gif" style="vertical-ali 169 <img src="candydoc/img/candydoc.gif" style="vertical-ali 170 on Fri Nov 26 16:41:46 2010 | 170 on Sat Nov 27 01:17:58 2010 171 171 172 </td></tr> 172 </td></tr> 173 </table> 173 </table> 174 </div> 174 </div> 175 <script> 175 <script> 176 explorer.packageExplorer.addModule("index"); 176 explorer.packageExplorer.addModule("index"); 177 explorer.packageExplorer.addModule("main"); 177 explorer.packageExplorer.addModule("main");

Modified doc/lex.html from [b039dcaea4552a8f] to [4b49ee7344141eea].

307 <script>explorer.outline.decSymbolLevel();</script> 307 <script>explorer.outline.decSymbolLevel();</script> 308 308 309 309 310 </td></tr> 310 </td></tr> 311 <tr><td id="docfooter"> 311 <tr><td id="docfooter"> 312 Page was generated with 312 Page was generated with 313 <img src="candydoc/img/candydoc.gif" style="vertical-ali 313 <img src="candydoc/img/candydoc.gif" style="vertical-ali 314 on Fri Nov 26 16:41:47 2010 | 314 on Sat Nov 27 01:17:59 2010 315 315 316 </td></tr> 316 </td></tr> 317 </table> 317 </table> 318 </div> 318 </div> 319 <script> 319 <script> 320 explorer.packageExplorer.addModule("index"); 320 explorer.packageExplorer.addModule("index"); 321 explorer.packageExplorer.addModule("main"); 321 explorer.packageExplorer.addModule("main");

Modified doc/main.html from [d5dd76810e38b7f6] to [0482b340bcdb09a1].

62 <script>explorer.outline.decSymbolLevel();</script> 62 <script>explorer.outline.decSymbolLevel();</script> 63 63 64 64 65 </td></tr> 65 </td></tr> 66 <tr><td id="docfooter"> 66 <tr><td id="docfooter"> 67 Page was generated with 67 Page was generated with 68 <img src="candydoc/img/candydoc.gif" style="vertical-ali 68 <img src="candydoc/img/candydoc.gif" style="vertical-ali 69 on Fri Nov 26 16:41:42 2010 | 69 on Sat Nov 27 01:17:56 2010 70 70 71 </td></tr> 71 </td></tr> 72 </table> 72 </table> 73 </div> 73 </div> 74 <script> 74 <script> 75 explorer.packageExplorer.addModule("index"); 75 explorer.packageExplorer.addModule("index"); 76 explorer.packageExplorer.addModule("main"); 76 explorer.packageExplorer.addModule("main");

Modified doc/parse.html from [e3b4b64f19f93798] to [b7809106bd8bbf5f].

56 <script>explorer.outline.decSymbolLevel();</script> 56 <script>explorer.outline.decSymbolLevel();</script> 57 57 58 58 59 </td></tr> 59 </td></tr> 60 <tr><td id="docfooter"> 60 <tr><td id="docfooter"> 61 Page was generated with 61 Page was generated with 62 <img src="candydoc/img/candydoc.gif" style="vertical-ali 62 <img src="candydoc/img/candydoc.gif" style="vertical-ali 63 on Fri Nov 26 16:41:48 2010 | 63 on Sat Nov 27 01:17:59 2010 64 64 65 </td></tr> 65 </td></tr> 66 </table> 66 </table> 67 </div> 67 </div> 68 <script> 68 <script> 69 explorer.packageExplorer.addModule("index"); 69 explorer.packageExplorer.addModule("index"); 70 explorer.packageExplorer.addModule("main"); 70 explorer.packageExplorer.addModule("main");

Modified doc/repl.html from [f38bae3012b6b256] to [06b9b45e10860394].

156 <script>explorer.outline.decSymbolLevel();</script> 156 <script>explorer.outline.decSymbolLevel();</script> 157 157 158 158 159 </td></tr> 159 </td></tr> 160 <tr><td id="docfooter"> 160 <tr><td id="docfooter"> 161 Page was generated with 161 Page was generated with 162 <img src="candydoc/img/candydoc.gif" style="vertical-ali 162 <img src="candydoc/img/candydoc.gif" style="vertical-ali 163 on Fri Nov 26 16:41:48 2010 | 163 on Sat Nov 27 01:18:00 2010 164 164 165 </td></tr> 165 </td></tr> 166 </table> 166 </table> 167 </div> 167 </div> 168 <script> 168 <script> 169 explorer.packageExplorer.addModule("index"); 169 explorer.packageExplorer.addModule("index"); 170 explorer.packageExplorer.addModule("main"); 170 explorer.packageExplorer.addModule("main");

Modified doc/runtime.html from [fb971a54db14120e] to [05c59f5e4897aa6d].

42 <script>explorer.outline.decSymbolLevel();</script> 42 <script>explorer.outline.decSymbolLevel();</script> 43 43 44 44 45 </td></tr> 45 </td></tr> 46 <tr><td id="docfooter"> 46 <tr><td id="docfooter"> 47 Page was generated with 47 Page was generated with 48 <img src="candydoc/img/candydoc.gif" style="vertical-ali 48 <img src="candydoc/img/candydoc.gif" style="vertical-ali 49 on Fri Nov 26 16:41:49 2010 | 49 on Sat Nov 27 01:18:00 2010 50 50 51 </td></tr> 51 </td></tr> 52 </table> 52 </table> 53 </div> 53 </div> 54 <script> 54 <script> 55 explorer.packageExplorer.addModule("index"); 55 explorer.packageExplorer.addModule("index"); 56 explorer.packageExplorer.addModule("main"); 56 explorer.packageExplorer.addModule("main");

Modified doc/test.html from [65937464daabbe41] to [2826fbbbd41fd9fd].

143 <script>explorer.outline.decSymbolLevel();</script> 143 <script>explorer.outline.decSymbolLevel();</script> 144 144 145 145 146 </td></tr> 146 </td></tr> 147 <tr><td id="docfooter"> 147 <tr><td id="docfooter"> 148 Page was generated with 148 Page was generated with 149 <img src="candydoc/img/candydoc.gif" style="vertical-ali 149 <img src="candydoc/img/candydoc.gif" style="vertical-ali 150 on Fri Nov 26 16:41:51 2010 | 150 on Sat Nov 27 01:18:02 2010 151 151 152 </td></tr> 152 </td></tr> 153 </table> 153 </table> 154 </div> 154 </div> 155 <script> 155 <script> 156 explorer.packageExplorer.addModule("index"); 156 explorer.packageExplorer.addModule("index"); 157 explorer.packageExplorer.addModule("main"); 157 explorer.packageExplorer.addModule("main");

Modified doc/tricks.html from [66f1242be8634b07] to [3a211e8310f22d0a].

246 <script>explorer.outline.decSymbolLevel();</script> 246 <script>explorer.outline.decSymbolLevel();</script> 247 247 248 248 249 </td></tr> 249 </td></tr> 250 <tr><td id="docfooter"> 250 <tr><td id="docfooter"> 251 Page was generated with 251 Page was generated with 252 <img src="candydoc/img/candydoc.gif" style="vertical-ali 252 <img src="candydoc/img/candydoc.gif" style="vertical-ali 253 on Fri Nov 26 16:41:52 2010 | 253 on Sat Nov 27 01:18:02 2010 254 254 255 </td></tr> 255 </td></tr> 256 </table> 256 </table> 257 </div> 257 </div> 258 <script> 258 <script> 259 explorer.packageExplorer.addModule("index"); 259 explorer.packageExplorer.addModule("index"); 260 explorer.packageExplorer.addModule("main"); 260 explorer.packageExplorer.addModule("main");

Modified doc/value.html from [4d6f8832c63e974c] to [56bfccf06cb302b1].

63 63 64 64 65 <dd><br><br> 65 <dd><br><br> 66 </dd> 66 </dd> 67 67 68 <script>explorer.outline.writeEnabled = true;</script> 68 <script>explorer.outline.writeEnabled = true;</script> 69 <dt><span class="decl">class 69 <dt><span class="decl">class 70 <span class="currsymbol">UndefinedValue</span> | 70 <span class="currsymbol">BottomValue</span> 71 <script>explorer.outline.addDecl('UndefinedValue');</script> | 71 <script>explorer.outline.addDecl('BottomValue');</script> 72 72 73 : polemy.value.Value; 73 : polemy.value.Value; 74 </span></dt> 74 </span></dt> 75 <script>explorer.outline.writeEnabled = false;</script> 75 <script>explorer.outline.writeEnabled = false;</script> 76 76 77 77 78 <dd><br><br> 78 <dd><br><br> ................................................................................................................................................................................ 259 <script>explorer.outline.decSymbolLevel();</script> 259 <script>explorer.outline.decSymbolLevel();</script> 260 260 261 261 262 </td></tr> 262 </td></tr> 263 <tr><td id="docfooter"> 263 <tr><td id="docfooter"> 264 Page was generated with 264 Page was generated with 265 <img src="candydoc/img/candydoc.gif" style="vertical-ali 265 <img src="candydoc/img/candydoc.gif" style="vertical-ali 266 on Fri Nov 26 16:41:50 2010 | 266 on Sat Nov 27 01:18:01 2010 267 267 268 </td></tr> 268 </td></tr> 269 </table> 269 </table> 270 </div> 270 </div> 271 <script> 271 <script> 272 explorer.packageExplorer.addModule("index"); 272 explorer.packageExplorer.addModule("index"); 273 explorer.packageExplorer.addModule("main"); 273 explorer.packageExplorer.addModule("main");

Modified doc/valueconv.html from [e08638d4763e1185] to [d3b97793d6c2afdf].

75 (T)(T <span class="funcparam">e</span>, Value delegate(AST) <span class="funcpar 75 (T)(T <span class="funcparam">e</span>, Value delegate(AST) <span class="funcpar 76 </span></dt> 76 </span></dt> 77 <script>explorer.outline.writeEnabled = false;</script> 77 <script>explorer.outline.writeEnabled = false;</script> 78 78 79 79 80 <dd>Convert AST to Table so that it can be used in Polemy<br><br> 80 <dd>Convert AST to Table so that it can be used in Polemy<br><br> 81 81 > 82 </dd> > 83 > 84 <script>explorer.outline.writeEnabled = true;</script> > 85 <dt><span class="decl">Value > 86 <span class="currsymbol">ast2table</span> > 87 <script>explorer.outline.addDecl('ast2table');</script> > 88 > 89 (T)(T <span class="funcparam">e</span>); > 90 </span></dt> > 91 <script>explorer.outline.writeEnabled = false;</script> > 92 > 93 > 94 <dd>No hook version<br><br> > 95 82 </dd> 96 </dd> 83 </dl> 97 </dl> 84 <script>explorer.outline.decSymbolLevel();</script> 98 <script>explorer.outline.decSymbolLevel();</script> 85 99 86 100 87 </td></tr> 101 </td></tr> 88 <tr><td id="docfooter"> 102 <tr><td id="docfooter"> 89 Page was generated with 103 Page was generated with 90 <img src="candydoc/img/candydoc.gif" style="vertical-ali 104 <img src="candydoc/img/candydoc.gif" style="vertical-ali 91 on Fri Nov 26 16:41:51 2010 | 105 on Sat Nov 27 01:18:01 2010 92 106 93 </td></tr> 107 </td></tr> 94 </table> 108 </table> 95 </div> 109 </div> 96 <script> 110 <script> 97 explorer.packageExplorer.addModule("index"); 111 explorer.packageExplorer.addModule("index"); 98 explorer.packageExplorer.addModule("main"); 112 explorer.packageExplorer.addModule("main");

Modified index.dd from [a7325259b4f09952] to [d2cf6de49dcafd42].

1 Ddoc 1 Ddoc 2 $(DDOC_AUTHORS k.inaba) 2 $(DDOC_AUTHORS k.inaba) 3 $(DDOC_LICENSE NYSL 0.9982 (http://www.kmonos.net/nysl/)) 3 $(DDOC_LICENSE NYSL 0.9982 (http://www.kmonos.net/nysl/)) 4 4 5 <p> 5 <p> 6 このファイルは、言語仕様などの簡単な説明です。 | 6 左のサイドバーの "Package" タブをクリックすると実装のソースのドキュメントが読めます。 7 </p> 7 </p> 8 <p> 8 <p> 9 とついでに、左イドバーの "Package" タブをクリックすると実装のソースのドキュメントが読めます。 | 9 のファイルは、言語仕様などやや辞書的な説明です。<br /> > 10 もっとざっくりとした、言語デザインの方向性の魂的なもについては、 > 11 「メタプログラミングの会」の発表スライドをご覧下さい > 12 </p> > 13 <p> > 14 あと、 やたらとマクロの章が長くなっていますが、 この部分は、 > 15 レイヤ機能を入れたら自動的にすごく自然にマクロが入るーと思って、 > 16 おまけで実装してみた程度のものです。 > 17 あんまり重要ではないので、適当にスルーして下さいませ > 18 単に、適当に入れたら適当で微妙な部分が多く残ってしまたので注意書きが増えているだけで…。 10 </p> 19 </p> 11 20 12 $(DDOC_MEMBERS 21 $(DDOC_MEMBERS 13 22 14 $(SECTION Syntax, $(SECBODY 23 $(SECTION Syntax, $(SECBODY 15 <p> 24 <p> 16 文法について。 25 文法について。 ................................................................................................................................................................................ 171 </pre> 180 </pre> 172 <p> 181 <p> 173 let-in を縦にチェインしたときだけ、同名変数を破壊的に上書きします 182 let-in を縦にチェインしたときだけ、同名変数を破壊的に上書きします 174 (再帰関数の定義が"うまく"いっているのはこの上書きのためです)。 183 (再帰関数の定義が"うまく"いっているのはこの上書きのためです)。 175 なんでこんなことになっているかというと、 184 なんでこんなことになっているかというと、 176 後で説明する「レイヤ」を使ったときに 185 後で説明する「レイヤ」を使ったときに 177 <tt>let foo = ... in @lay foo = ... in ...</tt> 186 <tt>let foo = ... in @lay foo = ... in ...</tt> 178 で他レイヤに重ね書きするためあります。 | 187 で他レイヤに重ね書きするためのつもりです。詳しくは後で 179 </p> 188 </p> 180 )) 189 )) 181 ) 190 ) 182 )) 191 )) 183 192 184 193 185 194 ................................................................................................................................................................................ 203 以下のデータ型があります。 212 以下のデータ型があります。 204 </p> 213 </p> 205 <ul> 214 <ul> 206 <li>整数: <tt>0</tt>, <tt>123</tt>, <tt>456666666666666666666666666666666666 215 <li>整数: <tt>0</tt>, <tt>123</tt>, <tt>456666666666666666666666666666666666 207 <li>文字列: <tt>"hello, world!"</tt>, ...</li> 216 <li>文字列: <tt>"hello, world!"</tt>, ...</li> 208 <li>関数: <tt>fun(x){x+1}</tt></li> 217 <li>関数: <tt>fun(x){x+1}</tt></li> 209 <li>テーブル: <tt>{car: 1, cdr: {car: 2, cdr: {}}}</tt></li> 218 <li>テーブル: <tt>{car: 1, cdr: {car: 2, cdr: {}}}</tt></li> 210 <li>未定義値: (特殊なケースで作られます。「レイヤ」の説明参照のこと。)</li> | 219 <li>ボトム: (特殊なケースで作られます。「レイヤ」の説明参照のこと。)</li> 211 </ul> 220 </ul> 212 <p> 221 <p> 213 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 222 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 214 テーブルはいわゆるプロトタイプチェーンを持っていて、 223 テーブルはいわゆるプロトタイプチェーンを持っていて、 215 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 224 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 216 フィールドの書き換えがないので、これは特に意味ないかもしれない…。 225 フィールドの書き換えがないので、これは特に意味ないかもしれない…。 217 </p> 226 </p> ................................................................................................................................................................................ 444 </pre> 453 </pre> 445 <p> 454 <p> 446 動きとしてはこうです。 455 動きとしてはこうです。 447 </p> 456 </p> 448 <ol> 457 <ol> 449 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 458 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 450 まず、<code>@macro</code> レイヤでコードを実行。</li> 459 まず、<code>@macro</code> レイヤでコードを実行。</li> 451 <li>返ってきた構文木を、<code>@value</code> レイヤ、 < 452 またはその関数を呼び出したときのレイヤで実行。</li> | 460 <li>返ってきた構文木を、その関数を呼び出したときのレイヤで実行。</li> 453 </ol> 461 </ol> 454 <p> 462 <p> 455 <code>@macro</code> レイヤも所詮ただのレイヤですので、 463 <code>@macro</code> レイヤも所詮ただのレイヤですので、 456 上で説明した方法で <code>@macro</code> レイヤに関数などを登録しておくことで、 464 上で説明した方法で <code>@macro</code> レイヤに関数などを登録しておくことで、 457 構文木の生成をいじることが可能です。まさにマクロ。 465 構文木の生成をいじることが可能です。まさにマクロ。 458 </p> 466 </p> 459 467 ................................................................................................................................................................................ 526 )}; 534 )}; 527 print( reverseArgs(1-2) ); $(D_COMMENT # 2-1 == 1) 535 print( reverseArgs(1-2) ); $(D_COMMENT # 2-1 == 1) 528 </pre> 536 </pre> 529 <p> 537 <p> 530 <tt>reverseArgs</tt> は、関数呼び出しの構文木の、引数の順番を逆転する関数です。 538 <tt>reverseArgs</tt> は、関数呼び出しの構文木の、引数の順番を逆転する関数です。 531 <tt>@macro(e)</tt> によってマクロレイヤにセットされている構文木引数を取り出し、 539 <tt>@macro(e)</tt> によってマクロレイヤにセットされている構文木引数を取り出し、 532 それを <tt>@value</tt> レイヤによる普通の計算プログラムで操作しています。 540 それを <tt>@value</tt> レイヤによる普通の計算プログラムで操作しています。 533 要は、<tt>@macro(...)</tt> はいわゆる「準クオート (quasiquote)」、 | 541 <tt>@macro(...)</tt> はいわゆる「準クオート (quasiquote)」、 534 <tt>@value(...)</tt> は「逆クオート (unquote)」に近い働きをします。 | 542 <tt>@value(...)</tt> は「逆クオート (unquote)」にちょっと近いかもしれません 535 </p> 543 </p> 536 <p> 544 <p> 537 <tt>@layer(...)</tt> だけでなく、関数のレイヤ指定引数なども同様に使うことができるので、 545 <tt>@layer(...)</tt> だけでなく、関数のレイヤ指定引数なども同様に使うことができるので、 538 一部の引数は <tt>@macro</tt>、一部の引数は <tt>@value</tt> レイヤで受け取る関数を書くなど、 546 一部の引数は <tt>@macro</tt>、一部の引数は <tt>@value</tt> レイヤで受け取る関数を書くなど、 539 さらに色々面白いことが可能です。 547 さらに色々面白いことが可能です。 540 </p> 548 </p> 541 )) 549 )) ................................................................................................................................................................................ 556 <p> 564 <p> 557 こんな感じのテーブルになります。 565 こんな感じのテーブルになります。 558 クラス名が <tt>is</tt> フィールドに、メンバ変数はそのままの名前で入ります。 566 クラス名が <tt>is</tt> フィールドに、メンバ変数はそのままの名前で入ります。 559 配列メンバは cons リストになって入ってきます。 567 配列メンバは cons リストになって入ってきます。 560 自分で構文木を作る時は、<tt>pos</tt> フィールドだけは省略しても構いません。 568 自分で構文木を作る時は、<tt>pos</tt> フィールドだけは省略しても構いません。 561 </p> 569 </p> 562 )) 570 )) 563 $(SECTION 微妙なところ, $(SECBODY | 571 $(SECTION 微妙なところ, $(SECBODY 564 <p> 572 <p> 565 ここまで、<tt>@macro</tt> が本当にただの1レイヤあるかのように説明してきましたが、 | 573 ここまで、<tt>@macro</tt> が本当にただの1レイヤ説明してきましたが、 566 実はちょっと幾つかのトリックが潜んでいます。 | 574 実はちょっとトリックが潜んでいます。 567 </p> 575 </p> 568 <pre> 576 <pre> 569 &gt;&gt; @macro twice(x) {x; x} in twice($(B @value)(print("Hello"))) 577 &gt;&gt; @macro twice(x) {x; x} in twice($(B @value)(print("Hello"))) 570 Hello 578 Hello 571 Hello 579 Hello 572 Hello 580 Hello 573 </pre> 581 </pre> 574 <p> 582 <p> 575 先ほどの例に <tt>@value</tt> を増やしたものですが、これでもやはり、Hello 583 先ほどの例に <tt>@value</tt> を増やしたものですが、これでもやはり、Hello 576 が2回 print されるようになります。 | 584 が2回 print されるようになります。これは本来はおかしな話で、<tt>print("Hello")</tt> > 585 は <tt>@value</tt> レイヤで実行されて値に落ちるはずなので、1回しか print されないはず。 > 586 </p> > 587 <p> > 588 実は、Polemy の中では、<tt>@macro</tt> レイヤと <tt>(rawmacro)</tt> > 589 レイヤという二つの異なるマクロ用レイヤが動いています > 590 </p> > 591 <ul> > 592 <li><tt>(rawmacro)</tt> も <tt>@macro</tt> も、コードを動かすとそ構文木を返す意味論。</li> > 593 <li>ただし、<tt>(rawmacro)</tt> も <tt>@macro</tt> も、 > 594 <tt>@macro</tt> レイヤに値のセットされた変数をみつけたとは、 > 595 その変数という構文木を作るのではなく、変数の内容を展開。</li> > 596 <li>また <tt>@macro</tt> は、 > 597 レイヤ指定式を見ると実行レイヤを切り替て、構文木生成モードをやめてしまう。</li> > 598 <li><tt>(rawmacro)</tt> は、 > 599 レイヤ指定式を見ても実行レイヤを切り替えないで構文木にする。</li> > 600 </ul> > 601 <p> > 602 ユーザーから直接 <tt>(rawmacro)</tt> は呼べませんが、 > 603 「関数やトップレベル実行開始前のマクロ処理は <tt>(rawmacro)</tt> で実行開始」 > 604 「<tt>@macro</tt> レイヤ以外で呼び出した関数の仮引数に <tt>@macro</tt> がついていたら、 > 605 その実引数は <tt>(rawmacro)</tt> で実行」 > 606 という2つのタイミングで <tt>(rawmacro)</tt> が動き出します > 607 <tt>(rawmacro)</tt> が <tt>@macro</tt> レイヤから変数を見つけてマロし始める時に、 > 608 そこで <tt>@macro</tt> に動作が移ります。 > 609 </p> > 610 <p> > 611 こうなっているのは、全部がレイヤ指定式に反応する <tt>@macro</tt> の動作だと、 > 612 レイヤを使ったプログラムが全て <tt>@value</tt> 実行時ではなく、 > 613 マクロ展開の時点で動き始めてしまって、おかしなことにるためです。 > 614 色々考えた結果、とりあえずこの中途半端な混合が具合がいのではないかということになりました。 > 615 </p> > 616 )) > 617 $(SECTION 微妙なところ2, $(SECBODY > 618 <p> > 619 「関数実行開始時に、まずマクロレイヤを実行」と書きまたが、この時、関数内関数まで辿りにいくので、 > 620 何重にもネストした関数を使っていると、内側の関数は、重にもマクロ展開が走ってしまいます。 > 621 これはなにかおかしい気がしますね。Scheme などはどうなっいるのか調べないと…。 > 622 </p> > 623 )) > 624 $(SECTION 微妙なところ3, $(SECBODY > 625 <p> > 626 これはエラーになります。 577 </p> 627 </p> 578 <pre> 628 <pre> 579 <tt>@macro</tt> レイヤと <tt>(rawmacro)</tt> レイヤという二つが協調して動作しています。 | 629 &gt;&gt; let _ = (@macro twice(x) {x;x} in twice(print("Hello"))) 580 (rawmacro) レイヤの話 | 630 polemy.failure.RuntimeException@C:\Develop\Projects\Polemy\polemy\value.d(10 581 < 582 [[limitations]] < 583 < 584 This @macro layer is a very primitive one, and not a perfect macro language. < 585 Two major limitations are seen in the following "it" example. < 586 < 587 >> @macro LetItBe(x, y) { let it = x in y }; < 588 < 589 The variable name is not hygenic, and so without any effort, the syntax tree < 590 can access the outer variable "it". < 591 < 592 >> def foo() { LetItBe( 1+2+3, it*it ) } < 593 >> foo() < 594 36 < 595 < 596 Of course, this is not just a limitation; it can sometimes allow us to write < 597 many interesting macros. < 598 < 599 The other problem is that the macro expansion is only done at function startu < 600 So < 601 < 602 >> LetItBe( 1+2+3, it*it ) < 603 ...\value.d(173): [<REPL>:24:1] variable LetItBe is not set in layer @value < 604 < 605 you cannot directly use the macro in the same scope as the definition. < 606 You need to wrap it up in a function (like the foo() in the above example). < > 631 [<REPL>:2:35] 'twice' is not set in @value layer 607 </pre> 632 </pre> > 633 <p> > 634 どういうことかというと、<tt>@macro</tt> で定義したマクロはつから使えるようになるかという話で、 > 635 この <tt>@macro twice(x) {x;x} in ...</tt> の部分は <tt>@value</tt> レイヤの式なので、 > 636 まずこの式全体のマクロ展開が終わったあとにしか実行さないのです。<tt>twice</tt> > 637 がマクロと見なされはじめるのは、<tt>@macro</tt> 実行が終わた後。 > 638 なので、 > 639 例えば <tt>twice(print("Hello"))</tt> の部分を無名関数にラップしてやれば、 > 640 マクロ展開を遅らせられて、 ちゃんと実行ができます。 > 641 </p> > 642 <p> > 643 これだと余りにも不便なので、関数のトップレベルの変数言式の列についてだけは、 > 644 <tt>@macro</tt> と <tt>@value</tt> の評価を交互にインターリーブるようにしました。 > 645 「関数やREPLのトップレベルの最初に宣言したマクロだけはその関数内で即座に使える」わけです。 > 646 これも Scheme の let-syntax などなどの動きを調べて勉強しないと…。 > 647 </p> 608 )) 648 )) 609 ) 649 ) 610 )) 650 )) 611 651 612 652 613 $(SECTION Built-in Primitives, $(SECBODY 653 $(SECTION Built-in Primitives, $(SECBODY 614 <p> 654 <p>

Modified polemy/eval.d from [10da2d7378e56ec4] to [9460508c714f0a1b].

15 import polemy.valueconv; 15 import polemy.valueconv; 16 import std.signals; 16 import std.signals; 17 17 18 /// Objects for maitaining global environment and evaluation of expression on it 18 /// Objects for maitaining global environment and evaluation of expression on it 19 class Evaluator 19 class Evaluator 20 { 20 { 21 public: 21 public: 22 /// Initialize evaluator with empty context < 23 this() { theContext = new Table; } < 24 < 25 /// Evaluate the AST 22 /// Evaluate the AST 26 Value evalAST(AST e) 23 Value evalAST(AST e) 27 { | 24 { return getLayerEval(ValueLayer).macroAndEval(e, theContext, La 28 return macroAndEval(e, ValueLayer, theContext, OverwriteCtx); < 29 } < 30 25 31 /// Evaluate the string 26 /// Evaluate the string 32 Value evalString(S,T...)(S str, T fn_ln_cn) 27 Value evalString(S,T...)(S str, T fn_ln_cn) 33 { < 34 return evalAST(parseString(str,fn_ln_cn)); | 28 { return evalAST(parseString(str,fn_ln_cn)); } 35 } < 36 29 37 /// Evaluate the file 30 /// Evaluate the file 38 Value evalFile(S,T...)(S filename, T ln_cn) 31 Value evalFile(S,T...)(S filename, T ln_cn) 39 { < 40 return evalAST(parseFile(filename,ln_cn)); | 32 { return evalAST(parseFile(filename,ln_cn)); } 41 } < 42 33 43 /// Get the global context 34 /// Get the global context 44 Table globalContext() 35 Table globalContext() > 36 { return theContext; } > 37 > 38 /// Initialize evaluator with empty context > 39 this() 45 { 40 { 46 return theContext; | 41 theContext = new Table; > 42 theLayers[ValueLayer] = new ValueLayerEval; > 43 theLayers[MacroLayer] = new MacroLayerEval; > 44 theLayers[RawMacroLayer] = new RawMacroLayerEval; 47 } 45 } 48 46 49 private: 47 private: 50 Table theContext; | 48 Table theContext; > 49 LayerEval[Layer] theLayers; 51 50 52 enum : bool { CascadeCtx=false, OverwriteCtx=true }; | 51 /// Get the layer evaluator from layer ID 53 < 54 LayerEval getLayerEvaluator(Layer lay) | 52 LayerEval getLayerEval(Layer lay) 55 { 53 { 56 if( lay == ValueLayer ) | 54 if(auto p = lay in theLayers) 57 return new ValueLayerEval; | 55 return *p; 58 if( lay == RawMacroLayer ) < 59 return new RawMacroLayerEval; < 60 if( lay == MacroLayer ) < 61 return new MacroLayerEval; < 62 return new UserDefinedLayerEval(lay); | 56 return theLayers[lay] = new UserDefinedLayerEval(lay); 63 } 57 } 64 58 > 59 /// Interface of layers 65 abstract class LayerEval 60 abstract class LayerEval 66 { 61 { > 62 enum : bool { CascadeCtx=false, OverwriteCtx=true }; > 63 67 /// Concrete layers should implement these 64 /// Concrete layers should implement these 68 Layer currentLayer(); | 65 protected Layer layerID(); 69 Value eval_( Die e, Table ctx, bool ctxMod );/// | 66 protected Value eval_( Die e, Table ctx, bool ctxMod );/// 70 Value eval_( Str e, Table ctx, bool ctxMod );/// | 67 protected Value eval_( Str e, Table ctx, bool ctxMod );/// 71 Value eval_( Int e, Table ctx, bool ctxMod );/// | 68 protected Value eval_( Int e, Table ctx, bool ctxMod );/// 72 Value eval_( Var e, Table ctx, bool ctxMod );/// | 69 protected Value eval_( Var e, Table ctx, bool ctxMod );/// 73 Value eval_( Lay e, Table ctx, bool ctxMod );/// | 70 protected Value eval_( Lay e, Table ctx, bool ctxMod );/// 74 Value eval_( Let e, Table ctx, bool ctxMod );/// | 71 protected Value eval_( Let e, Table ctx, bool ctxMod );/// 75 Value eval_( App e, Table ctx, bool ctxMod );/// | 72 protected Value eval_( App e, Table ctx, bool ctxMod );/// 76 Value eval_( Fun e, Table ctx, bool ctxMod );/// | 73 protected Value eval_( Fun e, Table ctx, bool ctxMod );/// > 74 > 75 /// Should override this also, if the layer may return null for > 76 Value evalToNonNull( AST e, Table ctx, bool ctxMod = CascadeCtx > 77 { return eval(e,ctx,ctxMod); } > 78 > 79 /// Do macro expansion first, and then eval. Should override thi > 80 Value macroAndEval( AST e, Table ctx, bool ctxMod = CascadeCtx ) > 81 { return evalToNonNull(e,ctx,ctxMod); } 77 82 78 /// dynamic-overload-resolution 83 /// dynamic-overload-resolution 79 Value eval( AST e, Table ctx, bool ctxMod ) | 84 Value eval( AST e, Table ctx, bool ctxMod = CascadeCtx ) 80 { 85 { 81 enum funName = "eval_"; // modify here t | 86 enum funName = "eval_"; // modify here f 82 alias TypeTuple!(e,ctx,ctxMod) params; // modify here t | 87 alias TypeTuple!(e,ctx,ctxMod) params; // modify here f 83 88 84 alias typeof(__traits(getOverloads, this, funName)) ovTy 89 alias typeof(__traits(getOverloads, this, funName)) ovTy 85 alias staticMap!(firstParam, ovTypes) fstTy 90 alias staticMap!(firstParam, ovTypes) fstTy 86 alias DerivedToFront!(fstTypes) fstTypes_sor 91 alias DerivedToFront!(fstTypes) fstTypes_sor 87 foreach(i, T; fstTypes_sorted) 92 foreach(i, T; fstTypes_sorted) 88 static if( is(T == typeof(params[0])) ) {} else 93 static if( is(T == typeof(params[0])) ) {} else 89 return __traits(getOverloads, this, funN 94 return __traits(getOverloads, this, funN 90 95 91 // modify here to customize the default behavior 96 // modify here to customize the default behavior 92 assert(false, text("eval() for ",typeid(e)," [",e.pos,"] 97 assert(false, text("eval() for ",typeid(e)," [",e.pos,"] 93 } 98 } 94 99 95 /// | 100 /// Function calling convention. > 101 /// Run all arugment AST in the appropriate layer and invoke the 96 Value invokeFunction(Value _f, AST[] args, Table ctx, LexPositio | 102 Value invokeFunction(Value f_, AST[] args, Table ctx, LexPositio 97 { 103 { 98 if(auto f = cast(FunValue)_f) | 104 FunValue f = cast(FunValue)f_; > 105 if( f is null ) > 106 throw genex!RuntimeException(pos, text("tried to > 107 if( f.params().length != args.length ) > 108 throw genex!RuntimeException(pos, > 109 sprintf!("%d arguments required but %d p 99 { | 110 100 Table newCtx = new Table(f.definitionContext(), | 111 Table newCtx = new Table(f.definitionContext(), Table.Ki 101 foreach(i,p; f.params()) | 112 foreach(i,p; f.params()) 102 if( p.layers.empty ) { | 113 if( p.layers.empty ) 103 Value v = this.eval(args[i], ctx < 104 if(v is null) v = ast2table(args < 105 newCtx.set(p.name, currentLayer( | 114 newCtx.set(p.name, layerID(), this.evalT > 115 else > 116 foreach(argLay; p.layers) > 117 { > 118 Layer ll = argLay; > 119 if( isMacroLayer(argLay) && type > 120 ll = RawMacroLayer; // e > 121 newCtx.set(p.name, argLay, getLa 106 } 122 } 107 else < 108 foreach(argLay; p.layers) { < 109 Layer ll = argLay; < 110 if( isMacroLayer(argLay) < 111 ll = RawMacroLay < 112 Value v = getLayerEvalua < 113 if(v is null) v = ast2ta < 114 newCtx.set(p.name, argLa < 115 } < 116 scope _ = new PushCallStack(pos, callstackmsg); | 123 scope _ = new PushCallStack(pos, callstackmsg); 117 return f.invoke(currentLayer(), newCtx, pos); | 124 return f.invoke(layerID(), newCtx, pos); 118 } < 119 throw genex!RuntimeException(pos, text("tried to call no < 120 } 125 } 121 126 122 /// | 127 /// Lift the value v to the current layer 123 Value lift(Value v, Table ctx, LexPosition pos) 128 Value lift(Value v, Table ctx, LexPosition pos) 124 { 129 { 125 Layer lay = currentLayer(); < 126 < 127 // functions are automatically lifterd | 130 // functions are automatically lifted by itself 128 if( cast(FunValue) v ) 131 if( cast(FunValue) v ) 129 return v; 132 return v; 130 133 > 134 Layer lay = layerID(); > 135 > 136 // load the lift function 131 if( !ctx.has(lay, LiftLayer) ) 137 if( !ctx.has(lay, LiftLayer) ) 132 throw genex!RuntimeException(pos, "lift function 138 throw genex!RuntimeException(pos, "lift function 133 139 134 // similar to invokeFunction, but with only one argument < 135 auto _f = ctx.get(lay, LiftLayer, pos); | 140 Value f_ = ctx.get(lay, LiftLayer, pos); 136 if(auto f = cast(FunValue)_f) | 141 FunValue f = cast(FunValue) f_; 137 { < > 142 if( f is null ) > 143 throw genex!RuntimeException(pos, 138 Table newCtx = new Table(f.definitionContext(), | 144 text("non-function ", f_, " is registere 139 auto ps = f.params(); | 145 if( f.params().length != 1 || f.params()[0].layers.lengt 140 if( ps.length != 1 ) < 141 throw genex!RuntimeException(pos, | 146 throw genex!RuntimeException(pos, 142 text("lift function for", lay, " < 143 if( ps[0].layers.length==0 || ps[0].layers.lengt < > 147 text("lift function must take exactly 1 144 { | 148 > 149 // invokeFunction > 150 Table newCtx = new Table(f.definitionContext(), Table.Ki 145 newCtx.set(ps[0].name, ValueLayer, v); | 151 newCtx.set(f.params()[0].name, ValueLayer, v); 146 scope _ = new PushCallStack(pos, lay); | 152 scope _ = new PushCallStack(pos, "lift to "~lay); 147 return f.invoke(ValueLayer, newCtx, pos) | 153 return f.invoke(ValueLayer, newCtx, pos); 148 } < 149 else < 150 throw genex!RuntimeException(pos, < 151 text("lift function for", lay, " < 152 } < 153 throw genex!RuntimeException(pos, < 154 text("non-function ", _f, " is registered as the < 155 } 154 } 156 } 155 } 157 156 158 /// Evaluator for standard @value semantics 157 /// Evaluator for standard @value semantics 159 class ValueLayerEval : LayerEval 158 class ValueLayerEval : LayerEval 160 { 159 { 161 override Layer currentLayer() | 160 override Layer layerID() 162 { 161 { 163 return ValueLayer; 162 return ValueLayer; 164 } 163 } 165 override Value eval_( Die e, Table ctx, bool ctxMod ) 164 override Value eval_( Die e, Table ctx, bool ctxMod ) 166 { 165 { 167 throw genex!RuntimeException(e.pos, "undefined case"); 166 throw genex!RuntimeException(e.pos, "undefined case"); 168 } 167 } ................................................................................................................................................................................ 172 } 171 } 173 override Value eval_( Int e, Table ctx, bool ctxMod ) 172 override Value eval_( Int e, Table ctx, bool ctxMod ) 174 { 173 { 175 return new IntValue(e.data); 174 return new IntValue(e.data); 176 } 175 } 177 override Value eval_( Var e, Table ctx, bool ctxMod ) 176 override Value eval_( Var e, Table ctx, bool ctxMod ) 178 { 177 { 179 return ctx.get(e.name, currentLayer(), e.pos); | 178 return ctx.get(e.name, layerID(), e.pos); 180 } 179 } 181 override Value eval_( Lay e, Table ctx, bool ctxMod ) 180 override Value eval_( Lay e, Table ctx, bool ctxMod ) 182 { 181 { 183 auto le = getLayerEvaluator(e.layer); | 182 return getLayerEval(e.layer).evalToNonNull(e.expr, ctx); 184 auto v = le.eval(e.expr,ctx,CascadeCtx); < 185 if( (v is null) && (cast(MacroLayerEval)le !is null) ) < 186 return ast2table(e.expr); < 187 else < 188 return v; < 189 } 183 } 190 override Value eval_( Let e, Table ctx, bool ctxMod ) 184 override Value eval_( Let e, Table ctx, bool ctxMod ) 191 { 185 { > 186 if( !ctxMod ) 192 Table newCtx = ctxMod ? ctx : new Table(ctx, Table.Kind. | 187 ctx = new Table(ctx, Table.Kind.NotPropagateSet) 193 Value ri = this.eval(e.init, newCtx, CascadeCtx); | 188 Value ri = this.eval(e.init, ctx); 194 if(e.name!="_") < 195 newCtx.set(e.name, e.layer.empty ? currentLayer( | 189 ctx.set(e.name, e.layer.empty ? layerID(): e.layer, ri); 196 return this.eval(e.expr, newCtx, OverwriteCtx); | 190 return this.eval(e.expr, ctx, OverwriteCtx); 197 } 191 } 198 override Value eval_( App e, Table ctx, bool ctxMod ) 192 override Value eval_( App e, Table ctx, bool ctxMod ) 199 { 193 { 200 Value f = this.eval( e.fun, ctx, CascadeCtx ); 194 Value f = this.eval( e.fun, ctx, CascadeCtx ); 201 return this.invokeFunction(f, e.args, ctx, e.pos, getNam 195 return this.invokeFunction(f, e.args, ctx, e.pos, getNam 202 } 196 } 203 override Value eval_( Fun e, Table ctx, bool ctxMod ) 197 override Value eval_( Fun e, Table ctx, bool ctxMod ) 204 { 198 { 205 return createNewFunction(e, ctx); 199 return createNewFunction(e, ctx); 206 } 200 } > 201 override Value macroAndEval( AST e, Table ctx, bool ctxMod ) > 202 { > 203 // incremental execution of let-expressions > 204 if(auto le = cast(Let)e) > 205 { > 206 AST ai = runMacro(le.init, ctx); > 207 > 208 if( !ctxMod ) > 209 ctx = new Table(ctx, Table.Kind.NotPropa > 210 > 211 Value vi = this.eval(ai, ctx); > 212 ctx.set(le.name, le.layer.empty ? layerID() : le > 213 return this.macroAndEval(le.expr, ctx, Overwrite > 214 } > 215 else > 216 return this.eval(runMacro(e,ctx,ctxMod), ctx, ct > 217 } 207 } 218 } 208 219 209 /// Evaluator for user-defined layer 220 /// Evaluator for user-defined layer 210 class UserDefinedLayerEval : ValueLayerEval 221 class UserDefinedLayerEval : ValueLayerEval 211 { 222 { 212 Layer layerID; | 223 Layer theID; 213 mixin SimpleConstructor; 224 mixin SimpleConstructor; 214 225 215 override Layer currentLayer() | 226 override Layer layerID() 216 { 227 { 217 return layerID; | 228 return theID; 218 } 229 } 219 override Value eval_( Die e, Table ctx, bool ctxMod ) 230 override Value eval_( Die e, Table ctx, bool ctxMod ) 220 { 231 { 221 return new UndefinedValue; | 232 return new BottomValue; 222 } 233 } 223 override Value eval_( Str e, Table ctx, bool ctxMod ) 234 override Value eval_( Str e, Table ctx, bool ctxMod ) 224 { 235 { 225 return this.lift(new StrValue(e.data), ctx, e.pos); | 236 return this.lift(super.eval_(e,ctx,ctxMod), ctx, e.pos); 226 } 237 } 227 override Value eval_( Int e, Table ctx, bool ctxMod ) 238 override Value eval_( Int e, Table ctx, bool ctxMod ) 228 { 239 { 229 return this.lift(new IntValue(e.data), ctx, e.pos); | 240 return this.lift(super.eval_(e,ctx,ctxMod), ctx, e.pos); 230 } 241 } 231 override Value eval_( Var e, Table ctx, bool ctxMod ) 242 override Value eval_( Var e, Table ctx, bool ctxMod ) 232 { 243 { 233 if( ctx.has(e.name, currentLayer()) ) | 244 if( ctx.has(e.name, layerID()) ) 234 return ctx.get(e.name, currentLayer()); | 245 return ctx.get(e.name, layerID()); 235 return this.lift(ctx.get(e.name, ValueLayer, e.pos), ctx 246 return this.lift(ctx.get(e.name, ValueLayer, e.pos), ctx 236 } 247 } 237 } 248 } 238 249 239 // Convention!! | 250 // Macro layer. For optimization, if AST didn't change it returns null 240 // returns null if never used macro-like feature < 241 class MacroLayerEval : LayerEval 251 class MacroLayerEval : LayerEval 242 { 252 { 243 override Layer currentLayer() | 253 override Layer layerID() 244 { 254 { 245 return MacroLayer; 255 return MacroLayer; > 256 } > 257 override Value evalToNonNull( AST e, Table ctx, bool ctxMod = Ca > 258 { > 259 Value v = this.eval(e, ctx, ctxMod); > 260 return v is null ? ast2table(e) : v; 246 } 261 } 247 override Value eval_( Die e, Table ctx, bool ctxMod ) 262 override Value eval_( Die e, Table ctx, bool ctxMod ) 248 { 263 { 249 return null; 264 return null; 250 } 265 } 251 override Value eval_( Str e, Table ctx, bool ctxMod ) 266 override Value eval_( Str e, Table ctx, bool ctxMod ) 252 { 267 { ................................................................................................................................................................................ 254 } 269 } 255 override Value eval_( Int e, Table ctx, bool ctxMod ) 270 override Value eval_( Int e, Table ctx, bool ctxMod ) 256 { 271 { 257 return null; 272 return null; 258 } 273 } 259 override Value eval_( Var e, Table ctx, bool ctxMod ) 274 override Value eval_( Var e, Table ctx, bool ctxMod ) 260 { 275 { 261 if( ctx.has(e.name, currentLayer()) ) | 276 if( ctx.has(e.name, layerID()) ) 262 return ctx.get(e.name, currentLayer(), e.pos); | 277 return ctx.get(e.name, layerID(), e.pos); 263 else < 264 return null; | 278 return null; 265 } 279 } 266 override Value eval_( Lay e, Table ctx, bool ctxMod ) 280 override Value eval_( Lay e, Table ctx, bool ctxMod ) 267 { 281 { 268 auto le = getLayerEvaluator(e.layer); < 269 return le.eval(e.expr,ctx,CascadeCtx); | 282 return getLayerEval(e.layer).eval(e.expr,ctx); 270 } 283 } 271 override Value eval_( Let e, Table ctx, bool ctxMod ) 284 override Value eval_( Let e, Table ctx, bool ctxMod ) 272 { 285 { > 286 if( !ctxMod ) 273 Table newCtx = ctxMod ? ctx : new Table(ctx, Table.Kind. | 287 ctx = new Table(ctx, Table.Kind.NotPropagateSet) > 288 274 Value ai = this.eval(e.init, newCtx, CascadeCtx); | 289 Value ai = this.eval(e.init, ctx); 275 newCtx.set(e.name, NoopLayer, null); | 290 ctx.set(e.name, NoopLayer, null); 276 Value ae = this.eval(e.expr, newCtx, OverwriteCtx); | 291 Value ae = this.eval(e.expr, ctx, OverwriteCtx); > 292 277 if( ai is null && ae is null ) | 293 if( ai is null && ae is null ) return null; 278 return null; < 279 if( ai is null ) ai = ast2table(e.init); 294 if( ai is null ) ai = ast2table(e.init); 280 if( ae is null ) ae = ast2table(e.expr); 295 if( ae is null ) ae = ast2table(e.expr); > 296 281 return ast2table(e, delegate Value (AST _){ 297 return ast2table(e, delegate Value (AST _){ 282 if(_ is e.init) { return ai; } 298 if(_ is e.init) { return ai; } 283 if(_ is e.expr) { return ae; } 299 if(_ is e.expr) { return ae; } 284 assert(false); 300 assert(false); 285 }); 301 }); 286 } 302 } 287 override Value eval_( App e, Table ctx, bool ctxMod ) 303 override Value eval_( App e, Table ctx, bool ctxMod ) 288 { 304 { 289 Value f = this.eval( e.fun, ctx, CascadeCtx ); | 305 Value f = this.eval( e.fun, ctx ); 290 if(auto ff = cast(FunValue)f) 306 if(auto ff = cast(FunValue)f) 291 return this.invokeFunction(ff, e.args, ctx, e.po 307 return this.invokeFunction(ff, e.args, ctx, e.po 292 else { | 308 else > 309 { 293 bool allNull = (f is null); 310 bool allNull = (f is null); 294 Value[] vas; 311 Value[] vas; 295 foreach(a; e.args) { | 312 foreach(a; e.args) > 313 { 296 Value va = this.eval(a, ctx, CascadeCtx) 314 Value va = this.eval(a, ctx, CascadeCtx) 297 if(va !is null) allNull = false; 315 if(va !is null) allNull = false; 298 vas ~= va; 316 vas ~= va; 299 } 317 } 300 if( allNull ) 318 if( allNull ) 301 return null; 319 return null; 302 return ast2table(e, delegate Value (AST _){ 320 return ast2table(e, delegate Value (AST _){ ................................................................................................................................................................................ 304 foreach(i,a; e.args) if(_ is a) return ( 322 foreach(i,a; e.args) if(_ is a) return ( 305 assert(false); 323 assert(false); 306 }); 324 }); 307 } 325 } 308 } 326 } 309 override Value eval_( Fun e, Table ctx, bool ctxMod ) 327 override Value eval_( Fun e, Table ctx, bool ctxMod ) 310 { 328 { 311 Table newCtx = new Table(ctx, Table.Kind.NotPropagateSet | 329 ctx = new Table(ctx, Table.Kind.NotPropagateSet); 312 foreach(p; e.params) 330 foreach(p; e.params) 313 newCtx.set(p.name, NoopLayer, null); | 331 ctx.set(p.name, NoopLayer, null); 314 Value af = this.eval(e.funbody, newCtx, CascadeCtx); | 332 Value af = this.eval(e.funbody, ctx); 315 if( af is null ) 333 if( af is null ) 316 return null; 334 return null; 317 return ast2table(e, (AST _){if(_ is e.funbody)return af; 335 return ast2table(e, (AST _){if(_ is e.funbody)return af; 318 } 336 } 319 } 337 } 320 338 > 339 /// (rawmacro) layer. almost same as @macro, but the Layer expression be 321 class RawMacroLayerEval : MacroLayerEval 340 class RawMacroLayerEval : MacroLayerEval 322 { 341 { 323 override Value eval_( Lay e, Table ctx, bool ctxMod ) 342 override Value eval_( Lay e, Table ctx, bool ctxMod ) 324 { 343 { 325 Value ae = this.eval(e.expr, ctx, CascadeCtx); | 344 Value ae = this.eval(e.expr, ctx); 326 return ae is null ? null 345 return ae is null ? null 327 : ast2table(e, delegate Value (AST _){if(_ is e.e 346 : ast2table(e, delegate Value (AST _){if(_ is e.e 328 } 347 } 329 } 348 } 330 349 331 private: | 350 private: // short utils 332 Value macroAndEval( AST e_, Layer lay, Table ctx, bool ctxMod ) < 333 { < 334 assert( !isASTLayer(lay) ); < 335 if(auto e = cast(Let)e_) < 336 { < 337 Value vai = getLayerEvaluator(RawMacroLayer).eval(e.init < 338 AST ai = (vai is null ? e.init : polemy2d!(AST)(vai, e.p < 339 351 340 if( !ctxMod ) < 341 ctx = new Table(ctx, Table.Kind.NotPropagateSet) < 342 < 343 Value vi = getLayerEvaluator(lay).eval(ai, ctx, CascadeC < 344 string theLayer = e.layer.empty ? lay : e.layer; < 345 ctx.set(e.name, theLayer, vi); < 346 < 347 return macroAndEval( e.expr, lay, ctx, OverwriteCtx ); < 348 } < 349 else < 350 { < 351 Value va = getLayerEvaluator(RawMacroLayer).eval(e_, ctx < 352 AST a = (va is null ? e_ : polemy2d!(AST)(va, e_.pos)); < 353 return getLayerEvaluator(lay).eval(a, ctx, ctxMod); < 354 } < 355 } < 356 < 357 private: < 358 string getNameIfPossible(AST e) 352 string getNameIfPossible(AST e) 359 { 353 { 360 if(auto v = cast(Var)e) 354 if(auto v = cast(Var)e) 361 return v.name; 355 return v.name; 362 return ""; 356 return ""; 363 } 357 } 364 358 > 359 AST runMacro(AST e, Table ctx, bool ctxMod=LayerEval.CascadeCtx) > 360 { > 361 Value v = getLayerEval(RawMacroLayer).eval(e, ctx, ctxMod); > 362 return (v is null ? e : polemy2d!(AST)(v, e.pos)); > 363 } > 364 > 365 private: 365 Value createNewFunction(Fun e, Table ctx) 366 Value createNewFunction(Fun e, Table ctx) 366 { 367 { 367 class UserDefinedFunValue : FunValue 368 class UserDefinedFunValue : FunValue 368 { 369 { 369 Fun ast; 370 Fun ast; 370 Table defCtx; 371 Table defCtx; 371 override const(Parameter[]) params() { return ast.params 372 override const(Parameter[]) params() { return ast.params ................................................................................................................................................................................ 385 if(auto r = cast(Value)rhs) return typeid(this). 386 if(auto r = cast(Value)rhs) return typeid(this). 386 throw genex!RuntimeException("comparison with va 387 throw genex!RuntimeException("comparison with va 387 } 388 } 388 override hash_t toHash() { 389 override hash_t toHash() { 389 return (cast(hash_t)cast(void*)ast) + (cast(hash 390 return (cast(hash_t)cast(void*)ast) + (cast(hash 390 } 391 } 391 392 392 AST macroCache; < 393 AST[void*] mandeCache; 393 AST[void*] mandeCache; 394 static class MemokeyType 394 static class MemokeyType 395 { 395 { 396 void* a; Layer b; Tuple!(string,Layer,Value)[] c | 396 void* a; Layer b; Table c; 397 hash_t toHash() { < 398 hash_t h = structuralHash(a) + structura < 399 foreach(e; c) < 400 h += structuralHash(e[0])+struct < 401 return h; < 402 } < 403 mixin SimpleToString; | 397 mixin SimpleClass; 404 mixin SimpleConstructor; < 405 mixin SimpleCompareWithoutToHash; < 406 } 398 } 407 static Tuple!(Value,int)[MemokeyType] memo; 399 static Tuple!(Value,int)[MemokeyType] memo; 408 400 409 override Value invoke(Layer lay, Table ctx, LexPosition 401 override Value invoke(Layer lay, Table ctx, LexPosition 410 { 402 { 411 if( isASTLayer(lay) ) { | 403 auto evlay = getLayerEval(lay); 412 Value v = getLayerEvaluator(lay).eval(as < 413 if( v is null ) v = ast2table(ast.funbod < 414 return v; < 415 } < 416 return macroAndEval(ast.funbody, lay, ctx, Casca < 417 /* < 418 auto nonMemoizedRun = (){ | 404 auto nonMemoizedRun = (){ return evlay.macroAndE 419 if( macroCache is null ) < 420 { < 421 auto va = macroAndEval(e.funbody < 422 macroCache = va[1]; < 423 return va[0]; < 424 } < 425 else < 426 return eval(macroCache, lay, ctx < 427 }; < 428 405 429 if( !isUserDefinedLayer(lay) ) 406 if( !isUserDefinedLayer(lay) ) 430 return nonMemoizedRun(); 407 return nonMemoizedRun(); 431 408 > 409 // automatic memoized co-recursive execution 432 MemokeyType memokey = new MemokeyType(cast(void* | 410 MemokeyType memokey = new MemokeyType(cast(void* 433 < 434 if(auto p = memokey in memo) 411 if(auto p = memokey in memo) 435 { 412 { 436 (*p)[1] ++; 413 (*p)[1] ++; 437 return (*p)[0]; 414 return (*p)[0]; 438 } 415 } 439 else 416 else 440 memo[memokey] = tuple(lift(new Undefined | 417 memo[memokey] = tuple(evlay.lift(new Bot 441 418 442 Value r = nonMemoizedRun(); 419 Value r = nonMemoizedRun(); 443 420 444 int touched = memo[memokey][1]; 421 int touched = memo[memokey][1]; 445 memo[memokey] = tuple(r, 12345678); 422 memo[memokey] = tuple(r, 12345678); 446 //if(touched) {DBG("rerun :: ",r);r = nonMemoize < 447 return r; 423 return r; 448 */ < 449 } 424 } 450 } 425 } 451 return new UserDefinedFunValue(e,ctx); 426 return new UserDefinedFunValue(e,ctx); 452 } 427 } 453 428 454 public: 429 public: 455 /// Add primitive function to the global context 430 /// Add primitive function to the global context ................................................................................................................................................................................ 499 } 474 } 500 } 475 } 501 } 476 } 502 theContext.set(name, defLay, new NativeFunValue(dg)); 477 theContext.set(name, defLay, new NativeFunValue(dg)); 503 } 478 } 504 } 479 } 505 480 > 481 version(unittest) 506 version(unittest) import polemy.runtime; | 482 import polemy.runtime; > 483 507 unittest 484 unittest 508 { 485 { 509 auto e = new Evaluator; 486 auto e = new Evaluator; 510 enrollRuntimeLibrary(e); 487 enrollRuntimeLibrary(e); 511 auto r = assert_nothrow( e.evalString(`var x = 21; x + x*x;`) ); 488 auto r = assert_nothrow( e.evalString(`var x = 21; x + x*x;`) ); 512 assert_eq( r, new IntValue(BigInt(21+21*21)) ); 489 assert_eq( r, new IntValue(BigInt(21+21*21)) ); 513 assert_eq( e.globalContext.get("x",ValueLayer), new IntValue(BigInt(21)) 490 assert_eq( e.globalContext.get("x",ValueLayer), new IntValue(BigInt(21)) 514 assert_nothrow( e.globalContext.get("x",ValueLayer) ); 491 assert_nothrow( e.globalContext.get("x",ValueLayer) ); 515 assert_throw!RuntimeException( e.globalContext.get("y",ValueLayer) ); 492 assert_throw!RuntimeException( e.globalContext.get("y",ValueLayer) ); 516 } 493 } > 494 517 unittest 495 unittest 518 { 496 { 519 auto e = new Evaluator; 497 auto e = new Evaluator; 520 enrollRuntimeLibrary(e); 498 enrollRuntimeLibrary(e); 521 auto r = assert_nothrow( e.evalString(`var x = 21; var x = x + x*x;`) ); 499 auto r = assert_nothrow( e.evalString(`var x = 21; var x = x + x*x;`) ); 522 assert_eq( r, new IntValue(BigInt(21+21*21)) ); 500 assert_eq( r, new IntValue(BigInt(21+21*21)) ); 523 assert_eq( e.globalContext.get("x",ValueLayer), new IntValue(21+21*21) ) 501 assert_eq( e.globalContext.get("x",ValueLayer), new IntValue(21+21*21) ) ................................................................................................................................................................................ 593 } 571 } 594 572 595 unittest 573 unittest 596 { 574 { 597 auto e = new Evaluator; 575 auto e = new Evaluator; 598 enrollRuntimeLibrary(e); 576 enrollRuntimeLibrary(e); 599 assert_throw!RuntimeException( e.evalString(`...`) ); 577 assert_throw!RuntimeException( e.evalString(`...`) ); 600 assert_eq( e.evalString(`@@foo(x){x}; @foo(...)`), new UndefinedValue ); | 578 assert_eq( e.evalString(`@@foo(x){x}; @foo(...)`), new BottomValue ); 601 } 579 }

Modified polemy/runtime.d from [f71ff7dc6628e423] to [d6bfebbae7e5dfaf].

57 e.addPrimitive("_isint", ValueLayer, 57 e.addPrimitive("_isint", ValueLayer, 58 (Value v){return new IntValue(cast(IntValue)v !is null);} ); 58 (Value v){return new IntValue(cast(IntValue)v !is null);} ); 59 e.addPrimitive("_isstr", ValueLayer, 59 e.addPrimitive("_isstr", ValueLayer, 60 (Value v){return new IntValue(cast(StrValue)v !is null);} ); 60 (Value v){return new IntValue(cast(StrValue)v !is null);} ); 61 e.addPrimitive("_isfun", ValueLayer, 61 e.addPrimitive("_isfun", ValueLayer, 62 (Value v){return new IntValue(cast(FunValue)v !is null);} ); 62 (Value v){return new IntValue(cast(FunValue)v !is null);} ); 63 e.addPrimitive("_isundefined", ValueLayer, 63 e.addPrimitive("_isundefined", ValueLayer, 64 (Value v){return new IntValue(cast(UndefinedValue)v !is null);} | 64 (Value v){return new IntValue(cast(BottomValue)v !is null);} ); 65 e.addPrimitive("_istable", ValueLayer, 65 e.addPrimitive("_istable", ValueLayer, 66 (Value v){return new IntValue(cast(Table)v !is null);} ); 66 (Value v){return new IntValue(cast(Table)v !is null);} ); 67 // table 67 // table 68 e.addPrimitive(".", ValueLayer, (Table t, StrValue s){ 68 e.addPrimitive(".", ValueLayer, (Table t, StrValue s){ 69 if( t.has(s.data, ValueLayer) ) 69 if( t.has(s.data, ValueLayer) ) 70 return t.get(s.data, ValueLayer); 70 return t.get(s.data, ValueLayer); 71 throw genex!RuntimeException(text("table do not have the field " 71 throw genex!RuntimeException(text("table do not have the field "

Modified polemy/value.d from [3d0cc7f551924493] to [37c7b437fe230ee4].

48 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( 48 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( 49 throw genex!RuntimeException("comparison with value and somithin 49 throw genex!RuntimeException("comparison with value and somithin 50 } 50 } 51 mixin SimpleToHash; 51 mixin SimpleToHash; 52 } 52 } 53 53 54 /// 54 /// 55 class UndefinedValue : Value | 55 class BottomValue : Value 56 { 56 { 57 mixin SimpleConstructor; 57 mixin SimpleConstructor; 58 override string toString() const { return "<undefined>"; } | 58 override string toString() const { return "_|_"; } 59 override int opCmp(Object rhs) { 59 override int opCmp(Object rhs) { 60 if(auto r = cast(StrValue)rhs) return 0; 60 if(auto r = cast(StrValue)rhs) return 0; 61 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( 61 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( 62 throw genex!RuntimeException("comparison with value and somithin 62 throw genex!RuntimeException("comparison with value and somithin 63 } 63 } 64 mixin SimpleToHash; 64 mixin SimpleToHash; 65 } 65 }

Modified sample/fib.pmy from [5b2c3c452aca5b18] to [4438bc82733dcb16].

> 1 # Standard Fibonacci function 1 def fib(x) 2 def fib(x) 2 { 3 { 3 if x<2 then 1 else fib(x-1) + fib(x-2) 4 if x<2 then 1 else fib(x-1) + fib(x-2) 4 }; 5 }; 5 6 6 let upto = fun(n, f){ 7 let upto = fun(n, f){ 7 if n > 0: upto(n-1,f); 8 if n > 0: upto(n-1,f); 8 f(n) 9 f(n) 9 }; 10 }; 10 11 11 var compose = fun(f,g){ fun(x){f(g(x))} }; 12 var compose = fun(f,g){ fun(x){f(g(x))} }; 12 var "<<" = compose; 13 var "<<" = compose; 13 14 14 upto(16, print<<fib); | 15 upto(18, print<<fib); > 16 > 17 > 18 ###################################### > 19 # Omake. Feel the automatic memoization! > 20 > 21 # Set up a mirror layer (do-the-same-thing layer) of @value > 22 @@m(x){x}; > 23 @m "+" (x,y) { @value(@m(x)+@m(y)) }; > 24 @m "-" (x,y) { @value(@m(x)-@m(y)) }; > 25 @m "<" (x,y) { @value(@m(x)<@m(y)) }; > 26 @m "if" (c,t,e) { @value(if @m(c) then @m(t()) else @m(e())) }; > 27 > 28 # Helper function to call fib in layer @m > 29 def fibm(x @value) { @m(fib(@value(x))) }; > 30 > 31 # User defined layers are automatically memoized. > 32 # So this is much faster. > 33 upto(18, print<<fibm);

Modified sample/helloworld.pmy from [da81646a4f1f8106] to [0b93991cb774eeae].

> 1 print( "Hello, World" ); > 2 1 # omake. how to use argv | 3 # Omake. How to use argv 2 def print_list(xs) 4 def print_list(xs) 3 { 5 { 4 case xs when {car: x, cdr: xs}: ( 6 case xs when {car: x, cdr: xs}: ( 5 print(x); 7 print(x); 6 print_list(xs) 8 print_list(xs) 7 ) 9 ) 8 }; 10 }; 9 print_list(argv); 11 print_list(argv); 10 < 11 # here is the helloworld < 12 print( "Hello, World" ); <