9 std::ostream & operator<< (std::ostream & out, const std::vector<T> & v) {
\r
12 if (comma) out << ", ";
\r
19 std::ostream & operator<< (std::ostream & out, const Type & t);
\r
20 std::ostream & operator<< (std::ostream & out, const Variable & v);
\r
21 std::ostream & operator<< (std::ostream & out, const Body & b);
\r
22 std::ostream & operator<< (std::ostream & out, const UnaryOperatorExpr & o);
\r
23 std::ostream & operator<< (std::ostream & out, const BinaryOperatorExpr & o);
\r
24 std::ostream & operator<< (std::ostream & out, const TernaryOperatorExpr & o);
\r
25 std::ostream & operator<< (std::ostream & out, const Expr & e);
\r
26 std::ostream & operator<< (std::ostream & out, const Stmt & s);
\r
28 void tocFunction (std::ostream & out, const Function & f, bool stub);
\r
29 void tocStruct (std::ostream & out, const Struct & s, bool stub);
\r
30 void tocProgram (std::ostream & out, const Program & p);
\r
32 static const int TAB_WIDTH = 2;
\r
33 static int indentation = 0;
\r
34 static void indent(std::ostream & out, int change = 0) {
\r
35 indentation += change;
\r
36 out << std::string(indentation, ' ');
\r
39 std::ostream & operator<< (std::ostream & out, const Type & t) {
\r
44 std::ostream & operator<< (std::ostream & out, const Variable & v) {
\r
45 out << v.type << " ";
\r
47 std::stringstream sstr;
\r
48 std::string s = v.name;
\r
50 for (auto m = v.type.modifiers.rbegin(); m != v.type.modifiers.rend(); m++) {
\r
51 if (m->type == TypeModifierType::Pointer) {
\r
52 sstr.str(std::string());
\r
53 sstr << "*(" << s << ")";
\r
57 sstr.str(std::string());
\r
58 sstr << "(" << s << ")[";
\r
59 if (m->_staticArray)
\r
60 sstr << m->_arraySize;
\r
69 std::ostream & operator<< (std::ostream & out, const Body & b) {
\r
74 for (auto v : b.variables) {
\r
81 for (auto s : b.statements) {
\r
91 std::ostream & operator<< (std::ostream & out, const UnaryOperatorExpr & o) {
\r
92 if (o.type == UnaryOperatorType::IncrementPost || o.type == UnaryOperatorType::DecrementPost) {
\r
93 out << UnaryOperatorTypeStrings[(int)o.type] << *o.expr;
\r
96 out << *o.expr << UnaryOperatorTypeStrings[(int)o.type];
\r
101 std::ostream & operator<< (std::ostream & out, const BinaryOperatorExpr & o) {
\r
102 out << *o.lexpr << " " << BinaryOperatorTypeStrings[(int)o.type] << " " << *o.rexpr;
\r
106 std::ostream & operator<< (std::ostream & out, const TernaryOperatorExpr & o) {
\r
107 out << *o.lexpr << " ? " << *o.rexprTrue << " : " << *o.rexprFalse;
\r
111 std::ostream & operator<< (std::ostream & out, const Expr & e) {
\r
112 if (e.parenthesized)
\r
116 case ExprType::Func:
\r
117 out << e._func.functionName << "(" << e._func.arguments << ")"; break;
\r
118 case ExprType::Lit:
\r
119 /**/ if (e._lit.type == LitType::Int) out << e._lit._int;
\r
120 else if (e._lit.type == LitType::Decimal) out << e._lit._decimal;
\r
121 else if (e._lit.type == LitType::String) out << e._lit._string;
\r
122 else if (e._lit.type == LitType::Bool) out << e._lit._bool;
\r
124 case ExprType::Identifier:
\r
125 out << e._identifier.name; break;
\r
126 case ExprType::Brackets:
\r
127 out << *e._brackets.lexpr << "[" << *e._brackets.rexpr << "]"; break;
\r
128 case ExprType::Dot:
\r
129 out << *e._dot.expr << "." << e._dot.ident.name; break;
\r
130 case ExprType::UnaryOperator:
\r
131 out << e._unaryOperator; break;
\r
132 case ExprType::BinaryOperator:
\r
133 out << e._binaryOperator; break;
\r
134 case ExprType::TernaryOperator:
\r
135 out << e._ternaryOperator; break;
\r
138 if (e.parenthesized)
\r
143 std::ostream & operator<< (std::ostream & out, const Stmt & s) {
\r
146 out << "if (" << s._if.condition << ")\n" << s._if.body; break;
\r
147 case StmtType::Switch:
\r
148 out << "switch (" << s._switch.ident.name << ")\n{\n";
\r
149 for (auto c : s._switch.cases) {
\r
151 out << "case " << *c.expr << ": " << c.body << "break;";
\r
156 case StmtType::For:
\r
158 s._for.varName << " = " << *s._for.initValue << "; " <<
\r
159 *s._for.condition << "; " <<
\r
161 ")\n" << s._for.body; break;
\r
162 case StmtType::While:
\r
163 out << "while (" << s._while.condition << ")\n" << s._while.body; break;
\r
164 case StmtType::Assign:
\r
165 out << s._assign.name << " = " << s._assign.expr << ";"; break;
\r
166 case StmtType::Return:
\r
167 out << "return " << s._return.expr << ";"; break;
\r
168 case StmtType::Expr:
\r
169 out << s._expr << ";"; break;
\r
176 void tocFunction (std::ostream & out, const Function & f, bool stub) {
\r
177 out << f.returnType << " " << f.name << " (" << f.parameters << ")";
\r
183 out << "\n" << f.body;
\r
186 void tocStruct (std::ostream & out, const Struct & s, bool stub) {
\r
187 out << "struct " << s.name;
\r
190 for (auto m : s.methods) {
\r
191 m.parameters.insert(m.parameters.begin(), {"this", {s.name, {{TypeModifierType::Pointer, false, -1}}}});
\r
192 out << m.returnType << " " <<
\r
193 s.name << "_" << m.name <<
\r
194 " (" << m.parameters << ");\n";
\r
201 for (auto m : s.members) {
\r
209 for (auto m : s.methods) {
\r
210 m.parameters.insert(m.parameters.begin(), {"this", {s.name, {{TypeModifierType::Pointer, false, -1}}}});
\r
211 out << m.returnType << " " << s.name << "_" << m.name << " (" << m.parameters << ")\n" << m.body;
\r
214 void tocProgram (std::ostream & out, const Program & p) {
\r
215 for (auto s : p.structs) {
\r
216 tocStruct(out, s, true);
\r
218 for (auto f : p.functions) {
\r
219 tocFunction(out, f, true);
\r
222 for (auto v : p.variables) {
\r
225 for (auto s : p.structs) {
\r
226 tocStruct(out, s, false);
\r
228 for (auto f : p.functions) {
\r
229 tocFunction(out, f, false);
\r