Diff
Not logged in

Differences From Artifact [76bd90b6c3824480]:

To Artifact [2816a291e16d0986]:


10 10 import polemy.ast; 11 11 import polemy.layer; 12 12 import polemy.value; 13 13 import std.string; 14 14 15 15 LexPosition extractPos( Table t ) 16 16 { 17 - Layer theLayer = ValueLayer; 18 - if(auto tt = t.access!Table(theLayer, "pos")) 17 + if(auto tt = t.access!Table(ValueLayer, "pos")) 19 18 { 20 - auto fn = tt.access!StrValue(theLayer, "filename"); 21 - auto ln = tt.access!IntValue(theLayer, "lineno"); 22 - auto cl = tt.access!IntValue(theLayer, "column"); 19 + auto fn = tt.access!StrValue(ValueLayer, "filename"); 20 + auto ln = tt.access!IntValue(ValueLayer, "lineno"); 21 + auto cl = tt.access!IntValue(ValueLayer, "column"); 23 22 if(fn !is null && ln !is null && cl !is null) 24 23 return new LexPosition(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt); 25 24 } 26 25 return null; 27 26 } 28 27 29 -Value[] tableAsConsList( Layer theLayer, Table t ) 30 -{ 31 - Value[] result; 32 - while(t) 33 - if(auto v = t.access!Value(theLayer, "car")) 34 - { 35 - result ~= v; 36 - t = t.access!Table(theLayer, "cdr"); 37 - } 38 - else 39 - break; 40 - return result; 41 -} 28 +/// Experimental!! Convert Polemy value to D Value 42 29 43 -AST[] tableToASTList( Layer theLayer, Table t ) 30 +T polemy2d(T)(Value _v, LexPosition callpos=null) 44 31 { 45 - AST[] result; 46 - foreach(v; tableAsConsList(theLayer, t)) 47 - if(auto t = cast(Table)v) 48 - result ~= tableToAST(theLayer,t); 49 - else 50 - throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (non-table in cons-list)"); 51 - return result; 52 -} 32 + static if(is(T==BigInt)) 33 + { 34 + if(auto v = cast(IntValue)_v) 35 + return v.data; 36 + } 37 + else 38 + static if(isIntegral!(T)) 39 + { 40 + if(auto v = cast(IntValue)_v) 41 + return cast(T) v.data.toLong(); 42 + } 43 + else 44 + static if(is(T==string)) 45 + { 46 + if(auto v = cast(StrValue)_v) 47 + return v.data; 48 + } 49 + else 50 + static if(is(T S : S[])) 51 + { 52 + if(auto t = cast(Table)_v) 53 + { 54 + S[] result; 55 + foreach(e; t.toList()) 56 + result ~= polemy2d!(S)(e, callpos); 57 + return result; 58 + } 59 + } 60 + else 61 + static if(is(T == AST)) 62 + { 63 + if(auto t = cast(Table)_v) 64 + { 65 + LexPosition pos = extractPos(t); 53 66 54 -AST tableToAST( Layer theLayer, Value vvvv ) 55 -{ 56 - Table t = cast(Table)vvvv; 57 - if( t is null ) 58 - throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (not a table)"); 67 + StrValue typ = cast(StrValue) t.access!StrValue(ValueLayer, "is"); 68 + if( typ is null ) 69 + throw genex!RuntimeException(text(`Invalid AST (no "is" field): `, _v)); 59 70 60 - auto nodeType = t.access!StrValue(theLayer, "is"); 61 - if( nodeType is null ) 62 - throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST {is:(not string)}"); 63 - auto pos = extractPos(t); 64 - switch(nodeType.data) 71 + foreach(AT; ListOfASTTypes) 72 + if(typ.data == typeid(AT).name.split(".")[$-1].tolower()) 73 + { 74 + typeof(AT.tupleof) mems; 75 + foreach(i,m; mems) 76 + { 77 + string name = AT.tupleof[i].stringof.split(".")[$-1]; 78 + Value vm = t.access!Value(ValueLayer, name); 79 + if( vm is null ) 80 + throw genex!RuntimeException(callpos, 81 + text(`Invalid AST (no "`,name,`" field) for "`, typ, `" node: `, _v)); 82 + mems[i] = polemy2d!(typeof(m))(vm, callpos); 83 + } 84 + return new AT(pos,mems); 85 + } 86 + throw genex!RuntimeException(callpos, text(`Invalid AST (unknown "is" field): `, typ)); 87 + } 88 + throw genex!RuntimeException(callpos, text(`Invalid AST (not a table): `, _v)); 89 + } 90 + else 91 + static if(is(T == class)) 65 92 { 66 - case "int": 67 - if(auto v = t.access!IntValue(theLayer, "data")) 68 - return new Int(pos, v.data); 69 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"int", data:(not int)}`); 70 - case "str": 71 - if(auto v = t.access!StrValue(theLayer, "data")) 72 - return new Str(pos, v.data); 73 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"str", data:(not string)}`); 74 - case "var": 75 - if(auto v = t.access!StrValue(theLayer, "name")) 76 - return new Var(pos, v.data); 77 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"var", name:(not string)}`); 78 - case "lay": 79 - if(auto v = t.access!StrValue(theLayer, "layer")) 80 - if(auto e = t.access!Table(theLayer, "expr")) 81 - return new Lay(pos, v.data, tableToAST(theLayer,e)); 82 - else 83 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", expr:(not table)}`); 84 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", layer:(not string)}`); 85 - case "let": 86 - if(auto n = t.access!StrValue(theLayer, "name")) 87 - if(auto e = t.access!Table(theLayer, "init")) 88 - if(auto b = t.access!Table(theLayer, "expr")) 93 + if(auto t = cast(Table)_v) 89 94 { 90 - string nn = n.data; 91 - auto ee = tableToAST(theLayer, e); 92 - auto bb = tableToAST(theLayer, b); 93 - Layer lay=""; 94 - if(auto l = t.access!StrValue(theLayer, "layer")) 95 - lay = l.data; 96 - return new Let(pos, nn, lay, ee, bb); 95 + typeof(T.tupleof) mems; 96 + foreach(i,m; mems) 97 + mems[i] = polemy2d!(typeof(m))(t.get(T.tupleof[i].stringof.split(".")[$-1], ValueLayer), callpos); 98 + return new T(mems); 97 99 } 98 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"let", name:"???", init:"???", expr:"???"}`); 99 - case "app": 100 - if(auto f = t.access!Table(theLayer, "fun")) 101 - if(auto a = t.access!Table(theLayer, "args")) 102 - return new App(pos, tableToAST(theLayer,f), tableToASTList(theLayer,a)); 103 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"app", fun:???, args:???}`); 104 - case "fun": 105 - if(auto p = t.access!Table(theLayer, "params")) 106 - if(auto b = t.access!Table(theLayer, "funbody")) 107 - { 108 - Parameter[] ps; 109 - foreach(v; tableAsConsList(theLayer, p)) 110 - { 111 - if(auto tt = cast(Table)v) 112 - if(auto ss = tt.access!StrValue(theLayer, "name")) 113 - if(auto ll = tt.access!Table(theLayer, "layers")) 114 - { 115 - Layer[] ls; 116 - foreach(lll; tableAsConsList(theLayer, ll)) 117 - if(auto l = cast(StrValue)lll) 118 - ls ~= l.data; 119 - else 120 - throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {bad fun params %s}`(lll)); 121 - ps ~= new Parameter(ss.data, ls); 122 - continue; 123 - } 124 - else 125 - { 126 - Layer[] emp; 127 - ps ~= new Parameter(ss.data, emp); 128 - continue; 129 - } 130 - throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {bad fun params %s}`(v)); 131 - } 132 - auto bb = tableToAST(theLayer, b); 133 - return new Fun(pos,ps,bb); 134 - } 135 - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"fun", param:???, body:???}`); 136 - default: 137 - throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {is: "%s"} unknown`(nodeType.data)); 138 100 } 101 + else 102 + static assert(false, "unknown type <"~T.stringof~"> during polemy2d decoding"); 103 + throw genex!RuntimeException(callpos, text("Cannot convert ",_v," to ",T.stringof)); 139 104 } 140 105 141 106 /// Cons of two pairs 142 107 143 108 Table makeCons(Value a, Value d) 144 109 { 145 110 Table t = new Table; 146 111 t.set("car", ValueLayer, a); 147 112 t.set("cdr", ValueLayer, d); 148 113 return t; 149 114 } 150 115 151 -/// Experimental!!! Convert D value (except AST) to Polemy Value 116 +/// Experimental!! Convert D value (except AST) to Polemy Value 152 117 153 118 Value d2polemy(T)(T e) 154 119 { 155 120 return ast2table(e, delegate Value(AST){ assert(false); }); 156 121 } 157 122 158 123 /// Convert AST to Table so that it can be used in Polemy ................................................................................ 180 145 { 181 146 assert( typeid(e) == typeid(T), text("abstracted: ", typeid(e), " vs ", typeid(T)) ); 182 147 auto t = new Table; 183 148 t.set("pos", ValueLayer, ast2table(e.pos,rec)); 184 149 t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[$-1].tolower())); 185 150 foreach(i,m; e.tupleof) 186 151 static if(is(typeof(m) : AST)) 187 - t.set(e.tupleof[i].stringof[2..$], ValueLayer, rec(m)); 152 + t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, rec(m)); 188 153 else 189 - t.set(e.tupleof[i].stringof[2..$], ValueLayer, ast2table(m,rec)); 154 + t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, ast2table(m,rec)); 190 155 return t; 191 156 } 192 157 else 193 158 static if(is(T == class)) 194 159 { 195 160 auto t = new Table; 196 161 foreach(i,m; e.tupleof)