diff --git a/include/xo/reader/apply_xs.hpp b/include/xo/reader/apply_xs.hpp index f3975dab..cf57b9ab 100644 --- a/include/xo/reader/apply_xs.hpp +++ b/include/xo/reader/apply_xs.hpp @@ -106,8 +106,11 @@ namespace xo { /** evaluates to the arguments to pass to @ref fn_ **/ std::vector> args_expr_v_; }; - } /*namespace scm */ + + namespace print { + PPDETAIL_ATOMIC(xo::scm::applyexprstatetype); + } } /*namespace xo*/ /* end apply_xs.hpp */ diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index d34b3254..76e1bcd8 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -107,6 +107,7 @@ namespace xo { parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; + virtual bool pretty_print(const print::ppindentinfo & ppii) const override; private: static std::unique_ptr make(); diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 2dc58e13..22b07f9e 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -57,6 +57,8 @@ namespace xo { parserstatemachine * p_psm) override; virtual void on_i64_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void on_f64_token(const token_type & tk, + parserstatemachine * p_psm) override; // ----- victory methods ----- diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 6d3f8cd6..24e5f6d0 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -7,6 +7,7 @@ #include "xo/expression/Expression.hpp" #include "xo/tokenizer/token.hpp" +#include "xo/indentlog/print/ppdetail_atomic.hpp" #include //#include @@ -145,6 +146,9 @@ namespace xo { /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; + /** pretty-print using @p ppii **/ + virtual bool pretty_print(const print::ppindentinfo & ppii) const; + // ----- input methods ----- /** handle incoming 'def' token **/ diff --git a/include/xo/reader/if_else_xs.hpp b/include/xo/reader/if_else_xs.hpp index ce7947d9..6086eac0 100644 --- a/include/xo/reader/if_else_xs.hpp +++ b/include/xo/reader/if_else_xs.hpp @@ -91,7 +91,10 @@ namespace xo { }; } /*namespace scm*/ + + namespace print { + PPDETAIL_ATOMIC(xo::scm::ifexprstatetype); + } } /*namespace xo*/ - -/** end if_else_xs.hpp **/ +/* end if_else_xs.hpp */ diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 0832add2..2eb39e2a 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -83,6 +83,7 @@ namespace xo { parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; + virtual bool pretty_print(const print::ppindentinfo & ppii) const override; private: static std::unique_ptr make(); @@ -105,6 +106,10 @@ namespace xo { }; } /*namespace scm*/ + + namespace print { + PPDETAIL_ATOMIC(xo::scm::lambdastatetype); + } } /*namespace xo*/ diff --git a/include/xo/reader/pretty_envframestack.hpp b/include/xo/reader/pretty_envframestack.hpp index be890b59..842368fa 100644 --- a/include/xo/reader/pretty_envframestack.hpp +++ b/include/xo/reader/pretty_envframestack.hpp @@ -10,6 +10,13 @@ namespace xo { namespace print { + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::envframestack * p) { + return p->pretty_print(ppii); + } + }; + template <> struct ppdetail { static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::envframestack * p) { diff --git a/include/xo/reader/pretty_exprstatestack.hpp b/include/xo/reader/pretty_exprstatestack.hpp index 4c2b04f1..bc8f6606 100644 --- a/include/xo/reader/pretty_exprstatestack.hpp +++ b/include/xo/reader/pretty_exprstatestack.hpp @@ -16,5 +16,19 @@ namespace xo { return p->pretty_print(ppii); } }; + + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::exprstatestack * p) { + return p->pretty_print(ppii); + } + }; + + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::exprstate * p) { + return p->pretty_print(ppii); + } + }; } /*namespace print*/ } /*namespace xo*/ diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 8713a9f0..ce77966d 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -6,6 +6,7 @@ #pragma once #include "exprstate.hpp" +#include "xo/reflect/TypeDescr.hpp" #include //#include @@ -90,6 +91,12 @@ namespace xo { bool admits_f64() const; + void apply_type_error(const char * self_name, + optype op, + bp expr1, + bp expr2, + parserstatemachine * p_psm) const; + virtual const char * get_expect_str() const override; virtual void on_expr(bp expr, @@ -113,6 +120,8 @@ namespace xo { parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; virtual void on_then_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_else_token(const token_type & tk, @@ -132,6 +141,7 @@ namespace xo { parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; + virtual bool pretty_print(const print::ppindentinfo & ppii) const override; private: static std::unique_ptr make(rp valex, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 2403359a..d5cf23df 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -351,11 +351,17 @@ namespace xo { void define_xs::print(std::ostream & os) const { os << ""; } + + bool + define_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "define_xs", + refrtag("defxs_type", defxs_type_)); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 03314cd7..77c5e696 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -152,8 +152,7 @@ namespace xo { { using xo::ast::Constant; - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(p_psm->debug_flag())); constexpr const char * c_self_name = "exprseq_xs::on_i64_token"; @@ -173,6 +172,32 @@ namespace xo { } } + void + exprseq_xs::on_f64_token(const token_type & tk, + parserstatemachine * p_psm) + { + using xo::ast::Constant; + + scope log(XO_DEBUG(p_psm->debug_flag())); + + constexpr const char * c_self_name = "exprseq_xs::on_i64_token"; + + if (xseqtype_ == exprseqtype::toplevel_interactive) + { + progress_xs::start(Constant::make(tk.f64_value()), p_psm); + } else { + /* policy: don't allow literals as toplevel expressions + * unless interactive session. + */ + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, + tk, + exp, + p_psm); + } + } + void exprseq_xs::on_typedescr(TypeDescr /*td*/, parserstatemachine * /*p_psm*/) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index e4311bd8..a9642063 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -21,6 +21,7 @@ namespace xo { //using xo::ast::Constant; //using xo::reflect::Reflect; using xo::reflect::TypeDescr; + using xo::print::ppindentinfo; namespace scm { const char * @@ -552,6 +553,13 @@ namespace xo { os << ">"; } + bool + exprstate::pretty_print(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "exprstate", + refrtag("type", exs_type_)); + } + void exprstate::illegal_input_error(const char * self_name, const token_type & tk) const diff --git a/src/reader/if_else_xs.cpp b/src/reader/if_else_xs.cpp index f94e6e9d..2fada024 100644 --- a/src/reader/if_else_xs.cpp +++ b/src/reader/if_else_xs.cpp @@ -7,6 +7,7 @@ //#include "exprstatestack.hpp" #include "parserstatemachine.hpp" #include "expect_expr_xs.hpp" +#include "xo/indentlog/print/ppdetail_atomic.hpp" namespace xo { namespace scm { diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 61144b54..bbbd19b8 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -212,6 +212,13 @@ namespace xo { << ">"; } + bool + lambda_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "lambda_xs", + refrtag("lmxs_type", lmxs_type_)); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index a09b8c26..150e092e 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -124,6 +124,21 @@ namespace xo { this->illegal_input_on_token(c_self_name, tk, exp, p_psm); } + void + progress_xs::apply_type_error(const char * self_name, + optype op, + bp expr1, + bp expr2, + parserstatemachine * p_psm) const + { + std::string errmsg = tostr("incompatible argument types T1,T2 to op", + xtag("op", op), + xtag("T1", expr1->valuetype()), + xtag("T2", expr2->valuetype())); + + p_psm->on_error(self_name, std::move(errmsg)); + } + rp progress_xs::assemble_expr(parserstatemachine * p_psm) { /* need to defer building Apply incase expr followed by higher-precedence operator: @@ -177,16 +192,56 @@ namespace xo { assert(false); case optype::op_add: - return Apply::make_add2_f64(lhs_, rhs_); - + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_add2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_add2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; case optype::op_subtract: - return Apply::make_sub2_f64(lhs_, rhs_); + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_sub2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_sub2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; case optype::op_multiply: - return Apply::make_mul2_f64(lhs_, rhs_); + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_mul2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_mul2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + + break; case optype::op_divide: - return Apply::make_div2_f64(lhs_, rhs_); + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_div2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_div2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; case optype::n_optype: /* unreachable */ @@ -250,9 +305,11 @@ namespace xo { rp expr2 = this->assemble_expr(p_psm); - std::unique_ptr self = p_psm->pop_exprstate(); + if (expr2) { + std::unique_ptr self = p_psm->pop_exprstate(); - p_psm->on_expr_with_semicolon(expr2); + p_psm->on_expr_with_semicolon(expr2); + } } void @@ -438,6 +495,27 @@ namespace xo { */ } + void + progress_xs::on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + rp expr = this->assemble_expr(p_psm); + + log && log(xtag("assembled-expr", expr)); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr(expr); + p_psm->on_rightbrace_token(tk); + + /* control here on input like: + * + * { n * n } + */ + } + namespace { optype tk2op(const tokentype & tktype) { @@ -599,6 +677,27 @@ namespace xo { os << ">"; } + bool + progress_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + if (ppii.upto()) { + return (ppii.pps()->print_upto("print_upto(refrtag("lhs", lhs_)) : true) + && (op_type_ != optype::invalid ? ppii.pps()->print_upto(refrtag("op", op_type_)) : true) + && (rhs_ ? ppii.pps()->print_upto(refrtag("rhs", rhs_)) : true) + && ppii.pps()->print_upto(">")); + } else { + ppii.pps()->write("pretty(refrtag("lhs", lhs_)); + if (op_type_ != optype::invalid) + ppii.pps()->pretty(refrtag("op", op_type_)); + if (rhs_) + ppii.pps()->pretty(refrtag("rhs", rhs_)); + ppii.pps()->write(">"); + return false; + } + } } /*namespace scm*/ } /*namespace xo*/