From 6a932912e37fa2fbb7a1dd7badd187803fd7d2fe Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 1 Feb 2026 00:16:37 -0500 Subject: [PATCH] xo-reader2: construct LambdaExpr to complete LambdaSsm + utest --- .../include/xo/expression2/StringTable.hpp | 5 ++++ .../src/expression2/DLambdaExpr.cpp | 12 ++++++-- .../src/expression2/DSequenceExpr.cpp | 7 ++++- .../src/expression2/StringTable.cpp | 30 +++++++++++++++++++ .../include/xo/reader2/ParserStateMachine.hpp | 3 ++ xo-reader2/src/reader2/DLambdaSsm.cpp | 19 ++++++++---- xo-reader2/src/reader2/ParserStateMachine.cpp | 6 ++++ xo-reader2/utest/SchematikaParser.test.cpp | 5 ++-- 8 files changed, 76 insertions(+), 11 deletions(-) diff --git a/xo-expression2/include/xo/expression2/StringTable.hpp b/xo-expression2/include/xo/expression2/StringTable.hpp index 54b0a826..471fbc0d 100644 --- a/xo-expression2/include/xo/expression2/StringTable.hpp +++ b/xo-expression2/include/xo/expression2/StringTable.hpp @@ -35,6 +35,11 @@ namespace xo { /** return unique string with contents @p key. Idempotent! **/ 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. * Act on failure according to policy @p p **/ diff --git a/xo-expression2/src/expression2/DLambdaExpr.cpp b/xo-expression2/src/expression2/DLambdaExpr.cpp index a27e788b..080e49b5 100644 --- a/xo-expression2/src/expression2/DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/DLambdaExpr.cpp @@ -1,10 +1,12 @@ -/** @file DLambda.cpp +/** @file DLambdaExpr.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "DLambdaExpr.hpp" #include "detail/IExpression_DLambdaExpr.hpp" +#include "DLocalSymtab.hpp" +#include "symtab/IPrintable_DLocalSymtab.hpp" #include #include #include @@ -17,6 +19,7 @@ namespace xo { using xo::reflect::TypeDescrBase; using xo::reflect::FunctionTdxInfo; using xo::reflect::typeseq; + using xo::print::quot; namespace scm { @@ -139,9 +142,14 @@ namespace xo { AExpression>(body_expr_); if (name_ && body) { + auto local_symtab_pr + = obj(local_symtab_); + return ppii.pps()->pretty_struct(ppii, "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("body", body)); } else { diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp index 73b9c2b5..a9783802 100644 --- a/xo-expression2/src/expression2/DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -6,6 +6,7 @@ #include "DSequenceExpr.hpp" #include "detail/IExpression_DSequenceExpr.hpp" #include +#include #include #include #include @@ -15,6 +16,7 @@ namespace xo { using xo::mm::AGCObject; + using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::reflect::typeseq; @@ -95,9 +97,12 @@ namespace xo { { using xo::print::ppstate; + auto expr_v_pr = obj(expr_v_); + return ppii.pps()->pretty_struct (ppii, - "DSequenceExpr"); + "DSequenceExpr", + refrtag("expr_v", expr_v_pr)); } // gc hooks for IGCObject_DSequenceExpr diff --git a/xo-expression2/src/expression2/StringTable.cpp b/xo-expression2/src/expression2/StringTable.cpp index ae48eea9..f59bb24d 100644 --- a/xo-expression2/src/expression2/StringTable.cpp +++ b/xo-expression2/src/expression2/StringTable.cpp @@ -72,6 +72,36 @@ namespace xo { 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 StringTable::verify_ok(verify_policy policy) const { diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 91c84ef1..d065e24f 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -82,6 +82,9 @@ namespace xo { **/ 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; * restore previous symtab at the end of lambda-expression definition. * See @ref pop_local_symtab diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 4b2d7df8..4ed77732 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -11,6 +11,7 @@ #include "DExpectExprSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" +#include #include #include //#include @@ -336,17 +337,23 @@ namespace xo { DLambdaSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { - if (lm_state_ == lambdastatetype::lm_4) { + if (lmstate_ == lambdastatetype::lm_4) { this->lmstate_ = lambdastatetype::lm_5; this->body_ = expr; // assemble lambda - obj lm_expr = DLambda::make(p_psm->expr_alloc(), - xxx typeref, - xxx name, - local_symtab_, - body_); + auto prefix = TypeRef::prefix_type::from_chars("lm"); + TypeRef tref = TypeRef::dwim(prefix, nullptr); + + const DUniqueString * name = p_psm->gensym("lambda"); + + auto lm_expr = obj + (DLambdaExpr::make(p_psm->expr_alloc(), + tref, + name, + local_symtab_, + body_)); p_psm->pop_ssm(); // this lambda p_psm->on_parsed_expression(lm_expr); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 82435b50..cf9c26c1 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -90,6 +90,12 @@ namespace xo { return stringtable_.intern(str); } + const DUniqueString * + ParserStateMachine::gensym(std::string_view str) + { + return stringtable_.gensym(str); + } + void ParserStateMachine::push_local_symtab(DLocalSymtab * symtab) { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index b30b67f3..0defdeb5 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -394,9 +394,10 @@ namespace xo { log && log(xtag("parser", &parser)); log && log(xtag("result", result)); - REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(parser.has_incomplete_expr() == false); REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); } //REQUIRE(result.is_error());