diff --git a/xo-expression/include/xo/expression/Apply.hpp b/xo-expression/include/xo/expression/Apply.hpp index 00e418da..556c2560 100644 --- a/xo-expression/include/xo/expression/Apply.hpp +++ b/xo-expression/include/xo/expression/Apply.hpp @@ -101,6 +101,7 @@ namespace xo { virtual void attach_envs(bp p) override; virtual void display(std::ostream & os) const override; + virtual std::uint32_t pretty_print(ppstate * pps, bool upto) const override; private: Apply(TypeDescr apply_valuetype, diff --git a/xo-expression/include/xo/expression/DefineExpr.hpp b/xo-expression/include/xo/expression/DefineExpr.hpp index 2f7ecfa7..c950c48b 100644 --- a/xo-expression/include/xo/expression/DefineExpr.hpp +++ b/xo-expression/include/xo/expression/DefineExpr.hpp @@ -76,6 +76,7 @@ namespace xo { } virtual void display(std::ostream & os) const override; + virtual std::uint32_t pretty_print(ppstate * pps, bool upto) const override; protected: /** diff --git a/xo-expression/include/xo/expression/GeneralizedExpression.hpp b/xo-expression/include/xo/expression/GeneralizedExpression.hpp index 7866284e..a0822a09 100644 --- a/xo-expression/include/xo/expression/GeneralizedExpression.hpp +++ b/xo-expression/include/xo/expression/GeneralizedExpression.hpp @@ -8,7 +8,6 @@ #include "xo/refcnt/Refcounted.hpp" #include "xo/reflect/TypeDescr.hpp" #include "exprtype.hpp" -//#include namespace xo { namespace ast { @@ -22,6 +21,7 @@ namespace xo { class GeneralizedExpression : public ref::Refcount { public: using TypeDescr = xo::reflect::TypeDescr; + using ppstate = xo::print::ppstate; public: GeneralizedExpression(exprtype extype, TypeDescr valuetype) @@ -34,6 +34,8 @@ namespace xo { virtual void display(std::ostream & os) const = 0; /** human-readable string representation **/ virtual std::string display_string() const; + /** pretty printing support. See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + virtual std::uint32_t pretty_print(ppstate * pps, bool upto) const; protected: /** useful when scaffolding expressions in a parser **/ diff --git a/xo-expression/include/xo/expression/Lambda.hpp b/xo-expression/include/xo/expression/Lambda.hpp index 41a5fdce..cfc94b58 100644 --- a/xo-expression/include/xo/expression/Lambda.hpp +++ b/xo-expression/include/xo/expression/Lambda.hpp @@ -98,6 +98,7 @@ namespace xo { virtual void attach_envs(bp p) override; virtual void display(std::ostream & os) const override; + virtual std::uint32_t pretty_print(ppstate * pps, bool upto) const override; protected: /** create type description for lambda with arguments @p argv diff --git a/xo-expression/include/xo/expression/LocalEnv.hpp b/xo-expression/include/xo/expression/LocalEnv.hpp index a66efa49..9f883e20 100644 --- a/xo-expression/include/xo/expression/LocalEnv.hpp +++ b/xo-expression/include/xo/expression/LocalEnv.hpp @@ -103,6 +103,12 @@ namespace xo { }; } /*namespace ast*/ + +#ifndef ppdetail_atomic + namespace print { + PPDETAIL_ATOMIC(xo::ast::LocalEnv); + } +#endif } /*namespace xo*/ diff --git a/xo-expression/include/xo/expression/Sequence.hpp b/xo-expression/include/xo/expression/Sequence.hpp index ce17a72c..243c4057 100644 --- a/xo-expression/include/xo/expression/Sequence.hpp +++ b/xo-expression/include/xo/expression/Sequence.hpp @@ -38,6 +38,7 @@ namespace xo { // ----- from GeneralizedExpression ---- virtual void display(std::ostream & os) const override; + virtual std::uint32_t pretty_print(ppstate * pps, bool upto) const override; private: /** sequence of expressions; evaluate in left-to-right order. diff --git a/xo-expression/src/expression/Apply.cpp b/xo-expression/src/expression/Apply.cpp index 631a2693..440601c7 100644 --- a/xo-expression/src/expression/Apply.cpp +++ b/xo-expression/src/expression/Apply.cpp @@ -2,7 +2,9 @@ #include "Apply.hpp" #include "Primitive.hpp" +#include "exprtype.hpp" #include "xo/indentlog/print/vector.hpp" +#include namespace xo { namespace ast { @@ -73,6 +75,43 @@ namespace xo { << xtag("argv", argv_) << ">"; } + + std::uint32_t + Apply::pretty_print(ppstate * pps, bool upto) const + { + if (upto) { + std::uint32_t saved = pps->pos(); + + if (!pps->has_margin()) + return false; + + if (!pps->print_upto("print_upto(xtag("fn", fn_))) + return false; + + if (!pps->print_upto(xtag("argv", argv_))) + return false; + + return pps->scan_no_newline(saved); + } else { + std::uint32_t ci0 = pps->lpos(); + std::uint32_t ci1 = ci0 + pps->indent_width(); + + pps->write("newline_indent(ci1); + pps->pretty(xtag("fn", fn_)); + + pps->newline_indent(ci1); + pps->pretty(xtag("argv", argv_)); + pps->write(">"); + + return false; + } + } + } /*namespace ast*/ } /*namespace xo*/ diff --git a/xo-expression/src/expression/DefineExpr.cpp b/xo-expression/src/expression/DefineExpr.cpp index e9b15b2d..cc7787be 100644 --- a/xo-expression/src/expression/DefineExpr.cpp +++ b/xo-expression/src/expression/DefineExpr.cpp @@ -5,6 +5,9 @@ #include "DefineExpr.hpp" #include "Variable.hpp" +#include "pretty_expression.hpp" +#include "xo/indentlog/print/pretty_tag.hpp" +#include namespace xo { namespace ast { @@ -61,6 +64,42 @@ namespace xo { << ">"; } /*display*/ + std::uint32_t + DefineExpr::pretty_print(ppstate * pps, bool upto) const + { + if (upto) { + std::uint32_t saved = pps->pos(); + + if (!pps->has_margin()) + return false; + + if (!pps->print_upto("print_upto(xtag("name", lhs_name_))) + return false; + + if (!pps->print_upto(xtag("rhs", rhs_))) + return false; + + return pps->scan_no_newline(saved); + } else { + std::uint32_t ci0 = pps->lpos(); + std::uint32_t ci1 = ci0 + pps->indent_width(); + + pps->write("newline_indent(ci1); + pps->pretty(xtag("name", lhs_name_)); + + pps->newline_indent(ci1); + pps->pretty(xtag("rhs", rhs_)); + pps->write(">"); + + return false; + } + } + // ----- DefineExprAccess ----- rp diff --git a/xo-expression/src/expression/GeneralizedExpression.cpp b/xo-expression/src/expression/GeneralizedExpression.cpp index 6239f700..2cc79655 100644 --- a/xo-expression/src/expression/GeneralizedExpression.cpp +++ b/xo-expression/src/expression/GeneralizedExpression.cpp @@ -1,6 +1,8 @@ /* @file GeneralizedExpression.cpp */ #include "GeneralizedExpression.hpp" +#include "pretty_expression.hpp" +#include namespace xo { namespace ast { @@ -8,6 +10,20 @@ namespace xo { GeneralizedExpression::display_string() const { return tostr(*this); } + + std::uint32_t + GeneralizedExpression::pretty_print(ppstate * pps, bool upto) const { + // Slooooow fallback for subtypes that don't implement pretty printing support + // Currently have support for: + // - Lambda + + std::uint32_t saved = pps->pos(); + pps->write(display_string()); + if (upto && !pps->has_margin()) + return false; + + return upto ? pps->scan_no_newline(saved) : true; + } } /*namespace ast*/ } /*namespace xo*/ diff --git a/xo-expression/src/expression/Lambda.cpp b/xo-expression/src/expression/Lambda.cpp index 67cfd545..2f24a9d0 100644 --- a/xo-expression/src/expression/Lambda.cpp +++ b/xo-expression/src/expression/Lambda.cpp @@ -1,9 +1,13 @@ /* @file Lambda.cpp */ #include "Lambda.hpp" +#include "exprtype.hpp" +#include "pretty_expression.hpp" #include "xo/reflect/TypeDescr.hpp" #include "xo/reflect/function/FunctionTdx.hpp" #include "xo/indentlog/print/vector.hpp" +#include "xo/indentlog/print/pretty_vector.hpp" +#include "xo/indentlog/print/pretty_tag.hpp" #include #include @@ -317,6 +321,50 @@ namespace xo { << ">"; } /*display*/ + std::uint32_t + Lambda::pretty_print(ppstate * pps, bool upto) const + { + if (upto) { + std::uint32_t saved = pps->pos(); + + if (!pps->has_margin()) + return false; + + if (!pps->print_upto("print_upto(xtag("name", name_))) + return false; + + if (!pps->print_upto(xtag("argv", local_env_->argv()))) + return false; + + if (!pps->print_upto(xtag("body", body_))) + return false; + + pps->write(">"); + + return pps->scan_no_newline(saved); + } else { + std::uint32_t ci0 = pps->lpos(); + std::uint32_t ci1 = ci0 + pps->indent_width(); + + pps->write("newline_indent(ci1); + pps->pretty(xtag("name", name_)); + + pps->newline_indent(ci1); + pps->pretty(xtag("argv", local_env_->argv())); + + pps->newline_indent(ci1); + pps->pretty(xtag("body", body_)); + pps->write(">"); + + return false; + } + } + // ----- Lambda Access ----- rp diff --git a/xo-expression/src/expression/Sequence.cpp b/xo-expression/src/expression/Sequence.cpp index 37e1dafd..a9812867 100644 --- a/xo-expression/src/expression/Sequence.cpp +++ b/xo-expression/src/expression/Sequence.cpp @@ -1,6 +1,7 @@ /* @file Sequence.cpp */ #include "Sequence.hpp" +#include "pretty_expression.hpp" #include namespace xo { @@ -71,6 +72,54 @@ namespace xo { os << ">"; } + + std::uint32_t + Sequence::pretty_print(ppstate * pps, bool upto) const + { + if (upto) { + std::uint32_t saved = pps->pos(); + + if (!pps->has_margin()) + return false; + + if (!pps->print_upto("has_margin()) + return false; + + std::string i_str = tostr("[", i, "]"); + + if (!pps->print_upto(xtag(i_str.c_str(), expr_i))) + return false; + ++i; + } + + if (!pps->has_margin()) + return false; + + return pps->scan_no_newline(saved); + } else { + std::uint32_t ci0 = pps->lpos(); + std::uint32_t ci1 = ci0 + pps->indent_width(); + + pps->write("newline_indent(ci1); + pps->pretty(xtag(i_str.c_str(), expr_i)); + ++i; + } + + pps->write(">"); + return false; + } + } } /*namespace scm*/ } /*namespace xo*/