From 79d32b61c60ce794e39562af77c3bb61641d91eb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 27 Nov 2025 11:50:34 -0500 Subject: [PATCH] xo-interpreter: plumb initial global symtab so builtins reach parser --- .../include/xo/interpreter/GlobalEnv.hpp | 2 ++ .../xo/interpreter/VirtualSchematikaMachine.hpp | 14 ++++++++------ .../src/interpreter/BuiltinPrimitives.cpp | 3 +++ xo-interpreter/src/interpreter/Schematika.cpp | 11 +++++++++-- .../src/interpreter/VirtualSchematikaMachine.cpp | 10 +++++++--- xo-jit/utest/MachPipeline.test.cpp | 2 +- xo-reader/examples/exprrepl/exprrepl.cpp | 5 +++-- xo-reader/examples/exprreplxx/exprreplxx.cpp | 4 +++- xo-reader/include/xo/reader/parser.hpp | 6 +++++- xo-reader/include/xo/reader/reader.hpp | 3 ++- xo-reader/src/reader/parser.cpp | 6 ++++-- xo-reader/src/reader/reader.cpp | 4 ++-- xo-reader/utest/parser.test.cpp | 5 ++++- xo-reader/utest/reader.test.cpp | 5 ++++- 14 files changed, 57 insertions(+), 23 deletions(-) diff --git a/xo-interpreter/include/xo/interpreter/GlobalEnv.hpp b/xo-interpreter/include/xo/interpreter/GlobalEnv.hpp index 28d15e81..bf43a755 100644 --- a/xo-interpreter/include/xo/interpreter/GlobalEnv.hpp +++ b/xo-interpreter/include/xo/interpreter/GlobalEnv.hpp @@ -26,6 +26,8 @@ namespace xo { gc::IAlloc * get_mm() const { return mm_; } #endif + const rp & symtab() const { return symtab_; } + // inherited from Env.. virtual bool local_contains_var(const std::string & vname) const final override; virtual gp * lookup_slot(const std::string & vname) final override; diff --git a/xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp b/xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp index 91e40312..5b4c29ed 100644 --- a/xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp +++ b/xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp @@ -5,7 +5,7 @@ #include "VsmInstr.hpp" #include "VsmStackFrame.hpp" #include "SchematikaError.hpp" -#include "Env.hpp" +#include "GlobalEnv.hpp" #include "xo/expression/Expression.hpp" #include "xo/object/ObjectConverter.hpp" #include "xo/alloc/Object.hpp" @@ -15,13 +15,13 @@ namespace xo { /** @brief state that may be shared across VirtualSchematikaMachine instances **/ struct VirtualSchematikaMachineFlyweight { explicit VirtualSchematikaMachineFlyweight(gc::IAlloc * mm, - gp env, + gp env, log_level log_level); /** memory allocator for interpreter operation. **/ gc::IAlloc * object_mm_ = nullptr; /** global environment **/ - gp toplevel_env_; + gp toplevel_env_; /** convert TaggedPtr->Object **/ xo::obj::ObjectConverter object_converter_; /** control logging level. higher values -> more logging **/ @@ -37,9 +37,11 @@ namespace xo { using IAlloc = xo::gc::IAlloc; public: - VirtualSchematikaMachine(IAlloc * mm, gp toplevel_env, log_level log_level); + VirtualSchematikaMachine(IAlloc * mm, gp toplevel_env, log_level log_level); ~VirtualSchematikaMachine(); + gp toplevel_env() const { return flyweight_.toplevel_env_; } + /** evaluate expression @p expr. * borrows calling thread until completion * return [value, error]. error ignored unless value is nullptr. @@ -48,7 +50,7 @@ namespace xo { * * Evaluate schematika expression @p expr in environment @p env **/ - std::pair, SchematikaError> eval(bp expr, gp env); + std::pair, SchematikaError> eval(bp expr, gp env); /** evaluate expression @p expr in toplevel environment **/ std::pair, SchematikaError> toplevel_eval(bp expr); @@ -123,7 +125,7 @@ namespace xo { * * caller saves! **/ - gp env_; + gp env_; /** vsm stack. callee saves! **/ diff --git a/xo-interpreter/src/interpreter/BuiltinPrimitives.cpp b/xo-interpreter/src/interpreter/BuiltinPrimitives.cpp index f9dc96cc..1f8f7a1e 100644 --- a/xo-interpreter/src/interpreter/BuiltinPrimitives.cpp +++ b/xo-interpreter/src/interpreter/BuiltinPrimitives.cpp @@ -24,6 +24,9 @@ namespace xo { void BuiltinPrimitives::install(gc::IAlloc * mm, gp env) { + scope log(XO_DEBUG(true)); + + // add(x,y) { gp rhs = xo::obj::make_primitive(mm, add64); TypeDescr td = Reflect::require(); diff --git a/xo-interpreter/src/interpreter/Schematika.cpp b/xo-interpreter/src/interpreter/Schematika.cpp index 942ea685..afa0a9ff 100644 --- a/xo-interpreter/src/interpreter/Schematika.cpp +++ b/xo-interpreter/src/interpreter/Schematika.cpp @@ -28,7 +28,7 @@ namespace xo { * rather than VirtualSchematikaMachine to own allocator * to preserve option to share it **/ - Impl(const Config & config, up mm, gp toplevel_env) : + Impl(const Config & config, up mm, gp toplevel_env) : config_{config}, mm_{std::move(mm)}, vsm_{mm_.get(), toplevel_env, config.vsm_log_level_} {} @@ -44,6 +44,11 @@ namespace xo { void welcome(std::ostream & os); + /** get one line of input. prompt if @p interactive, + * with prompt depending on @p parser_stack_size. + * Use @p rx to perform line editing (when @p interactive). + * Store completed line in @p input. + **/ bool replxx_getline(bool interactive, std::size_t parser_stack_size, replxx::Replxx & rx, @@ -133,6 +138,8 @@ namespace xo { void Schematika::Impl::interactive_repl() { + scope log(XO_DEBUG(true)); + using span_type = xo::scm::span; bool interactive = isatty(STDIN_FILENO); @@ -143,7 +150,7 @@ namespace xo { // rx.bind_key_internal(Replxx::KEY::control('p'), "history_previous"); // rx.bind_key_internal(Replxx::KEY::control('n'), "history_next"); - reader rdr(config_.debug_flag); + reader rdr(vsm_.toplevel_env()->symtab(), config_.debug_flag); rdr.begin_interactive_session(); string input_str; diff --git a/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp b/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp index 53ce2c17..0927e395 100644 --- a/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp +++ b/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp @@ -79,7 +79,7 @@ namespace xo { // ----- VirtualSchematikaMachineFlyweight ----- VirtualSchematikaMachineFlyweight::VirtualSchematikaMachineFlyweight(gc::IAlloc * mm, - gp env, + gp env, log_level ll) : object_mm_{mm}, toplevel_env_{env}, @@ -89,9 +89,11 @@ namespace xo { // ----- VirtualSchematikaMachine ----- VirtualSchematikaMachine::VirtualSchematikaMachine(gc::IAlloc * mm, - gp env, + gp env, log_level ll) : flyweight_{mm, env, ll} { + scope log(XO_DEBUG(true), xtag("env", env), xtag("symtab", env->symtab())); + this->env_ = env; // gc roots @@ -133,8 +135,10 @@ namespace xo { std::pair, SchematikaError> - VirtualSchematikaMachine::eval(bp expr, gp env) + VirtualSchematikaMachine::eval(bp expr, gp env) { + scope log(XO_DEBUG(true), xtag("env", env), xtag("symtab", env->symtab())); + this->pc_ = &VsmOps::eval_op; this->expr_ = expr.promote(); this->env_ = env; diff --git a/xo-jit/utest/MachPipeline.test.cpp b/xo-jit/utest/MachPipeline.test.cpp index f615427a..433365f6 100644 --- a/xo-jit/utest/MachPipeline.test.cpp +++ b/xo-jit/utest/MachPipeline.test.cpp @@ -1,7 +1,7 @@ /* @file MachPipeline.test.cpp */ #include "xo/jit/MachPipeline.hpp" -#include "xo/expression/Primitive.hpp" +#include "xo/expression/PrimitiveExpr.hpp" #include "xo/ratio/ratio.hpp" #include "xo/ratio/ratio_reflect.hpp" #include "xo/reflect/reflect_struct.hpp" diff --git a/xo-reader/examples/exprrepl/exprrepl.cpp b/xo-reader/examples/exprrepl/exprrepl.cpp index 6555e847..64e1c977 100644 --- a/xo-reader/examples/exprrepl/exprrepl.cpp +++ b/xo-reader/examples/exprrepl/exprrepl.cpp @@ -46,10 +46,11 @@ main() { using span_type = xo::scm::span; bool interactive = isatty(STDIN_FILENO); - bool c_debug_flag = false; - reader rdr(c_debug_flag); + auto toplevel_symtab = GlobalSymtab::make_empty(); + + reader rdr(toplevel_symtab, c_debug_flag); rdr.begin_interactive_session(); string input_str; diff --git a/xo-reader/examples/exprreplxx/exprreplxx.cpp b/xo-reader/examples/exprreplxx/exprreplxx.cpp index b338bd2e..e9d8079c 100644 --- a/xo-reader/examples/exprreplxx/exprreplxx.cpp +++ b/xo-reader/examples/exprreplxx/exprreplxx.cpp @@ -83,7 +83,9 @@ main() constexpr bool c_debug_flag = false; - reader rdr(c_debug_flag); + rp toplevel_symtab = GlobalSymtab::make_empty(); + + reader rdr(toplevel_symtab, c_debug_flag); rdr.begin_interactive_session(); string input_str; diff --git a/xo-reader/include/xo/reader/parser.hpp b/xo-reader/include/xo/reader/parser.hpp index 9ef70f83..9db626ee 100644 --- a/xo-reader/include/xo/reader/parser.hpp +++ b/xo-reader/include/xo/reader/parser.hpp @@ -9,6 +9,7 @@ #include "envframestack.hpp" #include "parser_result.hpp" #include "parserstatemachine.hpp" +#include "xo/expression/GlobalSymtab.hpp" #include namespace xo { @@ -161,9 +162,12 @@ namespace xo { /** create parser in initial state; * parser is ready to receive tokens via @ref include_token * + * At least for xo-interpreter will have non-empty symbol table. + * + * @p toplevel_symtab symbol table. * @p debug_flag true to enable debug logging **/ - explicit parser(bool debug_flag); + parser(const rp & toplevel_symtab, bool debug_flag); bool debug_flag() const { return psm_.debug_flag(); } diff --git a/xo-reader/include/xo/reader/reader.hpp b/xo-reader/include/xo/reader/reader.hpp index 546b923c..5d0ec503 100644 --- a/xo-reader/include/xo/reader/reader.hpp +++ b/xo-reader/include/xo/reader/reader.hpp @@ -8,6 +8,7 @@ #include "parser.hpp" #include "reader_error.hpp" #include "xo/expression/Expression.hpp" +#include "xo/expression/GlobalSymtab.hpp" #include "xo/expression/pretty_expression.hpp" #include "xo/tokenizer/tokenizer.hpp" @@ -78,7 +79,7 @@ namespace xo { using span_type = tokenizer_type::span_type; public: - explicit reader(bool debug_flag); + reader(const rp & toplevel_symtab, bool debug_flag); bool debug_flag() const { return parser_.debug_flag(); } diff --git a/xo-reader/src/reader/parser.cpp b/xo-reader/src/reader/parser.cpp index 2469593b..3c3f7050 100644 --- a/xo-reader/src/reader/parser.cpp +++ b/xo-reader/src/reader/parser.cpp @@ -24,13 +24,15 @@ namespace xo { namespace scm { // ----- parser ----- - parser::parser(bool debug_flag) + parser::parser(const rp & toplevel_symtab, bool debug_flag) : psm_{debug_flag} { +#ifdef OBSOLETE /* top-level environment. initially empty */ rp toplevel_env = GlobalSymtab::make_empty(); +#endif - this->psm_.env_stack_.push_envframe(toplevel_env); + this->psm_.env_stack_.push_envframe(toplevel_symtab); } bool diff --git a/xo-reader/src/reader/reader.cpp b/xo-reader/src/reader/reader.cpp index b19ea718..7bac4435 100644 --- a/xo-reader/src/reader/reader.cpp +++ b/xo-reader/src/reader/reader.cpp @@ -4,9 +4,9 @@ namespace xo { namespace scm { - reader::reader(bool debug_flag) : + reader::reader(const rp & toplevel_symtab, bool debug_flag) : tokenizer_{debug_flag}, - parser_{debug_flag} + parser_{toplevel_symtab, debug_flag} {} void diff --git a/xo-reader/utest/parser.test.cpp b/xo-reader/utest/parser.test.cpp index 004b8497..3d6f3fac 100644 --- a/xo-reader/utest/parser.test.cpp +++ b/xo-reader/utest/parser.test.cpp @@ -10,6 +10,7 @@ namespace xo { using parser_type = xo::scm::parser; using token_type = parser_type::token_type; + using xo::scm::GlobalSymtab; using xo::scm::exprstatetype; using xo::scm::define_xs; using xo::scm::defexprstatetype; @@ -23,7 +24,9 @@ namespace xo { for (std::size_t i_tc = 0; i_tc < 2; ++i_tc) { constexpr bool c_debug_flag = true; - parser_type parser(c_debug_flag); + rp toplevel_symtab = GlobalSymtab::make_empty(); + + parser_type parser(toplevel_symtab, c_debug_flag); scope log(XO_DEBUG(c_debug_flag), xtag("i_tc", i_tc)); diff --git a/xo-reader/utest/reader.test.cpp b/xo-reader/utest/reader.test.cpp index d9a55dd5..11d84edb 100644 --- a/xo-reader/utest/reader.test.cpp +++ b/xo-reader/utest/reader.test.cpp @@ -5,6 +5,7 @@ namespace xo { using xo::scm::reader; + using xo::scm::GlobalSymtab; namespace ut { namespace { @@ -30,7 +31,9 @@ namespace xo { for (std::size_t i_tc = 0; i_tc < s_testcase_v.size(); ++i_tc) { const test_case & tc = s_testcase_v[i_tc]; - reader rdr(c_debug_flag); + rp toplevel_symtab = GlobalSymtab::make_empty(); + + reader rdr(toplevel_symtab, c_debug_flag); scope log(XO_ENTER2(always, c_debug_flag, "reader.testcase"), xtag("i_tc", i_tc));