Diff
Not logged in

Differences From Artifact [fe3f0c39a200a0bc]:

To Artifact [a4c75e644b34fb64]:


17 17 18 18 /// Runtime values of Polemy 19 19 20 20 abstract class Value 21 21 { 22 22 } 23 23 24 +/// 24 25 class IntValue : Value 25 26 { 26 27 BigInt data; 27 28 28 29 mixin SimpleClass; 29 30 override string toString() const { return std.bigint.toDecimalString(cast(BigInt)data); } 30 31 } 31 32 33 +/// 32 34 class StrValue : Value 33 35 { 34 36 string data; 35 37 36 38 mixin SimpleClass; 37 39 override string toString() const { return data; } 38 40 } 39 41 42 +/// 40 43 class FunValue : Value 41 44 { 42 45 Value delegate(immutable LexPosition pos, string lay, Value[]) data; 43 46 44 47 mixin SimpleConstructor; 45 48 alias data call; 46 49 override string toString() const { return sprintf!"(function:%s:%s)"(data.ptr,data.funcptr); } 47 50 } 48 51 52 +/// 49 53 class UndValue : Value 50 54 { 51 55 mixin SimpleClass; 52 56 override string toString() const { return "<undefined>"; } 53 57 } 58 + 59 +/// Named Constructor for FunValue 60 + 61 +FunValue nativef(Value delegate(immutable LexPosition pos, Layer lay, Value[] args) dg) 62 +{ 63 + return new FunValue(dg); 64 +} 65 + 66 +/// Named Constructor for FunValue 67 + 68 +FunValue native(R,T...)(R delegate (T) dg) 69 +{ 70 + return nativef( delegate Value(immutable LexPosition pos, Layer lay, Value[] args) { 71 + if( lay != "@v" ) 72 + throw genex!RuntimeException(pos, "only @v layer can call native function"); 73 + if( T.length != args.length ) 74 + throw genex!RuntimeException(pos, "argument number mismatch!"); 75 + T typed_args; 76 + foreach(i, Ti; T) 77 + { 78 + typed_args[i] = cast(Ti) args[i]; 79 + if( typed_args[i] is null ) 80 + throw genex!RuntimeException(pos, sprintf!"type mismatch on the argument %d"(i+1)); 81 + } 82 + try { 83 + return dg(typed_args); 84 + } catch( RuntimeException e ) { 85 + throw e.pos is null ? new RuntimeException(pos, e.msg, e.file, e.line) : e; 86 + } 87 + }); 88 +} 54 89 55 90 /// Layer ID 56 91 57 92 alias string Layer; 58 93 59 94 /// Context (variable environment) 60 95 /// Simlar to prototype chain of ECMAScript etc. ................................................................................ 69 104 70 105 void set(string i, Layer lay, Value v, in LexPosition pos=null) 71 106 { 72 107 if( setIfExist(i, lay, v) ) 73 108 return; 74 109 data[i][lay] = v; 75 110 } 111 + 112 + bool has(string i, Layer lay, in LexPosition pos=null) 113 + { 114 + if( i in data ) { 115 + if( lay !in data[i] ) 116 + return false; 117 + return true; 118 + } 119 + if( prototype is null ) 120 + return false; 121 + return prototype.has(i, lay, pos); 122 + } 76 123 77 124 Value get(string i, Layer lay, in LexPosition pos=null) 78 125 { 79 126 if( i in data ) { 127 + // [TODO] consider forwarding to proto also in this case 80 128 if( lay !in data[i] ) 81 129 throw genex!RuntimeException(pos, sprintf!"variable %s is not set in layer %s"(i,lay)); 82 130 return data[i][lay]; 83 131 } 84 132 if( prototype is null ) 85 133 throw new RuntimeException(pos, sprintf!"variable %s not found"(i)); 86 134 return prototype.get(i, lay, pos);