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 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)) );