diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index fe5cd540..678e5eca 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -32,6 +32,8 @@ xo_add_genfacet( OUTPUT_CPP_DIR src/expression2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacet( TARGET xo-expression2-facet-expression @@ -66,6 +68,20 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-defineexpr + FACET_PKG xo_expression2 + FACET Expression + REPR DefineExpr + INPUT idl/IExpression_DDefineExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-uniquestring diff --git a/xo-expression2/idl/IExpression_DDefineExpr.json5 b/xo-expression2/idl/IExpression_DDefineExpr.json5 new file mode 100644 index 00000000..ff35d6d6 --- /dev/null +++ b/xo-expression2/idl/IExpression_DDefineExpr.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DDefineExpr state", + using_doxygen: true, + repr: "DDefineExpr", + doc: ["doc for IExpression+DDefineExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/Binding.hpp b/xo-expression2/include/xo/expression2/Binding.hpp index 455c1538..5f0f7e27 100644 --- a/xo-expression2/include/xo/expression2/Binding.hpp +++ b/xo-expression2/include/xo/expression2/Binding.hpp @@ -15,6 +15,7 @@ namespace xo { static constexpr int32_t s_link_global = -1; public: + Binding() : i_link_{-2}, j_slot_{-1} {} Binding(int32_t i_link, int32_t j_slot) : i_link_{i_link}, j_slot_{j_slot} {} @@ -32,6 +33,7 @@ namespace xo { * >= 0: number of parent links to traverse * to a fixed-size frame * -1: resolve globally + * -2: sentinel (binding info not computed) **/ int32_t i_link_ = s_link_sentinel; /** if @ref i_link_ >= 0, frame offset diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp new file mode 100644 index 00000000..94a37197 --- /dev/null +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -0,0 +1,75 @@ +/** @file DDefineExpr.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Expression.hpp" +#include "DVariable.hpp" +#include + +namespace xo { + namespace scm { + class DUniqueString; // see DUniqueString.hpp + + /** @class DDefineExpr + * @brief an expression that introduces a variable. + * + * Variable may optionally be declared with a type, + * and may come with an expression specifying an initial value + **/ + class DDefineExpr { + public: + using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; + + public: + /** create instance: define-expr using memory from @p mm + * with lhs name @p lhs_name and rhs expression @p rhs_expr + **/ + static DDefineExpr * make(obj mm, + const DUniqueString * lhs_name, + obj rhs_expr); + /** create empty skeleton. Rely on this for parsing + **/ + static DDefineExpr * make_empty(obj mm); + + DVariable * lhs() const { return lhs_var_; } + obj rhs() const noexcept { return rhs_; } + + const DUniqueString * name() const noexcept; + + void assign_lhs_name(const DUniqueString * name); + /** CONCESSION. will use DUniqueString* once we have StringTable **/ + void assign_lhs_name(std::string_view name); + + /** @defgroup scm-defineexpr-expression-facet **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::define; } + TypeRef typeref() const noexcept { return lhs_var_->typeref(); } + TypeDescr valuetype() const noexcept { return lhs_var_->typeref().td(); } + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + + private: + DDefineExpr(DVariable * lhs_var, + obj rhs); + + private: + /** variable being defined by this expression. + **/ + DVariable * lhs_var_ = nullptr; + + /** expression for initial value of this expression + **/ + obj rhs_; + + // std::set free_var_set_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp new file mode 100644 index 00000000..bb668ff3 --- /dev/null +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -0,0 +1,39 @@ +/** @file DGlobalSymtab.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Binding.hpp" + +namespace xo { + namespace scm { + class DUniqueString; + + /** @class DGlobalSymtab + * @brief symbol table for toplevel environment + **/ + struct DGlobalSymtab { + public: + + + public: + /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ + ///@{ + + /** true for global symbol table **/ + bool is_global_symtab() const noexcept { return true; } + + /** lookup binding for variable @p sym **/ + Binding lookup_binding(const DUniqueString * sym) const noexcept; + + ///@} + + private: + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalSymtab.hpp */ diff --git a/xo-expression2/include/xo/expression2/DVariable.hpp b/xo-expression2/include/xo/expression2/DVariable.hpp index 036d88ce..2208852e 100644 --- a/xo-expression2/include/xo/expression2/DVariable.hpp +++ b/xo-expression2/include/xo/expression2/DVariable.hpp @@ -19,15 +19,33 @@ namespace xo { **/ class DVariable { public: + using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; public: - DVariable(const DUniqueString & name, const TypeRef & typeref, Binding path) - : name_{name}, typeref_{typeref}, path_{path} {} + /** create instance + * @p mm memory allocator + * @p name variable name + * @p typeref type information for legal values + * (possibly just placeholder when relying on inference) + * @p path binding path to runtime value. + * This may be computed after parsing; + * mnust be resolved before execution. + **/ + static DVariable * make(obj mm, + const DUniqueString * name, + const TypeRef & typeref, + Binding path = Binding()); - const DUniqueString & name() const { return name_; } + DVariable(const DUniqueString * name, + const TypeRef & typeref, + Binding path); + + const DUniqueString * name() const { return name_; } Binding path() const { return path_; } + void assign_name(const DUniqueString * name) { this->name_ = name; } + /** @defgroup scm-variable-expression-facet**/ ///@{ @@ -40,7 +58,7 @@ namespace xo { private: /** symbol name **/ - const DUniqueString & name_; + const DUniqueString * name_; /** variable value always has type consistent * with this description **/ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp new file mode 100644 index 00000000..3ac7fd49 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DDefineExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DDefineExpr.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DDefineExpr.hpp" + +namespace xo { namespace scm { class IExpression_DDefineExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DDefineExpr + **/ + class IExpression_DDefineExpr { + public: + /** @defgroup scm-expression-ddefineexpr-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-ddefineexpr-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DDefineExpr & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DDefineExpr & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DDefineExpr & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DDefineExpr & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index 0d5e8299..d64a1191 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -23,8 +23,10 @@ namespace xo { #ifdef NOT_YET /** a literal constant that refers to a linkable named function **/ primitive, +#endif /** variable/function definition **/ define, +#ifdef NOT_YET /** variable assignment **/ assign, /** function call **/ @@ -55,7 +57,9 @@ namespace xo { case exprtype::constant: return "constant"; #ifdef NOT_YET case exprtype::primitive: return "primitive"; +#endif case exprtype::define: return "define"; +#ifdef NOT_YET case exprtype::assign: return "assign"; case exprtype::apply: return "apply"; case exprtype::lambda: return "lambda"; diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 9194bfa5..0fcd6541 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -6,12 +6,17 @@ set(SELF_SRCS DConstant.cpp DVariable.cpp + DDefineExpr.cpp TypeRef.cpp IExpression_Any.cpp IExpression_DConstant.cpp IExpression_DVariable.cpp + IExpression_DDefineExpr.cpp + + DLocalSymtab.cpp + DGlobalSymtab.cpp ISymbolTable_Any.cpp diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp new file mode 100644 index 00000000..14d1c52e --- /dev/null +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -0,0 +1,71 @@ +/** @file DDefineExpr.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DDefineExpr.hpp" +#include + +namespace xo { + using xo::facet::typeseq; + + namespace scm { + + DDefineExpr::DDefineExpr(DVariable * lhs_var, + obj rhs) + : lhs_var_{lhs_var}, rhs_{rhs} + {} + + DDefineExpr * + DDefineExpr::make(obj mm, + const DUniqueString * lhs_name, + obj rhs_expr) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DDefineExpr)); + + auto lhs_var = DVariable::make(mm, + lhs_name, + rhs_expr.typeref()); + + return new (mem) DDefineExpr(lhs_var, rhs_expr); + } + + DDefineExpr * + DDefineExpr::make_empty(obj mm) + { + return make(mm, + nullptr /*lhs_name*/, + obj() /*rhs_expr*/); + } + + const DUniqueString * + DDefineExpr::name() const noexcept + { + return lhs_var_->name(); + } + + void + DDefineExpr::assign_lhs_name(const DUniqueString * name) + { + lhs_var_->assign_name(name); + } + + void + DDefineExpr::assign_lhs_name(std::string_view name) + { + scope log(XO_DEBUG(true), "bogus impl - will require unique string"); + log && log(xtag("name", name)); + + //lhs_var_->assign_name(name); + } + + void + DDefineExpr::assign_valuetype(TypeDescr td) noexcept + { + lhs_var_->assign_valuetype(td); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineExpr.cpp */ diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp new file mode 100644 index 00000000..c11761d9 --- /dev/null +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -0,0 +1,27 @@ +/** @file DGlobalSymtab.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DGlobalSymtab.hpp" +#include "DUniqueString.hpp" +#include + +namespace xo { + namespace scm { + + Binding + DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept + { + (void)sym; + + scope log(XO_DEBUG(true), "stub"); + log && log(xtag("sym", std::string_view(*sym))); + + return Binding(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/DLocalSymtab.cpp b/xo-expression2/src/expression2/DLocalSymtab.cpp new file mode 100644 index 00000000..febd1463 --- /dev/null +++ b/xo-expression2/src/expression2/DLocalSymtab.cpp @@ -0,0 +1,25 @@ +/** @file DLocalSymtab.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DLocalSymtab.hpp" +#include "DUniqueString.hpp" +#include + +namespace xo { + namespace scm { + + Binding + DLocalSymtab::lookup_binding(const DUniqueString * sym) const noexcept + { + scope log(XO_DEBUG(true), "stub impl"); + log && log(xtag("sym", std::string_view(*sym))); + + return Binding(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLocalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/DVariable.cpp b/xo-expression2/src/expression2/DVariable.cpp index f589da7b..d27c71ef 100644 --- a/xo-expression2/src/expression2/DVariable.cpp +++ b/xo-expression2/src/expression2/DVariable.cpp @@ -7,12 +7,34 @@ #include "exprtype.hpp" namespace xo { + using xo::facet::typeseq; + namespace scm { + + DVariable * + DVariable::make(obj mm, + const DUniqueString * name, + const TypeRef & typeref, + Binding path) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DVariable)); + + return new (mem) DVariable(name, typeref, path); + } + + DVariable::DVariable(const DUniqueString * name, + const TypeRef & typeref, + Binding path) + : name_{name}, typeref_{typeref}, path_{path} + {} + void DVariable::assign_valuetype(TypeDescr td) noexcept { typeref_.resolve(td); } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp new file mode 100644 index 00000000..3222eabd --- /dev/null +++ b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DDefineExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DDefineExpr.json5] +**/ + +#include "detail/IExpression_DDefineExpr.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DDefineExpr::extype(const DDefineExpr & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DDefineExpr::typeref(const DDefineExpr & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DDefineExpr::valuetype(const DDefineExpr & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DDefineExpr::assign_valuetype(DDefineExpr & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DDefineExpr.cpp */ \ No newline at end of file diff --git a/xo-facet/include/xo/facet/facet_implementation.hpp b/xo-facet/include/xo/facet/facet_implementation.hpp index 5669860a..025645e8 100644 --- a/xo-facet/include/xo/facet/facet_implementation.hpp +++ b/xo-facet/include/xo/facet/facet_implementation.hpp @@ -92,7 +92,7 @@ namespace xo { //static_assert(false && "expect specialization which should provide ImplType trait"); }; - /** Retrieve facet implementation for a (facet, datatype) pair **/ + /** Retrieve facet implementation for a (facet,datatype) pair **/ template using FacetImplType = FacetImplementation::ImplType; diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 8bbe6bb4..a149173e 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -45,6 +45,12 @@ namespace xo { **/ void _do_eval_constant_op(); + /** evaluate a define-expression + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_define_op(); + /** evaluate a variable expression * Require: * - expression in @ref expr_ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index bd29e968..f7131e0a 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -45,6 +45,9 @@ namespace xo { case exprtype::constant: _do_eval_constant_op(); break; + case exprtype::define: + _do_eval_define_op(); + break; case exprtype::variable: _do_eval_variable_op(); break; @@ -61,6 +64,13 @@ namespace xo { this->pc_ = this->cont_; } + void + VirtualSchematikaMachine::_do_eval_define_op() + { + // not implemented + assert(false); + } + void VirtualSchematikaMachine::_do_eval_variable_op() { diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 2be2a98d..28811512 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -43,6 +43,15 @@ }, ], nonconst_methods: [ + { + name: "on_symbol_token", + doc: ["operate state machine for incoming symbol-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_def_token", doc: ["update state machine for incoming define-keyword-token @p tk"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 37ccc23d..3bc042c1 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -8,6 +8,8 @@ #include "ParserStateMachine.hpp" //#include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" +#include +#include #include namespace xo { @@ -69,21 +71,29 @@ namespace xo { **/ class DDefineSsm { public: + using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; public: /** @defgroup scm-define-ssm-facet constructors **/ ///@{ - DDefineSsm(); + /** constructor; using @p def_expr for initial expression scaffold **/ + explicit DDefineSsm(DDefineExpr * def_expr); - /** create instance using memory from @p parser_mm **/ - static DDefineSsm * make(DArena & parser_mm); + /** create instance using memory from @p parser_mm. + * Initial expression scaffold @p def_expr + **/ + static DDefineSsm * make(DArena & parser_mm, + DDefineExpr * def_expr); /** start nested parser for a define-expression, * on top of parser state machine @p p_psm + * Use @p parser_mm to allocate syntax state machines, + * and @p expr_mm to allocate expressions **/ static void start(DArena & parser_mm, + obj expr_mm, ParserStateMachine * p_psm); ///@} @@ -98,6 +108,12 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming symbol-token @p tk + * with overall parser state in @p p_psm + **/ + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ @@ -121,6 +137,11 @@ namespace xo { private: /** identify define-expression state **/ defexprstatetype defstate_; + + /** scaffolded define-expression. + * This will eventually be the output of this ssm + **/ + obj def_expr_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 1b611aaf..bef2bd68 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -56,6 +56,11 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming symbol token @p tk + * with overall parser state in @p p_psm + **/ + void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp index e179d4bd..39f9c2d1 100644 --- a/xo-reader2/include/xo/reader2/ParserResult.hpp +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -50,6 +50,8 @@ namespace xo { std::string_view error_src_fn_; const DString * error_description_ = nullptr; }; + + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index f5293bff..5a7a833f 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -6,6 +6,7 @@ #pragma once #include "ParserResult.hpp" +#include #include #include #include @@ -32,14 +33,14 @@ namespace xo { public: ParserStateMachine(const ArenaConfig & config, - obj * expr_alloc); + obj expr_alloc); /** @defgroup scm-parserstatemachine-accessors accessor methods **/ ///@{ bool debug_flag() const noexcept { return debug_flag_; } ParserStack * stack() const noexcept { return stack_; } - obj * expr_alloc() const noexcept { return expr_alloc_; } + obj expr_alloc() const noexcept { return expr_alloc_; } const ParserResult & result() const noexcept { return result_; } /** true iff state machine is currently idle (at top-level) **/ @@ -65,6 +66,9 @@ namespace xo { /** pop syntax state machine from top of @ref stack_ **/ void pop_ssm(); + /** add variable to current local environment (innermost lexical scope) **/ + void upsert_var(DVariable * var); + /** reset result to none **/ void reset_result(); @@ -84,10 +88,13 @@ namespace xo { **/ void on_token(const Token & tk); - /** update state for incoming define-token @p tk **/ + /** operate state machine for incoming symbol-token @p tk **/ + void on_symbol_token(const Token & tk); + + /** operate state machine for incoming define-token @p tk **/ void on_def_token(const Token & tk); - /** update state for incoming if-token @p tk **/ + /** operate state machine for incoming if-token @p tk **/ void on_if_token(const Token & tk); ///@} @@ -153,7 +160,7 @@ namespace xo { * scenario, where top-level Expressions can be discarded * once compiled. **/ - obj * expr_alloc_ = nullptr; + obj expr_alloc_; /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 075fb4fc..2f7d6d95 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -167,7 +167,7 @@ namespace xo { * @p debug_flag true to enable debug logging **/ SchematikaParser(const ArenaConfig & config, - obj * expr_alloc, + obj expr_alloc, bool debug_flag); bool debug_flag() const { return debug_flag_; } diff --git a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp index 56a8271b..deda9e1d 100644 --- a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index b181fd8d..4f428be5 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -54,12 +54,14 @@ public: virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; // nonconst methods - /** update stat machine for incoming parsed symbol @p sym **/ - virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; + /** operate state machine for incoming symbol-token @p tk **/ + virtual void on_symbol_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming define-keyword-token @p tk **/ virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming if-keyword-token @p tk **/ virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update stat machine for incoming parsed symbol @p sym **/ + virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; ///@} }; /*ASyntaxStateMachine*/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 046adacb..23b90621 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -59,9 +59,10 @@ namespace scm { [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } // nonconst methods - [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; + [[noreturn]] void on_symbol_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index cfb38fa7..d420ba16 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,12 +53,14 @@ namespace xo { static std::string_view get_expect_str(const DDefineSsm & self) noexcept; // non-const methods - /** update stat machine for incoming parsed symbol @p sym **/ - static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming define-keyword-token @p tk **/ static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 44cb6de4..ba8eb0b9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,12 +53,14 @@ namespace xo { static std::string_view get_expect_str(const DExpectSymbolSsm & self) noexcept; // non-const methods - /** update stat machine for incoming parsed symbol @p sym **/ - static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming define-keyword-token @p tk **/ static void on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 4da00f95..c1e61b40 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,12 +53,14 @@ namespace xo { static std::string_view get_expect_str(const DExprSeqState & self) noexcept; // non-const methods - /** update stat machine for incoming parsed symbol @p sym **/ - static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming define-keyword-token @p tk **/ static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 7de32e25..5a8e2fe3 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -50,8 +50,8 @@ namespace scm { } // non-const methods - void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { - return I::on_parsed_symbol(_dcast(data), sym, p_psm); + void on_symbol_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_symbol_token(_dcast(data), tk, p_psm); } void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_def_token(_dcast(data), tk, p_psm); @@ -59,6 +59,9 @@ namespace scm { void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_if_token(_dcast(data), tk, p_psm); } + void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { + return I::on_parsed_symbol(_dcast(data), sym, p_psm); + } ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index f35f4e72..786c83d0 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -55,8 +55,8 @@ public: } // non-const methods (still const in router!) - void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { - return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); + void on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_symbol_token(O::data(), tk, p_psm); } void on_def_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_def_token(O::data(), tk, p_psm); @@ -64,6 +64,9 @@ public: void on_if_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_if_token(O::data(), tk, p_psm); } + void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); + } ///@} /** @defgroup scm-syntaxstatemachine-member-vars **/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 8ac919e4..adf9f429 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -1,9 +1,10 @@ -/** @file DDefineSsm.cpp + /** @file DDefineSsm.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "DDefineSsm.hpp" +#include "DExpectSymbolSsm.hpp" #include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" #ifdef NOT_YET @@ -328,28 +329,33 @@ namespace xo { //////////////////////////////////////////////////////////////// - DDefineSsm::DDefineSsm() - : defstate_{defexprstatetype::def_0} + DDefineSsm::DDefineSsm(DDefineExpr * def_expr) + : defstate_{defexprstatetype::def_0}, + def_expr_{def_expr} {} DDefineSsm * - DDefineSsm::make(DArena & mm) + DDefineSsm::make(DArena & mm, + DDefineExpr * def_expr) { void * mem = mm.alloc(typeseq::id(), sizeof(DDefineSsm)); - return new (mem) DDefineSsm(); + return new (mem) DDefineSsm(def_expr); } void DDefineSsm::start(DArena & mm, + obj expr_mm, ParserStateMachine * p_psm) { //scope log(XO_DEBUG(p_psm->debug_flag())); assert(p_psm->stack()); - DDefineSsm * define_ssm = DDefineSsm::make(mm); + DDefineExpr * def_expr = DDefineExpr::make_empty(expr_mm); + + DDefineSsm * define_ssm = DDefineSsm::make(mm, def_expr); obj ssm = with_facet::mkobj(define_ssm); @@ -387,7 +393,7 @@ namespace xo { case defexprstatetype::def_0: case defexprstatetype::n_defexprstatetype: assert(false); // impossible - return nullptr; + return "impossible!?"; case defexprstatetype::def_1: return "symbol"; case defexprstatetype::def_2: @@ -409,11 +415,57 @@ namespace xo { DDefineSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { + if (this->defstate_ == defexprstatetype::def_1) { + this->defstate_ = defexprstatetype::def_2; + + def_expr_.data()->assign_lhs_name(sym); + + // if this is a genuine top-level define (i.e. nesting level = 0), + // then we need to upsert so we can refer to rhs later. + // + // In other contexts (e.g. body-of-lambda) will be rewriting + // { + // def y = foo(x,x); + // bar(y,y); + // } + // into something like + // { + // (lambda (y123) bar(y123,y123))(foo(x,x)); + // } + // + // This works in the body of lambda, because we don't evaluate anything + // until lambda definition is complete. + // + // For interactive top-level defs we want to evaluate as we go, + // so need incremental bindings. + + if (p_psm->is_at_toplevel()) { + /** remember variable binding in current lexical context **/ + p_psm->upsert_var(def_expr_.data()->lhs()); + } + + return; + } + p_psm->illegal_input_on_symbol("DDefineSsm::on_parsed_symbol", sym, this->get_expect_str()); } + void + DDefineSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + // note: + // in state def_1, DDefineSsm learns symbol via .on_parsed_symbol(). + // symbol token arriving here means encountered symbol while + // in some other, which can't happen for valid Schematika input + + p_psm->illegal_input_on_token("DDefineSssm::on_symbol_token", + tk, + this->get_expect_str()); + } + void DDefineSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) @@ -421,7 +473,8 @@ namespace xo { if (this->defstate_ == defexprstatetype::def_0) { this->defstate_ = defexprstatetype::def_1; - // expect_symbol_xs::start(p_psm->parser_alloc(), p_psm); + DExpectSymbolSsm::start(p_psm->parser_alloc(), p_psm); + return; } p_psm->illegal_input_on_token("DDefineSsm::on_define_token", diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index cca208f6..4afb9608 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -74,13 +74,48 @@ namespace xo { return "impossible-DExprSeqState::get_expr_str"; } + void + DExprSeqState::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { +#ifdef NOT_YET + obj var = p_psm->lookup_var(tk.text()); + + if (var) { + DProgressSsm::start(var, p_psm); + } else { + p_psm->unknown_variable_error("DExprSeqState::on_symbol_token", + tk, + this->get_expect_str(), + p_psm); + } +#endif + } + break; + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + p_psm->illegal_input_on_token("DExprSeqState::on_symbol_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_def_token(const Token & tk, ParserStateMachine * p_psm) { (void)tk; - DDefineSsm::start(p_psm->parser_alloc(), p_psm); + DDefineSsm::start(p_psm->parser_alloc(), + p_psm->expr_alloc(), + p_psm); /* keyword 'def' introduces a definition: * def pi : f64 = 3.14159265 diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 2076aa5f..44effd57 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -35,7 +35,7 @@ ISyntaxStateMachine_Any::_valid // nonconst methods auto -ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void +ISyntaxStateMachine_Any::on_symbol_token(Opaque, const Token &, ParserStateMachine *) -> void { _fatal(); } @@ -52,6 +52,12 @@ ISyntaxStateMachine_Any::on_if_token(Opaque, const Token &, ParserStateMachine * _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void +{ + _fatal(); +} + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 96020a95..34bd4569 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_symbol_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_symbol(sym, p_psm); + self.on_symbol_token(tk, p_psm); } auto ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void @@ -42,6 +42,11 @@ namespace xo { { self.on_if_token(tk, p_psm); } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index b2efaab5..f00b9c2f 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectSymbolSsm::on_symbol_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_symbol(sym, p_psm); + self.on_symbol_token(tk, p_psm); } auto ISyntaxStateMachine_DExpectSymbolSsm::on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void @@ -42,6 +42,11 @@ namespace xo { { self.on_if_token(tk, p_psm); } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 2279ea88..47c06ba3 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_symbol_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_symbol(sym, p_psm); + self.on_symbol_token(tk, p_psm); } auto ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void @@ -42,6 +42,11 @@ namespace xo { { self.on_if_token(tk, p_psm); } + auto + ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index c05ab217..2e61be95 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -17,7 +17,7 @@ namespace xo { namespace scm { ParserStateMachine::ParserStateMachine(const ArenaConfig & config, - obj * expr_alloc) + obj expr_alloc) : parser_alloc_{DArena::map(config)}, expr_alloc_{expr_alloc}, debug_flag_{config.debug_flag_} @@ -70,6 +70,13 @@ namespace xo { this->stack_ = ParserStack::pop(stack_, parser_alloc_); } + void + ParserStateMachine::upsert_var(DVariable * var) + { + scope log(XO_DEBUG(true), "stub impl"); + log && log(xtag("var", std::string_view(*(var->name())))); + } + void ParserStateMachine::reset_result() { @@ -111,6 +118,10 @@ namespace xo { } switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk); + break; + case tokentype::tk_def: this->on_def_token(tk); break; @@ -125,7 +136,6 @@ namespace xo { case tokentype::tk_i64: case tokentype::tk_f64: case tokentype::tk_string: - case tokentype::tk_symbol: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -165,6 +175,14 @@ namespace xo { } } + void + ParserStateMachine::on_symbol_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_symbol_token(tk, this); + } + void ParserStateMachine::on_def_token(const Token & tk) { @@ -205,7 +223,7 @@ namespace xo { assert(expr_alloc_); - auto errmsg = DString::from_view(*expr_alloc_, + auto errmsg = DString::from_view(expr_alloc_, std::string_view(errmsg_string)); this->capture_error(ssm_name, errmsg); @@ -228,7 +246,7 @@ namespace xo { assert(expr_alloc_); - auto errmsg = DString::from_view(*expr_alloc_, + auto errmsg = DString::from_view(expr_alloc_, std::string_view(errmsg_string)); this->capture_error(ssm_name, errmsg); diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 47f6918b..442da75e 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -19,7 +19,7 @@ namespace xo { // ----- SchematikaParser ----- SchematikaParser::SchematikaParser(const ArenaConfig & config, - obj * expr_alloc, + obj expr_alloc, bool debug_flag) : psm_{config, expr_alloc}, debug_flag_{debug_flag} @@ -38,13 +38,13 @@ namespace xo { void SchematikaParser::begin_interactive_session() { - DExprSeqState::establish_interactive(*(psm_.expr_alloc()), &psm_); + DExprSeqState::establish_interactive(psm_.expr_alloc(), &psm_); } void SchematikaParser::begin_batch_session() { - DExprSeqState::establish_batch(*(psm_.expr_alloc()), &psm_); + DExprSeqState::establish_batch(psm_.expr_alloc(), &psm_); } const ParserResult & diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index b333ff0c..6100392a 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -27,7 +27,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); REQUIRE(parser.debug_flag() == false); REQUIRE(parser.is_at_toplevel() == true); @@ -42,7 +42,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -60,7 +60,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_batch_session(); @@ -78,20 +78,30 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_batch_session(); - auto & result = parser.on_token(Token::def_token()); + { + auto & result = parser.on_token(Token::def_token()); + + // after begin_interactive_session, parser has toplevel exprseq + // but is still "at toplevel" in the sense of ready for input + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("foo")); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_error()); + } // define-expressions not properly implemented - // after begin_interactive_session, parser has toplevel exprseq - // but is still "at toplevel" in the sense of ready for input - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_error()); - REQUIRE(result.error_description()); + //REQUIRE(result.error_description()); } TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") @@ -103,7 +113,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_interactive_session();