Differences From Artifact [c3d65954914654a5]:
- File
polemy/eval.d
- 2010-11-09 06:02:32 - part of checkin [7de80acfb8] on branch trunk - Added ultra tenuki REPL (user: kinaba) [annotate]
To 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]
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 = true) | 104 Value eval(AST _e, Table ctx, bool splitCtx = false)
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 )
................................................................................................................................................................................
119 } 119 }
120 else 120 else
121 if( auto e = cast(LetExpression)_e ) 121 if( auto e = cast(LetExpression)_e )
122 { 122 {
123 // for letrec, we need this, but should avoid overwriting???? 123 // for letrec, we need this, but should avoid overwriting????
124 // ctx.set(e.var, "@val", new UndefinedValue, e.pos); 124 // ctx.set(e.var, "@val", new UndefinedValue, e.pos);
125 Value v = eval(e.init, ctx, true); 125 Value v = eval(e.init, ctx, true);
> 126 if(splitCtx)
> 127 ctx = new Table(ctx, Table.Kind.NotPropagateSet);
126 ctx.set(e.var, "@val", v, e.pos); 128 ctx.set(e.var, "@val", v, e.pos);
127 return eval(e.expr, ctx); 129 return eval(e.expr, ctx);
128 } 130 }
129 else 131 else
130 if( auto e = cast(FuncallExpression)_e ) 132 if( auto e = cast(FuncallExpression)_e )
131 { 133 {
132 Value _f = eval(e.fun, ctx); 134 Value _f = eval(e.fun, ctx);
................................................................................................................................................................................
171 assert_throw!RuntimeException( r.ctx.get("y","@val") ); 173 assert_throw!RuntimeException( r.ctx.get("y","@val") );
172 } 174 }
173 unittest 175 unittest
174 { 176 {
175 assert_nothrow( evalString(`print("Hello, world!");`) ); 177 assert_nothrow( evalString(`print("Hello, world!");`) );
176 assert_nothrow( evalString(`print(fun(){});`) ); 178 assert_nothrow( evalString(`print(fun(){});`) );
177 } 179 }
> 180 unittest
> 181 {
> 182 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
> 184 }
178 unittest 185 unittest
179 { 186 {
180 assert_nothrow( evalString(`var fac = fun(x){ 187 assert_nothrow( evalString(`var fac = fun(x){
181 1; 188 1;
182 }; 189 };
183 print(fac(3));`)); 190 print(fac(3));`));
184 assert_nothrow( evalString(`var fac = fun(x){ 191 assert_nothrow( evalString(`var fac = fun(x){