36c517dfc4 2010-11-23 kinaba: /** 36c517dfc4 2010-11-23 kinaba: * Authors: k.inaba 36c517dfc4 2010-11-23 kinaba: * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 36c517dfc4 2010-11-23 kinaba: * 36c517dfc4 2010-11-23 kinaba: * Convert values between Polemy and D 36c517dfc4 2010-11-23 kinaba: */ 36c517dfc4 2010-11-23 kinaba: module polemy.valueconv; 36c517dfc4 2010-11-23 kinaba: import polemy._common; 36c517dfc4 2010-11-23 kinaba: import polemy.failure; 36c517dfc4 2010-11-23 kinaba: import polemy.ast; 36c517dfc4 2010-11-23 kinaba: import polemy.layer; 36c517dfc4 2010-11-23 kinaba: import polemy.value; 36c517dfc4 2010-11-23 kinaba: import std.string; 36c517dfc4 2010-11-23 kinaba: 36c517dfc4 2010-11-23 kinaba: LexPosition extractPos( Table t ) 36c517dfc4 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: if(auto tt = t.access!Table(ValueLayer, "pos")) 36c517dfc4 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: auto fn = tt.access!StrValue(ValueLayer, "filename"); 2134cd44cc 2010-11-23 kinaba: auto ln = tt.access!IntValue(ValueLayer, "lineno"); 2134cd44cc 2010-11-23 kinaba: auto cl = tt.access!IntValue(ValueLayer, "column"); 36c517dfc4 2010-11-23 kinaba: if(fn !is null && ln !is null && cl !is null) 36c517dfc4 2010-11-23 kinaba: return new LexPosition(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt); 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: return null; 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: /// Experimental!! Convert Polemy value to D Value 36c517dfc4 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: T polemy2d(T)(Value _v, LexPosition callpos=null) 36c517dfc4 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: static if(is(T==BigInt)) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: if(auto v = cast(IntValue)_v) 2134cd44cc 2010-11-23 kinaba: return v.data; 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: else 2134cd44cc 2010-11-23 kinaba: static if(isIntegral!(T)) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: if(auto v = cast(IntValue)_v) 2134cd44cc 2010-11-23 kinaba: return cast(T) v.data.toLong(); 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: else 2134cd44cc 2010-11-23 kinaba: static if(is(T==string)) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: if(auto v = cast(StrValue)_v) 2134cd44cc 2010-11-23 kinaba: return v.data; 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: else 2134cd44cc 2010-11-23 kinaba: static if(is(T S : S[])) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: if(auto t = cast(Table)_v) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: S[] result; 2134cd44cc 2010-11-23 kinaba: foreach(e; t.toList()) 2134cd44cc 2010-11-23 kinaba: result ~= polemy2d!(S)(e, callpos); 2134cd44cc 2010-11-23 kinaba: return result; 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: else 2134cd44cc 2010-11-23 kinaba: static if(is(T == AST)) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: if(auto t = cast(Table)_v) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: LexPosition pos = extractPos(t); 36c517dfc4 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: StrValue typ = cast(StrValue) t.access!StrValue(ValueLayer, "is"); 2134cd44cc 2010-11-23 kinaba: if( typ is null ) 2134cd44cc 2010-11-23 kinaba: throw genex!RuntimeException(text(`Invalid AST (no "is" field): `, _v)); 36c517dfc4 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: foreach(AT; ListOfASTTypes) 2134cd44cc 2010-11-23 kinaba: if(typ.data == typeid(AT).name.split(".")[$-1].tolower()) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: typeof(AT.tupleof) mems; 2134cd44cc 2010-11-23 kinaba: foreach(i,m; mems) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: string name = AT.tupleof[i].stringof.split(".")[$-1]; 2134cd44cc 2010-11-23 kinaba: Value vm = t.access!Value(ValueLayer, name); 2134cd44cc 2010-11-23 kinaba: if( vm is null ) 2134cd44cc 2010-11-23 kinaba: throw genex!RuntimeException(callpos, 2134cd44cc 2010-11-23 kinaba: text(`Invalid AST (no "`,name,`" field) for "`, typ, `" node: `, _v)); 2134cd44cc 2010-11-23 kinaba: mems[i] = polemy2d!(typeof(m))(vm, callpos); 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: return new AT(pos,mems); 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: throw genex!RuntimeException(callpos, text(`Invalid AST (unknown "is" field): `, typ)); 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: throw genex!RuntimeException(callpos, text(`Invalid AST (not a table): `, _v)); 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: else 2134cd44cc 2010-11-23 kinaba: static if(is(T == class)) 36c517dfc4 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: if(auto t = cast(Table)_v) 36c517dfc4 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: typeof(T.tupleof) mems; 2134cd44cc 2010-11-23 kinaba: foreach(i,m; mems) 2134cd44cc 2010-11-23 kinaba: mems[i] = polemy2d!(typeof(m))(t.get(T.tupleof[i].stringof.split(".")[$-1], ValueLayer), callpos); 2134cd44cc 2010-11-23 kinaba: return new T(mems); 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: else 2134cd44cc 2010-11-23 kinaba: static assert(false, "unknown type <"~T.stringof~"> during polemy2d decoding"); 2134cd44cc 2010-11-23 kinaba: throw genex!RuntimeException(callpos, text("Cannot convert ",_v," to ",T.stringof)); 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: 36c517dfc4 2010-11-23 kinaba: /// Cons of two pairs 36c517dfc4 2010-11-23 kinaba: 36c517dfc4 2010-11-23 kinaba: Table makeCons(Value a, Value d) 36c517dfc4 2010-11-23 kinaba: { 36c517dfc4 2010-11-23 kinaba: Table t = new Table; 36c517dfc4 2010-11-23 kinaba: t.set("car", ValueLayer, a); 36c517dfc4 2010-11-23 kinaba: t.set("cdr", ValueLayer, d); 36c517dfc4 2010-11-23 kinaba: return t; 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: /// Experimental!! Convert D value (except AST) to Polemy Value 36c517dfc4 2010-11-23 kinaba: 36c517dfc4 2010-11-23 kinaba: Value d2polemy(T)(T e) 36c517dfc4 2010-11-23 kinaba: { 36c517dfc4 2010-11-23 kinaba: return ast2table(e, delegate Value(AST){ assert(false); }); 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: 36c517dfc4 2010-11-23 kinaba: /// Convert AST to Table so that it can be used in Polemy 36c517dfc4 2010-11-23 kinaba: 36c517dfc4 2010-11-23 kinaba: Value ast2table(T)(T e, Value delegate(AST) rec) 36c517dfc4 2010-11-23 kinaba: { 36c517dfc4 2010-11-23 kinaba: static if(is(T==BigInt) || isIntegral!(T)) 36c517dfc4 2010-11-23 kinaba: return new IntValue(e); 36c517dfc4 2010-11-23 kinaba: else 36c517dfc4 2010-11-23 kinaba: static if(is(Unqual!(T)==string)) 36c517dfc4 2010-11-23 kinaba: return new StrValue(e); 36c517dfc4 2010-11-23 kinaba: else 36c517dfc4 2010-11-23 kinaba: static if(is(T S : S[])) 36c517dfc4 2010-11-23 kinaba: { 36c517dfc4 2010-11-23 kinaba: Table lst = new Table; 36c517dfc4 2010-11-23 kinaba: foreach_reverse(a; e) 36c517dfc4 2010-11-23 kinaba: static if(is(S : AST)) 36c517dfc4 2010-11-23 kinaba: lst = makeCons(rec(a), lst); 36c517dfc4 2010-11-23 kinaba: else 36c517dfc4 2010-11-23 kinaba: lst = makeCons(ast2table(a,rec), lst); 36c517dfc4 2010-11-23 kinaba: return lst; 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: else 36c517dfc4 2010-11-23 kinaba: static if(is(T : AST)) 36c517dfc4 2010-11-23 kinaba: { 36c517dfc4 2010-11-23 kinaba: assert( typeid(e) == typeid(T), text("abstracted: ", typeid(e), " vs ", typeid(T)) ); 36c517dfc4 2010-11-23 kinaba: auto t = new Table; 36c517dfc4 2010-11-23 kinaba: t.set("pos", ValueLayer, ast2table(e.pos,rec)); 36c517dfc4 2010-11-23 kinaba: t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[$-1].tolower())); 36c517dfc4 2010-11-23 kinaba: foreach(i,m; e.tupleof) 36c517dfc4 2010-11-23 kinaba: static if(is(typeof(m) : AST)) 2134cd44cc 2010-11-23 kinaba: t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, rec(m)); 36c517dfc4 2010-11-23 kinaba: else 2134cd44cc 2010-11-23 kinaba: t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, ast2table(m,rec)); 36c517dfc4 2010-11-23 kinaba: return t; 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: else 36c517dfc4 2010-11-23 kinaba: static if(is(T == class)) 36c517dfc4 2010-11-23 kinaba: { 36c517dfc4 2010-11-23 kinaba: auto t = new Table; 36c517dfc4 2010-11-23 kinaba: foreach(i,m; e.tupleof) 36c517dfc4 2010-11-23 kinaba: static if(is(typeof(m) : AST)) 36c517dfc4 2010-11-23 kinaba: t.set(e.tupleof[i].stringof[2..$], ValueLayer, rec(m)); 36c517dfc4 2010-11-23 kinaba: else 36c517dfc4 2010-11-23 kinaba: t.set(e.tupleof[i].stringof[2..$], ValueLayer, ast2table(m,rec)); 36c517dfc4 2010-11-23 kinaba: return t; 36c517dfc4 2010-11-23 kinaba: } 36c517dfc4 2010-11-23 kinaba: else 36c517dfc4 2010-11-23 kinaba: static assert(false, "unknown type <"~T.stringof~"> during AST encoding"); 36c517dfc4 2010-11-23 kinaba: }