/** ** \file ast/pretty-printer.cc ** \brief Implementation of ast::PrettyPrinter. */ #include #include #include #include #include #include #include namespace ast { // Anonymous namespace: these functions are private to this file. namespace { /// Output \a e on \a ostr. inline std::ostream& operator<<(std::ostream& ostr, const Escapable& e) { if (escapes_display(ostr) // FIXME DONE: Some code was deleted here. && e.escape_get()) ostr << "/* escaping */ "; return ostr; } /// \brief Output \a e on \a ostr. /// /// Used to factor the output of the name declared, /// and its possible additional attributes. inline std::ostream& operator<<(std::ostream& ostr, const Dec& e) { ostr << e.name_get(); if (bindings_display(ostr)) ostr << " /* " << &e << " */"; return ostr; } } // namespace PrettyPrinter::PrettyPrinter(std::ostream& ostr) : ostr_(ostr) {} void PrettyPrinter::operator()(const SimpleVar& e) { ostr_ << e.name_get(); if (bindings_display(ostr_)) ostr_ << " /* " << e.def_get() << " */"; } void PrettyPrinter::operator()(const FieldVar& e) { // FIXME DONE: Some code was deleted here. ostr_ << e.var_get() << "." << e.name_get(); } /* Foo[10]. */ void PrettyPrinter::operator()(const SubscriptVar& e) { ostr_ << e.var_get() << '[' << misc::incindent << e.index_get() << misc::decindent << ']'; } void PrettyPrinter::operator()(const CastExp& e) { ostr_ << "_cast(" << e.exp_get() << ", " << e.ty_get() << ')'; } // FIXME DONE: Some code was deleted here. void PrettyPrinter::operator()(const NilExp&) { ostr_ << "nil"; } void PrettyPrinter::operator()(const IntExp& e) { ostr_ << e.value_get(); } void PrettyPrinter::operator()(const StringExp& e) { ostr_ << "\"" << misc::escape(e.value_get()) << "\""; } void PrettyPrinter::operator()(const ObjectExp& e) { ostr_ << "new " << e.type_name_get(); if (bindings_display(ostr_)) ostr_ << " /* " << &e.type_name_get() << " */"; } void PrettyPrinter::operator()(const CallExp& e) { ostr_ << e.name_get(); if (bindings_display(ostr_)) ostr_ << " /* " << e.def_get() << " */"; ostr_ << "("; if (!e.args_get().empty()) { ostr_ << misc::separate(e.args_get(), ", "); } ostr_ << ")"; } void PrettyPrinter::operator()(const MethodCallExp& e) { ostr_ << e.object_get() << "." << e.name_get(); if (bindings_display(ostr_)) ostr_ << " /* " << e.def_get() << " */"; ostr_ << "("; if (!e.args_get().empty()) { ostr_ << misc::separate(e.args_get(), ", "); } ostr_ << ")"; } void PrettyPrinter::operator()(const OpExp& e) { ostr_ << e.left_get() << " " << str(e.oper_get()) << " " << e.right_get(); } void PrettyPrinter::operator()(const RecordExp& e) { ostr_ << e.type_name_get(); ostr_ << " { "; if (!e.fields_get().empty()) { ostr_ << misc::separate(e.fields_get(), ", "); } ostr_ << " }"; } void PrettyPrinter::operator()(const RecordTy& e) { ostr_ << "{ "; if (!e.fields_get().empty()) { ostr_ << misc::separate(e.fields_get(), ", "); } ostr_ << " }"; } void PrettyPrinter::operator()(const ArrayTy& e) { ostr_ << "array of " << e.base_type_get(); } void PrettyPrinter::operator()(const ClassTy& e) { ostr_ << "class extends " << e.super_get() << "{" << misc::decendl; if (!e.chunks_get().chunks_get().empty()) { ostr_ << misc::separate(e.chunks_get(), "\n"); } ostr_ << " }" << misc::decendl; } void PrettyPrinter::operator()(const Field& e) { ostr_ << e.name_get() << " : " << e.type_name_get(); } void PrettyPrinter::operator()(const SeqExp& e) { if (e.exps_get().size() == 0) ostr_ << "()"; else if (e.exps_get().size() == 1) ostr_ << *e.exps_get().at(0); else if (e.exps_get().size() > 1) { ostr_ << '(' << misc::incendl << *e.exps_get().at(0); for (size_t i = 1; i < e.exps_get().size(); ++i) { ostr_ << ";" << misc::iendl << *e.exps_get().at(i); } ostr_ << misc::decendl << ")"; } } void PrettyPrinter::operator()(const AssignExp& e) { ostr_ << e.var_get() << " := " << e.exp_get(); } void PrettyPrinter::operator()(const IfExp& e) { ostr_ << "(if " << e.test_get() << " then" << misc::incendl << e.thenclause_get() << misc::decendl; ostr_ << "else" << misc::incendl << e.elseclause_get() << ")" << misc::decendl; } void PrettyPrinter::operator()(const WhileExp& e) { ostr_ << "(while "; if (bindings_display(ostr_)) { ostr_ << "/* " << &e << " /* "; } ostr_ << e.test_get() << " do" << misc::incendl << e.body_get() << ")" << misc::decendl; } void PrettyPrinter::operator()(const ForExp& e) { ostr_ << "(for "; if (bindings_display(ostr_)) { ostr_ << "/* " << &e << " */ "; } ostr_ << e.vardec_get().name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &e.vardec_get() << " */"; } ostr_ << " := " << *e.vardec_get().init_get() << " to " << e.hi_get() << " do" << misc::incendl << e.body_get() << ")"; } void PrettyPrinter::operator()(const BreakExp& e) { ostr_ << "break"; if (bindings_display(ostr_)) { ostr_ << " /* " << e.def_get() << " */"; } } void PrettyPrinter::operator()(const LetExp& e) { ostr_ << "let" << misc::incendl << e.chunks_get() << misc::decendl << "in" << misc::incendl << e.body_get() << misc::decendl << "end"; } void PrettyPrinter::operator()(const ArrayExp& e) { ostr_ << e.type_name_get() << "[" << e.size_get() << "] of " << e.init_get(); } void PrettyPrinter::operator()(const FieldInit& e) { ostr_ << e.name_get() << " = " << e.init_get(); } void PrettyPrinter::operator()(const VarChunk& e) { for (auto dec : e.decs_get()) { dec->accept(*this); ostr_ << misc::iendl; } } void PrettyPrinter::operator()(const VarDec& e) { ostr_ << "var " << static_cast(e) << e.name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &e << " */"; } if (e.type_name_get() != nullptr) ostr_ << " : " << *e.type_name_get(); if (e.init_get() != nullptr) ostr_ << " := " << *e.init_get(); else ostr_ << " := 0"; } void PrettyPrinter::operator()(const TypeChunk& e) { for (auto dec : e.decs_get()) { dec->accept(*this); ostr_ << misc::iendl; } } void PrettyPrinter::operator()(const TypeDec& e) { if (const auto c = dynamic_cast(&e.ty_get()); c) { ostr_ << "class " << e.name_get(); if (bindings_display(ostr_)) ostr_ << " /* " << &e << " */"; ostr_ << " extends " << c->super_get() << misc::iendl << "{" << misc::incendl; if (!c->chunks_get().chunks_get().empty()) { ostr_ << misc::separate(c->chunks_get(), "\n"); } ostr_ << misc::decendl << "}"; } else { ostr_ << "type " << e.name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &e << " */"; } ostr_ << " = " << e.ty_get(); } } void PrettyPrinter::operator()(const NameTy& e) { ostr_ << e.name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << e.def_get() << " */"; } } void PrettyPrinter::operator()(const FunctionChunk& e) { for (auto dec : e.decs_get()) { dec->accept(*this); ostr_ << misc::iendl; } } void PrettyPrinter::operator()(const FunctionDec& e) { if (e.body_get() == nullptr) ostr_ << "primitive "; else ostr_ << "function "; ostr_ << e.name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &e << " */"; } ostr_ << "("; auto decs = e.formals_get().decs_get(); if (!decs.empty()) { ostr_ << static_cast(*decs.at(0)) << decs.at(0)->name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &decs.at(0) << " */"; } ostr_ << " : " << *decs.at(0)->type_name_get(); for (size_t i = 1; i < decs.size(); ++i) { ostr_ << ", " << static_cast(*decs.at(i)) << decs.at(i)->name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &decs.at(i) << " */"; } ostr_ << " : " << *decs.at(i)->type_name_get(); } } ostr_ << ")"; if (e.result_get() != nullptr) { ostr_ << " : " << *e.result_get(); } if (e.body_get() != nullptr) { ostr_ << " =" << misc::incendl << *e.body_get() << misc::decindent; } ostr_ << misc::iendl; } void PrettyPrinter::operator()(const MethodChunk& e) { for (auto dec : e.decs_get()) { dec->accept(*this); ostr_ << misc::iendl; } } void PrettyPrinter::operator()(const MethodDec& e) { ostr_ << "method " << e.name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &e << " */"; } ostr_ << "("; auto decs = e.formals_get().decs_get(); if (!decs.empty()) { ostr_ << static_cast(*decs.at(0)) << decs.at(0)->name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &decs.at(0) << " */"; } ostr_ << " : " << *decs.at(0)->type_name_get(); for (size_t i = 1; i < decs.size(); ++i) { ostr_ << ", " << static_cast(*decs.at(i)) << decs.at(i)->name_get(); if (bindings_display(ostr_)) { ostr_ << " /* " << &decs.at(i) << " */"; } ostr_ << " : " << *decs.at(i)->type_name_get(); } } ostr_ << ")"; if (e.result_get() != nullptr) { ostr_ << " : " << *e.result_get(); } if (e.body_get() != nullptr) { ostr_ << " =" << misc::incendl << *e.body_get() << misc::decindent; } ostr_ << misc::iendl; } void PrettyPrinter::operator()(const AssertExp& e) { ostr_ << "assert " << e.cond_get(); } } // namespace ast