@@ -71,20 +71,20 @@ Value eval( Str e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) { if( isASTLayer(lay) ) return ast2table(e, (AST e){return eval(e,lay,ctx);}); - if( lay==ValueLayer ) - return new StrValue(e.data); - return lift(new StrValue(e.data), lay, ctx, e.pos); + if( isUserDefinedLayer(lay) ) + return lift(new StrValue(e.data), lay, ctx, e.pos); + return new StrValue(e.data); } Value eval( Int e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) { if( isASTLayer(lay) ) return ast2table(e, (AST e){return eval(e,lay,ctx);}); - if( lay==ValueLayer ) - return new IntValue(e.data); - return lift(new IntValue(e.data), lay, ctx, e.pos); + if( isUserDefinedLayer(lay) ) + return lift(new IntValue(e.data), lay, ctx, e.pos); + return new IntValue(e.data); } Value eval( Var e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) { @@ -92,11 +92,11 @@ if( isMacroLayer(lay) && ctx.has(e.name,MacroLayer) ) return ctx.get(e.name, MacroLayer, e.pos); else return ast2table(e, (AST e){return eval(e,lay,ctx);}); - if( lay==ValueLayer || ctx.has(e.name, lay) ) - return ctx.get(e.name, lay, e.pos); - return lift(ctx.get(e.name, ValueLayer, e.pos), lay, ctx, e.pos); + if( isUserDefinedLayer(lay) && !ctx.has(e.name, lay) ) + return lift(ctx.get(e.name, ValueLayer, e.pos), lay, ctx, e.pos); + return ctx.get(e.name, lay, e.pos); } Value eval( App e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) { @@ -137,9 +137,10 @@ { Table newCtx = overwriteCtx ? ctx : new Table(ctx, Table.Kind.NotPropagateSet); if( isASTLayer(lay) ) return ast2table(e, (AST ee){ - if(ee is e.expr) // need this for correct scoping (outer scope macro variables must be hidden!) + // need this for correct scoping (outer scope macro variables must be hidden!) + if(ee is e.expr) newCtx.set(e.name, ValueLayer, new UndefinedValue); return eval(ee,lay,newCtx); }); else @@ -254,16 +255,19 @@ override const(Parameter[]) params() { return ast.params; } override Table definitionContext() { return defCtx; } this(Fun ast, Table defCtx) { this.ast=ast; this.defCtx=defCtx; } - override string toString() const { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } + override string toString() const + { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } override int opCmp(Object rhs) { if(auto r = cast(UserDefinedFunValue)rhs) { - if(auto i = this.ast.opCmp(r.ast)) - return i; + auto a = cast(void*)this.ast; + auto b = cast(void*)r.ast; + if(ab) return +1; // [TODO] avoid using pointer value... return this.defCtx.opCmp(r.defCtx); } - if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r)); + if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r)); throw genex!RuntimeException("comparison with value and something other"); } mixin SimpleToHash; @@ -297,9 +301,9 @@ override string toString() { return sprintf!"(native:%x)"(dg.funcptr); } override int opCmp(Object rhs) { if(auto r = cast(NativeFunValue)rhs) return typeid(typeof(dg)).compare(&dg,&r.dg); if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r)); - throw genex!RuntimeException(LexPosition.dummy, "comparison with value and something other"); + throw genex!RuntimeException("comparison with value and something other"); } mixin SimpleToHash; R delegate(T) dg; @@ -314,14 +318,16 @@ override Value invoke(Layer lay, Table ctx, LexPosition pos) { if( lay != defLay ) - throw genex!RuntimeException(pos, text("only ", defLay, " layer can call native function: ", name)); + throw genex!RuntimeException(pos, + text("only ", defLay, " layer can call native function: ", name)); T typed_args; foreach(i, Ti; T) { typed_args[i] = cast(Ti) ctx.get(text(i), ValueLayer, pos); if( typed_args[i] is null ) - throw genex!RuntimeException(pos, sprintf!"type mismatch on the argument %d of native function: %s"(i+1,name)); + throw genex!RuntimeException(pos, + sprintf!"type mismatch on the argument %d of native function: %s"(i+1,name)); } try { return dg(typed_args); } catch( RuntimeException e ) {