Differences From Artifact [9d70fd9339035713]:
- File
polemy/eval.d
- 2010-11-11 02:40:08 - part of checkin [8e6fa743ee] on branch trunk - added layered parameter AST (only AST. no parser and no evaluator). (user: kinaba) [annotate]
To Artifact [a16d8d322739557e]:
- File
polemy/eval.d
- 2010-11-13 02:48:58 - part of checkin [1c01f44f52] on branch trunk - simplepatternmatch (user: kinaba) [annotate]
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)) );