Index: doc/_common.html ================================================================== --- doc/_common.html +++ doc/_common.html @@ -24,11 +24,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:13:45 2010 + on Fri Nov 26 16:41:43 2010 </td></tr> </table> </div> <script> Index: doc/ast.html ================================================================== --- doc/ast.html +++ doc/ast.html @@ -408,10 +408,24 @@ </dl> <script>explorer.outline.decSymbolLevel();</script> </dd> + +<script>explorer.outline.writeEnabled = true;</script> +<dt><span class="decl">class +<span class="currsymbol">Die</span> +<script>explorer.outline.addDecl('Die');</script> + +: polemy.ast.AST; +</span></dt> +<script>explorer.outline.writeEnabled = false;</script> + + +<dd>AST node for deadend<br><br> + +</dd> <script>explorer.outline.writeEnabled = true;</script> <dt><span class="decl">alias <span class="currsymbol">ListOfASTTypes</span> <script>explorer.outline.addDecl('ListOfASTTypes');</script> @@ -552,10 +566,23 @@ <script>explorer.outline.writeEnabled = false;</script> <dd><br><br> </dd> + +<script>explorer.outline.writeEnabled = true;</script> +<dt><span class="decl">alias +<span class="currsymbol">dieast</span> +<script>explorer.outline.addDecl('dieast');</script> + +; +</span></dt> +<script>explorer.outline.writeEnabled = false;</script> + + +<dd><br><br> +</dd> </dl> <script>explorer.outline.decSymbolLevel();</script> </dd> @@ -565,11 +592,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:13:46 2010 + on Fri Nov 26 16:41:44 2010 </td></tr> </table> </div> <script> Index: doc/eval.html ================================================================== --- doc/eval.html +++ doc/eval.html @@ -130,11 +130,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:13:46 2010 + on Fri Nov 26 16:41:45 2010 </td></tr> </table> </div> <script> Index: doc/failure.html ================================================================== --- doc/failure.html +++ doc/failure.html @@ -180,11 +180,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:13:47 2010 + on Fri Nov 26 16:41:45 2010 </td></tr> </table> </div> <script> Index: doc/fresh.html ================================================================== --- doc/fresh.html +++ doc/fresh.html @@ -48,11 +48,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:13:47 2010 + on Fri Nov 26 16:41:46 2010 </td></tr> </table> </div> <script> Index: doc/index.html ================================================================== --- doc/index.html +++ doc/index.html @@ -91,14 +91,16 @@ ID ::= 適当に識別子っぽい文字列 LAYER ::= "@" ID E ::= <font color=green># 変数宣言</font> - | ("var"|"let"|"def"|LAYER) ID "=" E (";"|"in") E - | ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}" (";"|"in") E - | ("var"|"let"|"def"|LAYER) ID "=" E - | ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}" + | DECL "=" E (";"|"in") E + | DECL "(" PARAMS ")" "{" E "}" (";"|"in") E + | DECL "=" E + | DECL "(" PARAMS ")" "{" E "}" + + where DECL ::= ("var"|"let"|"def"|LAYER) ID | "@" LAYER <font color=green># リテラル</font> | INTEGER <font color=green># 非負整数</font> | STRING <font color=green># "" でくくった文字列。\" と \\ は使える</font> | "{" ENTRYS "}" <font color=green># テーブル</font> @@ -112,10 +114,11 @@ PARAMS ::= (ID|LAYER)+ "," ... "," (ID|LAYER)+ ENTRYS ::= ID ":" E "," ... "," ID ":" E <font color=green># 演算子など</font> | "(" E ")" <font color=green># ただの括弧</font> + | "..." <font color=green># これを実行するとdie</font> | E BINOP E <font color=green># 二項演算子いろいろ</font> | E "." ID <font color=green># テーブルのフィールドアクセス</font> | E ".?" ID <font color=green># テーブルにフィールドがあるか否か</font> | E "{" ENTRYS "}" <font color=green># テーブル拡張</font> | "if" E ("then"|":"|"then" ":") E @@ -287,11 +290,11 @@ <ul> <li>整数: <tt>0</tt>, <tt>123</tt>, <tt>456666666666666666666666666666666666666789</tt>, ...</li> <li>文字列: <tt>"hello, world!"</tt>, ...</li> <li>関数: <tt>fun(x){x+1}</tt></li> <li>テーブル: <tt>{car: 1, cdr: {car: 2, cdr: {}}}</tt></li> - <li>未定義値: (undefined。特殊なケースで作られます)</li> + <li>未定義値: (特殊なケースで作られます。「レイヤ」の説明参照のこと。)</li> </ul> <p> 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 テーブルはいわゆるプロトタイプチェーンを持っていて、 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 @@ -327,10 +330,11 @@ } </pre> <p> 動かすときには、処理系がそれっぽい if-then-else に展開しています。 <tt>when</tt> を上から試していって、最初にマッチしたところを実行します。 +どれにもマッチしないとエラーでプログラム終了します。 </p> <pre> PAT ::= "_" <font color=green># ワイルドカード</font> | ID <font color=green># 変数パターン</font> | "{" ID ":" PAT "," ... "," ID : PAT "}" <font color=green># テーブルパターン</font> @@ -875,11 +879,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Fri Nov 26 10:02:52 2010 + on Fri Nov 26 16:41:52 2010 </td></tr> </table> </div> <script> Index: doc/layer.html ================================================================== --- doc/layer.html +++ doc/layer.html @@ -39,18 +39,31 @@ </dd> <script>explorer.outline.writeEnabled = true;</script> <dt><span class="decl"> -<span class="currsymbol">SystemLayer</span> -<script>explorer.outline.addDecl('SystemLayer');</script> +<span class="currsymbol">LiftLayer</span> +<script>explorer.outline.addDecl('LiftLayer');</script> + +</span></dt> +<script>explorer.outline.writeEnabled = false;</script> + + +<dd>Predefined layer for storing lift functions<br><br> + +</dd> + +<script>explorer.outline.writeEnabled = true;</script> +<dt><span class="decl"> +<span class="currsymbol">NoopLayer</span> +<script>explorer.outline.addDecl('NoopLayer');</script> </span></dt> <script>explorer.outline.writeEnabled = false;</script> -<dd>Predefined layer for internal data<br><br> +<dd>Predefined layer for just allocating a slot for table<br><br> </dd> <script>explorer.outline.writeEnabled = true;</script> <dt><span class="decl"> @@ -152,11 +165,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:13:48 2010 + on Fri Nov 26 16:41:46 2010 </td></tr> </table> </div> <script> Index: doc/lex.html ================================================================== --- doc/lex.html +++ doc/lex.html @@ -309,11 +309,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:05 2010 + on Fri Nov 26 16:41:47 2010 </td></tr> </table> </div> <script> Index: doc/main.html ================================================================== --- doc/main.html +++ doc/main.html @@ -64,11 +64,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:04 2010 + on Fri Nov 26 16:41:42 2010 </td></tr> </table> </div> <script> Index: doc/parse.html ================================================================== --- doc/parse.html +++ doc/parse.html @@ -58,11 +58,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:05 2010 + on Fri Nov 26 16:41:48 2010 </td></tr> </table> </div> <script> Index: doc/repl.html ================================================================== --- doc/repl.html +++ doc/repl.html @@ -158,11 +158,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:06 2010 + on Fri Nov 26 16:41:48 2010 </td></tr> </table> </div> <script> Index: doc/runtime.html ================================================================== --- doc/runtime.html +++ doc/runtime.html @@ -44,11 +44,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:30:12 2010 + on Fri Nov 26 16:41:49 2010 </td></tr> </table> </div> <script> Index: doc/test.html ================================================================== --- doc/test.html +++ doc/test.html @@ -145,11 +145,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:08 2010 + on Fri Nov 26 16:41:51 2010 </td></tr> </table> </div> <script> Index: doc/tricks.html ================================================================== --- doc/tricks.html +++ doc/tricks.html @@ -248,11 +248,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:09 2010 + on Fri Nov 26 16:41:52 2010 </td></tr> </table> </div> <script> Index: doc/value.html ================================================================== --- doc/value.html +++ doc/value.html @@ -261,11 +261,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:07 2010 + on Fri Nov 26 16:41:50 2010 </td></tr> </table> </div> <script> Index: doc/valueconv.html ================================================================== --- doc/valueconv.html +++ doc/valueconv.html @@ -86,11 +86,11 @@ </td></tr> <tr><td id="docfooter"> Page was generated with <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> - on Thu Nov 25 12:15:47 2010 + on Fri Nov 26 16:41:51 2010 </td></tr> </table> </div> <script> Index: index.dd ================================================================== --- index.dd +++ index.dd @@ -42,14 +42,16 @@ ID ::= 適当に識別子っぽい文字列 LAYER ::= "@" ID E ::= $(D_COMMENT # 変数宣言) - | ("var"|"let"|"def"|LAYER) ID "=" E (";"|"in") E - | ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}" (";"|"in") E - | ("var"|"let"|"def"|LAYER) ID "=" E - | ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}" + | DECL "=" E (";"|"in") E + | DECL "(" PARAMS ")" "{" E "}" (";"|"in") E + | DECL "=" E + | DECL "(" PARAMS ")" "{" E "}" + + where DECL ::= ("var"|"let"|"def"|LAYER) ID | "@" LAYER $(D_COMMENT # リテラル) | INTEGER $(D_COMMENT # 非負整数) | STRING $(D_COMMENT # "" でくくった文字列。\" と \\ は使える) | "{" ENTRYS "}" $(D_COMMENT # テーブル) @@ -63,10 +65,11 @@ PARAMS ::= (ID|LAYER)+ "," ... "," (ID|LAYER)+ ENTRYS ::= ID ":" E "," ... "," ID ":" E $(D_COMMENT # 演算子など) | "(" E ")" $(D_COMMENT # ただの括弧) + | "..." $(D_COMMENT # これを実行するとdie) | E BINOP E $(D_COMMENT # 二項演算子いろいろ) | E "." ID $(D_COMMENT # テーブルのフィールドアクセス) | E ".?" ID $(D_COMMENT # テーブルにフィールドがあるか否か) | E "{" ENTRYS "}" $(D_COMMENT # テーブル拡張) | "if" E ("then"|":"|"then" ":") E @@ -202,11 +205,11 @@ <ul> <li>整数: <tt>0</tt>, <tt>123</tt>, <tt>456666666666666666666666666666666666666789</tt>, ...</li> <li>文字列: <tt>"hello, world!"</tt>, ...</li> <li>関数: <tt>fun(x){x+1}</tt></li> <li>テーブル: <tt>{car: 1, cdr: {car: 2, cdr: {}}}</tt></li> - <li>未定義値: (undefined。特殊なケースで作られます)</li> + <li>未定義値: (特殊なケースで作られます。「レイヤ」の説明参照のこと。)</li> </ul> <p> 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 テーブルはいわゆるプロトタイプチェーンを持っていて、 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 @@ -234,10 +237,11 @@ } </pre> <p> 動かすときには、処理系がそれっぽい if-then-else に展開しています。 <tt>when</tt> を上から試していって、最初にマッチしたところを実行します。 +どれにもマッチしないとエラーでプログラム終了します。 </p> <pre> PAT ::= "_" $(D_COMMENT # ワイルドカード) | ID $(D_COMMENT # 変数パターン) | "{" ID ":" PAT "," ... "," ID : PAT "}" $(D_COMMENT # テーブルパターン) Index: polemy/ast.d ================================================================== --- polemy/ast.d +++ polemy/ast.d @@ -91,14 +91,20 @@ Parameter[] params; /// AST funbody; /// mixin SimpleClass; } + +/// AST node for deadend +class Die : AST +{ + mixin SimpleClass; +} /// List of AST Types -alias TypeTuple!(Int,Str,Var,Lay,Let,App,Fun) ListOfASTTypes; +alias TypeTuple!(Int,Str,Var,Lay,Let,App,Fun,Die) ListOfASTTypes; /// Handy Generator for AST nodes. To use this, mixin EasyAst; /*mixin*/ template EasyAST() @@ -115,6 +121,7 @@ alias genEast!Var var; /// alias genEast!Lay lay; /// alias genEast!Let let; /// alias genEast!App call; /// auto param(string name, string[] lay...) { return new Parameter(name, lay); } /// + alias genEast!Die dieast; /// } Index: polemy/eval.d ================================================================== --- polemy/eval.d +++ polemy/eval.d @@ -151,10 +151,19 @@ if(e.name!="_") newCtx.set(e.name, e.layer.empty ? lay : e.layer, ri); return eval(e.expr, lay, newCtx, OverwriteCtx); } } + + Value eval( Die e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) + { + if( isMacroLayer(lay) ) + return ast2table(e, (AST e){return eval(e,lay,ctx);}); + if( isUserDefinedLayer(lay) ) + return new UndefinedValue; + throw genex!RuntimeException(e.pos, "undefined case"); + } private: // little little bit incremental macro defining version. // enables @macro foo(x)=... in ... foo ..., only at the top level of the // interpreter and functions. better than nothing :P @@ -481,13 +490,21 @@ } unittest { auto e = new Evaluator; enrollRuntimeLibrary(e); - assert_nothrow( e.evalString(`case 1`) ); + assert_throw!RuntimeException( e.evalString(`case 1`) ); assert_nothrow( e.evalString(`case 1 when 1: 2`) ); // this is a shorthand for // @macro x = fun(){} in @macro(x) // so it is ok to fail, but it is really incovenient on REPL assert_nothrow( e.evalString(`@macro x=fun(){}`) ); } + +unittest +{ + auto e = new Evaluator; + enrollRuntimeLibrary(e); + assert_throw!RuntimeException( e.evalString(`...`) ); + assert_eq( e.evalString(`@@foo(x){x}; @foo(...)`), new UndefinedValue ); +} Index: polemy/parse.d ================================================================== --- polemy/parse.d +++ polemy/parse.d @@ -267,10 +267,14 @@ if( isNumber(lex.front.str) ) { scope(exit) lex.popFront; return new Int(pos, BigInt(cast(string)lex.front.str)); } + if( tryEat("...") ) + { + return new Die(pos); + } if( tryEat("@") ) { auto lay = "@"~eatId("for layer ID"); eat("(", "for layered execution"); auto e = Body(); @@ -358,12 +362,11 @@ new Fun(pos,[],judgement), thenDoThis) ); } else { - AST doNothing = new Fun(casePos,[], - new Str(casePos, sprintf!"(pattern match failure:%s)"(casePos))); + AST doNothing = new Fun(casePos,[], new Die(casePos)); return new Let(casePos, tryThisBranchVar, [], doNothing, thenDoThis); } } // hageshiku tenuki