Differences From Artifact [76bd90b6c3824480]:
- File
polemy/valueconv.d
- 2010-11-23 10:09:03 - part of checkin [36c517dfc4] on branch trunk - refactored d-value and polemy-value conversion (user: kinaba) [annotate]
To Artifact [2816a291e16d0986]:
- File
polemy/valueconv.d
- 2010-11-23 13:55:15 - part of checkin [2134cd44cc] on branch trunk - further clean-up for polemy2d (user: kinaba) [annotate]
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)