Differences From Artifact [97875541a42dbc7a]:
- File
polemy/eval.d
- 2010-11-20 16:35:14 - part of checkin [3464a035ec] on branch trunk - source code cleanup (user: kinaba) [annotate]
To Artifact [27ad20bc14df9938]:
- File
polemy/eval.d
- 2010-11-21 08:18:05 - part of checkin [a5fe6233c1] on branch trunk - layered parameters implemented (user: kinaba) [annotate]
26 ctx.set("&&", "@v", native( (IntValue lhs, IntValue rhs){return new IntV 26 ctx.set("&&", "@v", native( (IntValue lhs, IntValue rhs){return new IntV
27 ctx.set("<", "@v", native( (Value lhs, Value rhs){return new IntValue(Bi 27 ctx.set("<", "@v", native( (Value lhs, Value rhs){return new IntValue(Bi
28 ctx.set(">", "@v", native( (Value lhs, Value rhs){return new IntValue(Bi 28 ctx.set(">", "@v", native( (Value lhs, Value rhs){return new IntValue(Bi
29 ctx.set("<=", "@v", native( (Value lhs, Value rhs){return new IntValue(B 29 ctx.set("<=", "@v", native( (Value lhs, Value rhs){return new IntValue(B
30 ctx.set(">=", "@v", native( (Value lhs, Value rhs){return new IntValue(B 30 ctx.set(">=", "@v", native( (Value lhs, Value rhs){return new IntValue(B
31 ctx.set("==", "@v", native( (Value lhs, Value rhs){return new IntValue(B 31 ctx.set("==", "@v", native( (Value lhs, Value rhs){return new IntValue(B
32 ctx.set("!=", "@v", native( (Value lhs, Value rhs){return new IntValue(B 32 ctx.set("!=", "@v", native( (Value lhs, Value rhs){return new IntValue(B
33 ctx.set("print", "@v", new FunValue(delegate Value(immutable LexPosition | 33 ctx.set("print", "@v", native( (Value a){
34 foreach(a; args) <
35 write(a); <
36 writeln(""); | 34 writeln(a);
37 return new IntValue(BigInt(178)); 35 return new IntValue(BigInt(178));
38 })); 36 }));
39 ctx.set("if", "@v", new FunValue(delegate Value(immutable LexPosition po | 37 ctx.set("if", "@v", native( (IntValue x, FunValue ft, FunValue fe){
40 if( args.length != 3 ) | 38 auto toRun = (x.data==0 ? fe : ft);
41 throw genex!RuntimeException(pos, "if takes three argume | 39 return toRun.invoke(null, "@v", toRun.definitionContext());
42 if( auto x = cast(IntValue)args[0] ) | 40 // return toRun.invoke(pos, lay, toRun.definitionContext());
43 if( auto ft = cast(FunValue)args[1] ) <
44 if( auto fe = cast(FunValue)args[2] ) <
45 return (x.data == 0 ? fe : ft).call(pos,lay,[]); <
46 throw genex!RuntimeException(pos, "type mismatch in if"); <
47 })); 41 }));
48 ctx.set("_isint", "@v", native( (Value v){return new IntValue(BigInt(cas 42 ctx.set("_isint", "@v", native( (Value v){return new IntValue(BigInt(cas
49 ctx.set("_isstr", "@v", native( (Value v){return new IntValue(BigInt(cas 43 ctx.set("_isstr", "@v", native( (Value v){return new IntValue(BigInt(cas
50 ctx.set("_isfun", "@v", native( (Value v){return new IntValue(BigInt(cas 44 ctx.set("_isfun", "@v", native( (Value v){return new IntValue(BigInt(cas
51 ctx.set("_isundefined", "@v", native( (Value v){return new IntValue(BigI 45 ctx.set("_isundefined", "@v", native( (Value v){return new IntValue(BigI
52 ctx.set("_istable", "@v", native( (Value v){return new IntValue(BigInt(c 46 ctx.set("_istable", "@v", native( (Value v){return new IntValue(BigInt(c
53 ctx.set(".", "@v", native( (Table t, StrValue s){ 47 ctx.set(".", "@v", native( (Table t, StrValue s){
................................................................................................................................................................................
84 /// Entry point of this module 78 /// Entry point of this module
85 79
86 Tuple!(Value,"val",Table,"ctx") eval(AST e) 80 Tuple!(Value,"val",Table,"ctx") eval(AST e)
87 { 81 {
88 Table ctx = createGlobalContext(); 82 Table ctx = createGlobalContext();
89 return typeof(return)(eval(e, ctx, false, "@v"), ctx); 83 return typeof(return)(eval(e, ctx, false, "@v"), ctx);
90 } 84 }
> 85
> 86 Value invokeFunction(in LexPosition pos, Value _f, AST[] args, Table callerCtx,
> 87 {
> 88 if(auto f = cast(FunValue)_f)
> 89 {
> 90 Table ctx = new Table(f.definitionContext(), Table.Kind.NotPropa
> 91 foreach(i,p; f.params())
> 92 if( p.layers.empty )
> 93 if(lay=="@macro")
> 94 ctx.set(p.name, lay, macroEval(args[i],
> 95 else
> 96 ctx.set(p.name, lay, eval(args[i], calle
> 97 else
> 98 foreach(argLay; p.layers)
> 99 if(argLay=="@macro")
> 100 ctx.set(p.name, argLay, macroEva
> 101 else
> 102 ctx.set(p.name, argLay, eval(arg
> 103 return f.invoke(pos, lay, ctx);
> 104 }
> 105 throw genex!RuntimeException(pos, "tried to call non-function");
> 106 }
> 107
> 108 Value lift(in LexPosition pos, Value v, Layer lay, Table callerCtx)
> 109 {
> 110 // similar to invoke Function, but with only one argument bound to @v
> 111 Value _f = callerCtx.get(lay, "(system)", pos);
> 112 if(auto f = cast(FunValue)_f)
> 113 {
> 114 Table ctx = new Table(f.definitionContext(), Table.Kind.NotPropa
> 115 auto ps = f.params();
> 116 if( ps.length != 1 )
> 117 throw genex!RuntimeException(pos, "lift function must ta
> 118 if( ps[0].layers.length==0 || ps[0].layers.length==1 && ps[0].la
> 119 {
> 120 ctx.set(ps[0].name, "@v", v);
> 121 return f.invoke(pos, "@v", ctx);
> 122 }
> 123 else
> 124 throw genex!RuntimeException(pos, "lift function must ta
> 125 }
> 126 throw genex!RuntimeException(pos, "tried to call non-function");
> 127 }
91 128
92 /// Entry point of this module 129 /// Entry point of this module
93 /// If splitCtx = true, then inner variable declaration do not overwrite ctx. 130 /// If splitCtx = true, then inner variable declaration do not overwrite ctx.
94 /// lay is the layer ID for evaluation (standard value semantics uses "@v"). 131 /// lay is the layer ID for evaluation (standard value semantics uses "@v").
95 132
96 Value eval(AST e, Table ctx, bool splitCtx, Layer lay) 133 Value eval(AST e, Table ctx, bool splitCtx, Layer lay)
97 { 134 {
98 return e.match( 135 return e.match(
99 (StrLiteral e) 136 (StrLiteral e)
100 { 137 {
101 Value v = new StrValue(e.data); 138 Value v = new StrValue(e.data);
102 if( lay == "@v" ) 139 if( lay == "@v" )
103 return v; 140 return v;
104 else // rise | 141 else
105 return (cast(FunValue)ctx.get(lay, "(system)", e | 142 return lift(e.pos,v,lay,ctx);
106 }, 143 },
107 (IntLiteral e) 144 (IntLiteral e)
108 { 145 {
109 Value v = new IntValue(e.data); 146 Value v = new IntValue(e.data);
110 if( lay == "@v" ) 147 if( lay == "@v" )
111 return v; 148 return v;
112 else // rise 149 else // rise
113 return (cast(FunValue)ctx.get(lay, "(system)", e | 150 return lift(e.pos,v,lay,ctx);
114 }, 151 },
115 (VarExpression e) 152 (VarExpression e)
116 { 153 {
117 if( lay == "@v" ) 154 if( lay == "@v" )
118 return ctx.get(e.var, lay, e.pos); 155 return ctx.get(e.var, lay, e.pos);
119 try { 156 try {
120 return ctx.get(e.var, lay, e.pos); 157 return ctx.get(e.var, lay, e.pos);
121 } catch( Throwable ) { // [TODO] more precise... 158 } catch( Throwable ) { // [TODO] more precise...
122 // rise from @v <
123 return (cast(FunValue)ctx.get(lay, "(system)", e <
124 [ctx.get(e.var, "@v", e.pos)] | 159 return lift(e.pos, ctx.get(e.var, "@v", e.pos),
125 ); <
126 } 160 }
127 }, 161 },
128 (LayeredExpression e) 162 (LayeredExpression e)
129 { 163 {
130 if( e.lay == "@macro" ) 164 if( e.lay == "@macro" )
131 return macroEval(e.expr, ctx, false); 165 return macroEval(e.expr, ctx, false);
132 else 166 else
................................................................................................................................................................................
140 ctx = new Table(ctx, Table.Kind.NotPropagateSet) 174 ctx = new Table(ctx, Table.Kind.NotPropagateSet)
141 Value v = eval(e.init, ctx, true, lay); 175 Value v = eval(e.init, ctx, true, lay);
142 ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.po 176 ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.po
143 return eval(e.expr, ctx, false, lay); 177 return eval(e.expr, ctx, false, lay);
144 }, 178 },
145 (FuncallExpression e) 179 (FuncallExpression e)
146 { 180 {
147 Value _f = eval(e.fun, ctx, true, lay); | 181 return invokeFunction(e.pos, eval(e.fun, ctx, true, lay)
148 if( auto f = cast(FunValue)_f ) { <
149 Value[] args; <
150 foreach(a; e.args) <
151 args ~= eval(a, ctx, true, lay); <
152 return f.call(e.pos, lay, args); <
153 } <
154 throw genex!RuntimeException(e.pos, "Non-funcion is appl <
155 }, 182 },
156 (FunLiteral e) 183 (FunLiteral e)
157 { 184 {
158 Value[Value[]][Layer] memo; 185 Value[Value[]][Layer] memo;
159 AST macroMemo = null; // cache 186 AST macroMemo = null; // cache
160 187
161 // funvalue need not be rised 188 // funvalue need not be rised
162 // no, need to be rised !! suppose @t(fib)("int") 189 // no, need to be rised !! suppose @t(fib)("int")
163 return new FunValue(delegate Value(immutable LexPosition | 190 return new UserDefinedFunValue(e, ctx);
164 // TODO: only auto raised ones need memo? no? <
165 // auto memoization <
166 if( lay != "@v" && lay != "@macro" ) <
167 { <
168 if( auto memolay = lay in memo ) <
169 if( auto pv = args in *memolay ) <
170 return *pv; <
171 memo[lay][args] = (cast(FunValue)ctx.get <
172 [new UndValue] <
173 ); <
174 } <
175 <
176 if( e.params.length != args.length ) <
177 throw genex!RuntimeException(e.pos, spri <
178 (e.params.length, args.length)); <
179 Table ctxNeo = new Table(ctx, Table.Kind.NotProp <
180 foreach(i,p; e.params) <
181 ctxNeo.set(p.name, lay, args[i]); <
182 <
183 // @macro run!!! <
184 if( lay == "@macro" ) <
185 return macroEval(e.funbody, ctxNeo, fals <
186 if( macroMemo is null ) <
187 macroMemo = tableToAST("@v",macroEval(e. <
188 auto v = eval(macroMemo, ctxNeo, true, lay); <
189 <
190 //auto v = eval(e.funbody, ctxNeo, true, lay); <
191 // auto memoization <
192 if( lay != "@v" && lay != "@macro" ) <
193 memo[lay][args] = v; <
194 return v; <
195 }); <
196 }, 191 },
197 delegate Value (AST e) 192 delegate Value (AST e)
198 { 193 {
199 throw genex!RuntimeException(e.pos, sprintf!"Unknown Kin 194 throw genex!RuntimeException(e.pos, sprintf!"Unknown Kin
200 } 195 }
201 ); 196 );
202 } 197 }
................................................................................................................................................................................
248 t.set("is", theLayer, new StrValue("lay")); 243 t.set("is", theLayer, new StrValue("lay"));
249 t.set("layer", theLayer, new StrValue(e.lay)); 244 t.set("layer", theLayer, new StrValue(e.lay));
250 t.set("expr", theLayer, macroEval(e.expr,ctx,Alw 245 t.set("expr", theLayer, macroEval(e.expr,ctx,Alw
251 return cast(Value)t; 246 return cast(Value)t;
252 } 247 }
253 else 248 else
254 { 249 {
> 250 if( e.lay == "@macro" )
> 251 return macroEval(e.expr, ctx, false);
> 252 else
255 return eval(e.expr, ctx, true, e.lay); | 253 return eval(e.expr, ctx, true, e.lay);
256 } 254 }
257 }, 255 },
258 (LetExpression e) 256 (LetExpression e)
259 { 257 {
260 Table t = new Table; 258 Table t = new Table;
261 t.set("pos", theLayer, pos); 259 t.set("pos", theLayer, pos);
262 t.set("is", theLayer, new StrValue("let")); 260 t.set("is", theLayer, new StrValue("let"));
................................................................................................................................................................................
265 t.set("expr", theLayer, macroEval(e.expr,ctx,AlwaysMacro 263 t.set("expr", theLayer, macroEval(e.expr,ctx,AlwaysMacro
266 return t; 264 return t;
267 }, 265 },
268 (FuncallExpression e) 266 (FuncallExpression e)
269 { 267 {
270 Value _f = macroEval(e.fun,ctx,AlwaysMacro); 268 Value _f = macroEval(e.fun,ctx,AlwaysMacro);
271 269
272 // copy & pase from normal eval <
273 // [TODO] sync with @layerd parameters. <
274 if( auto f = cast(FunValue)_f ) { | 270 if( auto f = cast(FunValue)_f )
275 Value[] args; <
276 foreach(a; e.args) <
277 args ~= macroEval(a, ctx, AlwaysMacro); <
278 return f.call(e.pos, "@macro", args); // explici <
279 } <
> 271 return invokeFunction(e.pos, f, e.args, ctx, "@m
280 272
281 Table t = new Table; 273 Table t = new Table;
282 t.set("pos", theLayer, pos); 274 t.set("pos", theLayer, pos);
283 t.set("is", theLayer, new StrValue("app")); 275 t.set("is", theLayer, new StrValue("app"));
284 t.set("fun", theLayer, _f); 276 t.set("fun", theLayer, _f);
285 Table args = new Table; 277 Table args = new Table;
286 foreach_reverse(a; e.args) { 278 foreach_reverse(a; e.args) {
................................................................................................................................................................................
386 // there was a bug that declaration in the first line of function defini 378 // there was a bug that declaration in the first line of function defini
387 // cannot be recursive 379 // cannot be recursive
388 assert_nothrow( evalString(`def foo() { 380 assert_nothrow( evalString(`def foo() {
389 def bar(y) { if(y<1) {0} else {bar(0)} }; 381 def bar(y) { if(y<1) {0} else {bar(0)} };
390 bar(1) 382 bar(1)
391 }; foo()`) ); 383 }; foo()`) );
392 } 384 }
> 385