Diff
Not logged in

Differences From Artifact [9d70fd9339035713]:

To Artifact [a16d8d322739557e]:


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