File Annotation
Not logged in
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: 	}
f9c31f3cd8 2010-11-24        kinaba: 	return LexPosition.dummy;
36c517dfc4 2010-11-23        kinaba: }
36c517dfc4 2010-11-23        kinaba: 
2134cd44cc 2010-11-23        kinaba: /// Experimental!! Convert Polemy value to D Value
2134cd44cc 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);
2134cd44cc 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 )
ba11f1d551 2010-11-23        kinaba: 				throw genex!RuntimeException(callpos, text(`Invalid AST (no "is" field): `, _v));
36c517dfc4 2010-11-23        kinaba: 
2134cd44cc 2010-11-23        kinaba: 			foreach(AT; ListOfASTTypes)
153a14cec0 2010-11-24        kinaba: 				if(typ.data == typeid(AT).name.split(".")[$-1])
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;
f9c31f3cd8 2010-11-24        kinaba: 		if(e.pos is null) // special treatment
f9c31f3cd8 2010-11-24        kinaba: 		{
f9c31f3cd8 2010-11-24        kinaba: 			Table post = new Table;
f9c31f3cd8 2010-11-24        kinaba: 			post.set("filename", ValueLayer, new StrValue("nullpo"));
f9c31f3cd8 2010-11-24        kinaba: 			post.set("lineno", ValueLayer, new IntValue(0));
f9c31f3cd8 2010-11-24        kinaba: 			post.set("column", ValueLayer, new IntValue(0));
f9c31f3cd8 2010-11-24        kinaba: 			t.set("pos", ValueLayer, post);
f9c31f3cd8 2010-11-24        kinaba: 		}
f9c31f3cd8 2010-11-24        kinaba: 		else
f9c31f3cd8 2010-11-24        kinaba: 			t.set("pos", ValueLayer, ast2table(e.pos,rec));
153a14cec0 2010-11-24        kinaba: 		t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[$-1]));
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: }