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: {
36c517dfc4 2010-11-23        kinaba: 	Layer theLayer = ValueLayer;
36c517dfc4 2010-11-23        kinaba: 	if(auto tt = t.access!Table(theLayer, "pos"))
36c517dfc4 2010-11-23        kinaba: 	{
36c517dfc4 2010-11-23        kinaba: 		auto fn = tt.access!StrValue(theLayer, "filename");
36c517dfc4 2010-11-23        kinaba: 		auto ln = tt.access!IntValue(theLayer, "lineno");
36c517dfc4 2010-11-23        kinaba: 		auto cl = tt.access!IntValue(theLayer, "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: 
36c517dfc4 2010-11-23        kinaba: Value[] tableAsConsList( Layer theLayer, Table t )
36c517dfc4 2010-11-23        kinaba: {
36c517dfc4 2010-11-23        kinaba: 	Value[] result;
36c517dfc4 2010-11-23        kinaba: 	while(t)
36c517dfc4 2010-11-23        kinaba: 		if(auto v  = t.access!Value(theLayer, "car"))
36c517dfc4 2010-11-23        kinaba: 		{
36c517dfc4 2010-11-23        kinaba: 			result ~= v;
36c517dfc4 2010-11-23        kinaba: 			t = t.access!Table(theLayer, "cdr");
36c517dfc4 2010-11-23        kinaba: 		}
36c517dfc4 2010-11-23        kinaba: 		else
36c517dfc4 2010-11-23        kinaba: 			break;
36c517dfc4 2010-11-23        kinaba: 	return result;
36c517dfc4 2010-11-23        kinaba: }
36c517dfc4 2010-11-23        kinaba: 
36c517dfc4 2010-11-23        kinaba: AST[] tableToASTList( Layer theLayer, Table t )
36c517dfc4 2010-11-23        kinaba: {
36c517dfc4 2010-11-23        kinaba: 	AST[] result;
36c517dfc4 2010-11-23        kinaba: 	foreach(v; tableAsConsList(theLayer, t))
36c517dfc4 2010-11-23        kinaba: 		if(auto t = cast(Table)v)
36c517dfc4 2010-11-23        kinaba: 			result ~= tableToAST(theLayer,t);
36c517dfc4 2010-11-23        kinaba: 		else
36c517dfc4 2010-11-23        kinaba: 			throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (non-table in cons-list)");
36c517dfc4 2010-11-23        kinaba: 	return result;
36c517dfc4 2010-11-23        kinaba: }
36c517dfc4 2010-11-23        kinaba: 
36c517dfc4 2010-11-23        kinaba: AST tableToAST( Layer theLayer, Value vvvv )
36c517dfc4 2010-11-23        kinaba: {
36c517dfc4 2010-11-23        kinaba: 	Table t = cast(Table)vvvv;
36c517dfc4 2010-11-23        kinaba: 	if( t is null )
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (not a table)");
36c517dfc4 2010-11-23        kinaba: 
36c517dfc4 2010-11-23        kinaba: 	auto nodeType = t.access!StrValue(theLayer, "is");
36c517dfc4 2010-11-23        kinaba: 	if( nodeType is null )
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST {is:(not string)}");
36c517dfc4 2010-11-23        kinaba: 	auto pos = extractPos(t);
36c517dfc4 2010-11-23        kinaba: 	switch(nodeType.data)
36c517dfc4 2010-11-23        kinaba: 	{
36c517dfc4 2010-11-23        kinaba: 	case "int":
36c517dfc4 2010-11-23        kinaba: 		if(auto v = t.access!IntValue(theLayer, "data"))
36c517dfc4 2010-11-23        kinaba: 			return new Int(pos, v.data);
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"int", data:(not int)}`);
36c517dfc4 2010-11-23        kinaba: 	case "str":
36c517dfc4 2010-11-23        kinaba: 		if(auto v = t.access!StrValue(theLayer, "data"))
36c517dfc4 2010-11-23        kinaba: 			return new Str(pos, v.data);
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"str", data:(not string)}`);
36c517dfc4 2010-11-23        kinaba: 	case "var":
36c517dfc4 2010-11-23        kinaba: 		if(auto v = t.access!StrValue(theLayer, "name"))
36c517dfc4 2010-11-23        kinaba: 			return new Var(pos, v.data);
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"var", name:(not string)}`);
36c517dfc4 2010-11-23        kinaba: 	case "lay":
36c517dfc4 2010-11-23        kinaba: 		if(auto v = t.access!StrValue(theLayer, "layer"))
36c517dfc4 2010-11-23        kinaba: 			if(auto e = t.access!Table(theLayer, "expr"))
36c517dfc4 2010-11-23        kinaba: 				return new Lay(pos, v.data, tableToAST(theLayer,e));
36c517dfc4 2010-11-23        kinaba: 			else
36c517dfc4 2010-11-23        kinaba: 				throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", expr:(not table)}`);
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", layer:(not string)}`);
36c517dfc4 2010-11-23        kinaba: 	case "let":
36c517dfc4 2010-11-23        kinaba: 		if(auto n = t.access!StrValue(theLayer, "name"))
36c517dfc4 2010-11-23        kinaba: 		if(auto e = t.access!Table(theLayer, "init"))
36c517dfc4 2010-11-23        kinaba: 		if(auto b = t.access!Table(theLayer, "expr"))
36c517dfc4 2010-11-23        kinaba: 		{
36c517dfc4 2010-11-23        kinaba: 			string nn = n.data;
36c517dfc4 2010-11-23        kinaba: 			auto ee = tableToAST(theLayer, e);
36c517dfc4 2010-11-23        kinaba: 			auto bb = tableToAST(theLayer, b);
36c517dfc4 2010-11-23        kinaba: 			Layer lay="";
36c517dfc4 2010-11-23        kinaba: 			if(auto l = t.access!StrValue(theLayer, "layer"))
36c517dfc4 2010-11-23        kinaba: 				lay = l.data;
36c517dfc4 2010-11-23        kinaba: 			return new Let(pos, nn, lay, ee, bb);
36c517dfc4 2010-11-23        kinaba: 		}
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"let", name:"???", init:"???", expr:"???"}`);
36c517dfc4 2010-11-23        kinaba: 	case "app":
36c517dfc4 2010-11-23        kinaba: 		if(auto f = t.access!Table(theLayer, "fun"))
36c517dfc4 2010-11-23        kinaba: 		if(auto a = t.access!Table(theLayer, "args"))
36c517dfc4 2010-11-23        kinaba: 			return new App(pos, tableToAST(theLayer,f), tableToASTList(theLayer,a));
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"app", fun:???, args:???}`);
36c517dfc4 2010-11-23        kinaba: 	case "fun":
36c517dfc4 2010-11-23        kinaba: 		if(auto p = t.access!Table(theLayer, "params"))
36c517dfc4 2010-11-23        kinaba: 		if(auto b = t.access!Table(theLayer, "funbody"))
36c517dfc4 2010-11-23        kinaba: 		{
36c517dfc4 2010-11-23        kinaba: 			Parameter[] ps;
36c517dfc4 2010-11-23        kinaba: 			foreach(v; tableAsConsList(theLayer, p))
36c517dfc4 2010-11-23        kinaba: 			{
36c517dfc4 2010-11-23        kinaba: 				if(auto tt = cast(Table)v)
36c517dfc4 2010-11-23        kinaba: 				if(auto ss = tt.access!StrValue(theLayer, "name"))
36c517dfc4 2010-11-23        kinaba: 				if(auto ll = tt.access!Table(theLayer, "layers"))
36c517dfc4 2010-11-23        kinaba: 				{
36c517dfc4 2010-11-23        kinaba: 					Layer[] ls;
36c517dfc4 2010-11-23        kinaba: 					foreach(lll; tableAsConsList(theLayer, ll))
36c517dfc4 2010-11-23        kinaba: 						if(auto l = cast(StrValue)lll)
36c517dfc4 2010-11-23        kinaba: 							ls ~= l.data;
36c517dfc4 2010-11-23        kinaba: 						else
36c517dfc4 2010-11-23        kinaba: 							throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {bad fun params %s}`(lll));
36c517dfc4 2010-11-23        kinaba: 					ps ~= new Parameter(ss.data, ls);
36c517dfc4 2010-11-23        kinaba: 					continue;
36c517dfc4 2010-11-23        kinaba: 				}
36c517dfc4 2010-11-23        kinaba: 				else
36c517dfc4 2010-11-23        kinaba: 				{
36c517dfc4 2010-11-23        kinaba: 					Layer[] emp;
36c517dfc4 2010-11-23        kinaba: 					ps ~= new Parameter(ss.data, emp);
36c517dfc4 2010-11-23        kinaba: 					continue;
36c517dfc4 2010-11-23        kinaba: 				}
36c517dfc4 2010-11-23        kinaba: 				throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {bad fun params %s}`(v));
36c517dfc4 2010-11-23        kinaba: 			}
36c517dfc4 2010-11-23        kinaba: 			auto bb = tableToAST(theLayer, b);
36c517dfc4 2010-11-23        kinaba: 			return new Fun(pos,ps,bb);
36c517dfc4 2010-11-23        kinaba: 		}
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"fun", param:???, body:???}`);
36c517dfc4 2010-11-23        kinaba: 	default:
36c517dfc4 2010-11-23        kinaba: 		throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {is: "%s"} unknown`(nodeType.data));
36c517dfc4 2010-11-23        kinaba: 	}
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: 
36c517dfc4 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))
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 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: }