@@ -152,8 +152,17 @@ 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 @@ -482,12 +491,20 @@ 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 ); +}