8 std::ostream & operator<< (std::ostream & out, const std::vector<T> & v) {
\r
11 if (comma) out << ", ";
\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
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
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
38 std::ostream & operator<< (std::ostream & out, const Type & t) {
\r
43 std::ostream & operator<< (std::ostream & out, const Variable & v) {
\r
44 out << v.type << " " << v.name;
\r
48 std::ostream & operator<< (std::ostream & out, const Body & b) {
\r
53 for (auto v : b.variables) {
\r
60 for (auto s : b.statements) {
\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
75 out << *o.expr << UnaryOperatorTypeStrings[(int)o.type];
\r
80 std::ostream & operator<< (std::ostream & out, const BinaryOperatorExpr & o) {
\r
81 out << *o.lexpr << " " << BinaryOperatorTypeStrings[(int)o.type] << " " << *o.rexpr;
\r
85 std::ostream & operator<< (std::ostream & out, const TernaryOperatorExpr & o) {
\r
86 out << *o.lexpr << " ? " << *o.rexprTrue << " : " << *o.rexprFalse;
\r
90 std::ostream & operator<< (std::ostream & out, const Expr & e) {
\r
92 case ExprType::Func:
\r
93 out << e._func.functionName << "(" << e._func.arguments << ")"; break;
\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
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
116 std::ostream & operator<< (std::ostream & out, const Stmt & s) {
\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
124 out << "case " << *c.expr << ": " << c.body << "break;";
\r
129 case StmtType::For:
\r
131 s._for.varName << " = " << *s._for.initValue << "; " <<
\r
132 *s._for.condition << "; " <<
\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
149 void tocFunction (std::ostream & out, const Function & f, bool stub) {
\r
150 out << f.returnType << " " << f.name << " (" << f.parameters << ")";
\r
156 out << "\n" << f.body;
\r
159 void tocStruct (std::ostream & out, const Struct & s, bool stub) {
\r
160 out << "struct " << s.name;
\r
163 for (auto m : s.methods) {
\r
164 out << m.returnType << " " << s.name << "_" << m.name << " (" << m.parameters << ");\n";
\r
171 for (auto m : s.members) {
\r
179 for (auto m : s.methods) {
\r
180 out << m.returnType << " " << s.name << "_" << m.name << " (" << m.parameters << ")\n" << m.body;
\r
183 void tocProgram (std::ostream & out, const Program & p) {
\r
184 for (auto s : p.structs) {
\r
185 tocStruct(out, s, true);
\r
187 for (auto s : p.structs) {
\r
188 tocStruct(out, s, false);
\r
191 for (auto v : p.variables) {
\r
195 for (auto f : p.functions) {
\r
196 tocFunction(out, f, true);
\r
198 for (auto f : p.functions) {
\r
199 tocFunction(out, f, false);
\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
211 // for (auto * decl : ctx->decl()) {
\r
212 // if (decl->varDecl() != nullptr) {
\r
213 // toc(o, decl->varDecl());
\r
216 // else if (decl->structDecl() != nullptr) toc(o, decl->structDecl());
\r
217 // else if (decl->funcDecl() != nullptr) toc(o, decl->funcDecl()->func());
\r
220 // void toc(std::ostream & o, TocParser::VarDeclContext * ctx) {
\r
222 // << ctx->var()->type()->getText()
\r
224 // << ctx->var()->varName()->getText();
\r
226 // if (ctx->var()->expr() != nullptr) {
\r
228 // toc(o, ctx->var()->expr());
\r
231 // void toc(std::ostream & o, TocParser::FuncContext * ctx) {
\r
233 // << ctx->type()->getText()
\r
235 // << ctx->funcName()->getText()
\r
238 // if (ctx->parameter()->firstParameter() != nullptr) {
\r
240 // << ctx->parameter()->firstParameter()->var()->type()->getText()
\r
242 // << ctx->parameter()->firstParameter()->var()->varName()->getText();
\r
244 // for (auto * par : ctx->parameter()->additionalParameter()) {
\r
247 // << par->var()->type()->getText()
\r
249 // << par->var()->varName()->getText();
\r
253 // out << ")\n{\n";
\r
255 // toc(o, ctx->body());
\r
259 // void toc(std::ostream & o, TocParser::StructDeclContext * ctx) {
\r
261 // << "typedef struct "
\r
262 // << ctx->structName()->getText()
\r
265 // for (auto * member : ctx->structMember()) {
\r
266 // if (member->structVar() != nullptr) {
\r
268 // << member->structVar()->var()->type()->getText()
\r
270 // << member->structVar()->var()->varName()->getText()
\r
275 // << ctx->structName()->getText()
\r
277 // for (auto * member : ctx->structMember()) {
\r
278 // if (member->structMethod() != nullptr) {
\r
280 // << member->structMethod()->func()->type()->getText()
\r
282 // << ctx->structName()->getText()
\r
284 // << member->structMethod()->func()->funcName()->getText()
\r
286 // << ctx->structName()->getText()
\r
289 // if (member->structMethod()->func()->parameter()->firstParameter() != nullptr) {
\r
292 // << member->structMethod()->func()->parameter()->firstParameter()->var()->type()->getText()
\r
294 // << member->structMethod()->func()->parameter()->firstParameter()->var()->varName()->getText();
\r
296 // for (auto * par : member->structMethod()->func()->parameter()->additionalParameter()) {
\r
299 // << par->var()->type()->getText()
\r
301 // << par->var()->varName()->getText();
\r
305 // out << ")\n{\n";
\r
307 // toc(o, member->structMethod()->func()->body());
\r
313 // void toc(std::ostream & o, TocParser::BodyContext * ctx) {
\r
314 // for (auto * stmt : ctx->stmt()) {
\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
327 // if (ctx->conditional() == nullptr && ctx->loop() == nullptr)
\r
330 // void toc(std::ostream & o, TocParser::IfCondContext * ctx) {
\r
332 // toc(o, ctx->expr());
\r
333 // out << ")\n{\n";
\r
334 // toc(o, ctx->body());
\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
344 // void toc(std::ostream & o, TocParser::AssignmentContext * ctx) {
\r
345 // toc(o, ctx->identifier());
\r
347 // toc(o, ctx->expr());
\r
349 // void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx) {
\r
350 // out << "return ";
\r
351 // toc(o, ctx->expr());
\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
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
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
376 // void toc(std::ostream & o, TocParser::FuncCallContext * ctx) {
\r
378 // << ctx->funcName()->getText()
\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
386 // void toc(std::ostream & o, TocParser::IdentifierContext * ctx) {
\r
387 // out << ctx->getText();
\r
389 // void toc(std::ostream & o, TocParser::LiteralContext * ctx) {
\r
390 // if (ctx->INTLIT() != nullptr) out << ctx->INTLIT()->getText();
\r
392 // void toc(std::ostream & o, TocParser::SubscriptContext * ctx) {
\r
393 // toc(o, ctx->nonSubscriptExpr());
\r
395 // toc(o, ctx->expr());
\r
398 // void toc(std::ostream & o, TocParser::MemberAccessContext * ctx) {
\r
399 // toc(o, ctx->identifier(0));
\r
401 // toc(o, ctx->identifier(1));
\r
403 // void toc(std::ostream & o, TocParser::ParenExprContext * ctx) {
\r
405 // toc(o, ctx->expr());
\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
413 // << ctx->BINARY_OPERATOR(i)->getText()
\r
415 // toc(o, ctx->nonOpExpr(i + 1));
\r
419 // void toc_stub(std::ostream & o, TocParser::FuncContext * ctx) {
\r
421 // << ctx->type()->getText()
\r
423 // << ctx->funcName()->getText()
\r
426 // if (ctx->parameter()->firstParameter() != nullptr) {
\r
428 // << ctx->parameter()->firstParameter()->var()->type()->getText()
\r
430 // << ctx->parameter()->firstParameter()->var()->varName()->getText();
\r
432 // for (auto * par : ctx->parameter()->additionalParameter()) {
\r
435 // << par->var()->type()->getText()
\r
437 // << par->var()->varName()->getText();
\r
443 // void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx) {
\r
446 // << ctx->structName()->getText()
\r