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