xo-expression: + GeneralizedExpression pretty-printing [WIP]

This commit is contained in:
Roland Conybeare 2025-07-13 21:20:19 -05:00
commit 0b0d8ffdc0
11 changed files with 204 additions and 1 deletions

View file

@ -101,6 +101,7 @@ namespace xo {
virtual void attach_envs(bp<Environment> 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,

View file

@ -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:
/**

View file

@ -8,7 +8,6 @@
#include "xo/refcnt/Refcounted.hpp"
#include "xo/reflect/TypeDescr.hpp"
#include "exprtype.hpp"
//#include <cstdint>
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 **/

View file

@ -98,6 +98,7 @@ namespace xo {
virtual void attach_envs(bp<Environment> 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

View file

@ -103,6 +103,12 @@ namespace xo {
};
} /*namespace ast*/
#ifndef ppdetail_atomic
namespace print {
PPDETAIL_ATOMIC(xo::ast::LocalEnv);
}
#endif
} /*namespace xo*/

View file

@ -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.

View file

@ -2,7 +2,9 @@
#include "Apply.hpp"
#include "Primitive.hpp"
#include "exprtype.hpp"
#include "xo/indentlog/print/vector.hpp"
#include <cstdint>
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("<Apply"))
return false;
if (!pps->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("<Apply");
pps->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*/

View file

@ -5,6 +5,9 @@
#include "DefineExpr.hpp"
#include "Variable.hpp"
#include "pretty_expression.hpp"
#include "xo/indentlog/print/pretty_tag.hpp"
#include <cstdint>
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("<Define"))
return false;
if (!pps->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("<Define");
pps->newline_indent(ci1);
pps->pretty(xtag("name", lhs_name_));
pps->newline_indent(ci1);
pps->pretty(xtag("rhs", rhs_));
pps->write(">");
return false;
}
}
// ----- DefineExprAccess -----
rp<DefineExprAccess>

View file

@ -1,6 +1,8 @@
/* @file GeneralizedExpression.cpp */
#include "GeneralizedExpression.hpp"
#include "pretty_expression.hpp"
#include <cstdint>
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*/

View file

@ -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 <map>
#include <sstream>
@ -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("<Lambda"))
return false;
if (!pps->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("<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->write(">");
return false;
}
}
// ----- Lambda Access -----
rp<LambdaAccess>

View file

@ -1,6 +1,7 @@
/* @file Sequence.cpp */
#include "Sequence.hpp"
#include "pretty_expression.hpp"
#include <cstddef>
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("<Sequence"))
return false;
std::size_t i = 0;
for (const auto & expr_i : expr_v_) {
if (!pps->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("<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));
++i;
}
pps->write(">");
return false;
}
}
} /*namespace scm*/
} /*namespace xo*/