Diff
Not logged in

Differences From Artifact [d315cdb0d9e5cf48]:

To Artifact [a63938dc88b0c424]:


8 import polemy._common; 8 import polemy._common; 9 import polemy.lex : LexPosition; 9 import polemy.lex : LexPosition; 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 std.typecons; 13 import std.typecons; 14 import std.stdio; 14 import std.stdio; > 15 > 16 // [todo] move to value.d > 17 > 18 FunValue nativef(Value delegate(immutable LexPosition pos, Layer lay, Value[] ar > 19 { > 20 return new FunValue(dg); > 21 } > 22 > 23 FunValue native(R,T...)(R delegate (T) dg) > 24 { > 25 return nativef( delegate Value(immutable LexPosition pos, Layer lay, Val > 26 if( lay != "@v" ) > 27 throw genex!RuntimeException(pos, "only @v layer can cal > 28 if( T.length != args.length ) > 29 throw genex!RuntimeException(pos, "argument number misma > 30 T typed_args; > 31 foreach(i, Ti; T) > 32 { > 33 typed_args[i] = cast(Ti) args[i]; > 34 if( typed_args[i] is null ) > 35 throw genex!RuntimeException(pos, sprintf!"type > 36 } > 37 try { > 38 return dg(typed_args); > 39 } catch( RuntimeException e ) { > 40 throw e.pos is null ? new RuntimeException(pos, e.msg, e > 41 } > 42 }); > 43 } 15 44 16 /// 45 /// 17 Table createGlobalContext() 46 Table createGlobalContext() 18 { 47 { 19 auto ctx = new Table; 48 auto ctx = new Table; 20 // [TODO] autogenerate these typechecks | 49 ctx.set("+", "@v", native( (IntValue lhs, IntValue rhs){return new IntVa 21 ctx.set("+", "@v", new FunValue(delegate Value(immutable LexPosition pos | 50 ctx.set("-", "@v", native( (IntValue lhs, IntValue rhs){return new IntVa 22 if( args.length != 2 ) | 51 ctx.set("*", "@v", native( (IntValue lhs, IntValue rhs){return new IntVa 23 throw genex!RuntimeException(pos, "+ takes two arguments | 52 ctx.set("/", "@v", native( (IntValue lhs, IntValue rhs){return new IntVa 24 if( auto x = cast(IntValue)args[0] ) | 53 ctx.set("%", "@v", native( (IntValue lhs, IntValue rhs){return new IntVa 25 if( auto y = cast(IntValue)args[1] ) | 54 ctx.set("<", "@v", native( (IntValue lhs, IntValue rhs){return new IntVa 26 return new IntValue(x.data+y.data); | 55 ctx.set(">", "@v", native( (IntValue lhs, IntValue rhs){return new IntVa 27 throw genex!RuntimeException(pos, "cannot add non-integers"); | 56 ctx.set("<=", "@v", native( (IntValue lhs, IntValue rhs){return new IntV 28 })); | 57 ctx.set(">=", "@v", native( (IntValue lhs, IntValue rhs){return new IntV 29 ctx.set("-", "@v", new FunValue(delegate Value(immutable LexPosition pos | 58 ctx.set("==", "@v", native( (IntValue lhs, IntValue rhs){return new IntV 30 if( args.length != 2 ) | 59 ctx.set("!=", "@v", native( (IntValue lhs, IntValue rhs){return new IntV 31 throw genex!RuntimeException(pos, "- takes two arguments < 32 if( auto x = cast(IntValue)args[0] ) < 33 if( auto y = cast(IntValue)args[1] ) < 34 return new IntValue(x.data-y.data); < 35 throw genex!RuntimeException(pos, "cannot subtract non-integers" < 36 })); < 37 ctx.set("*", "@v", new FunValue(delegate Value(immutable LexPosition pos < 38 if( args.length != 2 ) < 39 throw genex!RuntimeException(pos, "* takes two arguments < 40 if( auto x = cast(IntValue)args[0] ) < 41 if( auto y = cast(IntValue)args[1] ) < 42 return new IntValue(x.data*y.data); < 43 throw genex!RuntimeException(pos, "cannot multiply non-integers" < 44 })); < 45 ctx.set("/", "@v", new FunValue(delegate Value(immutable LexPosition pos < 46 if( args.length != 2 ) < 47 throw genex!RuntimeException(pos, "/ takes two arguments < 48 if( auto x = cast(IntValue)args[0] ) < 49 if( auto y = cast(IntValue)args[1] ) < 50 return new IntValue(x.data/y.data); < 51 throw genex!RuntimeException(pos, "cannot divide non-integers"); < 52 })); < 53 ctx.set("<", "@v", new FunValue(delegate Value(immutable LexPosition pos < 54 if( args.length != 2 ) < 55 throw genex!RuntimeException(pos, "< takes two arguments < 56 if( auto x = cast(IntValue)args[0] ) < 57 if( auto y = cast(IntValue)args[1] ) < 58 return new IntValue(BigInt(to!int(x.data < y.dat < 59 throw genex!RuntimeException(pos, "cannot compare non-integers") < 60 })); < 61 ctx.set(">", "@v", new FunValue(delegate Value(immutable LexPosition pos < 62 if( args.length != 2 ) < 63 throw genex!RuntimeException(pos, "> takes two arguments < 64 if( auto x = cast(IntValue)args[0] ) < 65 if( auto y = cast(IntValue)args[1] ) < 66 return new IntValue(BigInt(to!int(x.data>y.data) < 67 throw genex!RuntimeException(pos, "cannot compare non-integers") < 68 })); < 69 ctx.set("print", "@v", new FunValue(delegate Value(immutable LexPosition 60 ctx.set("print", "@v", new FunValue(delegate Value(immutable LexPosition 70 foreach(a; args) 61 foreach(a; args) 71 write(a); 62 write(a); 72 writeln(""); 63 writeln(""); 73 return new IntValue(BigInt(178)); 64 return new IntValue(BigInt(178)); 74 })); 65 })); 75 ctx.set("if", "@v", new FunValue(delegate Value(immutable LexPosition po 66 ctx.set("if", "@v", new FunValue(delegate Value(immutable LexPosition po ................................................................................................................................................................................ 105 Table ctx = createGlobalContext(); 96 Table ctx = createGlobalContext(); 106 return typeof(return)(eval(e, ctx, false, "@v"), ctx); 97 return typeof(return)(eval(e, ctx, false, "@v"), ctx); 107 } 98 } 108 99 109 /// Entry point of this module 100 /// Entry point of this module 110 /// If splitCtx = true, then inner variable declaration do not overwrite ctx. 101 /// If splitCtx = true, then inner variable declaration do not overwrite ctx. 111 /// lay is the layer ID for evaluation (standard value semantics uses "@v"). 102 /// lay is the layer ID for evaluation (standard value semantics uses "@v"). 112 import std.typetuple; < > 103 113 Value eval(AST e, Table ctx, bool splitCtx, Layer lay) 104 Value eval(AST e, Table ctx, bool splitCtx, Layer lay) 114 { 105 { 115 return e.match( 106 return e.match( 116 (StrLiteral e) 107 (StrLiteral e) 117 { 108 { 118 Value v = new StrValue(e.data); 109 Value v = new StrValue(e.data); 119 if( lay == "@v" ) 110 if( lay == "@v" ) 120 return v; 111 return v; 121 else | 112 else // rise 122 return (cast(FunValue)ctx.get(lay, "(system)", e 113 return (cast(FunValue)ctx.get(lay, "(system)", e 123 }, 114 }, 124 (IntLiteral e) 115 (IntLiteral e) 125 { 116 { 126 Value v = new IntValue(e.data); 117 Value v = new IntValue(e.data); 127 if( lay == "@v" ) 118 if( lay == "@v" ) 128 return v; 119 return v; 129 else // are these "@v"s appropriate??? | 120 else // rise 130 return (cast(FunValue)ctx.get(lay, "(system)", e 121 return (cast(FunValue)ctx.get(lay, "(system)", e 131 }, 122 }, 132 (VarExpression e) 123 (VarExpression e) 133 { 124 { 134 try { 125 try { 135 return ctx.get(e.var, lay, e.pos); 126 return ctx.get(e.var, lay, e.pos); 136 } catch( RuntimeException ) { 127 } catch( RuntimeException ) { 137 // rise | 128 // rise from @v 138 return (cast(FunValue)ctx.get(lay, "(system)", e 129 return (cast(FunValue)ctx.get(lay, "(system)", e 139 [ctx.get(e.var, "@v", e.pos)] 130 [ctx.get(e.var, "@v", e.pos)] 140 ); 131 ); 141 } 132 } 142 }, 133 }, 143 (LayeredExpression e) 134 (LayeredExpression e) 144 { 135 { ................................................................................................................................................................................ 163 args ~= eval(a, ctx, true, lay); 154 args ~= eval(a, ctx, true, lay); 164 return f.call(e.pos, lay, args); 155 return f.call(e.pos, lay, args); 165 } 156 } 166 throw genex!RuntimeException(e.pos, "Non-funcion is appl 157 throw genex!RuntimeException(e.pos, "Non-funcion is appl 167 }, 158 }, 168 (FunLiteral e) 159 (FunLiteral e) 169 { 160 { > 161 // funvalue need not be rised 170 return new FunValue(delegate Value(immutable LexPosition 162 return new FunValue(delegate Value(immutable LexPosition 171 if( e.params.length != args.length ) 163 if( e.params.length != args.length ) 172 throw genex!RuntimeException(e.pos, spri 164 throw genex!RuntimeException(e.pos, spri 173 (e.params.length, args.length)); 165 (e.params.length, args.length)); 174 Table ctxNeo = new Table(ctx, Table.Kind.NotProp 166 Table ctxNeo = new Table(ctx, Table.Kind.NotProp 175 foreach(i,p; e.params) 167 foreach(i,p; e.params) 176 ctxNeo.set(p.name, lay, args[i]); 168 ctxNeo.set(p.name, lay, args[i]);