Diff
Not logged in

Differences From Artifact [0386a7dd31807f87]:

To Artifact [19366410c0eeb209]:


43 43 44 44 45 /// 45 /// 46 abstract class FunValue : Value 46 abstract class FunValue : Value 47 { 47 { 48 const(Parameter[]) params(); 48 const(Parameter[]) params(); 49 Table definitionContext(); 49 Table definitionContext(); 50 Value invoke(in LexPosition pos, Layer lay, Table ctx); | 50 Value invoke(LexPosition pos, Layer lay, Table ctx); 51 } < 52 < 53 import polemy.eval; // circular... < 54 version = MacroCache; < 55 //version = AutoMemoization; < 56 //version = AutoRerun; < 57 < 58 /// < 59 class UserDefinedFunValue : FunValue < 60 { < 61 FunLiteral ast; < 62 Table defCtx; < 63 < 64 this(FunLiteral ast, Table defCtx) { this.ast=ast; this.defCtx=defCtx; } < 65 override string toString() const { return sprintf!"(function:%x:%x)"(cas < 66 override bool opEquals(Object rhs_) const /// member-by-member equality < 67 { < 68 if( auto rhs = cast(typeof(this))rhs_ ) < 69 return this.ast==rhs.ast && this.defCtx==rhs.defCtx; < 70 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), < 71 } < 72 override hash_t toHash() const /// member-by-member hash < 73 { < 74 return typeid(this.ast).getHash(&this.ast) + typeid(this.defCtx) < 75 } < 76 override int opCmp(Object rhs_) /// member-by-member compare < 77 { < 78 if( auto rhs = cast(typeof(this))rhs_ ) < 79 { < 80 if(auto i = this.ast.opCmp(rhs.ast)) < 81 return i; < 82 return this.defCtx.opCmp(rhs.defCtx); < 83 } < 84 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), < 85 } < 86 < 87 private AST preprocessed_funbody; < 88 private Value[Value[]][Layer] memo; < 89 < 90 override const(Parameter[]) params() { return ast.params; } < 91 override Table definitionContext() { return defCtx; } < 92 override Value invoke(in LexPosition pos, Layer lay, Table ctx) < 93 { < 94 // TODO: only auto raised ones need memo? no? < 95 // how can we integrate re-run ?? < 96 version(AutoMemoization) < 97 { < 98 Value[] memokey; < 99 if( lay != ValueLayer && lay != MacroLayer ) < 100 { < 101 foreach(i,p; ast.params) < 102 memokey ~= ctx.get(p.name, lay); // lay? < 103 if( auto memolay = lay in memo ) < 104 if( auto pv = memokey in *memolay ) < 105 return *pv; < 106 memo[lay][memokey] = lift(ast.pos,new UndValue,l < 107 } < 108 } < 109 < 110 // @macro run!!! < 111 if( lay == MacroLayer ) < 112 return macroEval(ast.funbody, ctx, false); < 113 < 114 version(MacroCache) { < 115 if( preprocessed_funbody is null ) { < 116 // .prototype!, forced macro cannot access param < 117 ctx.kill = true; scope(exit)ctx.kill=false; < 118 preprocessed_funbody = tableToAST(ValueLayer,mac < 119 } < 120 } else { < 121 if( preprocessed_funbody is null ) { < 122 // .prototype!, forced macro cannot access param < 123 ctx.kill = true; scope(exit)ctx.kill=false; < 124 preprocessed_funbody = tableToAST(ValueLayer,mac < 125 } < 126 } < 127 < 128 auto v = eval(preprocessed_funbody, ctx, true, lay); < 129 version(AutoMemoization) < 130 { < 131 if( lay != ValueLayer && lay != MacroLayer ) < 132 { < 133 memo[lay][memokey] = v; < 134 version(AutoReRun) < 135 memo[lay][memokey] = eval(preprocessed_funbody, < 136 } < 137 } < 138 return v; < 139 } < 140 } < 141 < 142 /// < 143 abstract class NativeFunValue : FunValue < 144 { < 145 Parameter[] params_data; < 146 override const(Parameter[]) params() { return params_data; } < 147 override Table definitionContext() { return new Table; } // todo: cache < 148 } < 149 < 150 /// Named Constructor for FunValue < 151 < 152 FunValue native(R,T...)(R delegate (T) dg) < 153 { < 154 return new class NativeFunValue { < 155 this() < 156 { < 157 foreach(i, Ti; T) < 158 params_data ~= new Parameter(text(i), []); < 159 } < 160 override Value invoke(in LexPosition pos, Layer lay, Table ctx) < 161 { < 162 if( lay != ValueLayer ) < 163 throw genex!RuntimeException(pos, "only "~ValueL < 164 T typed_args; < 165 foreach(i, Ti; T) { < 166 typed_args[i] = cast(Ti) ctx.get(text(i), ValueL < 167 if( typed_args[i] is null ) < 168 throw genex!RuntimeException(pos, sprint < 169 } < 170 try { < 171 return dg(typed_args); < 172 } catch( RuntimeException e ) { < 173 throw e.pos is null ? new RuntimeException(pos, < 174 } < 175 } < 176 }; < 177 } 51 } 178 52 179 /// Context (variable environment) 53 /// Context (variable environment) 180 /// Simlar to prototype chain of ECMAScript etc. 54 /// Simlar to prototype chain of ECMAScript etc. 181 /// But extended with the notion of "Layer" 55 /// But extended with the notion of "Layer" 182 56 183 class Table : Value 57 class Table : Value ................................................................................................................................................................................ 184 { 58 { 185 enum Kind {PropagateSet, NotPropagateSet}; 59 enum Kind {PropagateSet, NotPropagateSet}; 186 bool kill = false; // to refactor 60 bool kill = false; // to refactor 187 61 188 this( Table proto=null, Kind k = Kind.PropagateSet ) 62 this( Table proto=null, Kind k = Kind.PropagateSet ) 189 { this.prototype = proto; this.kind = k; } 63 { this.prototype = proto; this.kind = k; } 190 64 191 void set(string i, Layer lay, Value v, in LexPosition pos=null) | 65 void set(string i, Layer lay, Value v, LexPosition pos=null) 192 { 66 { 193 if( setIfExist(i, lay, v) ) 67 if( setIfExist(i, lay, v) ) 194 return; 68 return; 195 data[i][lay] = v; 69 data[i][lay] = v; 196 } 70 } 197 71 198 bool has(string i, Layer lay, in LexPosition pos=null) | 72 bool has(string i, Layer lay) const 199 { 73 { 200 if( i in data ) { 74 if( i in data ) { 201 if( lay !in data[i] ) 75 if( lay !in data[i] ) 202 return false; 76 return false; 203 if(kill) 77 if(kill) 204 return false; 78 return false; 205 return true; 79 return true; 206 } 80 } 207 if( prototype is null ) 81 if( prototype is null ) 208 return false; 82 return false; 209 return prototype.has(i, lay, pos); | 83 return prototype.has(i, lay); 210 } 84 } 211 85 212 Value get(string i, Layer lay, in LexPosition pos=null) | 86 Value get(string i, Layer lay, LexPosition pos=null) 213 { 87 { 214 if( i in data ) { 88 if( i in data ) { 215 // [TODO] consider forwarding to proto also in this case 89 // [TODO] consider forwarding to proto also in this case 216 if( lay !in data[i] ) 90 if( lay !in data[i] ) 217 throw genex!RuntimeException(pos, sprintf!"'%s' 91 throw genex!RuntimeException(pos, sprintf!"'%s' 218 if(kill) 92 if(kill) 219 throw genex!RuntimeException(pos, sprintf!"'%s' 93 throw genex!RuntimeException(pos, sprintf!"'%s' ................................................................................................................................................................................ 244 string result; 118 string result; 245 bool first = true; 119 bool first = true; 246 foreach(k, l2d; data) 120 foreach(k, l2d; data) 247 foreach(l,d; l2d) 121 foreach(l,d; l2d) 248 { 122 { 249 if(first) first=false; else result~=", "; 123 if(first) first=false; else result~=", "; 250 result ~= k; 124 result ~= k; > 125 if( l.empty ) > 126 result ~= "(emptylayer)"; > 127 else if( l != ValueLayer ) 251 result ~= l; | 128 result ~= l; 252 result ~= ":"; 129 result ~= ":"; 253 result ~= text(cast(Value)d); 130 result ~= text(cast(Value)d); 254 } 131 } 255 if( prototype !is null ) 132 if( prototype !is null ) 256 { 133 { 257 result ~= " / "; 134 result ~= " / "; 258 result ~= prototype.toStringWithoutParen(); 135 result ~= prototype.toStringWithoutParen(); ................................................................................................................................................................................ 371 if( nodeType is null ) 248 if( nodeType is null ) 372 throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST 249 throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST 373 auto pos = extractPos(t); 250 auto pos = extractPos(t); 374 switch(nodeType.data) 251 switch(nodeType.data) 375 { 252 { 376 case "int": 253 case "int": 377 if(auto v = t.access!IntValue(theLayer, "data")) 254 if(auto v = t.access!IntValue(theLayer, "data")) 378 return new IntLiteral(pos, v.data); | 255 return new Int(pos, v.data); 379 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 256 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 380 case "str": 257 case "str": 381 if(auto v = t.access!StrValue(theLayer, "data")) 258 if(auto v = t.access!StrValue(theLayer, "data")) 382 return new StrLiteral(pos, v.data); | 259 return new Str(pos, v.data); 383 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 260 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 384 case "var": 261 case "var": 385 if(auto v = t.access!StrValue(theLayer, "name")) 262 if(auto v = t.access!StrValue(theLayer, "name")) 386 return new VarExpression(pos, v.data); | 263 return new Var(pos, v.data); 387 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 264 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 388 case "lay": 265 case "lay": 389 if(auto v = t.access!StrValue(theLayer, "layer")) 266 if(auto v = t.access!StrValue(theLayer, "layer")) 390 if(auto e = t.access!Table(theLayer, "expr")) 267 if(auto e = t.access!Table(theLayer, "expr")) 391 return new LayExpression(pos, v.data, tableToAST | 268 return new Lay(pos, v.data, tableToAST(theLayer, 392 else 269 else 393 throw genex!RuntimeException(cast(LexPosition)nu 270 throw genex!RuntimeException(cast(LexPosition)nu 394 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 271 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 395 case "let": 272 case "let": 396 if(auto n = t.access!StrValue(theLayer, "name")) 273 if(auto n = t.access!StrValue(theLayer, "name")) 397 if(auto e = t.access!Table(theLayer, "init")) 274 if(auto e = t.access!Table(theLayer, "init")) 398 if(auto b = t.access!Table(theLayer, "expr")) 275 if(auto b = t.access!Table(theLayer, "expr")) ................................................................................................................................................................................ 399 { 276 { 400 string nn = n.data; 277 string nn = n.data; 401 auto ee = tableToAST(theLayer, e); 278 auto ee = tableToAST(theLayer, e); 402 auto bb = tableToAST(theLayer, b); 279 auto bb = tableToAST(theLayer, b); 403 Layer lay=""; 280 Layer lay=""; 404 if(auto l = t.access!StrValue(theLayer, "layer")) 281 if(auto l = t.access!StrValue(theLayer, "layer")) 405 lay = l.data; 282 lay = l.data; 406 return new LetExpression(pos, nn, lay, ee, bb); | 283 return new Let(pos, nn, lay, ee, bb); 407 } 284 } 408 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 285 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 409 case "app": 286 case "app": 410 if(auto f = t.access!Table(theLayer, "fun")) 287 if(auto f = t.access!Table(theLayer, "fun")) 411 if(auto a = t.access!Table(theLayer, "args")) 288 if(auto a = t.access!Table(theLayer, "args")) 412 return new FuncallExpression(pos, tableToAST(theLayer,f) | 289 return new App(pos, tableToAST(theLayer,f), tableToASTLi 413 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 290 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 414 case "fun": 291 case "fun": 415 if(auto p = t.access!Table(theLayer, "params")) 292 if(auto p = t.access!Table(theLayer, "params")) 416 if(auto b = t.access!Table(theLayer, "funbody")) 293 if(auto b = t.access!Table(theLayer, "funbody")) 417 { 294 { 418 Parameter[] ps; 295 Parameter[] ps; 419 foreach(v; tableAsConsList(theLayer, p)) 296 foreach(v; tableAsConsList(theLayer, p)) ................................................................................................................................................................................ 436 Layer[] emp; 313 Layer[] emp; 437 ps ~= new Parameter(ss.data, emp); 314 ps ~= new Parameter(ss.data, emp); 438 continue; 315 continue; 439 } 316 } 440 throw genex!RuntimeException(cast(LexPosition)nu 317 throw genex!RuntimeException(cast(LexPosition)nu 441 } 318 } 442 auto bb = tableToAST(theLayer, b); 319 auto bb = tableToAST(theLayer, b); 443 return new FunLiteral(pos,ps,bb); | 320 return new Fun(pos,ps,bb); 444 } 321 } 445 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 322 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST 446 default: 323 default: 447 throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Inv 324 throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Inv 448 } 325 } 449 } 326 } > 327 > 328 Table makeCons(Value a, Value d) > 329 { > 330 Table t = new Table; > 331 t.set("car", ValueLayer, a); > 332 t.set("cdr", ValueLayer, d); > 333 return t; > 334 } > 335 > 336 Table fromPos(LexPosition pos) > 337 { > 338 Table t = new Table; > 339 if( pos !is null ) { > 340 t.set("filename", ValueLayer, new StrValue(pos.filename)); > 341 t.set("lineno", ValueLayer, new IntValue(BigInt(pos.lineno))); > 342 t.set("column", ValueLayer, new IntValue(BigInt(pos.column))); > 343 } else { > 344 t.set("filename", ValueLayer, new StrValue("nullpos")); > 345 t.set("lineno", ValueLayer, new IntValue(BigInt(0))); > 346 t.set("column", ValueLayer, new IntValue(BigInt(0))); > 347 } > 348 return t; > 349 }