Check-in [b97bd4f713]
Not logged in
Overview
SHA1 Hash:b97bd4f71330654c51496a03e0c22101ef0691e5
Date: 2010-11-23 18:36:27
User: kinaba
Comment:automatic AST to table encoder
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified main.d from [e659b2cb410288fd] to [cbf6e2570b5a90b0].

10 import std.array; 10 import std.array; 11 import polemy.value; 11 import polemy.value; 12 import polemy.failure; 12 import polemy.failure; 13 import polemy.layer; 13 import polemy.layer; 14 import polemy.parse; 14 import polemy.parse; 15 import polemy.ast; 15 import polemy.ast; 16 import polemy.eval; 16 import polemy.eval; > 17 import polemy.runtime; 17 18 18 enum VersionNoMajor = 0; 19 enum VersionNoMajor = 0; 19 enum VersionNoMinor = 1; 20 enum VersionNoMinor = 1; 20 enum VersionNoRev = 0; 21 enum VersionNoRev = 0; 21 22 22 /// Read-Eval-Print-Loop 23 /// Read-Eval-Print-Loop 23 24 ................................................................................................................................................................................ 24 class REPL 25 class REPL 25 { 26 { 26 Evaluator ev; 27 Evaluator ev; 27 /// Load the prelude environment 28 /// Load the prelude environment 28 this() 29 this() 29 { 30 { 30 ev = new Evaluator; 31 ev = new Evaluator; > 32 enrollRuntimeLibrary(ev); 31 } 33 } 32 34 33 /// Print the version number etc. 35 /// Print the version number etc. 34 void greet() 36 void greet() 35 { 37 { 36 writefln("Welcome to Polemy %d.%d.%d", VersionNoMajor, VersionNo 38 writefln("Welcome to Polemy %d.%d.%d", VersionNoMajor, VersionNo 37 } 39 }

Modified polemy/ast.d from [cf8f245149fce4dc] to [f7a981003352ec6b].

9 import polemy.failure; 9 import polemy.failure; 10 import polemy.layer; 10 import polemy.layer; 11 11 12 /// 12 /// 13 abstract class AST 13 abstract class AST 14 { 14 { 15 LexPosition pos; 15 LexPosition pos; > 16 16 mixin SimpleConstructor; 17 mixin SimpleConstructor; 17 mixin SimplePatternMatch; < 18 } 18 } 19 19 20 /// 20 /// 21 class Int : AST 21 class Int : AST 22 { 22 { 23 BigInt data; 23 BigInt data; > 24 24 mixin SimpleClass; 25 mixin SimpleClass; 25 this(LexPosition pos, int n) {super(pos); data = n;} 26 this(LexPosition pos, int n) {super(pos); data = n;} 26 this(LexPosition pos, long n) {super(pos); data = n;} 27 this(LexPosition pos, long n) {super(pos); data = n;} 27 this(LexPosition pos, BigInt n) {super(pos); data = n;} 28 this(LexPosition pos, BigInt n) {super(pos); data = n;} 28 this(LexPosition pos, string n) {super(pos); data = BigInt(n);} 29 this(LexPosition pos, string n) {super(pos); data = BigInt(n);} 29 } 30 } 30 31 31 /// 32 /// 32 class Str : AST 33 class Str : AST 33 { 34 { 34 string data; 35 string data; > 36 35 mixin SimpleClass; 37 mixin SimpleClass; 36 } 38 } 37 39 38 /// 40 /// 39 class Var : AST 41 class Var : AST 40 { 42 { 41 string name; 43 string name; > 44 42 mixin SimpleClass; 45 mixin SimpleClass; 43 } 46 } 44 47 45 /// 48 /// 46 class Lay : AST 49 class Lay : AST 47 { 50 { 48 Layer layer; 51 Layer layer; 49 AST expr; 52 AST expr; > 53 50 mixin SimpleClass; 54 mixin SimpleClass; 51 } 55 } 52 56 53 /// 57 /// 54 class Let : AST 58 class Let : AST 55 { 59 { 56 string name; 60 string name; 57 Layer layer; 61 Layer layer; 58 AST init; 62 AST init; 59 AST expr; 63 AST expr; > 64 60 mixin SimpleClass; 65 mixin SimpleClass; 61 } 66 } 62 67 63 /// 68 /// 64 class App : AST 69 class App : AST 65 { 70 { 66 AST fun; 71 AST fun; 67 AST[] args; 72 AST[] args; 68 this(LexPosition pos, AST fun, AST[] args...) < 69 { super(pos); this.fun=fun; this.args=args.dup; } < > 73 70 mixin SimpleClass; 74 mixin SimpleClass; > 75 this(LexPosition pos, AST fun, AST[] args...) { super(pos); this.fun=fun 71 } 76 } 72 77 73 /// 78 /// 74 class Parameter 79 class Parameter 75 { 80 { 76 string name; 81 string name; 77 Layer[] layers; 82 Layer[] layers; > 83 78 mixin SimpleClass; 84 mixin SimpleClass; 79 } 85 } 80 86 81 /// 87 /// 82 class Fun : AST 88 class Fun : AST 83 { 89 { 84 Parameter[] params; 90 Parameter[] params; 85 AST funbody; 91 AST funbody; > 92 86 mixin SimpleClass; 93 mixin SimpleClass; 87 } 94 } 88 95 89 /// Handy Generator for AST nodes. To use this, mixin EasyAst; 96 /// Handy Generator for AST nodes. To use this, mixin EasyAst; 90 97 91 /*mixin*/ 98 /*mixin*/ 92 template EasyAST() 99 template EasyAST()

