]> gitweb.ps.run Git - toc/blob - src/toc.h
function resolution, pre generics
[toc] / src / toc.h
1 #pragma once\r
2 \r
3 #include <iostream>\r
4 #include <sstream>\r
5 \r
6 #include "repr.h"\r
7 #include "typeInfo.h"\r
8 \r
9 template<typename T>\r
10 std::string vectorStr (const std::vector<T> & v, const std::string & separator, bool end = false)\r
11 {\r
12   std::stringstream sstr;\r
13 \r
14   bool putSeparator = false;\r
15   for (auto t : v)\r
16   {\r
17     if (putSeparator) sstr << separator;\r
18     else putSeparator = true;\r
19     sstr << t;\r
20   }\r
21   if (end && !v.empty())\r
22     sstr << separator;\r
23 \r
24   return sstr.str();\r
25 }\r
26 \r
27 std::ostream & operator<< (std::ostream & out, const Type & t);\r
28 std::ostream & operator<< (std::ostream & out, const Variable & v);\r
29 std::ostream & operator<< (std::ostream & out, const Body & b);\r
30 std::ostream & operator<< (std::ostream & out, const Expr & e);\r
31 std::ostream & operator<< (std::ostream & out, const Stmt & s);\r
32 \r
33 void tocFunction (std::ostream & out, const Function & f, bool stub);\r
34 void tocStruct   (std::ostream & out, const Struct & s, bool stub);\r
35 void tocProgram  (std::ostream & out, const Program & p);\r
36 void tocNamespace  (std::ostream & out, const Namespace & n, bool stub);\r
37 \r
38 static const int TAB_WIDTH = 2;\r
39 static int indentation = 0;\r
40 static void indent(std::ostream & out, int change = 0)\r
41 {\r
42   indentation += change;\r
43   out << std::string(indentation, ' ');\r
44 }\r
45 \r
46 static std::vector<std::string> namespaces;\r
47 static std::string namespacePrefix() {\r
48   std::stringstream sstr;\r
49   for (auto n : namespaces)\r
50   {\r
51     sstr << n << "_";\r
52   }\r
53   return sstr.str();\r
54 }\r
55 \r
56 static Program globalPrg;\r
57 static std::shared_ptr<Context> globalCtx;\r
58 \r
59 std::ostream & operator<< (std::ostream & out, const Type & t)\r
60 {\r
61   TypeInfo ti = typeType(globalPrg, t);\r
62   if (ti.isStruct)\r
63     out << "struct ";\r
64   out << vectorStr(t.namespacePrefixes, "_", true) << t.name;\r
65 \r
66   return out;\r
67 }\r
68 std::ostream & operator<< (std::ostream & out, const Variable & v)\r
69 {\r
70   out << v.type << " ";\r
71 \r
72   std::stringstream sstr;\r
73   std::string s = v.name;\r
74 \r
75   for (auto m = v.type.modifiers.rbegin(); m != v.type.modifiers.rend(); m++)\r
76   {\r
77     if (m->type == TypeModifierType::Pointer)\r
78     {\r
79       sstr.str(std::string());\r
80       sstr << "*(" << s << ")";\r
81       s = sstr.str();\r
82     }\r
83     else\r
84     {\r
85       sstr.str(std::string());\r
86       sstr << "(" << s << ")[";\r
87       if (m->_staticArray)\r
88         sstr << m->_arraySize;\r
89       sstr << "]";\r
90       s = sstr.str();\r
91     }\r
92   }\r
93   out << s;\r
94 \r
95   return out;\r
96 }\r
97 std::ostream & operator<< (std::ostream & out, const Body & b)\r
98 {\r
99   b.ctx->parent = globalCtx;\r
100   globalCtx = b.ctx;\r
101 \r
102   indent(out);\r
103   out << "{\n";\r
104   indentation += 2;\r
105 \r
106   for (auto v : b.ctx->variables)\r
107   {\r
108     indent(out);\r
109     out << v << ";\n";\r
110   }\r
111 \r
112   out << "\n";\r
113   \r
114   for (auto s : b.statements)\r
115   {\r
116     indent(out);\r
117     out << s << "\n";\r
118   }\r
119 \r
120   indent(out, -2);\r
121   out << "}\n";\r
122 \r
123   globalCtx = b.ctx->parent;\r
124 \r
125   return out;\r
126 }\r
127 std::ostream & operator<< (std::ostream & out, const Expr & e)\r
128 {\r
129   switch (e.type)\r
130   {\r
131   case ExprType::Func:\r
132   {\r
133     if (e._func.namespacePrefixes.empty())\r
134     {\r
135       TypeInfo ti = typeExpr(globalPrg, namespaces, globalCtx, e);\r
136       \r
137     }\r
138     out << vectorStr(e._func.namespacePrefixes, "_", true) << e._func.functionName << "(" << vectorStr(e._func.arguments, ", ") << ")"; break;\r
139   }\r
140   case ExprType::Method:\r
141   {\r
142     TypeInfo ti = typeExpr(globalPrg, namespaces, globalCtx, *e._method.expr);\r
143     out <<\r
144       vectorStr(ti.type.namespacePrefixes, "_", true) <<\r
145       ti.type.name << "_" << e._method.methodName <<\r
146       "(&" << *e._method.expr << (e._method.arguments.empty() ? "" : ", ") <<\r
147       vectorStr(e._method.arguments, ", ") << ")"; break;\r
148   }\r
149   case ExprType::Lit:\r
150     /**/ if (e._lit.type == LitType::Int) out << e._lit._int;\r
151     else if (e._lit.type == LitType::Decimal) out << e._lit._decimal;\r
152     else if (e._lit.type == LitType::String) out << e._lit._string;\r
153     else if (e._lit.type == LitType::Bool) out << e._lit._bool;\r
154     break;\r
155   case ExprType::Paren:\r
156     out << "(" << e._paren.expr << ")"; break;\r
157   case ExprType::Dot:\r
158     out << *e._dot.expr << "." << e._dot.identifier; break;\r
159   case ExprType::PrefixOp:\r
160     out << PrefixOperatorTypeStrings[(int)e._prefixOp.type] << *e._prefixOp.expr; break;\r
161   case ExprType::PostfixOp:\r
162     out << *e._postfixOp.expr << PostfixOperatorTypeStrings[(int)e._postfixOp.type]; break;\r
163   case ExprType::BinaryOp:\r
164     out << *e._binaryOp.lexpr <<\r
165     " " << BinaryOperatorTypeStrings[(int)e._binaryOp.type] << " " <<\r
166     *e._binaryOp.rexpr; break;\r
167   case ExprType::TernaryOp:\r
168     out << *e._ternaryOp.lexpr <<\r
169       " ? " << *e._ternaryOp.rexprTrue <<\r
170       " : " << *e._ternaryOp.rexprFalse; break;\r
171   case ExprType::Bracket:\r
172     out << *e._brackets.lexpr << "[" << *e._brackets.rexpr << "]"; break;\r
173   case ExprType::Identifier:\r
174     out << vectorStr(e._identifier.namespacePrefixes, "_", true) << e._identifier.identifier; break;\r
175   }\r
176 \r
177   return out;\r
178 }\r
179 std::ostream & operator<< (std::ostream & out, const Stmt & s)\r
180 {\r
181   switch (s.type)\r
182   {\r
183   case StmtType::If:\r
184     out << "if (" << s._if.condition << ")\n" << s._if.body; break;\r
185   case StmtType::Switch:\r
186     out << "switch (" << s._switch.ident << ")\n{\n";\r
187     for (auto c : s._switch.cases)\r
188     {\r
189       indent(out, 2);\r
190       out << "case " << *c.expr << ": " << c.body << "break;";\r
191     }\r
192     indent(out, -2);\r
193     out << "}\n";\r
194     break;\r
195   case StmtType::For:\r
196     out << "for (" <<\r
197       s._for.init << "; " <<\r
198       *s._for.condition << "; " <<\r
199       *s._for.action <<\r
200       ")\n" << s._for.body; break;\r
201   case StmtType::While:\r
202     out << "while (" << s._while.condition << ")\n" << s._while.body; break;\r
203   case StmtType::Assign:\r
204     out << s._assign.lexpr << " = " << s._assign.rexpr << ";"; break;\r
205   case StmtType::Return:\r
206     out << "return " << s._return.expr << ";"; break;\r
207   case StmtType::Expr:\r
208     out << s._expr << ";"; break;\r
209   }\r
210 \r
211   return out;\r
212 }\r
213 \r
214 \r
215 void tocFunction (std::ostream & out, const Function & f, bool stub)\r
216 {\r
217   if (!stub && !f.defined) return;\r
218 \r
219   out << f.returnType << " " << namespacePrefix() << f.name << " (" << vectorStr(f.parameters, ", ") << ")";\r
220 \r
221   if (stub)\r
222   {\r
223     out << ";\n";\r
224   }\r
225   else\r
226   {\r
227     out << "\n" << f.body;\r
228   }\r
229 }\r
230 void tocStruct (std::ostream & out, const Struct & s, bool stub)\r
231 {\r
232   out << "struct " << namespacePrefix() << s.name;\r
233   if (stub)\r
234   {\r
235     out << ";\n";\r
236     for (auto m : s.methods)\r
237     {\r
238       Function f = m;\r
239 \r
240       f.parameters.insert(f.parameters.begin(),\r
241       {"this",\r
242         {\r
243           namespaces,\r
244           s.name,\r
245           {\r
246             {TypeModifierType::Pointer, false, -1}\r
247           }\r
248         }\r
249       });\r
250       out << f.returnType << " " <<\r
251         namespacePrefix() << s.name << "_" << f.name <<\r
252         " (" << vectorStr(f.parameters, ", ") << ");\n";\r
253     }\r
254     return;\r
255   }\r
256   out << "\n{\n";\r
257   indentation += 2;\r
258 \r
259   for (auto m : s.members)\r
260   {\r
261     indent(out);\r
262     out << m << ";\n";\r
263   }\r
264 \r
265   indent(out, -2);\r
266   out << "};\n";\r
267   \r
268   for (auto m : s.methods)\r
269   {\r
270     Function f = m;\r
271     f.parameters.insert(f.parameters.begin(),\r
272       {"this",\r
273         {\r
274           namespaces,\r
275           s.name,\r
276           {\r
277             {TypeModifierType::Pointer, false, -1}\r
278           }\r
279         }\r
280       });\r
281     out << f.returnType << " " <<\r
282     namespacePrefix() << s.name << "_" << f.name <<\r
283     " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
284   }\r
285 }\r
286 void tocProgram (std::ostream & out, const Program & p)\r
287 {\r
288   globalCtx = p.ctx;\r
289 \r
290   globalPrg = p;\r
291   for (auto n : p.namespaces)\r
292   {\r
293     tocNamespace(out, n, true);\r
294   }\r
295   out << "\n\n";\r
296   for (auto s : p.structs)\r
297   {\r
298     tocStruct(out, s, true);\r
299   }\r
300   out << "\n\n";\r
301   for (auto f : p.functions)\r
302   {\r
303     tocFunction(out, f, true);\r
304   }\r
305   out << "\n\n";\r
306 \r
307   for (auto v : p.ctx->variables)\r
308   {\r
309     out << v << ";\n";\r
310   }\r
311   out << "\n\n";\r
312   for (auto n : p.namespaces)\r
313   {\r
314     tocNamespace(out, n, false);\r
315   }\r
316   out << "\n\n";\r
317   for (auto s : p.structs)\r
318   {\r
319     tocStruct(out, s, false);\r
320   }\r
321   out << "\n\n";\r
322   for (auto f : p.functions)\r
323   {\r
324     tocFunction(out, f, false);\r
325   }\r
326   out << "\n\n";\r
327 }\r
328 \r
329 \r
330 void tocNamespace  (std::ostream & out, const Namespace & n, bool stub)\r
331 {\r
332   n.ctx->parent = globalCtx;\r
333   globalCtx = n.ctx;\r
334 \r
335   namespaces.push_back(n.name);\r
336   if (!stub)\r
337   {\r
338     for (auto v : n.ctx->variables)\r
339     {\r
340       out << v << ";\n";\r
341     }\r
342     out << "\n\n";\r
343   }\r
344   for (auto n : n.namespaces)\r
345   {\r
346     tocNamespace(out, n, stub);\r
347     out << "\n\n";\r
348   }\r
349   for (auto s : n.structs)\r
350   {\r
351     tocStruct(out, s, stub);\r
352     out << "\n\n";\r
353   }\r
354   for (auto f : n.functions)\r
355   {\r
356     tocFunction(out, f, stub);\r
357     out << "\n\n";\r
358   }\r
359   namespaces.pop_back();\r
360 \r
361   globalCtx = n.ctx->parent;\r
362 }