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