pretty printing -- copmlete for xo::ast::GeneralizedExpression

This commit is contained in:
Roland Conybeare 2025-07-19 11:47:03 -05:00
commit b8ae0f95fa
28 changed files with 327 additions and 116 deletions

View file

@ -3,7 +3,9 @@
#include "Apply.hpp"
#include "Primitive.hpp"
#include "exprtype.hpp"
#include "pretty_expression.hpp"
#include "xo/indentlog/print/vector.hpp"
#include "xo/indentlog/print/pretty_vector.hpp"
#include <cstdint>
namespace xo {
@ -77,39 +79,35 @@ namespace xo {
}
std::uint32_t
Apply::pretty_print(ppstate * pps, bool upto) const
Apply::pretty_print(const ppindentinfo & ppii) const
{
if (upto) {
std::uint32_t saved = pps->pos();
return ppii.pps()->pretty_struct(ppii, "Apply",
refrtag("fn", fn_),
refrtag("argv", argv_));
if (!pps->has_margin())
return false;
#ifdef OBSOLETE
ppstate * pps = ppii.pps();
if (ppii.upto()) {
if (!pps->print_upto("<Apply"))
return false;
if (!pps->print_upto(xtag("fn", fn_)))
if (!pps->print_upto_tag("fn", fn_))
return false;
if (!pps->print_upto(xtag("argv", argv_)))
if (!pps->print_upto_tag("argv", argv_))
return false;
return pps->scan_no_newline(saved);
return true;
} else {
std::uint32_t ci0 = pps->lpos();
std::uint32_t ci1 = ci0 + pps->indent_width();
pps->write("<Apply");
pps->newline_indent(ci1);
pps->pretty(xtag("fn", fn_));
pps->newline_indent(ci1);
pps->pretty(xtag("argv", argv_));
pps->newline_pretty_tag(ppii.ci1(), "fn", fn_);
pps->newline_pretty_tag(ppii.ci1(), "argv", argv_);
pps->write(">");
return false;
}
#endif
}
} /*namespace ast*/

View file

@ -4,7 +4,10 @@
*/
#include "AssignExpr.hpp"
#include "pretty_expression.hpp"
#include "pretty_variable.hpp"
#include "xo/indentlog/print/tag.hpp"
#include <cstdint>
namespace xo {
namespace ast {
@ -86,6 +89,13 @@ namespace xo {
<< xtag("rhs", rhs_)
<< ">";
}
std::uint32_t
AssignExpr::pretty_print(const ppindentinfo & ppii) const {
return ppii.pps()->pretty_struct(ppii, "AssignExpr",
refrtag("lhs", lhs_),
refrtag("rhs", rhs_));
}
} /*namespace ast*/
} /*namespace xo*/

View file

@ -4,6 +4,7 @@
*/
#include "ConvertExpr.hpp"
#include "pretty_expression.hpp"
namespace xo {
namespace ast {
@ -31,6 +32,13 @@ namespace xo {
<< ">";
}
std::uint32_t
ConvertExpr::pretty_print(const ppindentinfo & ppii) const {
return ppii.pps()->pretty_struct(ppii, "Convert",
rtag("dest_type", print::quot(this->valuetype()->short_name())),
refrtag("arg", arg_));
}
// ----- ConvertExprAccess -----
rp<ConvertExprAccess>

View file

@ -6,7 +6,6 @@
#include "DefineExpr.hpp"
#include "Variable.hpp"
#include "pretty_expression.hpp"
#include "xo/indentlog/print/pretty_tag.hpp"
#include <cstdint>
namespace xo {
@ -65,39 +64,33 @@ namespace xo {
} /*display*/
std::uint32_t
DefineExpr::pretty_print(ppstate * pps, bool upto) const
DefineExpr::pretty_print(const ppindentinfo & ppii) const
{
if (upto) {
std::uint32_t saved = pps->pos();
return ppii.pps()->pretty_struct(ppii, "Define",
refrtag("name", lhs_name_),
refrtag("rhs", rhs_));
if (!pps->has_margin())
return false;
#ifdef OBSOLETE
ppstate * pps = ppii.pps();
if (ppii.upto()) {
if (!pps->print_upto("<Define"))
return false;
if (!pps->print_upto(xtag("name", lhs_name_)))
if (!pps->print_upto_tag("name", lhs_name_))
return false;
if (!pps->print_upto_tag("rhs", rhs_))
return false;
if (!pps->print_upto(xtag("rhs", rhs_)))
return false;
return pps->scan_no_newline(saved);
return true;
} else {
std::uint32_t ci0 = pps->lpos();
std::uint32_t ci1 = ci0 + pps->indent_width();
pps->write("<Define");
pps->newline_indent(ci1);
pps->pretty(xtag("name", lhs_name_));
pps->newline_indent(ci1);
pps->pretty(xtag("rhs", rhs_));
pps->newline_pretty_tag(ppii.ci1(), "name", lhs_name_);
pps->newline_pretty_tag(ppii.ci1(), "rhs", rhs_);
pps->write(">");
return false;
}
#endif
}
// ----- DefineExprAccess -----

View file

@ -11,19 +11,28 @@ namespace xo {
return tostr(*this);
}
#ifdef SUPERSEDED // currently all derived expression types support pretty printing
std::uint32_t
GeneralizedExpression::pretty_print(ppstate * pps, bool upto) const {
GeneralizedExpression::pretty_print(const ppindentinfo & ppii) const {
// Slooooow fallback for subtypes that don't implement pretty printing support
// Currently have support for:
// - Variable
// - Lambda
// - DefineExpr
// - Sequence
// - Apply
// - Primitive
// - IfExpr
ppstate * pps = ppii.pps();
std::uint32_t saved = pps->pos();
pps->write(display_string());
if (upto && !pps->has_margin())
if (ppii.upto() && !pps->has_margin())
return false;
return upto ? pps->scan_no_newline(saved) : true;
return ppii.upto() ? pps->scan_no_newline(saved) : true;
}
#endif
} /*namespace ast*/
} /*namespace xo*/

View file

@ -20,7 +20,33 @@ namespace xo {
void
GlobalEnv::print(std::ostream & os) const {
os << "<globalenv" << xtag("size", global_map_.size()) << ">";
os << "<GlobalEnv"
<< xtag("size", global_map_.size())
<< ">";
}
std::uint32_t
GlobalEnv::pretty_print(const xo::print::ppindentinfo & ppii) const
{
using xo::print::ppstate;
ppstate * pps = ppii.pps();
if (ppii.upto()) {
if (!pps->print_upto("<GlobalEnv"))
return false;
if (!pps->print_upto_tag("size", global_map_.size()))
return false;
pps->write(">");
return true;
} else {
pps->write("<GlobalEnv");
pps->newline_pretty_tag(ppii.ci1(), "size", global_map_.size());
pps->write(">");
return false;
}
}
} /*namespace ast*/
} /*namespace xo*/

View file

@ -1,7 +1,9 @@
/* @file IfExpr.cpp */
#include "IfExpr.hpp"
#include "xo/indentlog/print/vector.hpp"
#include "pretty_expression.hpp"
#include "pretty_variable.hpp"
//#include "xo/indentlog/print/vector.hpp"
namespace xo {
namespace ast {
@ -38,6 +40,14 @@ namespace xo {
<< xtag("when_false", when_false_)
<< ">";
} /*display*/
std::uint32_t
IfExpr::pretty_print(const ppindentinfo & ppii) const {
return ppii.pps()->pretty_struct(ppii, "IfExpr",
refrtag("test", test_),
refrtag("when_true", when_true_),
refrtag("when_false", when_false_));
}
} /*namespace ast*/
} /*namespace xo*/

View file

@ -3,11 +3,11 @@
#include "Lambda.hpp"
#include "exprtype.hpp"
#include "pretty_expression.hpp"
#include "pretty_variable.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 <map>
#include <sstream>
@ -322,47 +322,38 @@ namespace xo {
} /*display*/
std::uint32_t
Lambda::pretty_print(ppstate * pps, bool upto) const
Lambda::pretty_print(const ppindentinfo & ppii) const
{
if (upto) {
std::uint32_t saved = pps->pos();
return ppii.pps()->pretty_struct(ppii, "Lambda",
refrtag("name", name_),
refrtag("argv", local_env_->argv()),
refrtag("body", body_));
if (!pps->has_margin())
return false;
#ifdef OBSOLETE
ppstate * pps = ppii.pps();
if (ppii.upto()) {
if (!pps->print_upto("<Lambda"))
return false;
if (!pps->print_upto(xtag("name", name_)))
if (!pps->print_upto_tag("name", name_))
return false;
if (!pps->print_upto(xtag("argv", local_env_->argv())))
if (!pps->print_upto_tag("argv", local_env_->argv()))
return false;
if (!pps->print_upto(xtag("body", body_)))
if (!pps->print_upto_tag("body", body_))
return false;
pps->write(">");
return pps->scan_no_newline(saved);
return true;
} else {
std::uint32_t ci0 = pps->lpos();
std::uint32_t ci1 = ci0 + pps->indent_width();
pps->write("<Lambda");
pps->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->newline_pretty_tag(ppii.ci1(), "name", name_);
pps->newline_pretty_tag(ppii.ci1(), "argv", local_env_->argv());
pps->newline_pretty_tag(ppii.ci1(), "body", body_);
pps->write(">");
return false;
}
#endif
}
// ----- Lambda Access -----
@ -413,5 +404,4 @@ namespace xo {
} /*namespace ast*/
} /*namespace xo*/
/* end Lambda.cpp */

View file

@ -4,8 +4,11 @@
*/
#include "LocalEnv.hpp"
#include "pretty_variable.hpp"
#include "xo/indentlog/print/pretty_vector.hpp"
#include "xo/indentlog/print/vector.hpp"
namespace xo {
namespace ast {
rp<LocalEnv>
@ -112,6 +115,33 @@ namespace xo {
<< xtag("argv", argv_)
<< ">";
}
std::uint32_t
LocalEnv::pretty_print(const xo::print::ppindentinfo & ppii) const {
using xo::print::ppstate;
ppstate * pps = ppii.pps();
if (ppii.upto()) {
if (!pps->print_upto("<LocalEnv"))
return false;
if (!pps->print_upto_tag("this", (void*)this))
return false;
if (!pps->print_upto_tag("argv", argv_))
return false;
pps->write(">");
return true;
} else {
pps->write("<LocalEnv");
pps->newline_pretty_tag(ppii.ci1(), "this", (void*)this);
pps->newline_pretty_tag(ppii.ci1(), "argv", argv_);
pps->write(">");
return false;
}
}
} /*namespace ast*/
} /*namespace xo*/

View file

@ -74,14 +74,11 @@ namespace xo {
}
std::uint32_t
Sequence::pretty_print(ppstate * pps, bool upto) const
Sequence::pretty_print(const ppindentinfo & ppii) const
{
if (upto) {
std::uint32_t saved = pps->pos();
if (!pps->has_margin())
return false;
ppstate * pps = ppii.pps();
if (ppii.upto()) {
if (!pps->print_upto("<Sequence"))
return false;
@ -91,8 +88,7 @@ namespace xo {
return false;
std::string i_str = tostr("[", i, "]");
if (!pps->print_upto(xtag(i_str.c_str(), expr_i)))
if (!pps->print_upto_tag(i_str.c_str(), expr_i))
return false;
++i;
}
@ -100,19 +96,18 @@ namespace xo {
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(">");
return true;
} else {
pps->write("<Sequence");
std::size_t i = 0;
for (const auto & expr_i : expr_v_) {
std::string i_str = tostr("[", i, "]");
pps->newline_indent(ci1);
pps->pretty(xtag(i_str.c_str(), expr_i));
pps->newline_pretty_tag(ppii.ci1(),
i_str.c_str(),
expr_i);
++i;
}

View file

@ -2,6 +2,7 @@
#include "Variable.hpp"
#include "Environment.hpp"
#include "pretty_expression.hpp"
namespace xo {
namespace ast {
@ -37,6 +38,59 @@ namespace xo {
os << xtag("type", "nullptr");
os << ">";
} /*display*/
std::uint32_t
Variable::pretty_print(const ppindentinfo & ppii) const {
/* 1. rtag instead of refrtag:
* print::quot() is a temporary rvalue; lifetime ends before control enters pretty_struct()
*/
return ppii.pps()->pretty_struct(ppii, "Variable",
refrtag("name", name_),
rtag("type", print::quot(this->valuetype()
? this->valuetype()->short_name()
: "nullptr")));
#ifdef OBSOLETE
ppstate * pps = ppii.pps();
if (ppii.upto()) {
if (!pps->print_upto("<Variable"))
return false;
if (!pps->print_upto_tag("name", name_))
return false;
if (this->valuetype()) {
if (!pps->print_upto_tag("type", this->valuetype()->short_name()))
return false;
} else {
if (!pps->print_upto_tag("type", "nullptr"))
return false;
}
pps->write(">");
return true;
} else {
pps->write("<Variable");
pps->newline_pretty_tag(ppii.ci1(), "name", name_);
/* use tag instead of rtag for type,
* since not guaranteed to print machine-readably
*/
if (this->valuetype()) {
pps->newline_indent(ppii.ci1());
pps->pretty(xtag("type", this->valuetype()->short_name()));
} else {
pps->newline_pretty_tag(ppii.ci1(), "type", "nullptr");
}
pps->write(">");
return false;
}
#endif
}
} /*namespace ast*/
} /*namespace xo*/