Diff
Not logged in

Differences From Artifact [9d70fd9339035713]:

To Artifact [a16d8d322739557e]:


105 Table ctx = createGlobalContext(); 105 Table ctx = createGlobalContext(); 106 return typeof(return)(eval(e, ctx, false, "@v"), ctx); 106 return typeof(return)(eval(e, ctx, false, "@v"), ctx); 107 } 107 } 108 108 109 /// Entry point of this module 109 /// Entry point of this module 110 /// If splitCtx = true, then inner variable declaration do not overwrite ctx. 110 /// If splitCtx = true, then inner variable declaration do not overwrite ctx. 111 /// lay is the layer ID for evaluation (standard value semantics uses "@v"). 111 /// lay is the layer ID for evaluation (standard value semantics uses "@v"). 112 < > 112 import std.typetuple; 113 Value eval(AST _e, Table ctx, bool splitCtx, Layer lay) | 113 Value eval(AST e, Table ctx, bool splitCtx, Layer lay) 114 { 114 { > 115 return e.match( 115 if( auto e = cast(StrLiteral)_e ) | 116 (StrLiteral e) 116 { | 117 { 117 return new StrValue(e.data); | 118 return new StrValue(e.data); 118 } | 119 }, 119 else < 120 if( auto e = cast(IntLiteral)_e ) | 120 (IntLiteral e) 121 { | 121 { 122 return new IntValue(e.data); | 122 return new IntValue(e.data); 123 } | 123 }, 124 else < 125 if( auto e = cast(VarExpression)_e ) | 124 (VarExpression e) 126 { | 125 { 127 return ctx.get(e.var, lay, e.pos); | 126 return ctx.get(e.var, lay, e.pos); 128 } | 127 }, 129 else < 130 if( auto e = cast(LayeredExpression)_e ) | 128 (LayeredExpression e) 131 { | 129 { 132 return eval(e.expr, ctx, false, e.lay); | 130 return eval(e.expr, ctx, false, e.lay); 133 } | 131 }, 134 else < 135 if( auto e = cast(LetExpression)_e ) | 132 (LetExpression e) 136 { | 133 { 137 // for letrec, we need this, but should avoid overwriting???? | 134 // for letrec, we need this, but should avoid overwritin 138 // ctx.set(e.var, "@v", new UndefinedValue, e.pos); | 135 // ctx.set(e.var, "@v", new UndefinedValue, e.pos); 139 Value v = eval(e.init, ctx, true, lay); | 136 Value v = eval(e.init, ctx, true, lay); 140 if(splitCtx) | 137 if(splitCtx) 141 ctx = new Table(ctx, Table.Kind.NotPropagateSet); | 138 ctx = new Table(ctx, Table.Kind.NotPropagateSet) 142 ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.pos); | 139 ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.po 143 return eval(e.expr, ctx, false, lay); | 140 return eval(e.expr, ctx, false, lay); 144 } | 141 }, 145 else < 146 if( auto e = cast(FuncallExpression)_e ) | 142 (FuncallExpression e) 147 { | 143 { 148 Value _f = eval(e.fun, ctx, true, lay); | 144 Value _f = eval(e.fun, ctx, true, lay); 149 if( auto f = cast(FunValue)_f ) { | 145 if( auto f = cast(FunValue)_f ) { 150 Value[] args; | 146 Value[] args; 151 foreach(a; e.args) | 147 foreach(a; e.args) 152 args ~= eval(a, ctx, true, lay); | 148 args ~= eval(a, ctx, true, lay); 153 return f.call(e.pos, lay, args); | 149 return f.call(e.pos, lay, args); 154 } else < > 150 } 155 throw genex!RuntimeException(e.pos, "Non-funcion is appl 151 throw genex!RuntimeException(e.pos, "Non-funcion is appl 156 } | 152 }, 157 else < 158 if( auto e = cast(FunLiteral)_e ) | 153 (FunLiteral e) 159 { | 154 { 160 return new FunValue(delegate Value(immutable LexPosition pos, st | 155 return new FunValue(delegate Value(immutable LexPosition 161 if( e.params.length != args.length ) | 156 if( e.params.length != args.length ) 162 throw genex!RuntimeException(e.pos, sprintf!"Arg | 157 throw genex!RuntimeException(e.pos, spri 163 (e.params.length, args.length)); | 158 (e.params.length, args.length)); 164 Table ctxNeo = new Table(ctx, Table.Kind.NotPropagateSet | 159 Table ctxNeo = new Table(ctx, Table.Kind.NotProp 165 foreach(i,p; e.params) | 160 foreach(i,p; e.params) 166 ctxNeo.set(p.name, lay, args[i]); | 161 ctxNeo.set(p.name, lay, args[i]); 167 return eval(e.funbody, ctxNeo, true, lay); | 162 return eval(e.funbody, ctxNeo, true, lay); 168 }); | 163 }); 169 } | 164 }, > 165 delegate Value (AST e) > 166 { 170 throw genex!RuntimeException(_e.pos, sprintf!"Unknown Kind of Expression | 167 throw genex!RuntimeException(e.pos, sprintf!"Unknown Kin > 168 } > 169 ); 171 } 170 } 172 171 173 unittest 172 unittest 174 { 173 { 175 auto r = assert_nothrow( evalString(`var x = 21; x + x*x;`) ); 174 auto r = assert_nothrow( evalString(`var x = 21; x + x*x;`) ); 176 assert_eq( r.val, new IntValue(BigInt(21+21*21)) ); 175 assert_eq( r.val, new IntValue(BigInt(21+21*21)) ); 177 assert_eq( r.ctx.get("x","@v"), new IntValue(BigInt(21)) ); 176 assert_eq( r.ctx.get("x","@v"), new IntValue(BigInt(21)) );