diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/ast/pretty-printer.cc | |
Diffstat (limited to 'tiger-compiler/src/ast/pretty-printer.cc')
| -rw-r--r-- | tiger-compiler/src/ast/pretty-printer.cc | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/tiger-compiler/src/ast/pretty-printer.cc b/tiger-compiler/src/ast/pretty-printer.cc new file mode 100644 index 0000000..91dbc87 --- /dev/null +++ b/tiger-compiler/src/ast/pretty-printer.cc @@ -0,0 +1,419 @@ +/** + ** \file ast/pretty-printer.cc + ** \brief Implementation of ast::PrettyPrinter. + */ + +#include <ast/all.hh> +#include <ast/libast.hh> +#include <ast/pretty-printer.hh> +#include <misc/escape.hh> +#include <misc/indent.hh> +#include <misc/separator.hh> + +#include <type/class.hh> + +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<Escapable>(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<const ClassTy*>(&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<Escapable>(*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<Escapable>(*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<Escapable>(*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<Escapable>(*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 |
