Differences From Artifact [73d121b46bcd4718]:
- File
polemy/eval.d
- 2010-11-09 07:27:21 - part of checkin [0f02103885] on branch trunk - let, var, def became layer-neutral definition (not @val). scope splitting (let x=1;let x=2;let y=(let x=3);x is 1) is correctly implemented now. (user: kinaba) [annotate]
To Artifact [cdb82702a34f8def]:
- File
polemy/eval.d
- 2010-11-09 10:28:08 - part of checkin [dc93ad8cf6] on branch trunk - layered exec expression @lay(...) added (user: kinaba) [annotate]
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){