Check-in [a5fe6233c1]
Not logged in
Overview
SHA1 Hash:a5fe6233c190c89c9cae8608a34df26727136a7f
Date: 2010-11-21 17:18:05
User: kinaba
Comment:layered parameters implemented
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified polemy/eval.d from [97875541a42dbc7a] to [27ad20bc14df9938].

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

Modified polemy/value.d from [f1d2e31afdaaee9d] to [f1a01bb8ba2daf26].

29 { 29 { 30 string data; 30 string data; 31 31 32 mixin SimpleClass; 32 mixin SimpleClass; 33 override string toString() const { return data; } 33 override string toString() const { return data; } 34 } 34 } 35 35 36 /// < 37 class FunValue : Value < 38 { < 39 Value delegate(immutable LexPosition pos, string lay, Value[]) data; < 40 < 41 mixin SimpleConstructor; < 42 alias data call; < 43 override string toString() const { return sprintf!"(function:%s:%s)"(dat < 44 } < 45 < 46 /// 36 /// 47 class UndValue : Value 37 class UndValue : Value 48 { 38 { 49 mixin SimpleClass; 39 mixin SimpleClass; 50 override string toString() const { return "<undefined>"; } 40 override string toString() const { return "<undefined>"; } 51 } 41 } 52 42 53 /// Named Constructor for FunValue < 54 43 > 44 /// > 45 abstract class FunValue : Value > 46 { > 47 const(Parameter[]) params(); > 48 Table definitionContext(); 55 FunValue nativef(Value delegate(immutable LexPosition pos, Layer lay, Value[] ar | 49 Value invoke(in LexPosition pos, Layer lay, Table ctx); > 50 } > 51 > 52 import polemy.eval; // circular... > 53 > 54 /// > 55 class UserDefinedFunValue : FunValue > 56 { > 57 FunLiteral ast; > 58 Table defCtx; > 59 override const(Parameter[]) params() { return ast.params; } > 60 override Table definitionContext() { return defCtx; } > 61 override Value invoke(in LexPosition pos, Layer lay, Table ctx) > 62 { > 63 // TODO: only auto raised ones need memo? no? > 64 // auto memoization > 65 /* > 66 if( lay != "@v" && lay != "@macro" ) > 67 { > 68 if( auto memolay = lay in memo ) > 69 if( auto pv = args in *memolay ) > 70 return *pv; > 71 memo[lay][args] = lift(e.pos,new UndValue,lay,ctx); > 72 } > 73 > 74 */ > 75 // @macro run!!! > 76 if( lay == "@macro" ) > 77 return macroEval(ast.funbody, ctx, false); > 78 /*TODO memo*/ AST macroMemo; > 79 if( macroMemo is null ) { > 80 // .prototype!, forced macro cannot access parameters > 81 ctx.kill = true; scope(exit)ctx.kill=false; > 82 macroMemo = tableToAST("@v",macroEval(ast.funbody, ctx, > 83 } > 84 auto v = eval(macroMemo, ctx, true, lay); > 85 > 86 //auto v = eval(e.funbody, ctxNeo, true, lay); > 87 // auto memoization > 88 // if( lay != "@v" && lay != "@macro" ) > 89 // memo[lay][args] = v; > 90 return v; > 91 } > 92 > 93 mixin SimpleClass; > 94 override string toString() const { return sprintf!"(function:%x:%x)"(cas > 95 } > 96 > 97 /// > 98 abstract class NativeFunValue : FunValue 56 { 99 { 57 return new FunValue(dg); | 100 Parameter[] params_data; > 101 override const(Parameter[]) params() { return params_data; } > 102 override Table definitionContext() { return new Table; } // todo: cache 58 } 103 } 59 104 60 /// Named Constructor for FunValue 105 /// Named Constructor for FunValue 61 106 62 FunValue native(R,T...)(R delegate (T) dg) 107 FunValue native(R,T...)(R delegate (T) dg) 63 { 108 { 64 return nativef( delegate Value(immutable LexPosition pos, Layer lay, Val | 109 return new class NativeFunValue { 65 if( lay != "@v" ) | 110 this() 66 throw genex!RuntimeException(pos, "only @v layer can cal < 67 if( T.length != args.length ) < 68 throw genex!RuntimeException(pos, "argument number misma < 69 T typed_args; < > 111 { 70 foreach(i, Ti; T) | 112 foreach(i, Ti; T) > 113 params_data ~= new Parameter(text(i), []); > 114 } > 115 override Value invoke(in LexPosition pos, Layer lay, Table ctx) 71 { 116 { > 117 if( lay != "@v" ) > 118 throw genex!RuntimeException(pos, "only @v layer > 119 T typed_args; > 120 foreach(i, Ti; T) { 72 typed_args[i] = cast(Ti) args[i]; | 121 typed_args[i] = cast(Ti) ctx.get(text(i), "@v"); 73 if( typed_args[i] is null ) | 122 if( typed_args[i] is null ) 74 throw genex!RuntimeException(pos, sprintf!"type | 123 throw genex!RuntimeException(pos, sprint 75 } | 124 } 76 try { | 125 try { 77 return dg(typed_args); | 126 return dg(typed_args); 78 } catch( RuntimeException e ) { | 127 } catch( RuntimeException e ) { 79 throw e.pos is null ? new RuntimeException(pos, e.msg, e | 128 throw e.pos is null ? new RuntimeException(pos, > 129 } 80 } 130 } 81 }); | 131 }; 82 } 132 } 83 133 84 /// Layer ID 134 /// Layer ID 85 135 86 alias string Layer; 136 alias string Layer; 87 137 88 /// Context (variable environment) 138 /// Context (variable environment) 89 /// Simlar to prototype chain of ECMAScript etc. 139 /// Simlar to prototype chain of ECMAScript etc. 90 /// But extended with the notion of "Layer" 140 /// But extended with the notion of "Layer" 91 141 92 class Table : Value 142 class Table : Value 93 { 143 { 94 enum Kind {PropagateSet, NotPropagateSet}; 144 enum Kind {PropagateSet, NotPropagateSet}; > 145 bool kill = false; // to refactor 95 146 96 this( Table proto=null, Kind k = Kind.PropagateSet ) 147 this( Table proto=null, Kind k = Kind.PropagateSet ) 97 { this.prototype = proto; this.kind = k; } 148 { this.prototype = proto; this.kind = k; } 98 149 99 void set(string i, Layer lay, Value v, in LexPosition pos=null) 150 void set(string i, Layer lay, Value v, in LexPosition pos=null) 100 { 151 { 101 if( setIfExist(i, lay, v) ) 152 if( setIfExist(i, lay, v) ) ................................................................................................................................................................................ 103 data[i][lay] = v; 154 data[i][lay] = v; 104 } 155 } 105 156 106 bool has(string i, Layer lay, in LexPosition pos=null) 157 bool has(string i, Layer lay, in LexPosition pos=null) 107 { 158 { 108 if( i in data ) { 159 if( i in data ) { 109 if( lay !in data[i] ) 160 if( lay !in data[i] ) > 161 return false; > 162 if(kill) 110 return false; 163 return false; 111 return true; 164 return true; 112 } 165 } 113 if( prototype is null ) 166 if( prototype is null ) 114 return false; 167 return false; 115 return prototype.has(i, lay, pos); 168 return prototype.has(i, lay, pos); 116 } 169 } ................................................................................................................................................................................ 117 170 118 Value get(string i, Layer lay, in LexPosition pos=null) 171 Value get(string i, Layer lay, in LexPosition pos=null) 119 { 172 { 120 if( i in data ) { 173 if( i in data ) { 121 // [TODO] consider forwarding to proto also in this case 174 // [TODO] consider forwarding to proto also in this case 122 if( lay !in data[i] ) 175 if( lay !in data[i] ) 123 throw genex!RuntimeException(pos, sprintf!"varia 176 throw genex!RuntimeException(pos, sprintf!"varia > 177 if(kill) > 178 throw genex!RuntimeException(pos, sprintf!"varia 124 return data[i][lay]; 179 return data[i][lay]; 125 } 180 } 126 if( prototype is null ) 181 if( prototype is null ) 127 throw new RuntimeException(pos, sprintf!"variable %s not 182 throw new RuntimeException(pos, sprintf!"variable %s not 128 return prototype.get(i, lay, pos); 183 return prototype.get(i, lay, pos); 129 } 184 } 130 185

Modified sample/macro.pmy from [827dbc8186458d43] to [a38c7267da8f14a3].

47 print(maxNormal(printAndReturn(100),printAndReturn(200))); 47 print(maxNormal(printAndReturn(100),printAndReturn(200))); 48 print("--------------"); 48 print("--------------"); 49 print(maxBad(printAndReturn(100),printAndReturn(200))); 49 print(maxBad(printAndReturn(100),printAndReturn(200))); 50 print("--------------"); 50 print("--------------"); 51 print( LetItBe( 1+2+3, it*it ) ); 51 print( LetItBe( 1+2+3, it*it ) ); 52 print("--------------"); 52 print("--------------"); 53 print(pow10(2)); 53 print(pow10(2)); 54 < 55 }; 54 }; 56 55 57 main() 56 main()