]> gitweb.ps.run Git - toc/blob - src/toc.h
toc now uses internal representation instead of ast
[toc] / src / toc.h
1 #pragma once\r
2 \r
3 #include <iostream>\r
4 \r
5 #include "repr.h"\r
6 \r
7 template<typename T>\r
8 std::ostream & operator<< (std::ostream & out, const std::vector<T> & v) {\r
9   bool comma = false;\r
10   for (auto t : v) {\r
11     if (comma) out << ", ";\r
12     else comma = true;\r
13     out << t;\r
14   }\r
15   return out;\r
16 }\r
17 \r
18 std::ostream & operator<< (std::ostream & out, const Type & t);\r
19 std::ostream & operator<< (std::ostream & out, const Variable & v);\r
20 std::ostream & operator<< (std::ostream & out, const Body & b);\r
21 std::ostream & operator<< (std::ostream & out, const OperatorExpr & o);\r
22 std::ostream & operator<< (std::ostream & out, const Expr & e);\r
23 std::ostream & operator<< (std::ostream & out, const Stmt & s);\r
24 \r
25 void tocFunction (std::ostream & out, const Function & f, bool stub);\r
26 void tocStruct   (std::ostream & out, const Struct & s, bool stub);\r
27 void tocProgram  (std::ostream & out, const Program & p);\r
28 \r
29 static const int TAB_WIDTH = 2;\r
30 static int indentation = 0;\r
31 static void indent(std::ostream & out, int change = 0) {\r
32   indentation += change;\r
33   out << std::string(indentation, ' ');\r
34 }\r
35 \r
36 std::ostream & operator<< (std::ostream & out, const Type & t) {\r
37   out << t.name;\r
38 \r
39   return out;\r
40 }\r
41 std::ostream & operator<< (std::ostream & out, const Variable & v) {\r
42   out << v.type << " " << v.name;\r
43 \r
44   return out;\r
45 }\r
46 std::ostream & operator<< (std::ostream & out, const Body & b) {\r
47   indent(out);\r
48   out << "{\n";\r
49   indentation += 2;\r
50 \r
51   for (auto v : b.variables) {\r
52     indent(out);\r
53     out << v << ";\n";\r
54   }\r
55 \r
56   out << "\n";\r
57   \r
58   for (auto s : b.statements) {\r
59     indent(out);\r
60     out << s << ";\n";\r
61   }\r
62 \r
63   indent(out, -2);\r
64   out << "}\n";\r
65 \r
66   return out;\r
67 }\r
68 std::ostream & operator<< (std::ostream & out, const OperatorExpr & o) {\r
69   out << *o.lexpr << " ";\r
70 \r
71   switch (o.type) {\r
72   case OperatorType::Plus:        out << "+"; break;\r
73   case OperatorType::Minus:       out << "-"; break;\r
74   case OperatorType::Multiply:    out << "*"; break;\r
75   case OperatorType::Divide:      out << "/"; break;\r
76   case OperatorType::Equals:      out << "=="; break;\r
77   case OperatorType::NotEquals:   out << "!="; break;\r
78   case OperatorType::LessThan:    out << "<"; break;\r
79   case OperatorType::GreaterThan: out << ">"; break;\r
80   }\r
81 \r
82   out << " " << *o.rexpr;\r
83 \r
84   return out;\r
85 }\r
86 std::ostream & operator<< (std::ostream & out, const Expr & e) {\r
87   switch (e.type) {\r
88   case ExprType::Brackets:\r
89     out << *e._brackets.lexpr << "[" << *e._brackets.rexpr << "]"; break;\r
90   case ExprType::Call:\r
91     out << e._call.functionName << "(" << e._call.arguments << ")"; break;\r
92   case ExprType::Dot:\r
93     out << e._dot.name << "." << *e._dot.lexpr; break;\r
94   case ExprType::Literal:\r
95     out << e._literal.i; break;\r
96   case ExprType::Operator:\r
97     out << e._operator; break;\r
98   case ExprType::Variable:\r
99     out << e._variable.name; break;\r
100   }\r
101 \r
102   return out;\r
103 }\r
104 std::ostream & operator<< (std::ostream & out, const Stmt & s) {\r
105   switch (s.type) {\r
106   case StmtType::Assign:\r
107     out << s._assign.lexpr << "=" << s._assign.rexpr; break;\r
108    case StmtType::Expr:\r
109      out << s._expr; break;\r
110   case StmtType::If:\r
111     out << "if (" << s._if.condition << ")\n" << s._if.body; break;\r
112   case StmtType::Return:\r
113     out << "return " << s._return.expr; break;\r
114   case StmtType::While:\r
115     out << "while (" << s._while.condition << ")\n" << s._while.body; break;\r
116   }\r
117 \r
118   return out;\r
119 }\r
120 \r
121 \r
122 void tocFunction (std::ostream & out, const Function & f, bool stub) {\r
123   out << f.returnType << " " << f.name << " (";\r
124 \r
125   bool comma = false;\r
126   for (auto p : f.parameters) {\r
127     if (comma) out << ", ";\r
128     else comma = true;\r
129 \r
130     out << p.type << " " << p.name;\r
131   }\r
132 \r
133   out << ")";\r
134 \r
135   if (stub) {\r
136     out << ";\n";\r
137   }\r
138   else {\r
139     out << "\n" << f.body;\r
140   }\r
141 }\r
142 void tocStruct (std::ostream & out, const Struct & s, bool stub) {\r
143   out << "struct " << s.name;\r
144   if (stub) {\r
145     out << ";\n";\r
146     return;\r
147   }\r
148   out << "\n{\n";\r
149   indentation += 2;\r
150 \r
151   for (auto m : s.members) {\r
152     indent(out);\r
153     out << m << ";\n";\r
154   }\r
155 \r
156   indent(out, -2);\r
157   out << "};\n";\r
158 }\r
159 void tocProgram (std::ostream & out, const Program & p) {\r
160   for (auto s : p.structs) {\r
161     tocStruct(out, s, true);\r
162   }\r
163   for (auto s : p.structs) {\r
164     tocStruct(out, s, false);\r
165   }\r
166 \r
167   for (auto v : p.variables) {\r
168     out << v << ";\n";\r
169   }\r
170 \r
171   for (auto f : p.functions) {\r
172     tocFunction(out, f, true);\r
173   }\r
174   for (auto f : p.functions) {\r
175     tocFunction(out, f, false);\r
176   }\r
177 }\r
178 \r
179 \r
180 \r
181 \r
182 // void toc(std::ostream & o, TocParser::ProgContext * ctx) {\r
183 //   for (auto * decl : ctx->decl()) {\r
184 //     /**/ if (decl->structDecl() != nullptr) toc_stub(o, decl->structDecl());\r
185 //     else if (decl->funcDecl()   != nullptr) toc_stub(o, decl->funcDecl()->func());\r
186 //   }\r
187 //   for (auto * decl : ctx->decl()) {\r
188 //     if (decl->varDecl()    != nullptr) {\r
189 //       toc(o, decl->varDecl());\r
190 //       out << ";\n";\r
191 //     }\r
192 //     else if (decl->structDecl() != nullptr) toc(o, decl->structDecl());\r
193 //     else if (decl->funcDecl()   != nullptr) toc(o, decl->funcDecl()->func());\r
194 //   }\r
195 // }\r
196 // void toc(std::ostream & o, TocParser::VarDeclContext * ctx) {\r
197 //   o\r
198 //     << ctx->var()->type()->getText()\r
199 //     << " "\r
200 //     << ctx->var()->varName()->getText();\r
201   \r
202 //   if (ctx->var()->expr() != nullptr) {\r
203 //     out << " = ";\r
204 //     toc(o, ctx->var()->expr());\r
205 //   }\r
206 // }\r
207 // void toc(std::ostream & o, TocParser::FuncContext * ctx) {\r
208 //   o\r
209 //     << ctx->type()->getText()\r
210 //     << " "\r
211 //     << ctx->funcName()->getText()\r
212 //     << "(";\r
213 \r
214 //   if (ctx->parameter()->firstParameter() != nullptr) {\r
215 //     o\r
216 //       << ctx->parameter()->firstParameter()->var()->type()->getText()\r
217 //       << " "\r
218 //       << ctx->parameter()->firstParameter()->var()->varName()->getText();\r
219 \r
220 //     for (auto * par : ctx->parameter()->additionalParameter()) {\r
221 //       o\r
222 //         << ", "\r
223 //         << par->var()->type()->getText()\r
224 //         << " "\r
225 //         << par->var()->varName()->getText();\r
226 //     }\r
227 //   }\r
228 \r
229 //   out << ")\n{\n";\r
230 \r
231 //   toc(o, ctx->body());\r
232 \r
233 //   out << "}\n";\r
234 // }\r
235 // void toc(std::ostream & o, TocParser::StructDeclContext * ctx) {\r
236 //   o\r
237 //     << "typedef struct "\r
238 //     << ctx->structName()->getText()\r
239 //     << "\n{\n";\r
240 \r
241 //   for (auto * member : ctx->structMember()) {\r
242 //     if (member->structVar() != nullptr) {\r
243 //       o\r
244 //         << member->structVar()->var()->type()->getText()\r
245 //         << " "\r
246 //         << member->structVar()->var()->varName()->getText()\r
247 //         << ";\n";\r
248 //     }\r
249 //   }\r
250 //   out << "} "\r
251 //     << ctx->structName()->getText()\r
252 //     << ";\n";\r
253 //   for (auto * member : ctx->structMember()) {\r
254 //     if (member->structMethod() != nullptr) {\r
255 //       o\r
256 //         << member->structMethod()->func()->type()->getText()\r
257 //         << " "\r
258 //         << ctx->structName()->getText()\r
259 //         << "_"\r
260 //         << member->structMethod()->func()->funcName()->getText()\r
261 //         << "("\r
262 //         << ctx->structName()->getText()\r
263 //         << " * this";\r
264 \r
265 //       if (member->structMethod()->func()->parameter()->firstParameter() != nullptr) {\r
266 //         o\r
267 //           << ", "\r
268 //           << member->structMethod()->func()->parameter()->firstParameter()->var()->type()->getText()\r
269 //           << " "\r
270 //           << member->structMethod()->func()->parameter()->firstParameter()->var()->varName()->getText();\r
271 \r
272 //         for (auto * par : member->structMethod()->func()->parameter()->additionalParameter()) {\r
273 //           o\r
274 //             << ", "\r
275 //             << par->var()->type()->getText()\r
276 //             << " "\r
277 //             << par->var()->varName()->getText();\r
278 //         }\r
279 //       }\r
280 \r
281 //       out << ")\n{\n";\r
282 \r
283 //       toc(o, member->structMethod()->func()->body());\r
284 \r
285 //       out << "}\n";\r
286 //     }\r
287 //   }\r
288 // }\r
289 // void toc(std::ostream & o, TocParser::BodyContext * ctx) {\r
290 //   for (auto * stmt : ctx->stmt()) {\r
291 //     toc(o, stmt);\r
292 //     out << "\n";\r
293 //   }\r
294 // }\r
295 // void toc(std::ostream & o, TocParser::StmtContext * ctx) {\r
296 //   /**/ if (ctx->varDecl() != nullptr) toc(o, ctx->varDecl());\r
297 //   else if (ctx->conditional() != nullptr) toc(o, ctx->conditional()->ifCond());\r
298 //   else if (ctx->loop() != nullptr) toc(o, ctx->loop()->whileLoop());\r
299 //   else if (ctx->assignment() != nullptr) toc(o, ctx->assignment());\r
300 //   else if (ctx->returnStmt() != nullptr) toc(o, ctx->returnStmt());\r
301 //   else if (ctx->expr() != nullptr) toc(o, ctx->expr());\r
302 \r
303 //   if (ctx->conditional() == nullptr && ctx->loop() == nullptr)\r
304 //     out << ";";\r
305 // }\r
306 // void toc(std::ostream & o, TocParser::IfCondContext * ctx) {\r
307 //   out << "if (";\r
308 //   toc(o, ctx->expr());\r
309 //   out << ")\n{\n";\r
310 //   toc(o, ctx->body());\r
311 //   out << "}\n";\r
312 // }\r
313 // void toc(std::ostream & o, TocParser::WhileLoopContext * ctx) {\r
314 //   out << "while (";\r
315 //   toc(o, ctx->expr());\r
316 //   out << ")\n{\n";\r
317 //   toc(o, ctx->body());\r
318 //   out << "}\n";\r
319 // }\r
320 // void toc(std::ostream & o, TocParser::AssignmentContext * ctx) {\r
321 //   toc(o, ctx->identifier());\r
322 //   out << " = ";\r
323 //   toc(o, ctx->expr());\r
324 // }\r
325 // void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx) {\r
326 //   out << "return ";\r
327 //   toc(o, ctx->expr());\r
328 // }\r
329 // void toc(std::ostream & o, TocParser::ExprContext * ctx) {\r
330 //     /**/ if (ctx->funcCall()     != nullptr) toc(o, ctx->funcCall());\r
331 //     else if (ctx->identifier()   != nullptr) toc(o, ctx->identifier());\r
332 //     else if (ctx->literal()      != nullptr) toc(o, ctx->literal());\r
333 //     else if (ctx->subscript()    != nullptr) toc(o, ctx->subscript());\r
334 //     else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
335 //     else if (ctx->parenExpr()    != nullptr) toc(o, ctx->parenExpr());\r
336 //     else if (ctx->operatorExpr() != nullptr) toc(o, ctx->operatorExpr()->binaryOperator());\r
337 // }\r
338 // void toc(std::ostream & o, TocParser::NonOpExprContext * ctx) {\r
339 //     /**/ if (ctx->funcCall()     != nullptr) toc(o, ctx->funcCall());\r
340 //     else if (ctx->identifier()   != nullptr) toc(o, ctx->identifier());\r
341 //     else if (ctx->literal()      != nullptr) toc(o, ctx->literal());\r
342 //     else if (ctx->subscript()    != nullptr) toc(o, ctx->subscript());\r
343 //     else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
344 //     else if (ctx->parenExpr()    != nullptr) toc(o, ctx->parenExpr());\r
345 // }\r
346 // void toc(std::ostream & o, TocParser::NonSubscriptExprContext * ctx) {\r
347 //     /**/ if (ctx->funcCall()     != nullptr) toc(o, ctx->funcCall());\r
348 //     else if (ctx->identifier()   != nullptr) toc(o, ctx->identifier());\r
349 //     else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
350 //     else if (ctx->parenExpr()    != nullptr) toc(o, ctx->parenExpr());\r
351 // }\r
352 // void toc(std::ostream & o, TocParser::FuncCallContext * ctx) {\r
353 //   o\r
354 //     << ctx->funcName()->getText()\r
355 //     << "(";\r
356 //   for (int i = 0; i < ctx->expr().size(); i++) {\r
357 //     if (i != 0) out << ", ";\r
358 //     toc(o, ctx->expr(i));\r
359 //   }\r
360 //   out << ")";\r
361 // }\r
362 // void toc(std::ostream & o, TocParser::IdentifierContext * ctx) {\r
363 //   out << ctx->getText();\r
364 // }\r
365 // void toc(std::ostream & o, TocParser::LiteralContext * ctx) {\r
366 //   if (ctx->INTLIT() != nullptr) out << ctx->INTLIT()->getText();\r
367 // }\r
368 // void toc(std::ostream & o, TocParser::SubscriptContext * ctx) {\r
369 //   toc(o, ctx->nonSubscriptExpr());\r
370 //   out << "[";\r
371 //   toc(o, ctx->expr());\r
372 //   out << "]";\r
373 // }\r
374 // void toc(std::ostream & o, TocParser::MemberAccessContext * ctx) {\r
375 //   toc(o, ctx->identifier(0));\r
376 //   out << ".";\r
377 //   toc(o, ctx->identifier(1));\r
378 // }\r
379 // void toc(std::ostream & o, TocParser::ParenExprContext * ctx) {\r
380 //   out << "(";\r
381 //   toc(o, ctx->expr());\r
382 //   out << ")";\r
383 // }\r
384 // void toc(std::ostream & o, TocParser::BinaryOperatorContext * ctx) {\r
385 //   for (int i = 0; i < ctx->BINARY_OPERATOR().size(); i++) {\r
386 //     toc(o, ctx->nonOpExpr(i));\r
387 //     o\r
388 //       << " "\r
389 //       << ctx->BINARY_OPERATOR(i)->getText()\r
390 //       << " ";\r
391 //     toc(o, ctx->nonOpExpr(i + 1));\r
392 //   }\r
393 // }\r
394 \r
395 // void toc_stub(std::ostream & o, TocParser::FuncContext * ctx) {\r
396 //   o\r
397 //     << ctx->type()->getText()\r
398 //     << " "\r
399 //     << ctx->funcName()->getText()\r
400 //     << "(";\r
401 \r
402 //   if (ctx->parameter()->firstParameter() != nullptr) {\r
403 //     o\r
404 //       << ctx->parameter()->firstParameter()->var()->type()->getText()\r
405 //       << " "\r
406 //       << ctx->parameter()->firstParameter()->var()->varName()->getText();\r
407 \r
408 //     for (auto * par : ctx->parameter()->additionalParameter()) {\r
409 //       o\r
410 //         << ", "\r
411 //         << par->var()->type()->getText()\r
412 //         << " "\r
413 //         << par->var()->varName()->getText();\r
414 //     }\r
415 //   }\r
416 \r
417 //   out << ");\n";\r
418 // }\r
419 // void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx) {\r
420 //   o\r
421 //     << "struct "\r
422 //     << ctx->structName()->getText()\r
423 //     << ";\n";\r
424 // }\r