xo-reader2: apply expr now parses up to rightparen

This commit is contained in:
Roland Conybeare 2026-02-12 00:02:56 -05:00
commit 2cf7f2744f
3 changed files with 93 additions and 28 deletions

View file

@ -0,0 +1,17 @@
/** @file Arena.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
// reminder: we can't put this AAllocator
// (or APrintable for that matter) support in xo-arena,
// because xo-arena is a dependency of xo-facet, which is in turn
// a dependency of xo-alloc2
//
#include <xo/arena/DArena.hpp>
#include "arena/IAllocator_DArena.hpp"
/* end Arena.hpp */

View file

@ -81,7 +81,8 @@ namespace xo {
* that we parse f before parser knows that it will be
* followed by leftparen
**/
explicit DApplySsm(obj<AExpression> fn_expr,
explicit DApplySsm(applyexprstatetype applystate,
obj<AExpression> fn_expr,
DArray * args);
/** create instance using memory from @p parser_mm.
@ -140,6 +141,13 @@ namespace xo {
void on_token(const Token & tk,
ParserStateMachine * p_psm);
/** update this apply-ssm with data from nested ssm:
* expression @p expr, followed by token @p tk.
**/
void on_parsed_expression_with_token(obj<AExpression> expr,
const Token & tk,
ParserStateMachine * p_psm);
///@}
#ifdef NOT_YET
@ -165,6 +173,15 @@ namespace xo {
///@}
private:
/** @defgroup ssm-applyssm-mpl-methods **/
///@{
///@}
private:
/** @defgroup ssm-applyssm-member-variables **/
///@{
/** current state of parser for this apply expression **/
applyexprstatetype applystate_ = applyexprstatetype::apply_0;
/** evaluates to function to be invoked **/
@ -177,6 +194,8 @@ namespace xo {
* place to optimize)
**/
DArray * args_expr_v_ = nullptr;
///@}
};
} /*namespace scm */

View file

@ -5,12 +5,15 @@
#include "ApplySsm.hpp"
#include "ExpectExprSsm.hpp"
#include <xo/facet/FacetRegistry.hpp>
#include <xo/alloc2/Arena.hpp>
#include <xo/reflectutil/typeseq.hpp>
//#include "parserstatemachine.hpp"
//#include "expect_expr_xs.hpp"
namespace xo {
using xo::mm::AGCObject;
using xo::print::APrintable;
using xo::reflect::typeseq;
@ -45,21 +48,23 @@ namespace xo {
DArray * args)
: applystate_{applystate},
fn_expr_{fn_expr},
arg_expr_v_{args}
args_expr_v_{args}
{
if (fn_expr) {
this->applystate_ = applyexprstatetype::apply_1;
}
assert(args->empty());
assert(args->is_empty());
}
DApplySsm *
DApplySsm::make(DArena & mm,
DApplySsm::make(DArena & arena,
obj<AExpression> fn_expr)
{
void * mem = mm.alloc(typeseq::id<DApplySsm>(),
sizeof(DApplySsm));
obj<AAllocator,DArena> mm(&arena);
void * mem = arena.alloc(typeseq::id<DApplySsm>(),
sizeof(DApplySsm));
/* allocate room for 8 arguments (during parsing)
* will reallocate to expand if needed.
@ -186,51 +191,75 @@ namespace xo {
void
DApplySsm::on_parsed_expression_with_token(obj<AExpression> expr,
const Token & tk)
const Token & tk,
ParserStateMachine * p_psm)
{
/* maybe we'll find control comes here also on function position?
* hasn't come up when applyssm recognized via leftparen
*/
if (applystate_ == applyexprstatetype::apply_2) {
obj<AGCObject> expr_gco = expr.to_facet<AGCObject>();
assert(expr_gco);
obj<AAllocator,DArena> mm(&(p_psm->parser_alloc()));
if (args_expr_v_->size() == args_expr_v_->capacity()) {
// need to expand .args_expr_v_ capacity.
// Could use DArena checkpoint to redo this in place,
// since argument array must be on the top of the stack.
obj<AAllocator,DArena> mm(&(p_psm->parser_alloc()));
DArray * argv_2x = DArray::empty(mm, 2 * args_expr_v_->capacity());
for (DArray::size_type i = 0, n = arg_expr_v_->size(); i < n; ++i) {
argv_2x->push_back((*argv_)[i]);
for (DArray::size_type i = 0, n = args_expr_v_->size(); i < n; ++i) {
argv_2x->push_back((*args_expr_v_)[i]);
}
this->args_expr_v_ = argv_2x;
}
if (args_expr_v_->size() < args_expr_v_->capacity()) {
args_expr_v_->push_back(expr);
}
if (args_expr_v_->size() < args_expr_v_->capacity())
args_expr_v_->push_back(expr_gco);
if (tk.tk_type() == tokentype::tk_rightparen) {
// expression completes apply
// begin assemble_expr()..
// TODO: assemble apply expression..
std::uint32_t n_args = args_expr_v_->size();
assert(false);
DApplyExpr * apply
= (DApplyExpr::scaffold
(mm,
TypeRef::dwim(TypeRef::prefix_type::from_chars("apply"),
nullptr),
fn_expr_,
n_args));
for (std::uint32_t i_arg = 0; i_arg < n_args; ++i_arg) {
auto arg_expr
= args_expr_v_->at(i_arg).to_facet<AExpression>();
apply->assign_arg(i_arg, arg_expr);
}
// ..end assemble_expr()
obj<AExpression,DApplyExpr> apply_ex(apply);
p_psm->pop_ssm();
p_psm->on_parsed_expression(apply_ex);
return;
} else if (tk.tk_type() == tokentype::tk_comma) {
// 1. want to remain in state apply_2
// 2. expr from nested ssm already incorporated
// into .args_expr_v_
// -> so updated state already achieved.
return;
}
if ((tk.tk_type() == tokentype::tk_comma)
|| (tk.tk_type() == tokentype::tk_rightparen)) {
// do stuff,
//return;
}
// complain
assert(false);
}
Super::on_parsed_expression_with_token(expr, tk);
Super::on_parsed_expression_with_token(expr, tk, p_psm);
}
#ifdef NOT_YET
@ -319,7 +348,7 @@ namespace xo {
bool
DApplySsm::pretty(const ppindentinfo & ppii) const
{
// TODO: const-correct version of obj<> template
// TODO: const-correct version of obj<> template
auto fn_expr = const_cast<DApplySsm*>(this)->fn_expr_.to_facet<APrintable>();
bool fn_expr_present(fn_expr);