@@ -13,130 +13,95 @@ import std.string; LexPosition extractPos( Table t ) { - Layer theLayer = ValueLayer; - if(auto tt = t.access!Table(theLayer, "pos")) + if(auto tt = t.access!Table(ValueLayer, "pos")) { - auto fn = tt.access!StrValue(theLayer, "filename"); - auto ln = tt.access!IntValue(theLayer, "lineno"); - auto cl = tt.access!IntValue(theLayer, "column"); + auto fn = tt.access!StrValue(ValueLayer, "filename"); + auto ln = tt.access!IntValue(ValueLayer, "lineno"); + auto cl = tt.access!IntValue(ValueLayer, "column"); if(fn !is null && ln !is null && cl !is null) return new LexPosition(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt); } return null; } -Value[] tableAsConsList( Layer theLayer, Table t ) -{ - Value[] result; - while(t) - if(auto v = t.access!Value(theLayer, "car")) - { - result ~= v; - t = t.access!Table(theLayer, "cdr"); - } - else - break; - return result; -} +/// Experimental!! Convert Polemy value to D Value -AST[] tableToASTList( Layer theLayer, Table t ) +T polemy2d(T)(Value _v, LexPosition callpos=null) { - AST[] result; - foreach(v; tableAsConsList(theLayer, t)) - if(auto t = cast(Table)v) - result ~= tableToAST(theLayer,t); - else - throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (non-table in cons-list)"); - return result; -} + static if(is(T==BigInt)) + { + if(auto v = cast(IntValue)_v) + return v.data; + } + else + static if(isIntegral!(T)) + { + if(auto v = cast(IntValue)_v) + return cast(T) v.data.toLong(); + } + else + static if(is(T==string)) + { + if(auto v = cast(StrValue)_v) + return v.data; + } + else + static if(is(T S : S[])) + { + if(auto t = cast(Table)_v) + { + S[] result; + foreach(e; t.toList()) + result ~= polemy2d!(S)(e, callpos); + return result; + } + } + else + static if(is(T == AST)) + { + if(auto t = cast(Table)_v) + { + LexPosition pos = extractPos(t); -AST tableToAST( Layer theLayer, Value vvvv ) -{ - Table t = cast(Table)vvvv; - if( t is null ) - throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (not a table)"); + StrValue typ = cast(StrValue) t.access!StrValue(ValueLayer, "is"); + if( typ is null ) + throw genex!RuntimeException(text(`Invalid AST (no "is" field): `, _v)); - auto nodeType = t.access!StrValue(theLayer, "is"); - if( nodeType is null ) - throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST {is:(not string)}"); - auto pos = extractPos(t); - switch(nodeType.data) + foreach(AT; ListOfASTTypes) + if(typ.data == typeid(AT).name.split(".")[$-1].tolower()) + { + typeof(AT.tupleof) mems; + foreach(i,m; mems) + { + string name = AT.tupleof[i].stringof.split(".")[$-1]; + Value vm = t.access!Value(ValueLayer, name); + if( vm is null ) + throw genex!RuntimeException(callpos, + text(`Invalid AST (no "`,name,`" field) for "`, typ, `" node: `, _v)); + mems[i] = polemy2d!(typeof(m))(vm, callpos); + } + return new AT(pos,mems); + } + throw genex!RuntimeException(callpos, text(`Invalid AST (unknown "is" field): `, typ)); + } + throw genex!RuntimeException(callpos, text(`Invalid AST (not a table): `, _v)); + } + else + static if(is(T == class)) { - case "int": - if(auto v = t.access!IntValue(theLayer, "data")) - return new Int(pos, v.data); - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"int", data:(not int)}`); - case "str": - if(auto v = t.access!StrValue(theLayer, "data")) - return new Str(pos, v.data); - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"str", data:(not string)}`); - case "var": - if(auto v = t.access!StrValue(theLayer, "name")) - return new Var(pos, v.data); - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"var", name:(not string)}`); - case "lay": - if(auto v = t.access!StrValue(theLayer, "layer")) - if(auto e = t.access!Table(theLayer, "expr")) - return new Lay(pos, v.data, tableToAST(theLayer,e)); - else - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", expr:(not table)}`); - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", layer:(not string)}`); - case "let": - if(auto n = t.access!StrValue(theLayer, "name")) - if(auto e = t.access!Table(theLayer, "init")) - if(auto b = t.access!Table(theLayer, "expr")) + if(auto t = cast(Table)_v) { - string nn = n.data; - auto ee = tableToAST(theLayer, e); - auto bb = tableToAST(theLayer, b); - Layer lay=""; - if(auto l = t.access!StrValue(theLayer, "layer")) - lay = l.data; - return new Let(pos, nn, lay, ee, bb); + typeof(T.tupleof) mems; + foreach(i,m; mems) + mems[i] = polemy2d!(typeof(m))(t.get(T.tupleof[i].stringof.split(".")[$-1], ValueLayer), callpos); + return new T(mems); } - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"let", name:"???", init:"???", expr:"???"}`); - case "app": - if(auto f = t.access!Table(theLayer, "fun")) - if(auto a = t.access!Table(theLayer, "args")) - return new App(pos, tableToAST(theLayer,f), tableToASTList(theLayer,a)); - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"app", fun:???, args:???}`); - case "fun": - if(auto p = t.access!Table(theLayer, "params")) - if(auto b = t.access!Table(theLayer, "funbody")) - { - Parameter[] ps; - foreach(v; tableAsConsList(theLayer, p)) - { - if(auto tt = cast(Table)v) - if(auto ss = tt.access!StrValue(theLayer, "name")) - if(auto ll = tt.access!Table(theLayer, "layers")) - { - Layer[] ls; - foreach(lll; tableAsConsList(theLayer, ll)) - if(auto l = cast(StrValue)lll) - ls ~= l.data; - else - throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {bad fun params %s}`(lll)); - ps ~= new Parameter(ss.data, ls); - continue; - } - else - { - Layer[] emp; - ps ~= new Parameter(ss.data, emp); - continue; - } - throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {bad fun params %s}`(v)); - } - auto bb = tableToAST(theLayer, b); - return new Fun(pos,ps,bb); - } - throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"fun", param:???, body:???}`); - default: - throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {is: "%s"} unknown`(nodeType.data)); } + else + static assert(false, "unknown type <"~T.stringof~"> during polemy2d decoding"); + throw genex!RuntimeException(callpos, text("Cannot convert ",_v," to ",T.stringof)); } /// Cons of two pairs @@ -147,9 +112,9 @@ t.set("cdr", ValueLayer, d); return t; } -/// Experimental!!! Convert D value (except AST) to Polemy Value +/// Experimental!! Convert D value (except AST) to Polemy Value Value d2polemy(T)(T e) { return ast2table(e, delegate Value(AST){ assert(false); }); @@ -183,11 +148,11 @@ t.set("pos", ValueLayer, ast2table(e.pos,rec)); t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[$-1].tolower())); foreach(i,m; e.tupleof) static if(is(typeof(m) : AST)) - t.set(e.tupleof[i].stringof[2..$], ValueLayer, rec(m)); + t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, rec(m)); else - t.set(e.tupleof[i].stringof[2..$], ValueLayer, ast2table(m,rec)); + t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, ast2table(m,rec)); return t; } else static if(is(T == class))