xo-reader2: construct LambdaExpr to complete LambdaSsm + utest

This commit is contained in:
Roland Conybeare 2026-02-01 00:16:37 -05:00
commit 6a932912e3
8 changed files with 76 additions and 11 deletions

View file

@ -35,6 +35,11 @@ namespace xo {
/** return unique string with contents @p key. Idempotent! **/ /** return unique string with contents @p key. Idempotent! **/
const DUniqueString * intern(std::string_view key); const DUniqueString * intern(std::string_view key);
/** generate unique symbol -- guaranteed not to collide
* with existing symbol in this table.
**/
const DUniqueString * gensym(std::string_view prefix);
/** verify StringTable invariants. /** verify StringTable invariants.
* Act on failure according to policy @p p * Act on failure according to policy @p p
**/ **/

View file

@ -1,10 +1,12 @@
/** @file DLambda.cpp /** @file DLambdaExpr.cpp
* *
* @author Roland Conybeare, Jan 2026 * @author Roland Conybeare, Jan 2026
**/ **/
#include "DLambdaExpr.hpp" #include "DLambdaExpr.hpp"
#include "detail/IExpression_DLambdaExpr.hpp" #include "detail/IExpression_DLambdaExpr.hpp"
#include "DLocalSymtab.hpp"
#include "symtab/IPrintable_DLocalSymtab.hpp"
#include <xo/alloc2/Allocator.hpp> #include <xo/alloc2/Allocator.hpp>
#include <xo/printable2/Printable.hpp> #include <xo/printable2/Printable.hpp>
#include <xo/facet/FacetRegistry.hpp> #include <xo/facet/FacetRegistry.hpp>
@ -17,6 +19,7 @@ namespace xo {
using xo::reflect::TypeDescrBase; using xo::reflect::TypeDescrBase;
using xo::reflect::FunctionTdxInfo; using xo::reflect::FunctionTdxInfo;
using xo::reflect::typeseq; using xo::reflect::typeseq;
using xo::print::quot;
namespace scm { namespace scm {
@ -139,9 +142,14 @@ namespace xo {
AExpression>(body_expr_); AExpression>(body_expr_);
if (name_ && body) { if (name_ && body) {
auto local_symtab_pr
= obj<APrintable,DLocalSymtab>(local_symtab_);
return ppii.pps()->pretty_struct(ppii, return ppii.pps()->pretty_struct(ppii,
"LambdaExpr", "LambdaExpr",
refrtag("name", name_), refrtag("tref", typeref_),
refrtag("name", quot(std::string_view(*name_))),
refrtag("local_symtab", local_symtab_pr),
//refrtag("argv", local_env_->argv()), //refrtag("argv", local_env_->argv()),
refrtag("body", body)); refrtag("body", body));
} else { } else {

View file

@ -6,6 +6,7 @@
#include "DSequenceExpr.hpp" #include "DSequenceExpr.hpp"
#include "detail/IExpression_DSequenceExpr.hpp" #include "detail/IExpression_DSequenceExpr.hpp"
#include <xo/object2/array/IGCObject_DArray.hpp> #include <xo/object2/array/IGCObject_DArray.hpp>
#include <xo/object2/array/IPrintable_DArray.hpp>
#include <xo/gc/GCObject.hpp> #include <xo/gc/GCObject.hpp>
#include <xo/alloc2/Allocator.hpp> #include <xo/alloc2/Allocator.hpp>
#include <xo/printable2/Printable.hpp> #include <xo/printable2/Printable.hpp>
@ -15,6 +16,7 @@
namespace xo { namespace xo {
using xo::mm::AGCObject; using xo::mm::AGCObject;
using xo::print::APrintable;
using xo::facet::FacetRegistry; using xo::facet::FacetRegistry;
using xo::reflect::typeseq; using xo::reflect::typeseq;
@ -95,9 +97,12 @@ namespace xo {
{ {
using xo::print::ppstate; using xo::print::ppstate;
auto expr_v_pr = obj<APrintable,DArray>(expr_v_);
return ppii.pps()->pretty_struct return ppii.pps()->pretty_struct
(ppii, (ppii,
"DSequenceExpr"); "DSequenceExpr",
refrtag("expr_v", expr_v_pr));
} }
// gc hooks for IGCObject_DSequenceExpr // gc hooks for IGCObject_DSequenceExpr

View file

@ -72,6 +72,36 @@ namespace xo {
return nullptr; return nullptr;
} }
const DUniqueString *
StringTable::gensym(std::string_view prefix)
{
static std::size_t s_counter = 0;
while (true) {
++s_counter;
char buf[80];
assert(prefix.size() + 20 < sizeof(buf));
int n = snprintf(buf, sizeof(buf),
"%s:%lu",
prefix.data(), s_counter);
if ((0 < n) && (std::size_t(n) < sizeof(buf)))
buf[n] = '\0';
else
buf[sizeof(buf)-1] = '\0';
std::string_view sv(buf);
const DUniqueString * retval = this->lookup(sv);
if (!retval) {
/* not already in string view -> we have viable candidate */
retval = this->intern(sv);
return retval;
}
}
}
bool bool
StringTable::verify_ok(verify_policy policy) const StringTable::verify_ok(verify_policy policy) const
{ {

View file

@ -82,6 +82,9 @@ namespace xo {
**/ **/
const DUniqueString * intern_string(std::string_view str); const DUniqueString * intern_string(std::string_view str);
/** get unique (within stringtable) string, beginning with @p prefix **/
const DUniqueString * gensym(std::string_view prefix);
/** push nested local symtab while parsing the body of a lambda expression; /** push nested local symtab while parsing the body of a lambda expression;
* restore previous symtab at the end of lambda-expression definition. * restore previous symtab at the end of lambda-expression definition.
* See @ref pop_local_symtab * See @ref pop_local_symtab

View file

@ -11,6 +11,7 @@
#include "DExpectExprSsm.hpp" #include "DExpectExprSsm.hpp"
#include "ParserStateMachine.hpp" #include "ParserStateMachine.hpp"
#include "syntaxstatetype.hpp" #include "syntaxstatetype.hpp"
#include <xo/expression2/detail/IExpression_DLambdaExpr.hpp>
#include <xo/expression2/DVariable.hpp> #include <xo/expression2/DVariable.hpp>
#include <xo/expression2/detail/IExpression_DVariable.hpp> #include <xo/expression2/detail/IExpression_DVariable.hpp>
//#include <xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp> //#include <xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp>
@ -336,17 +337,23 @@ namespace xo {
DLambdaSsm::on_parsed_expression(obj<AExpression> expr, DLambdaSsm::on_parsed_expression(obj<AExpression> expr,
ParserStateMachine * p_psm) ParserStateMachine * p_psm)
{ {
if (lm_state_ == lambdastatetype::lm_4) { if (lmstate_ == lambdastatetype::lm_4) {
this->lmstate_ = lambdastatetype::lm_5; this->lmstate_ = lambdastatetype::lm_5;
this->body_ = expr; this->body_ = expr;
// assemble lambda // assemble lambda
obj<AExpression,DLambda> lm_expr = DLambda::make(p_psm->expr_alloc(), auto prefix = TypeRef::prefix_type::from_chars("lm");
xxx typeref, TypeRef tref = TypeRef::dwim(prefix, nullptr);
xxx name,
local_symtab_, const DUniqueString * name = p_psm->gensym("lambda");
body_);
auto lm_expr = obj<AExpression,DLambdaExpr>
(DLambdaExpr::make(p_psm->expr_alloc(),
tref,
name,
local_symtab_,
body_));
p_psm->pop_ssm(); // this lambda p_psm->pop_ssm(); // this lambda
p_psm->on_parsed_expression(lm_expr); p_psm->on_parsed_expression(lm_expr);

View file

@ -90,6 +90,12 @@ namespace xo {
return stringtable_.intern(str); return stringtable_.intern(str);
} }
const DUniqueString *
ParserStateMachine::gensym(std::string_view str)
{
return stringtable_.gensym(str);
}
void void
ParserStateMachine::push_local_symtab(DLocalSymtab * symtab) ParserStateMachine::push_local_symtab(DLocalSymtab * symtab)
{ {

View file

@ -394,9 +394,10 @@ namespace xo {
log && log(xtag("parser", &parser)); log && log(xtag("parser", &parser));
log && log(xtag("result", result)); log && log(xtag("result", result));
REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(parser.has_incomplete_expr() == false);
REQUIRE(!result.is_error()); REQUIRE(!result.is_error());
REQUIRE(result.is_incomplete()); REQUIRE(result.is_expression());
REQUIRE(result.result_expr());
} }
//REQUIRE(result.is_error()); //REQUIRE(result.is_error());