diff --git a/idl/SyntaxStateMachine.json5 b/idl/SyntaxStateMachine.json5 index 2be2a98d..28811512 100644 --- a/idl/SyntaxStateMachine.json5 +++ b/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/include/xo/reader2/DDefineSsm.hpp b/include/xo/reader2/DDefineSsm.hpp index 37ccc23d..3bc042c1 100644 --- a/include/xo/reader2/DDefineSsm.hpp +++ b/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/include/xo/reader2/DExprSeqState.hpp b/include/xo/reader2/DExprSeqState.hpp index 1b611aaf..bef2bd68 100644 --- a/include/xo/reader2/DExprSeqState.hpp +++ b/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/include/xo/reader2/ParserResult.hpp b/include/xo/reader2/ParserResult.hpp index e179d4bd..39f9c2d1 100644 --- a/include/xo/reader2/ParserResult.hpp +++ b/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/include/xo/reader2/ParserStateMachine.hpp b/include/xo/reader2/ParserStateMachine.hpp index f5293bff..5a7a833f 100644 --- a/include/xo/reader2/ParserStateMachine.hpp +++ b/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/include/xo/reader2/SchematikaParser.hpp b/include/xo/reader2/SchematikaParser.hpp index 075fb4fc..2f7d6d95 100644 --- a/include/xo/reader2/SchematikaParser.hpp +++ b/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/include/xo/reader2/SyntaxStateMachine.hpp b/include/xo/reader2/SyntaxStateMachine.hpp index 56a8271b..deda9e1d 100644 --- a/include/xo/reader2/SyntaxStateMachine.hpp +++ b/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/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index b181fd8d..4f428be5 100644 --- a/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/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/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 046adacb..23b90621 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/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/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index cfb38fa7..d420ba16 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/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/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 44cb6de4..ba8eb0b9 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/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/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 4da00f95..c1e61b40 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/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/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 7de32e25..5a8e2fe3 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/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/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index f35f4e72..786c83d0 100644 --- a/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/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/src/reader2/DDefineSsm.cpp b/src/reader2/DDefineSsm.cpp index 8ac919e4..adf9f429 100644 --- a/src/reader2/DDefineSsm.cpp +++ b/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/src/reader2/DExprSeqState.cpp b/src/reader2/DExprSeqState.cpp index cca208f6..4afb9608 100644 --- a/src/reader2/DExprSeqState.cpp +++ b/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/src/reader2/ISyntaxStateMachine_Any.cpp b/src/reader2/ISyntaxStateMachine_Any.cpp index 2076aa5f..44effd57 100644 --- a/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/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/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 96020a95..34bd4569 100644 --- a/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/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/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index b2efaab5..f00b9c2f 100644 --- a/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/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/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 2279ea88..47c06ba3 100644 --- a/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/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/src/reader2/ParserStateMachine.cpp b/src/reader2/ParserStateMachine.cpp index c05ab217..2e61be95 100644 --- a/src/reader2/ParserStateMachine.cpp +++ b/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/src/reader2/SchematikaParser.cpp b/src/reader2/SchematikaParser.cpp index 47f6918b..442da75e 100644 --- a/src/reader2/SchematikaParser.cpp +++ b/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/utest/SchematikaParser.test.cpp b/utest/SchematikaParser.test.cpp index b333ff0c..6100392a 100644 --- a/utest/SchematikaParser.test.cpp +++ b/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();