]> gitweb.ps.run Git - toc/blob - src/toc.h
complete grammar
[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::Brackets:\r
93     out << *e._brackets.lexpr << "[" << *e._brackets.rexpr << "]"; break;\r
94   case ExprType::Call:\r
95     out << e._call.functionName << "(" << e._call.arguments << ")"; break;\r
96   case ExprType::Dot:\r
97     out << e._dot.name << "." << *e._dot.lexpr; break;\r
98   case ExprType::Literal:\r
99     out << e._literal.i; break;\r
100   case ExprType::Operator:\r
101     out << e._operator; break;\r
102   case ExprType::Variable:\r
103     out << e._variable.name; break;\r
104   }\r
105 \r
106   return out;\r
107 }\r
108 std::ostream & operator<< (std::ostream & out, const Stmt & s) {\r
109   switch (s.type) {\r
110   case StmtType::Assign:\r
111     out << s._assign.lexpr << "=" << s._assign.rexpr; break;\r
112    case StmtType::Expr:\r
113      out << s._expr; break;\r
114   case StmtType::If:\r
115     out << "if (" << s._if.condition << ")\n" << s._if.body; break;\r
116   case StmtType::Return:\r
117     out << "return " << s._return.expr; break;\r
118   case StmtType::While:\r
119     out << "while (" << s._while.condition << ")\n" << s._while.body; break;\r
120   }\r
121 \r
122   return out;\r
123 }\r
124 \r
125 \r
126 void tocFunction (std::ostream & out, const Function & f, bool stub) {\r
127   out << f.returnType << " " << f.name << " (";\r
128 \r
129   bool comma = false;\r
130   for (auto p : f.parameters) {\r
131     if (comma) out << ", ";\r
132     else comma = true;\r
133 \r
134     out << p.type << " " << p.name;\r
135   }\r
136 \r
137   out << ")";\r
138 \r
139   if (stub) {\r
140     out << ";\n";\r
141   }\r
142   else {\r
143     out << "\n" << f.body;\r
144   }\r
145 }\r
146 void tocStruct (std::ostream & out, const Struct & s, bool stub) {\r
147   out << "struct " << s.name;\r
148   if (stub) {\r
149     out << ";\n";\r
150     return;\r
151   }\r
152   out << "\n{\n";\r
153   indentation += 2;\r
154 \r
155   for (auto m : s.members) {\r
156     indent(out);\r
157     out << m << ";\n";\r
158   }\r
159 \r
160   indent(out, -2);\r
161   out << "};\n";\r
162 }\r
163 void tocProgram (std::ostream & out, const Program & p) {\r
164   for (auto s : p.structs) {\r
165     tocStruct(out, s, true);\r
166   }\r
167   for (auto s : p.structs) {\r
168     tocStruct(out, s, false);\r
169   }\r
170 \r
171   for (auto v : p.variables) {\r
172     out << v << ";\n";\r
173   }\r
174 \r
175   for (auto f : p.functions) {\r
176     tocFunction(out, f, true);\r
177   }\r
178   for (auto f : p.functions) {\r
179     tocFunction(out, f, false);\r
180   }\r
181 }\r
182 \r
183 \r
184 \r
185 \r
186 // void toc(std::ostream & o, TocParser::ProgContext * ctx) {\r
187 //   for (auto * decl : ctx->decl()) {\r
188 //     /**/ if (decl->structDecl() != nullptr) toc_stub(o, decl->structDecl());\r
189 //     else if (decl->funcDecl()   != nullptr) toc_stub(o, decl->funcDecl()->func());\r
190 //   }\r
191 //   for (auto * decl : ctx->decl()) {\r
192 //     if (decl->varDecl()    != nullptr) {\r
193 //       toc(o, decl->varDecl());\r
194 //       out << ";\n";\r
195 //     }\r
196 //     else if (decl->structDecl() != nullptr) toc(o, decl->structDecl());\r
197 //     else if (decl->funcDecl()   != nullptr) toc(o, decl->funcDecl()->func());\r
198 //   }\r
199 // }\r
200 // void toc(std::ostream & o, TocParser::VarDeclContext * ctx) {\r
201 //   o\r
202 //     << ctx->var()->type()->getText()\r
203 //     << " "\r
204 //     << ctx->var()->varName()->getText();\r
205   \r
206 //   if (ctx->var()->expr() != nullptr) {\r
207 //     out << " = ";\r
208 //     toc(o, ctx->var()->expr());\r
209 //   }\r
210 // }\r
211 // void toc(std::ostream & o, TocParser::FuncContext * ctx) {\r
212 //   o\r
213 //     << ctx->type()->getText()\r
214 //     << " "\r
215 //     << ctx->funcName()->getText()\r
216 //     << "(";\r
217 \r
218 //   if (ctx->parameter()->firstParameter() != nullptr) {\r
219 //     o\r
220 //       << ctx->parameter()->firstParameter()->var()->type()->getText()\r
221 //       << " "\r
222 //       << ctx->parameter()->firstParameter()->var()->varName()->getText();\r
223 \r
224 //     for (auto * par : ctx->parameter()->additionalParameter()) {\r
225 //       o\r
226 //         << ", "\r
227 //         << par->var()->type()->getText()\r
228 //         << " "\r
229 //         << par->var()->varName()->getText();\r
230 //     }\r
231 //   }\r
232 \r
233 //   out << ")\n{\n";\r
234 \r
235 //   toc(o, ctx->body());\r
236 \r
237 //   out << "}\n";\r
238 // }\r
239 // void toc(std::ostream & o, TocParser::StructDeclContext * ctx) {\r
240 //   o\r
241 //     << "typedef struct "\r
242 //     << ctx->structName()->getText()\r
243 //     << "\n{\n";\r
244 \r
245 //   for (auto * member : ctx->structMember()) {\r
246 //     if (member->structVar() != nullptr) {\r
247 //       o\r
248 //         << member->structVar()->var()->type()->getText()\r
249 //         << " "\r
250 //         << member->structVar()->var()->varName()->getText()\r
251 //         << ";\n";\r
252 //     }\r
253 //   }\r
254 //   out << "} "\r
255 //     << ctx->structName()->getText()\r
256 //     << ";\n";\r
257 //   for (auto * member : ctx->structMember()) {\r
258 //     if (member->structMethod() != nullptr) {\r
259 //       o\r
260 //         << member->structMethod()->func()->type()->getText()\r
261 //         << " "\r
262 //         << ctx->structName()->getText()\r
263 //         << "_"\r
264 //         << member->structMethod()->func()->funcName()->getText()\r
265 //         << "("\r
266 //         << ctx->structName()->getText()\r
267 //         << " * this";\r
268 \r
269 //       if (member->structMethod()->func()->parameter()->firstParameter() != nullptr) {\r
270 //         o\r
271 //           << ", "\r
272 //           << member->structMethod()->func()->parameter()->firstParameter()->var()->type()->getText()\r
273 //           << " "\r
274 //           << member->structMethod()->func()->parameter()->firstParameter()->var()->varName()->getText();\r
275 \r
276 //         for (auto * par : member->structMethod()->func()->parameter()->additionalParameter()) {\r
277 //           o\r
278 //             << ", "\r
279 //             << par->var()->type()->getText()\r
280 //             << " "\r
281 //             << par->var()->varName()->getText();\r
282 //         }\r
283 //       }\r
284 \r
285 //       out << ")\n{\n";\r
286 \r
287 //       toc(o, member->structMethod()->func()->body());\r
288 \r
289 //       out << "}\n";\r
290 //     }\r
291 //   }\r
292 // }\r
293 // void toc(std::ostream & o, TocParser::BodyContext * ctx) {\r
294 //   for (auto * stmt : ctx->stmt()) {\r
295 //     toc(o, stmt);\r
296 //     out << "\n";\r
297 //   }\r
298 // }\r
299 // void toc(std::ostream & o, TocParser::StmtContext * ctx) {\r
300 //   /**/ if (ctx->varDecl() != nullptr) toc(o, ctx->varDecl());\r
301 //   else if (ctx->conditional() != nullptr) toc(o, ctx->conditional()->ifCond());\r
302 //   else if (ctx->loop() != nullptr) toc(o, ctx->loop()->whileLoop());\r
303 //   else if (ctx->assignment() != nullptr) toc(o, ctx->assignment());\r
304 //   else if (ctx->returnStmt() != nullptr) toc(o, ctx->returnStmt());\r
305 //   else if (ctx->expr() != nullptr) toc(o, ctx->expr());\r
306 \r
307 //   if (ctx->conditional() == nullptr && ctx->loop() == nullptr)\r
308 //     out << ";";\r
309 // }\r
310 // void toc(std::ostream & o, TocParser::IfCondContext * ctx) {\r
311 //   out << "if (";\r
312 //   toc(o, ctx->expr());\r
313 //   out << ")\n{\n";\r
314 //   toc(o, ctx->body());\r
315 //   out << "}\n";\r
316 // }\r
317 // void toc(std::ostream & o, TocParser::WhileLoopContext * ctx) {\r
318 //   out << "while (";\r
319 //   toc(o, ctx->expr());\r
320 //   out << ")\n{\n";\r
321 //   toc(o, ctx->body());\r
322 //   out << "}\n";\r
323 // }\r
324 // void toc(std::ostream & o, TocParser::AssignmentContext * ctx) {\r
325 //   toc(o, ctx->identifier());\r
326 //   out << " = ";\r
327 //   toc(o, ctx->expr());\r
328 // }\r
329 // void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx) {\r
330 //   out << "return ";\r
331 //   toc(o, ctx->expr());\r
332 // }\r
333 // void toc(std::ostream & o, TocParser::ExprContext * ctx) {\r
334 //     /**/ if (ctx->funcCall()     != nullptr) toc(o, ctx->funcCall());\r
335 //     else if (ctx->identifier()   != nullptr) toc(o, ctx->identifier());\r
336 //     else if (ctx->literal()      != nullptr) toc(o, ctx->literal());\r
337 //     else if (ctx->subscript()    != nullptr) toc(o, ctx->subscript());\r
338 //     else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
339 //     else if (ctx->parenExpr()    != nullptr) toc(o, ctx->parenExpr());\r
340 //     else if (ctx->operatorExpr() != nullptr) toc(o, ctx->operatorExpr()->binaryOperator());\r
341 // }\r
342 // void toc(std::ostream & o, TocParser::NonOpExprContext * ctx) {\r
343 //     /**/ if (ctx->funcCall()     != nullptr) toc(o, ctx->funcCall());\r
344 //     else if (ctx->identifier()   != nullptr) toc(o, ctx->identifier());\r
345 //     else if (ctx->literal()      != nullptr) toc(o, ctx->literal());\r
346 //     else if (ctx->subscript()    != nullptr) toc(o, ctx->subscript());\r
347 //     else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
348 //     else if (ctx->parenExpr()    != nullptr) toc(o, ctx->parenExpr());\r
349 // }\r
350 // void toc(std::ostream & o, TocParser::NonSubscriptExprContext * ctx) {\r
351 //     /**/ if (ctx->funcCall()     != nullptr) toc(o, ctx->funcCall());\r
352 //     else if (ctx->identifier()   != nullptr) toc(o, ctx->identifier());\r
353 //     else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
354 //     else if (ctx->parenExpr()    != nullptr) toc(o, ctx->parenExpr());\r
355 // }\r
356 // void toc(std::ostream & o, TocParser::FuncCallContext * ctx) {\r
357 //   o\r
358 //     << ctx->funcName()->getText()\r
359 //     << "(";\r
360 //   for (int i = 0; i < ctx->expr().size(); i++) {\r
361 //     if (i != 0) out << ", ";\r
362 //     toc(o, ctx->expr(i));\r
363 //   }\r
364 //   out << ")";\r
365 // }\r
366 // void toc(std::ostream & o, TocParser::IdentifierContext * ctx) {\r
367 //   out << ctx->getText();\r
368 // }\r
369 // void toc(std::ostream & o, TocParser::LiteralContext * ctx) {\r
370 //   if (ctx->INTLIT() != nullptr) out << ctx->INTLIT()->getText();\r
371 // }\r
372 // void toc(std::ostream & o, TocParser::SubscriptContext * ctx) {\r
373 //   toc(o, ctx->nonSubscriptExpr());\r
374 //   out << "[";\r
375 //   toc(o, ctx->expr());\r
376 //   out << "]";\r
377 // }\r
378 // void toc(std::ostream & o, TocParser::MemberAccessContext * ctx) {\r
379 //   toc(o, ctx->identifier(0));\r
380 //   out << ".";\r
381 //   toc(o, ctx->identifier(1));\r
382 // }\r
383 // void toc(std::ostream & o, TocParser::ParenExprContext * ctx) {\r
384 //   out << "(";\r
385 //   toc(o, ctx->expr());\r
386 //   out << ")";\r
387 // }\r
388 // void toc(std::ostream & o, TocParser::BinaryOperatorContext * ctx) {\r
389 //   for (int i = 0; i < ctx->BINARY_OPERATOR().size(); i++) {\r
390 //     toc(o, ctx->nonOpExpr(i));\r
391 //     o\r
392 //       << " "\r
393 //       << ctx->BINARY_OPERATOR(i)->getText()\r
394 //       << " ";\r
395 //     toc(o, ctx->nonOpExpr(i + 1));\r
396 //   }\r
397 // }\r
398 \r
399 // void toc_stub(std::ostream & o, TocParser::FuncContext * ctx) {\r
400 //   o\r
401 //     << ctx->type()->getText()\r
402 //     << " "\r
403 //     << ctx->funcName()->getText()\r
404 //     << "(";\r
405 \r
406 //   if (ctx->parameter()->firstParameter() != nullptr) {\r
407 //     o\r
408 //       << ctx->parameter()->firstParameter()->var()->type()->getText()\r
409 //       << " "\r
410 //       << ctx->parameter()->firstParameter()->var()->varName()->getText();\r
411 \r
412 //     for (auto * par : ctx->parameter()->additionalParameter()) {\r
413 //       o\r
414 //         << ", "\r
415 //         << par->var()->type()->getText()\r
416 //         << " "\r
417 //         << par->var()->varName()->getText();\r
418 //     }\r
419 //   }\r
420 \r
421 //   out << ");\n";\r
422 // }\r
423 // void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx) {\r
424 //   o\r
425 //     << "struct "\r
426 //     << ctx->structName()->getText()\r
427 //     << ";\n";\r
428 // }\r