Modified polemy/eval.d from [b119954d6ce43301] to [5a9949a1eb8839b1].

8 import polemy._common; 8 import polemy._common; 9 import polemy.failure; 9 import polemy.failure; 10 import polemy.ast; 10 import polemy.ast; 11 import polemy.parse; 11 import polemy.parse; 12 import polemy.value; 12 import polemy.value; 13 import polemy.layer; 13 import polemy.layer; 14 14 > 15 /// Objects for maitaining global environment and evaluation of expression on it 15 class Evaluator 16 class Evaluator 16 { 17 { 17 public: 18 public: > 19 /// Initialize evaluator with empty context 18 this() { theContext = new Table; } 20 this() { theContext = new Table; } 19 21 > 22 /// Evaluate the AST 20 Value evalAST(AST e) 23 Value evalAST(AST e) 21 { 24 { 22 return eval(e, ValueLayer, theContext, OverwriteCtx); 25 return eval(e, ValueLayer, theContext, OverwriteCtx); 23 } 26 } 24 27 > 28 /// Evaluate the string 25 Value evalString(S,T...)(S str, T fn_ln_cn) 29 Value evalString(S,T...)(S str, T fn_ln_cn) 26 { 30 { 27 return evalAST(parseString(str,fn_ln_cn)); 31 return evalAST(parseString(str,fn_ln_cn)); 28 } 32 } 29 33 > 34 /// Evaluate the file 30 Value evalFile(S,T...)(S filename, T ln_cn) 35 Value evalFile(S,T...)(S filename, T ln_cn) 31 { 36 { 32 return evalAST(parseFile(filename,ln_cn)); 37 return evalAST(parseFile(filename,ln_cn)); 33 } 38 } 34 39 > 40 /// Get the global context 35 Table globalContext() 41 Table globalContext() 36 { 42 { 37 return theContext; 43 return theContext; 38 } 44 } 39 45 40 private: 46 private: 41 Table theContext; 47 Table theContext; 42 48 43 private: < 44 enum : bool { CascadeCtx=false, OverwriteCtx=true }; 49 enum : bool { CascadeCtx=false, OverwriteCtx=true }; 45 < 46 Value eval( AST e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 50 Value eval( AST e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 47 { 51 { 48 // dynamic-overload-resolution-pattern: modify here 52 // dynamic-overload-resolution-pattern: modify here 49 enum funName = "eval"; 53 enum funName = "eval"; 50 alias TypeTuple!(e,lay,ctx,overwriteCtx) params; 54 alias TypeTuple!(e,lay,ctx,overwriteCtx) params; 51 55 52 // dynamic-overload-resolution-pattern: dispatch 56 // dynamic-overload-resolution-pattern: dispatch ................................................................................................................................................................................ 57 static if( is(T == typeof(params[0])) ) {} else if( auto 61 static if( is(T == typeof(params[0])) ) {} else if( auto 58 return __traits(getOverloads, this, funName)[i]( 62 return __traits(getOverloads, this, funName)[i]( 59 63 60 // dynamic-overload-resolution-pattern: default behavior 64 // dynamic-overload-resolution-pattern: default behavior 61 assert(false, text("eval() for ",typeid(e)," [",e.pos,"] is not 65 assert(false, text("eval() for ",typeid(e)," [",e.pos,"] is not 62 } 66 } 63 67 64 private: < 65 Value eval( Str e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 68 Value eval( Str e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 66 { 69 { 67 Value v = new StrValue(e.data); | 70 if( isMacroishLayer(lay) ) 68 if( lay==RawMacroLayer || lay==MacroLayer ) | 71 return ast2table(e, (AST e){return eval(e,lay,ctx);}); 69 { < 70 auto ast = new Table; < 71 ast.set("pos", ValueLayer, fromPos(e.pos)); < 72 ast.set("is", ValueLayer, new StrValue("str")); < 73 ast.set("data", ValueLayer, v); < 74 return ast; < 75 } < 76 if( lay==ValueLayer ) 72 if( lay==ValueLayer ) 77 return v; | 73 return new StrValue(e.data); 78 return lift(v, lay, ctx, e.pos); | 74 return lift(new StrValue(e.data), lay, ctx, e.pos); 79 } 75 } 80 76 81 Value eval( Int e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 77 Value eval( Int e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 82 { 78 { 83 Value v = new IntValue(e.data); | 79 if( isMacroishLayer(lay) ) 84 if( lay==RawMacroLayer || lay==MacroLayer ) | 80 return ast2table(e, (AST e){return eval(e,lay,ctx);}); 85 { < 86 auto ast = new Table; < 87 ast.set("pos", ValueLayer, fromPos(e.pos)); < 88 ast.set("is", ValueLayer, new StrValue("int")); < 89 ast.set("data", ValueLayer, v); < 90 return ast; < 91 } < 92 if( lay==ValueLayer ) 81 if( lay==ValueLayer ) 93 return v; | 82 return new IntValue(e.data); 94 return lift(v, lay, ctx, e.pos); | 83 return lift(new IntValue(e.data), lay, ctx, e.pos); 95 } 84 } 96 85 97 Value eval( Var e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 86 Value eval( Var e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 98 { 87 { 99 if( lay==RawMacroLayer || lay==MacroLayer ) | 88 if( isMacroishLayer(lay) ) 100 { < 101 if( ctx.has(e.name,MacroLayer) ) 89 if( ctx.has(e.name,MacroLayer) ) 102 return ctx.get(e.name, MacroLayer, e.pos); 90 return ctx.get(e.name, MacroLayer, e.pos); 103 auto ast = new Table; | 91 else 104 ast.set("pos", ValueLayer, fromPos(e.pos)); | 92 return ast2table(e, (AST e){return eval(e,lay,ct 105 ast.set("is", ValueLayer, new StrValue("var")); < 106 ast.set("name", ValueLayer, new StrValue(e.name)); < 107 return ast; < 108 } < 109 if( lay==ValueLayer || ctx.has(e.name, lay) ) 93 if( lay==ValueLayer || ctx.has(e.name, lay) ) 110 return ctx.get(e.name, lay, e.pos); 94 return ctx.get(e.name, lay, e.pos); 111 return lift(ctx.get(e.name, ValueLayer, e.pos), lay, ctx, e.pos) 95 return lift(ctx.get(e.name, ValueLayer, e.pos), lay, ctx, e.pos) 112 } 96 } 113 97 114 Value eval( App e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 98 Value eval( App e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 115 { 99 { 116 Value f = eval( e.fun, lay, ctx ); 100 Value f = eval( e.fun, lay, ctx ); 117 if( lay==RawMacroLayer || lay==MacroLayer ) | 101 if( isMacroishLayer(lay) ) 118 { < 119 if( auto ff = cast(FunValue)f ) 102 if( auto ff = cast(FunValue)f ) 120 return invokeFunction(ff, e.args, MacroLayer, ct 103 return invokeFunction(ff, e.args, MacroLayer, ct 121 Table ast = new Table; < 122 ast.set("pos", ValueLayer, fromPos(e.pos)); < 123 ast.set("is", ValueLayer, new StrValue("app")); < 124 ast.set("fun", ValueLayer, f); < 125 Table args = new Table; < 126 foreach_reverse(a; e.args) < 127 args = makeCons(eval(a, lay, ctx), args); < 128 ast.set("args", ValueLayer, args); < 129 return ast; < 130 } < 131 else | 104 else 132 { < > 105 return ast2table(e, (AST e){return eval(e,lay,ct 133 return invokeFunction(f, e.args, lay, ctx, e.pos); | 106 return invokeFunction(f, e.args, lay, ctx, e.pos); 134 } < 135 } 107 } 136 108 137 Value eval( Fun e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 109 Value eval( Fun e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 138 { 110 { 139 if( lay==RawMacroLayer || lay==MacroLayer ) | 111 if( isMacroishLayer(lay) ) 140 { | 112 return ast2table(e, (AST e){return eval(e,lay,ctx);}); 141 Table t = new Table; < 142 t.set("pos", ValueLayer, fromPos(e.pos)); < 143 t.set("is", ValueLayer, new StrValue("fun")); < 144 t.set("funbody", ValueLayer, eval(e.funbody,lay,ctx)); < 145 Table params = new Table; < 146 foreach_reverse(p; e.params) < 147 { < 148 Table lays = new Table; < 149 foreach_reverse(l; p.layers) < 150 lays = makeCons(new StrValue(l), lays); < 151 Table kv = new Table; < 152 kv.set("name", ValueLayer, new StrValue(p.name)) < 153 kv.set("layers", ValueLayer, lays); < 154 Table cons = new Table; < 155 params = makeCons(kv, params); < 156 } < 157 t.set("params", ValueLayer, params); < 158 return t; < 159 } < 160 else 113 else 161 { < 162 return createNewFunction(e, ctx); 114 return createNewFunction(e, ctx); 163 } < 164 } 115 } 165 116 166 Value eval( Lay e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 117 Value eval( Lay e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 167 { 118 { 168 if( lay == RawMacroLayer ) | 119 if( isNoLayerChangeLayer(lay) ) 169 { | 120 return ast2table(e, (AST e){return eval(e,lay,ctx);}); 170 Value r = eval(e.expr, lay, ctx); < 171 auto ast = new Table; // todo: pos < 172 ast.set("pos", ValueLayer, fromPos(e.pos)); < 173 ast.set("is", ValueLayer, new StrValue("lay")); < 174 ast.set("layer", ValueLayer, new StrValue(e.layer)); < 175 ast.set("expr", ValueLayer, r); < 176 return ast; < 177 } < 178 else 121 else 179 return eval(e.expr, e.layer, ctx); 122 return eval(e.expr, e.layer, ctx); 180 } 123 } 181 124 182 Value eval( Let e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 125 Value eval( Let e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 183 { 126 { 184 // todo @macro let 127 // todo @macro let 185 if( lay==RawMacroLayer || lay==MacroLayer ) | 128 if( isMacroishLayer(lay) ) 186 { | 129 return ast2table(e, (AST e){return eval(e,lay,ctx);}); 187 auto ast = new Table; // todo: pos < 188 ast.set("pos", ValueLayer, fromPos(e.pos)); < 189 ast.set("is", ValueLayer, new StrValue("let")); < 190 ast.set("name", ValueLayer, new StrValue(e.name)); < 191 ast.set("layer", ValueLayer, new StrValue(e.layer)); < 192 ast.set("init", ValueLayer, eval(e.init, lay, ctx)); < 193 ast.set("expr", ValueLayer, eval(e.expr, lay, ctx)); < 194 return ast; < 195 } < 196 else 130 else 197 { 131 { 198 if( !overwriteCtx ) 132 if( !overwriteCtx ) 199 ctx = new Table(ctx, Table.Kind.NotPropagateSet) 133 ctx = new Table(ctx, Table.Kind.NotPropagateSet) 200 Value ri = eval(e.init, lay, ctx); 134 Value ri = eval(e.init, lay, ctx); 201 string theLayer = e.layer.empty ? (lay==RawMacroLayer ? | 135 string theLayer = e.layer.empty ? lay : e.layer; // neut 202 ctx.set(e.name, theLayer, ri); 136 ctx.set(e.name, theLayer, ri); 203 return eval(e.expr, lay, ctx, OverwriteCtx); 137 return eval(e.expr, lay, ctx, OverwriteCtx); 204 } 138 } 205 } 139 } 206 140 207 private: 141 private: 208 Value invokeFunction(Value _f, AST[] args, Layer lay, Table ctx, LexPosi 142 Value invokeFunction(Value _f, AST[] args, Layer lay, Table ctx, LexPosi ................................................................................................................................................................................ 212 Table newCtx = new Table(f.definitionContext(), Table.Ki 146 Table newCtx = new Table(f.definitionContext(), Table.Ki 213 foreach(i,p; f.params()) 147 foreach(i,p; f.params()) 214 if( p.layers.empty ) 148 if( p.layers.empty ) 215 newCtx.set(p.name, (lay==RawMacroLayer ? 149 newCtx.set(p.name, (lay==RawMacroLayer ? 216 else 150 else 217 foreach(argLay; p.layers) 151 foreach(argLay; p.layers) 218 newCtx.set(p.name, argLay, eval( 152 newCtx.set(p.name, argLay, eval( 219 return f.invoke(pos, lay, newCtx); | 153 return f.invoke(lay==RawMacroLayer ? MacroLayer : lay, n 220 } 154 } 221 throw genex!RuntimeException(pos, text("tried to call non-functi 155 throw genex!RuntimeException(pos, text("tried to call non-functi 222 } 156 } 223 157 224 Value lift(Value v, Layer lay, Table ctx, LexPosition pos=null) 158 Value lift(Value v, Layer lay, Table ctx, LexPosition pos=null) 225 { 159 { > 160 assert( !isMacroishLayer(lay), "lift to the @macro layer should > 161 226 // functions are automatically lifterd 162 // functions are automatically lifterd 227 if( cast(FunValue) v ) 163 if( cast(FunValue) v ) 228 return v; 164 return v; 229 165 230 // similar to invoke Function, but with only one argument bound 166 // similar to invoke Function, but with only one argument bound 231 if(auto f = cast(FunValue)ctx.get(lay, SystemLayer, pos)) 167 if(auto f = cast(FunValue)ctx.get(lay, SystemLayer, pos)) 232 { 168 { ................................................................................................................................................................................ 233 Table newCtx = new Table(f.definitionContext(), Table.Ki 169 Table newCtx = new Table(f.definitionContext(), Table.Ki 234 auto ps = f.params(); 170 auto ps = f.params(); 235 if( ps.length != 1 ) 171 if( ps.length != 1 ) 236 throw genex!RuntimeException(pos, "lift function 172 throw genex!RuntimeException(pos, "lift function 237 if( ps[0].layers.length==0 || ps[0].layers.length==1 && 173 if( ps[0].layers.length==0 || ps[0].layers.length==1 && 238 { 174 { 239 newCtx.set(ps[0].name, ValueLayer, v); 175 newCtx.set(ps[0].name, ValueLayer, v); 240 return f.invoke(pos, ValueLayer, newCtx); | 176 return f.invoke(ValueLayer, newCtx, pos); 241 } 177 } 242 else 178 else 243 throw genex!RuntimeException(pos, "lift function 179 throw genex!RuntimeException(pos, "lift function 244 } 180 } 245 throw genex!RuntimeException(pos, "tried to call non-function"); 181 throw genex!RuntimeException(pos, "tried to call non-function"); 246 } 182 } 247 183 ................................................................................................................................................................................ 273 if(auto i = this.ast.opCmp(rhs.ast)) 209 if(auto i = this.ast.opCmp(rhs.ast)) 274 return i; 210 return i; 275 return this.defCtx.opCmp(rhs.defCtx); 211 return this.defCtx.opCmp(rhs.defCtx); 276 } 212 } 277 assert(false, sprintf!"Cannot compare %s with %s 213 assert(false, sprintf!"Cannot compare %s with %s 278 } 214 } 279 215 280 override Value invoke(LexPosition pos, Layer lay, Table | 216 override Value invoke(Layer lay, Table ctx, LexPosition 281 { 217 { 282 if( lay == MacroLayer ) 218 if( lay == MacroLayer ) 283 return eval(ast.funbody, lay, ctx); 219 return eval(ast.funbody, lay, ctx); > 220 if( afterMacroAST is null ) 284 auto macroed = tableToAST(ValueLayer, eval(e.fun | 221 afterMacroAST = tableToAST(ValueLayer, e 285 return eval(macroed, lay, ctx); | 222 return eval(afterMacroAST, lay, ctx); 286 } 223 } > 224 > 225 AST afterMacroAST; 287 } 226 } 288 return new UserDefinedFunValue(e,ctx); 227 return new UserDefinedFunValue(e,ctx); 289 } 228 } 290 229 291 public: 230 public: 292 /// TODO: move up | 231 /// Add primitive function to the global context 293 /// TDOO: to other layers? < 294 void addPrimitive(R,T...)(string name, Layer lay, R delegate (T) dg) | 232 void addPrimitive(R,T...)(string name, Layer defLay, R delegate (T) dg) 295 { 233 { 296 class NativeFunValue : FunValue 234 class NativeFunValue : FunValue 297 { 235 { 298 Parameter[] params_data; < 299 override string toString() { return sprintf!"(native:%x) < 300 override const(Parameter[]) params() { return params_dat 236 override const(Parameter[]) params() { return params_dat 301 override Table definitionContext() { return new Table; } | 237 override Table definitionContext() { return theContext > 238 > 239 override string toString() { return sprintf!"(native:%x) > 240 override int opCmp(Object rhs) { > 241 if(auto r = cast(NativeFunValue)rhs) return type > 242 if(auto r = cast(Value)rhs) return type > 243 throw genex!RuntimeException(LexPosition.dummy, > 244 } > 245 mixin SimpleToHash; > 246 > 247 R delegate(T) dg; > 248 Parameter[] params_data; > 249 > 250 this(R delegate(T) dg) > 251 { 302 this(){ | 252 this.dg = dg; 303 foreach(i, Ti; T) 253 foreach(i, Ti; T) 304 params_data ~= new Parameter(text(i), [] 254 params_data ~= new Parameter(text(i), [] 305 } 255 } > 256 306 override Value invoke(LexPosition pos, Layer lay, Table | 257 override Value invoke(Layer lay, Table ctx, LexPosition 307 { 258 { 308 if( lay != ValueLayer ) | 259 if( lay != defLay ) 309 throw genex!RuntimeException(pos, "only | 260 throw genex!RuntimeException(pos, text(" 310 T typed_args; 261 T typed_args; 311 foreach(i, Ti; T) { 262 foreach(i, Ti; T) { 312 typed_args[i] = cast(Ti) ctx.get(text(i) | 263 typed_args[i] = cast(Ti) ctx.get(text(i) 313 if( typed_args[i] is null ) 264 if( typed_args[i] is null ) 314 throw genex!RuntimeException(pos | 265 throw genex!RuntimeException(pos 315 } 266 } 316 try { 267 try { 317 return dg(typed_args); 268 return dg(typed_args); 318 } catch( RuntimeException e ) { 269 } catch( RuntimeException e ) { 319 throw e.pos is null ? new RuntimeExcepti 270 throw e.pos is null ? new RuntimeExcepti 320 } 271 } 321 } 272 } 322 } 273 } 323 theContext.set(name, lay, new NativeFunValue); | 274 theContext.set(name, defLay, new NativeFunValue(dg)); 324 } 275 } 325 } 276 } 326 277 327 version(unittest) import polemy.runtime; 278 version(unittest) import polemy.runtime; 328 unittest 279 unittest 329 { 280 { 330 auto e = new Evaluator; 281 auto e = new Evaluator;

