Diff
Not logged in

Differences From Artifact [73d121b46bcd4718]:

To Artifact [cdb82702a34f8def]:


97 97 98 98 Tuple!(Value,"val",Table,"ctx") eval(AST e) 99 99 { 100 100 Table ctx = createGlobalContext(); 101 101 return typeof(return)(eval(e, ctx), ctx); 102 102 } 103 103 104 -Value eval(AST _e, Table ctx, bool splitCtx = false) 104 +Value eval(AST _e, Table ctx, bool splitCtx = false, Layer lay="@val") 105 105 { 106 106 if( auto e = cast(StrLiteral)_e ) 107 107 { 108 108 return new StrValue(e.data); 109 109 } 110 110 else 111 111 if( auto e = cast(IntLiteral)_e ) 112 112 { 113 113 return new IntValue(e.data); 114 114 } 115 115 else 116 116 if( auto e = cast(VarExpression)_e ) 117 117 { 118 - return ctx.get(e.var, "@val", e.pos); 118 + return ctx.get(e.var, lay, e.pos); 119 + } 120 + else 121 + if( auto e = cast(LayeredExpression)_e ) 122 + { 123 + return eval(e.expr, ctx, false, e.lay); 119 124 } 120 125 else 121 126 if( auto e = cast(LetExpression)_e ) 122 127 { 123 128 // for letrec, we need this, but should avoid overwriting???? 124 129 // ctx.set(e.var, "@val", new UndefinedValue, e.pos); 125 130 Value v = eval(e.init, ctx, true); 126 131 if(splitCtx) 127 132 ctx = new Table(ctx, Table.Kind.NotPropagateSet); 128 - ctx.set(e.var, "@val", v, e.pos); 133 + ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.pos); 129 134 return eval(e.expr, ctx); 130 135 } 131 136 else 132 137 if( auto e = cast(FuncallExpression)_e ) 133 138 { 134 139 Value _f = eval(e.fun, ctx); 135 140 if( auto f = cast(FunValue)_f ) { ................................................................................ 178 183 assert_nothrow( evalString(`print(fun(){});`) ); 179 184 } 180 185 unittest 181 186 { 182 187 assert_eq( evalString(`let x=1; let y=(let x=2); x`).val, new IntValue(BigInt(1)) ); 183 188 assert_eq( evalString(`let x=1; let y=(let x=2;fun(){x}); y()`).val, new IntValue(BigInt(2)) ); 184 189 } 190 +unittest 191 +{ 192 + assert_eq( evalString(`@a x=1; @b x=2; @a(x)`).val, new IntValue(BigInt(1)) ); 193 + assert_eq( evalString(`@a x=1; @b x=2; @b(x)`).val, new IntValue(BigInt(2)) ); 194 + assert_eq( evalString(`let x=1; let _ = (@a x=2;2); x`).val, new IntValue(BigInt(1)) ); 195 + assert_throw!Error( evalString(`let x=1; let _ = (@a x=2;2); @a(x)`) ); 196 +} 197 + 185 198 unittest 186 199 { 187 200 assert_nothrow( evalString(`var fac = fun(x){ 188 201 1; 189 202 }; 190 203 print(fac(3));`)); 191 204 assert_nothrow( evalString(`var fac = fun(x){