Modified polemy/layer.d from [79038e8ac0f7ba6a] to [62182a8e7452f9e8].

12 12 13 alias string Layer; 13 alias string Layer; 14 14 15 enum : Layer 15 enum : Layer 16 { 16 { 17 SystemLayer = "(system)", /// Predefined layer for internal data 17 SystemLayer = "(system)", /// Predefined layer for internal data 18 ValueLayer = "@value", /// Predefined layer for normal run 18 ValueLayer = "@value", /// Predefined layer for normal run 19 MacroLayer = "@macro", /// Predefined layer for macro run | 19 MacroLayer = "@macro", /// Predefined layer for macro run (@lay() 20 RawMacroLayer = "(rawmacro)", /// Predefined layer for raw-macro run | 20 RawMacroLayer = "(rawmacro)", /// Predefined layer for macro run (@lay() > 21 } > 22 > 23 bool isMacroishLayer( Layer lay ) > 24 { > 25 return lay==MacroLayer || lay==RawMacroLayer; > 26 } > 27 > 28 bool isNoLayerChangeLayer( Layer lay ) > 29 { > 30 return lay==RawMacroLayer; 21 } 31 }

Modified polemy/value.d from [19366410c0eeb209] to [b6c76b48bfdecce6].

5 * Runtime data structures for Polemy programming language. 5 * Runtime data structures for Polemy programming language. 6 */ 6 */ 7 module polemy.value; 7 module polemy.value; 8 import polemy._common; 8 import polemy._common; 9 import polemy.failure; 9 import polemy.failure; 10 import polemy.ast; 10 import polemy.ast; 11 import polemy.layer; 11 import polemy.layer; > 12 import std.string; 12 13 13 /// Runtime values of Polemy 14 /// Runtime values of Polemy 14 15 15 abstract class Value 16 abstract class Value 16 { 17 { > 18 override bool opEquals(Object rhs) { return 0==opCmp(rhs); } 17 } 19 } 18 20 19 /// 21 /// 20 class IntValue : Value 22 class IntValue : Value 21 { 23 { 22 BigInt data; 24 BigInt data; 23 25 > 26 this(int n) { this.data = n; } > 27 this(long n) { this.data = n; } > 28 this(BigInt n) { this.data = n; } > 29 this(string n) { this.data = BigInt(n); } > 30 override string toString() const { return toDecimalString(cast(BigInt)da > 31 override int opCmp(Object rhs) { > 32 if(auto r = cast(IntValue)rhs) return data.opCmp(r.data); > 33 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( > 34 throw genex!RuntimeException(LexPosition.dummy, "comparison with > 35 } 24 mixin SimpleClass; | 36 mixin SimpleToHash; 25 override string toString() const { return std.bigint.toDecimalString(cas < 26 } 37 } 27 38 28 /// 39 /// 29 class StrValue : Value 40 class StrValue : Value 30 { 41 { 31 string data; 42 string data; 32 43 33 mixin SimpleClass; | 44 mixin SimpleConstructor; 34 override string toString() const { return data; } 45 override string toString() const { return data; } > 46 override int opCmp(Object rhs) { > 47 if(auto r = cast(StrValue)rhs) return typeid(string).compare(&da > 48 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( > 49 throw genex!RuntimeException(LexPosition.dummy, "comparison with > 50 } > 51 mixin SimpleToHash; 35 } 52 } 36 53 37 /// 54 /// 38 class UndValue : Value | 55 class UndefinedValue : Value 39 { 56 { 40 mixin SimpleClass; | 57 mixin SimpleConstructor; 41 override string toString() const { return "<undefined>"; } 58 override string toString() const { return "<undefined>"; } > 59 override int opCmp(Object rhs) { > 60 if(auto r = cast(StrValue)rhs) return 0; > 61 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( > 62 throw genex!RuntimeException(LexPosition.dummy, "comparison with > 63 } > 64 mixin SimpleToHash; 42 } 65 } 43 < 44 66 45 /// 67 /// 46 abstract class FunValue : Value 68 abstract class FunValue : Value 47 { 69 { 48 const(Parameter[]) params(); 70 const(Parameter[]) params(); 49 Table definitionContext(); 71 Table definitionContext(); 50 Value invoke(LexPosition pos, Layer lay, Table ctx); | 72 Value invoke(Layer lay, Table ctx, LexPosition pos); 51 } 73 } 52 74 53 /// Context (variable environment) 75 /// Context (variable environment) 54 /// Simlar to prototype chain of ECMAScript etc. 76 /// Simlar to prototype chain of ECMAScript etc. 55 /// But extended with the notion of "Layer" 77 /// But extended with the notion of "Layer" 56 78 57 class Table : Value 79 class Table : Value ................................................................................................................................................................................ 334 } 356 } 335 357 336 Table fromPos(LexPosition pos) 358 Table fromPos(LexPosition pos) 337 { 359 { 338 Table t = new Table; 360 Table t = new Table; 339 if( pos !is null ) { 361 if( pos !is null ) { 340 t.set("filename", ValueLayer, new StrValue(pos.filename)); 362 t.set("filename", ValueLayer, new StrValue(pos.filename)); 341 t.set("lineno", ValueLayer, new IntValue(BigInt(pos.lineno))); | 363 t.set("lineno", ValueLayer, new IntValue(pos.lineno)); 342 t.set("column", ValueLayer, new IntValue(BigInt(pos.column))); | 364 t.set("column", ValueLayer, new IntValue(pos.column)); 343 } else { 365 } else { 344 t.set("filename", ValueLayer, new StrValue("nullpos")); 366 t.set("filename", ValueLayer, new StrValue("nullpos")); 345 t.set("lineno", ValueLayer, new IntValue(BigInt(0))); | 367 t.set("lineno", ValueLayer, new IntValue(0)); 346 t.set("column", ValueLayer, new IntValue(BigInt(0))); | 368 t.set("column", ValueLayer, new IntValue(0)); 347 } 369 } 348 return t; 370 return t; 349 } 371 } > 372 > 373 /// Convert AST to Table so that it can be used in Polemy > 374 /// TODO: generalize to DValue2PolemyValue > 375 > 376 Value ast2table(T)(T e, Value delegate(AST) rec) > 377 { > 378 assert( typeid(e) == typeid(T) ); > 379 > 380 static if(is(T==BigInt) || is(T==long) || is(T==int)) > 381 return new IntValue(e); > 382 else > 383 static if(is(T==string)) > 384 return new StrValue(e); > 385 else > 386 static if(is(T S : S[])) > 387 { > 388 Table lst = new Table; > 389 foreach_reverse(a; e) > 390 static if(is(S : AST)) > 391 lst = makeCons(rec(a), lst); > 392 else > 393 lst = makeCons(ast2table(a,rec), lst); > 394 return lst; > 395 } > 396 else > 397 static if(is(T : AST)) > 398 { > 399 auto t = new Table; > 400 t.set("pos", ValueLayer, fromPos(e.pos)); > 401 t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[ > 402 foreach(i,m; e.tupleof) > 403 static if(is(typeof(m) : AST)) > 404 t.set(e.tupleof[i].stringof[2..$], ValueLayer, r > 405 else > 406 t.set(e.tupleof[i].stringof[2..$], ValueLayer, a > 407 return t; > 408 } > 409 else > 410 static if(is(T == class)) > 411 { > 412 auto t = new Table; > 413 foreach(i,m; e.tupleof) > 414 static if(is(typeof(m) : AST)) > 415 t.set(e.tupleof[i].stringof[2..$], ValueLayer, r > 416 else > 417 t.set(e.tupleof[i].stringof[2..$], ValueLayer, a > 418 return t; > 419 } > 420 else > 421 static assert(false, "unknown type <"~T.stringof~"> during AST e > 422 }

Modified tricks/tricks.d from [004818c087feff6a] to [cc1b586b87325960].

98 assert( !__traits(compiles, { 98 assert( !__traits(compiles, { 99 class Tamp : Tomp { mixin SimpleConstructor; } 99 class Tamp : Tomp { mixin SimpleConstructor; } 100 }) ); 100 }) ); 101 } 101 } 102 102 103 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 103 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 104 104 > 105 template SimpleToHash() > 106 { > 107 override hash_t toHash() const /// member-by-member hash > 108 { > 109 hash_t h = 0; > 110 foreach(mem; this.tupleof) > 111 h += typeid(mem).getHash(&mem); > 112 return h; > 113 } > 114 } > 115 > 116 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class > 117 105 /*mixin*/ 118 /*mixin*/ 106 template SimpleCompare() 119 template SimpleCompare() 107 { 120 { 108 override bool opEquals(Object rhs_) const /// member-by-member equality 121 override bool opEquals(Object rhs_) const /// member-by-member equality 109 { 122 { 110 if( auto rhs = cast(typeof(this))rhs_ ) 123 if( auto rhs = cast(typeof(this))rhs_ ) 111 { 124 { ................................................................................................................................................................................ 113 if( this.tupleof[i] != (cast(const)rhs).tupleof[ 126 if( this.tupleof[i] != (cast(const)rhs).tupleof[ 114 return false; 127 return false; 115 return true; 128 return true; 116 } 129 } 117 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), 130 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), 118 } 131 } 119 132 120 override hash_t toHash() const /// member-by-member hash | 133 mixin SimpleToHash; 121 { < 122 hash_t h = 0; < 123 foreach(mem; this.tupleof) < 124 h += typeid(mem).getHash(&mem); < 125 return h; < 126 } < 127 134 128 override int opCmp(Object rhs_) const /// member-by-member compare 135 override int opCmp(Object rhs_) const /// member-by-member compare 129 { 136 { 130 if( auto rhs = cast(typeof(this))rhs_ ) 137 if( auto rhs = cast(typeof(this))rhs_ ) 131 { 138 { 132 foreach(i,_; this.tupleof) 139 foreach(i,_; this.tupleof) 133 if( this.tupleof[i] != (cast(const)rhs).tupleof[ 140 if( this.tupleof[i] != (cast(const)rhs).tupleof[ ................................................................................................................................................................................ 215 template SimpleClass() 222 template SimpleClass() 216 { 223 { 217 mixin SimpleConstructor; 224 mixin SimpleConstructor; 218 mixin SimpleCompare; 225 mixin SimpleCompare; 219 mixin SimpleToString; 226 mixin SimpleToString; 220 } 227 } 221 228 222 /// Simple PatternMatcher < 223 < 224 /*mixin*/ < 225 template SimplePatternMatch() < 226 { < 227 SPM_Return!(PP) match(string fn=__FILE__, size_t ln=__LINE__, PP...)(PP < 228 { < 229 foreach(i,_; pts) < 230 { < 231 alias pts[i] pt; // bug? pts[i]-->pt do not work < 232 static if(__traits(compiles, SPM_isMatchTag(pt))) < 233 { < 234 if( auto v = cast(pt.dynamicType)this ) < 235 return pt(v.tupleof); < 236 } < 237 else < 238 static if(__traits(compiles, SPM_isMatchAny(pt))) < 239 { < 240 return pt(); < 241 } < 242 else < 243 { < 244 if( auto v = cast(SPM_PTT!(pt)[0])this ) < 245 return pt(v); < 246 } < 247 } < 248 SPM_throwAssertError(fn, ln, "pattern matching failure"); < 249 assert(false); < 250 } < 251 } < 252 < 253 /// Pattern case clause < 254 < 255 SPM_MatchTag!(T, fn) when(T, alias fn)() < 256 { < 257 SPM_MatchTag!(T, fn) m; < 258 return m; < 259 } < 260 < 261 /// Pattern case clause < 262 < 263 SPM_MatchAny!(fn) otherwise(alias fn)() < 264 { < 265 SPM_MatchAny!(fn) m; < 266 return m; < 267 } < 268 < 269 // implementation detail of SimplePatternMatch < 270 < 271 void SPM_throwAssertError(T...)(T t) { core.exception.onAssertErrorMsg(t); } < 272 < 273 struct SPM_MatchTag(T, alias fn) < 274 { < 275 alias T dynamicType; < 276 auto opCall(typeof(T.tupleof) s) { return fn(s); } < 277 } < 278 < 279 struct SPM_MatchAny(alias fn) < 280 { < 281 auto opCall() { return fn(); } < 282 } < 283 < 284 template SPM_PTT(alias p) < 285 { < 286 alias ParameterTypeTuple!(p) SPM_PTT; < 287 } < 288 < 289 template SPM_Each(P) < 290 { < 291 static if(__traits(compiles, SPM_isMatchTag(P.init))) < 292 alias typeof(P(P.dynamicType.tupleof)) SPM_Each; < 293 else < 294 static if(__traits(compiles, SPM_isMatchAny(P.init))) < 295 alias typeof(P()) SPM_Each; < 296 else < 297 alias ReturnType!(P) SPM_Each; < 298 } < 299 < 300 template SPM_aVoid(T:void, TS...) { alias SPM_aVoid!(TS) SPM_aVoid; } < 301 template SPM_aVoid(T, TS...) { alias TypeTuple!(T,SPM_aVoid!(TS)) SPM_aVoid; } < 302 template SPM_aVoid() { alias TypeTuple!() SPM_aVoid; } < 303 < 304 template SPM_Return(PP...) < 305 { < 306 alias CommonType!(SPM_aVoid!(staticMap!(SPM_Each, PP))) SPM_Return; < 307 } < 308 < 309 void SPM_isMatchTag(T,alias fn)(SPM_MatchTag!(T,fn)){} < 310 void SPM_isMatchAny(alias fn)(SPM_MatchAny!(fn)){} < 311 < 312 unittest < 313 { < 314 static abstract class Base { < 315 mixin SimplePatternMatch; < 316 } < 317 class D1 : Base { < 318 int x; < 319 real y; < 320 mixin SimpleConstructor; < 321 } < 322 class D2 : Base { < 323 string s; < 324 mixin SimpleConstructor; < 325 } < 326 class D3 : Base { < 327 int[int] m; < 328 mixin SimpleConstructor; < 329 } < 330 < 331 Base d1 = new D1(1, 2.3); < 332 Base d2 = new D2("foobar"); < 333 Base d3 = new D3(null); (cast(D3)d3).m[1]=10; < 334 < 335 // normal dispatch < 336 assert_eq( d1.match( < 337 (D1 x){return 1;}, < 338 (D2 x){return 2;} < 339 ), 1); < 340 assert_eq( d2.match( < 341 (D1 x){return 1;}, < 342 (D2 x){return 2;} < 343 ), 2); < 344 assert_throw!AssertError( d3.match( < 345 (D1 x){return 1;}, < 346 (D2 x){return 2;} < 347 )); < 348 assert_eq( d3.match( < 349 (D1 x){return 1;}, < 350 (D2 x){return 2;}, < 351 (Base x){return 3;} < 352 ), 3); < 353 assert_eq( d2.match( < 354 (D1 x){return 1;}, < 355 (D2 x){return 2;}, < 356 (Base x){return 3;} < 357 ), 2); < 358 assert_eq( d2.match( < 359 (D1 x){return 1;}, < 360 (Base x){return 3;}, < 361 (D2 x){return 2;} < 362 ), 3); < 363 < 364 // member decomposing match < 365 assert_eq( d1.match( < 366 when!(D1, (x, y){return x + cast(int)y;}), < 367 when!(D2, (x){return x.length;}), < 368 when!(D3, (x){return x[1];}) < 369 ), 3); < 370 assert_eq( d2.match( < 371 when!(D1, (x, y){return x + cast(int)y;}), < 372 when!(D2, (x){return x.length;}), < 373 when!(D3, (x){return x[1];}) < 374 ), 6); < 375 assert_eq( d3.match( < 376 when!(D1, (x, y){return x + cast(int)y;}), < 377 when!(D2, (x){return x.length;}), < 378 when!(D3, (x){return x[1];}) < 379 ), 10); < 380 assert_throw!AssertError( d3.match( < 381 when!(D1, (x, y){return x + cast(int)y;}), < 382 when!(D2, (x){return x.length;}) < 383 )); < 384 assert_eq( d2.match( < 385 when!(D1, (x, y){return x + cast(int)y;}), < 386 when!(D2, (x){return x.length;}), < 387 otherwise!({return 999;}) < 388 ), 6); < 389 assert_eq( d2.match( < 390 when!(D1, (x, y){return x + cast(int)y;}), < 391 otherwise!({return 999;}), < 392 when!(D2, (x){return x.length;}) < 393 ), 999); < 394 } < 395 < 396 /// Will be used for dynamic overload resolution pattern 229 /// Will be used for dynamic overload resolution pattern 397 230 398 template firstParam(T) 231 template firstParam(T) 399 { 232 { 400 alias ParameterTypeTuple!(T)[0] firstParam; 233 alias ParameterTypeTuple!(T)[0] firstParam; 401 } 234 }