From d11f6ca5977b1f6b79b201652ce37e631f6d48ba Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 6 Jun 2026 22:12:50 -0400 Subject: [PATCH] .xo-interpreter subrepo tidy --- .xo-interpreter/CMakeLists.txt | 41 - .xo-interpreter/README.md | 1 - .../cmake/xo-bootstrap-macros.cmake | 41 - .../cmake/xo_interpreterConfig.cmake.in | 8 - .xo-interpreter/docs/CMakeLists.txt | 9 - .xo-interpreter/docs/README | 41 - .xo-interpreter/docs/_static/README | 1 - .xo-interpreter/docs/_static/img/favicon.ico | Bin 309936 -> 0 bytes .xo-interpreter/docs/conf.py | 39 - .xo-interpreter/docs/index.rst | 12 - .xo-interpreter/docs/install.rst | 202 ---- .xo-interpreter/example/CMakeLists.txt | 1 - .xo-interpreter/example/replxx/CMakeLists.txt | 17 - .xo-interpreter/example/replxx/replxx.cpp | 19 - .../xo/interpreter/BuiltinPrimitives.hpp | 36 - .../include/xo/interpreter/Env.hpp | 47 - .../xo/interpreter/ExpressionBoxed.hpp | 48 - .../include/xo/interpreter/GlobalEnv.hpp | 73 -- .../include/xo/interpreter/LocalEnv.hpp | 95 -- .../include/xo/interpreter/Schematika.hpp | 70 -- .../xo/interpreter/SchematikaError.hpp | 28 - .../interpreter/VirtualSchematikaMachine.hpp | 187 ---- .../include/xo/interpreter/VsmInstr.hpp | 80 -- .../include/xo/interpreter/VsmStackFrame.hpp | 83 -- .../xo/interpreter/init_interpreter.hpp | 21 - .../src/interpreter/BuiltinPrimitives.cpp | 94 -- .../src/interpreter/CMakeLists.txt | 24 - .../src/interpreter/ExpressionBoxed.cpp | 59 -- .xo-interpreter/src/interpreter/GlobalEnv.cpp | 127 --- .xo-interpreter/src/interpreter/LocalEnv.cpp | 185 ---- .../src/interpreter/Schematika.cpp | 284 ------ .../interpreter/VirtualSchematikaMachine.cpp | 865 ------------------ .xo-interpreter/src/interpreter/VsmInstr.cpp | 16 - .../src/interpreter/VsmStackFrame.cpp | 177 ---- .../src/interpreter/init_interpreter.cpp | 27 - .xo-interpreter/utest/CMakeLists.txt | 12 - .xo-interpreter/utest/LocalEnv.test.cpp | 134 --- .../utest/interpreter_utest_main.cpp | 6 - 38 files changed, 3210 deletions(-) delete mode 100644 .xo-interpreter/CMakeLists.txt delete mode 100644 .xo-interpreter/README.md delete mode 100644 .xo-interpreter/cmake/xo-bootstrap-macros.cmake delete mode 100644 .xo-interpreter/cmake/xo_interpreterConfig.cmake.in delete mode 100644 .xo-interpreter/docs/CMakeLists.txt delete mode 100644 .xo-interpreter/docs/README delete mode 100644 .xo-interpreter/docs/_static/README delete mode 100644 .xo-interpreter/docs/_static/img/favicon.ico delete mode 100644 .xo-interpreter/docs/conf.py delete mode 100644 .xo-interpreter/docs/index.rst delete mode 100644 .xo-interpreter/docs/install.rst delete mode 100644 .xo-interpreter/example/CMakeLists.txt delete mode 100644 .xo-interpreter/example/replxx/CMakeLists.txt delete mode 100644 .xo-interpreter/example/replxx/replxx.cpp delete mode 100644 .xo-interpreter/include/xo/interpreter/BuiltinPrimitives.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/Env.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/ExpressionBoxed.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/GlobalEnv.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/LocalEnv.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/Schematika.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/SchematikaError.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/VsmInstr.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp delete mode 100644 .xo-interpreter/include/xo/interpreter/init_interpreter.hpp delete mode 100644 .xo-interpreter/src/interpreter/BuiltinPrimitives.cpp delete mode 100644 .xo-interpreter/src/interpreter/CMakeLists.txt delete mode 100644 .xo-interpreter/src/interpreter/ExpressionBoxed.cpp delete mode 100644 .xo-interpreter/src/interpreter/GlobalEnv.cpp delete mode 100644 .xo-interpreter/src/interpreter/LocalEnv.cpp delete mode 100644 .xo-interpreter/src/interpreter/Schematika.cpp delete mode 100644 .xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp delete mode 100644 .xo-interpreter/src/interpreter/VsmInstr.cpp delete mode 100644 .xo-interpreter/src/interpreter/VsmStackFrame.cpp delete mode 100644 .xo-interpreter/src/interpreter/init_interpreter.cpp delete mode 100644 .xo-interpreter/utest/CMakeLists.txt delete mode 100644 .xo-interpreter/utest/LocalEnv.test.cpp delete mode 100644 .xo-interpreter/utest/interpreter_utest_main.cpp diff --git a/.xo-interpreter/CMakeLists.txt b/.xo-interpreter/CMakeLists.txt deleted file mode 100644 index a14ee394..00000000 --- a/.xo-interpreter/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -# xo-interpreter/CMakeLists.txt - -cmake_minimum_required(VERSION 3.10) - -project (xo_interpreter VERSION 0.1) - -include(GNUInstallDirs) -include(cmake/xo-bootstrap-macros.cmake) - -xo_cxx_toplevel_options3() - -# ---------------------------------------------------------------- -# c++ settings - -set(PROJECT_CXX_FLAGS "") -#set(PROJECT_CXX_FLAGS "-fconcepts-diagnostics-depth=2") # gcc-only! -add_definitions(${PROJECT_CXX_FLAGS}) - -# ---------------------------------------------------------------- - -# note on ordering: must read .cmake defn of lib before configuring any examples -add_subdirectory(src/interpreter) -xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) - -# ---------------------------------------------------------------- - -add_subdirectory(example) -add_subdirectory(utest) - -# ---------------------------------------------------------------- - -#if (XO_ENABLE_EXAMPLES) -# install(TARGETS xo_interpreter_ex1 DESTINATION bin/xo/example) -#endif() - -# ---------------------------------------------------------------- -# docs targets depend on all other library/utest targets -# -#add_subdirectory(docs) - -# end CMakeLists.txt diff --git a/.xo-interpreter/README.md b/.xo-interpreter/README.md deleted file mode 100644 index 133805c0..00000000 --- a/.xo-interpreter/README.md +++ /dev/null @@ -1 +0,0 @@ -# xo-interpreter diff --git a/.xo-interpreter/cmake/xo-bootstrap-macros.cmake b/.xo-interpreter/cmake/xo-bootstrap-macros.cmake deleted file mode 100644 index 592272c0..00000000 --- a/.xo-interpreter/cmake/xo-bootstrap-macros.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# ---------------------------------------------------------------- -# for example: -# $ PREFIX=/usr/local # for example -# $ cmake -DCMAKE_MODULE_PATH=prefix -DCMAKE_INSTALL_PREFIX=$PREFIX -B .build -# -# will get -# CMAKE_MODULE_PATH -# from xo-cmake-config --cmake-module-path -# -# and expect .cmake macros in -# CMAKE_MODULE_PATH/xo_macros/xo_cxx.cmake -# ---------------------------------------------------------------- - -find_program(XO_CMAKE_CONFIG_EXECUTABLE NAMES xo-cmake-config REQUIRED) - -if ("${XO_CMAKE_CONFIG_EXECUTABLE}" STREQUAL "XO_CMAKE_CONFIG_EXECUTABLE-NOT_FOUND") - message(FATAL "could not find xo-cmake-config executable") -endif() - -message(STATUS "XO_CMAKE_CONFIG_EXECUTABLE=${XO_CMAKE_CONFIG_EXECUTABLE}") - -if (XO_SUBMODULE_BUILD) - if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) - # local version of xo-cmake macros - set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/xo-cmake/cmake") - message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") - endif() -else() - if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) - # default to typical install location for xo-project-macros - execute_process(COMMAND ${XO_CMAKE_CONFIG_EXECUTABLE} --cmake-module-path OUTPUT_VARIABLE CMAKE_MODULE_PATH) - message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") - endif() -endif() - -# needs to have been installed somewhere on CMAKE_MODULE_PATH, -# (e.g. from xo-cmake with the same value for CMAKE_INSTALL_PREFIX) -# -include(xo_macros/xo_cxx) - -xo_cxx_bootstrap_message() diff --git a/.xo-interpreter/cmake/xo_interpreterConfig.cmake.in b/.xo-interpreter/cmake/xo_interpreterConfig.cmake.in deleted file mode 100644 index a1dba569..00000000 --- a/.xo-interpreter/cmake/xo_interpreterConfig.cmake.in +++ /dev/null @@ -1,8 +0,0 @@ -@PACKAGE_INIT@ - -include(CMakeFindDependencyMacro) -find_dependency(xo_alloc) -#find_dependency(xo_flatstring) -include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Share.cmake") -check_required_components("@PROJECT_NAME@") diff --git a/.xo-interpreter/docs/CMakeLists.txt b/.xo-interpreter/docs/CMakeLists.txt deleted file mode 100644 index b9df2dd6..00000000 --- a/.xo-interpreter/docs/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# xo-alloc/docs/CMakeLists.txt - -xo_doxygen_collect_deps() -xo_docdir_doxygen_config() -xo_docdir_sphinx_config( - index.rst install.rst) - -# see xo-reader/doc or xo-unit/doc for working examples -# example.rst install.rst implementation.rst diff --git a/.xo-interpreter/docs/README b/.xo-interpreter/docs/README deleted file mode 100644 index 6aff5d41..00000000 --- a/.xo-interpreter/docs/README +++ /dev/null @@ -1,41 +0,0 @@ -standalone build - - +-----------------------------------------------+ - | cmake | - | CMakeLists.txt | - | $PREFIX/share/cmake/xo_macros/xo_cxx.cmake | - +-----------------------------------------------+ - | - | +----------------------+ - +------------------------------------------------->| .build/docs/Doxyfile | - | +----------------------+ - | ^ - | (cmake) | - | /------------/ - | | - | +---------------------------------------+ +-----------------+ - +---->| doxygen |--------->| .build/docs/dox | - | | $PREFIX/share/xo-macros/Doxyfile.in | (doxygen)| +- html/ | - | +---------------------------------------+ | +- xml/ | - | +-----------------+ - | | - | |(sphinx) - | | - | v - | +---------------------------------------+ +--------------------+ - \---->| sphinx |------->| .build/docs/sphinx | - | +- conf.py | | +- html/ | - | +- _static/ | +--------------------+ - | +- *.rst | - +---------------------------------------+ - -umbrella build relies on top-level cmake macros - -files - - README this file - CMakeLists.txt build entry point - conf.py sphinx config - _static static files for sphinx - - index.rst toplevel sphinx document; entry point diff --git a/.xo-interpreter/docs/_static/README b/.xo-interpreter/docs/_static/README deleted file mode 100644 index 8230095c..00000000 --- a/.xo-interpreter/docs/_static/README +++ /dev/null @@ -1 +0,0 @@ -add any static {.html, .js, ..} files for sphinx to pickup here \ No newline at end of file diff --git a/.xo-interpreter/docs/_static/img/favicon.ico b/.xo-interpreter/docs/_static/img/favicon.ico deleted file mode 100644 index 4163dd69c734f8186cf1ce5e726213cebd231c31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309936 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 uml diagrams - ] - -# note: breathe requires doxygen xml output -> must have GENERATE_XML = YES in Doxyfile.in -# match project name in Doxyfile.in -breathe_default_project = "xodoxxml" - -templates_path = ['_templates'] -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -pygments_style = 'sphinx' - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -#html_theme = 'alabaster' -html_theme = 'sphinx_rtd_theme' -html_static_path = ['_static'] -html_favicon = '_static/img/favicon.ico' diff --git a/.xo-interpreter/docs/index.rst b/.xo-interpreter/docs/index.rst deleted file mode 100644 index e5b5a1c2..00000000 --- a/.xo-interpreter/docs/index.rst +++ /dev/null @@ -1,12 +0,0 @@ -.. xo-interpreter documentation master file. - -xo-interpreter documentation -============================ - -xo-interpreter provides an interpreter for the Schematika language - -.. toctree:: - :maxdepth: 2 - :caption: xo-interpreter contents - - install diff --git a/.xo-interpreter/docs/install.rst b/.xo-interpreter/docs/install.rst deleted file mode 100644 index 827bb1b0..00000000 --- a/.xo-interpreter/docs/install.rst +++ /dev/null @@ -1,202 +0,0 @@ -.. _install: - -.. toctree: - :maxdepth: 2 - -Source -====== - -Source code lives on github `here`_ - -.. _here: https://github.com/rconybea/xo-interpreter - -To clone from git: - -.. code-block:: bash - - git clone https://github.com/rconybea/xo-interpreter - -Tested with gcc 14.2 - -Install -======= - -One-step Install ----------------- - -Install xo-interpreter along with the rest of *XO* from `xo-umbrella2 source`_: -see install instructions for xo-umbrella2. - -.. _xo-umbrella2 source: https://github.com/rconybea/xo-umbrella2 - -Essential Xo Dependencies -------------------------- - -``xo-interpreter`` uses several supporting libraries from elsewhere in the *XO* project: - -- `xo-reader source`_ (Schematika expression parser) -- `xo-expression source`_ (Schematika AST representation) -- `xo-tokenizer source`_ (Schematika lexer) -- `xo-object source`_ (gc-eligible runtime polymorphism) -- `xo-randomgen source`_ (fast pseudo-random number generators) -- `xo-alloc source`_ (arena allocators, garbage collector) -- `xo-unit source`_ (dimension checking library) -- `xo-ratio source`_ (exact ratio library) -- `xo-flatstring source`_ (no-allocation string library) -- `xo-callback source`_ (callback library) -- `xo-reflectutil source`_ (reflection utils for participating libs) -- `xo-reflect source`_ (reflection library) -- `xo-refcnt source`_ (reference-counting library) -- `xo-subsys source`_ (utility library) -- `xo-indentlog source`_ (structured logging, pretty-printing) -- `xo-cmake source`_ (shared cmake macros) - -.. _xo-reader source: https://github.com/rconybea/xo-reader -.. _xo-expression source: https://github.com/rconybea/xo-expression -.. _xo-tokenizer source: https://github.com/rconybea/xo-tokenizer -.. _xo-object source: https://github.com/rconybea/xo-object -.. _xo-randomgen source: https://github.com/rconybea/xo-randomgen -.. _xo-alloc source: https://github.com/rconybea/xo-alloc -.. _xo-unit source: https://github.com/rconybea/xo-unit -.. _xo-ratio source: https://github.com/rconybea/xo-ratio -.. _xo-flatstring source: https://github.comr/rconybea/xo-flatstring -.. _xo-callback source: https://github.com/rconybea/xo-callback -.. _xo-reflect source: https://github.com/rconybea/xo-reflect -.. _xo-refcnt source: https://github.com/rconybea/refcnt -.. _xo-subsys source: https://github.com/rconybea/subsys -.. _xo-indentlog source: https://github.com/rconybea/indentlog -.. _xo-cmake source: https://github.com/rconybea/xo-cmake - -Building from source --------------------- - -Instructions for building xo-interpreter from source, along with only its essential dependencies. - -Install scripts for XO libraries depend on helper scripts installed from `xo-cmake`. - -Preamble: - -.. code-block:: bash - - mkdir -p ~/proj/xo - cd ~/proj/xo - - git clone https://github.com/rconybea/xo-cmake - - PREFIX=$HOME/local # or desired installation path - - # will want PREFIX/bin in PATH to use xo-cmake helpers - PATH=$PREFIX/bin:$PATH - -Isntall `xo-cmake`: - -.. code-block:: bash - - cmake -B xo-cmake/.build -S xo-cmake - cmake --install xo-cmake/.build - -Now that we have xo-build in PATH, can build+install XO components in topological order: - -.. code-block:: bash - - xo-build --clone --configure --build --install xo-indentlog - xo-build --clone --configure --build --install xo-subsys - xo-build --clone --configure --build --install xo-refcnt - xo-build --clone --configure --build --install xo-reflect - xo-build --clone --configure --build --install xo-reflectutil - xo-build --clone --configure --build --install xo-callback - xo-build --clone --configure --build --install xo-flatstring - xo-build --clone --configure --build --install xo-ratio - xo-build --clone --configure --build --install xo-unit - xo-build --clone --configure --build --install xo-alloc - xo-build --clone --configure --build --install xo-randomgen - xo-build --clone --configure --build --install xo-object - xo-build --clone --configure --build --install xo-tokenizer - xo-build --clone --configure --build --install xo-expression - xo-build --clone --configure --build --install xo-reader - -Directories under ``PREFIX`` will then contain something like: - -.. code-block:: - - PREFIX - += bin - | +- xo-build - │ +- xo-cmake-config - │ \- xo-cmake-lcov-harness - +─ include - | \- xo - │ +- alloc/ - | +- callback/ - | +- cxxutil/ - | +- expression/ - | | +- typeinf/ - | | .. - | +- flatstring/ - | +- indentlog/ - | | +- machdep/ - | | +- print/ - | | +- timeutil/ - | | .. - | +- object/ - | +- randomgen/ - | +- ratio/ - | +- reader/ - | +- refcnt/ - | +- reflect/ - | | +- atomic/ - | | +- function/ - | | +- pointer/ - | | +- struct/ - | | +- vector/ - | | .. - | +- reflectutil/ - | +- subsys/ - | +- tokenizer/ - | \- unit/ - +- lib - | +- cmake - | | +- callback/ - | | +- indentlog/ - | | +- randomgen/ - | | +- refcnt/ - | | +- reflect/ - | | +- subsys/ - | | +- xo_alloc/ - | | +- xo_expression/ - | | +- xo_flatstring/ - | | +- xo_object/ - | | +- xo_ratio/ - | | +- xo_reader/ - | | +- xo_reflectutil/ - | | +- xo_tokenizer/ - | | \- xo_unit/ - | +- librefcnt.so - | .. - \- share - +- cmake - | \- xo-macros - | +- code-coverage.cmake - | +- xo_cxx.cmake - | \- xo-project-macros.cmake - +- etc - | \- xo - | \- subsystem_list - +- xo-macros - +- Doxyfile.in - +- gen-ccov.in - \- xo-bootstrap-macros.cmake - -CMake Support -------------- - -To use built-in cmake support, when using ``xo-interpreter`` from another project: - -Make sure ``PREFIX/lib/cmake`` is searched by cmake (for example include it in ``CMAKE_PREFIX_PATH``) - -Add to your ``CMakeLists.txt``: - -.. code-block:: cmake - - FindPackage(xo_interpreter CONFIG REQUIRED) - target_link_libraries(mytarget PUBLIC xo_interpreter) diff --git a/.xo-interpreter/example/CMakeLists.txt b/.xo-interpreter/example/CMakeLists.txt deleted file mode 100644 index ce7aaf20..00000000 --- a/.xo-interpreter/example/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(replxx) diff --git a/.xo-interpreter/example/replxx/CMakeLists.txt b/.xo-interpreter/example/replxx/CMakeLists.txt deleted file mode 100644 index 96f11ae4..00000000 --- a/.xo-interpreter/example/replxx/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# xo-interpreter/example/replxx/CMakeLists.txt - -set(SELF_EXE xo_interpreter_replxx) -set(SELF_SRCS replxx.cpp) - -if (XO_ENABLE_EXAMPLES) - xo_add_executable(${SELF_EXE} ${SELF_SRCS}) - xo_self_dependency(${SELF_EXE} xo_interpreter) - # TODO: consider promoting to regular app - xo_dependency(${SELF_EXE} xo_reader) - xo_external_target_dependency(${SELF_EXE} replxx replxx::replxx) - - find_package(Threads REQUIRED) - target_link_libraries(${SELF_EXE} PUBLIC Threads::Threads) -endif() - -# end CMakeLists.txt diff --git a/.xo-interpreter/example/replxx/replxx.cpp b/.xo-interpreter/example/replxx/replxx.cpp deleted file mode 100644 index ef677594..00000000 --- a/.xo-interpreter/example/replxx/replxx.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/** @file replxx.cpp **/ - -#include "xo/interpreter/Schematika.hpp" - -int -main(int argc, char ** argv) -{ - using xo::log_level; - using xo::scm::Schematika; - - Schematika::Config cfg; - cfg.debug_flag = true; - cfg.vsm_log_level_ = log_level::verbose; - Schematika scm = Schematika::make(cfg); - - scm.interactive_repl(); -} - -/* end replxx.cpp */ diff --git a/.xo-interpreter/include/xo/interpreter/BuiltinPrimitives.hpp b/.xo-interpreter/include/xo/interpreter/BuiltinPrimitives.hpp deleted file mode 100644 index 39995b23..00000000 --- a/.xo-interpreter/include/xo/interpreter/BuiltinPrimitives.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/** @file BuiltinPrimitives.hpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#include "xo/object/ObjectConverter.hpp" -#include "xo/allocutil/IAlloc.hpp" -#include "Primitive.hpp" -#include "GlobalEnv.hpp" - -namespace xo { - namespace scm { - struct BuiltinPrimitives { - public: - using ObjectConverter = xo::obj::ObjectConverter; - - template - static void install_pm(gc::IAlloc * mm, rp pm_expr, gp env) { - gp rhs - = xo::obj::make_primitive(mm, pm_expr->name(), pm_expr->value()); - - /* store in env using this variable-expr */ - rp lhs - = Variable::make(pm_expr->name(), pm_expr->value_td()); - - gp * addr = env->establish_var(lhs.borrow()); - - *addr = rhs; - } - - static void install(gc::IAlloc * mm, gp env); - }; - } -} - -/* end BuiltinPrimitives.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/Env.hpp b/.xo-interpreter/include/xo/interpreter/Env.hpp deleted file mode 100644 index bce51319..00000000 --- a/.xo-interpreter/include/xo/interpreter/Env.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/** @file Env.hpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#pragma once - -#include "xo/alloc/Object.hpp" -#include "xo/refcnt/Refcounted.hpp" - -namespace xo { - namespace scm { - class Variable; // see xo::scm::Variable in xo/expression/Variable.hpp - - /** @class Env - * @brief runtime environment, holding variable bindings for schematika interpreter - * - * Garbage-collected - * - * TODO: rename xo-expression xo::scm::Environment -> xo::scm::SymbolTable - **/ - class Env : public Object { - public: - /** true iff @p vname is present in Symtab for innermost environment **/ - virtual bool local_contains_var(const std::string & vname) const = 0; - - /** Fetch storage location for innermost binding of variable with name @p vname. - * nullptr if not found - **/ - virtual gp * lookup_slot(const std::string & vname) = 0; - - /** require storage for variable @p v. - * will also establish binding path. - * - * Intended for introducing a new variable, - * replacing any previous variable with the same name. - * - * Beware of invalidating type correctness - * - * @return slot address for runtime value of @p v - **/ - virtual gp * establish_var(bp v) = 0; - - //gp lookup_symbol(const std::string & name) const; - }; - } /*namespace scm*/ -} /*namespace xo*/ diff --git a/.xo-interpreter/include/xo/interpreter/ExpressionBoxed.hpp b/.xo-interpreter/include/xo/interpreter/ExpressionBoxed.hpp deleted file mode 100644 index 5668a08a..00000000 --- a/.xo-interpreter/include/xo/interpreter/ExpressionBoxed.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/** @file ExpressionBoxed.hpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#pragma once - -#include "xo/alloc/Object.hpp" -#include "xo/expression/Expression.hpp" - -namespace xo { - namespace scm { - /** @class ExpressionBoxed - * @brief xo::scm::Expression, adapted to xo::Object interface - **/ - class ExpressionBoxed : public Object { - public: - explicit ExpressionBoxed(bp c); - - /** create boxed version of @p c, using allocator @p mm **/ - static gp make(gc::IAlloc * mm, - bp c); - - /** runtime downcast **/ - static gp from(gp x) { - return gp::from(x); - } - - const rp & contents() const { return contents_; } - - // inherited from Object - virtual TaggedPtr self_tp() const final override; - virtual void display(std::ostream & os) const final override; - virtual std::size_t _shallow_size() const final override; - virtual Object * _shallow_copy(gc::IAlloc * mm) const final override; - virtual std::size_t _forward_children(gc::IAlloc * /*gc*/) final override; - - private: - /** reference-counted Expression pointer - * - * NOTE correctness requires finalization support in xo::gc::GC - **/ - rp contents_; - }; - } /*namespace scm*/ -} /*namespace xo*/ - -/* end ExpressionBoxed.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/GlobalEnv.hpp b/.xo-interpreter/include/xo/interpreter/GlobalEnv.hpp deleted file mode 100644 index 50e765ba..00000000 --- a/.xo-interpreter/include/xo/interpreter/GlobalEnv.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/** @file GlobalEnv.hpp **/ - -#pragma once - -#include "Env.hpp" -#include "xo/allocutil/IAlloc.hpp" -#include "xo/expression/GlobalSymtab.hpp" - -namespace xo { - namespace scm { - /** @class GlobalEnv - * @brief Top-level global environment - **/ - class GlobalEnv : public Env { - public: - using map_type = std::map>; - - public: - /** Create top-level global environment, allocating via @p mm. - * Expect one of these per interpreter session. - **/ - static gp make_empty(gc::IAlloc * mm, - const rp & symtab); - -#ifdef NOT_USING - 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; - virtual gp * establish_var(bp var) final override; - - // inherited from Object.. - virtual TaggedPtr self_tp() const final override; - virtual void display(std::ostream & os) const final override; - virtual std::size_t _shallow_size() const final override; - virtual Object * _shallow_copy(gc::IAlloc * mm) const final override; - virtual std::size_t _forward_children(gc::IAlloc * mm) final override; - - private: - GlobalEnv(const GlobalEnv & x); - GlobalEnv(gc::IAlloc * mm, const rp & symtab); - - private: - /** memory manager to use **/ - gc::IAlloc * mm_ = nullptr; - - /** global symbol table. - * variables known to @c symtab_ are represented by - * corresponding values in @p slot_map_ - **/ - rp symtab_; - - /** environment contents. - * expression @c symtab_->lookup_binding(vname) - * has associated value @c slot_map_.at(vname) - * - * TODO: replace with something subject to GC ? - * every member of @ref slot_map_ will have to be a - * GC root - * - * TODO: probably want to hash here instead. - * May also want lhs names to be separately hashed symbols - **/ - up slot_map_; - }; - } /*namespace scm*/ -} /*namespace xo*/ - -/* end GlobalEnv.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/LocalEnv.hpp b/.xo-interpreter/include/xo/interpreter/LocalEnv.hpp deleted file mode 100644 index 9745a854..00000000 --- a/.xo-interpreter/include/xo/interpreter/LocalEnv.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/** @file LocalEnv.hpp **/ - -#include "Env.hpp" -#include "CVector.hpp" -#include "xo/allocutil/IAlloc.hpp" -#include "xo/expression/LocalSymtab.hpp" -#include -#include - -namespace xo { - namespace scm { - /** @class LocalEnv - * @brief Represent a single runtime stack frame for a Schematika function - * - * LocalEnv intended to be used for interpreted functions. - * - * Compiled functions will still likely have stack frames, but need not use the - * @ref LocalEnv class - * - * memory layout: - * ^ - * +-----------------------+ | - * | vtable | | - * +-----------------------+ | - * | .parent +------/ - * +------------+----------+ - * | .slot_v_ | .n_ | - * | +----------+ - * | | .v_ +------\ - * +------------+----------+ <--/ - * | .v_[0] +---------> Object(1) - * +-----------------------+ - * . .. . - * +-----------------------+ - * | .v_[.n_-1] +---------> Object(n) - * +-----------------------+ - **/ - class LocalEnv : public Env { - public: - using TaggedPtr = xo::reflect::TaggedPtr; - - public: - LocalEnv(gc::IAlloc * mm, gp p, const rp & s, std::size_t n); - - /** create frame using allocator @p mm, - * with parent @p p and exactly @p n_slot object pointers. - * variable types are taken from symbol table @p s. - **/ - static gp make(gc::IAlloc * mm, - gp p, - const rp & s, - std::size_t n_slot); - - /** reflect LocalEnv object representation **/ - static void reflect_self(); - - gp parent() const { return parent_; } - std::size_t size() const { return slot_v_.size(); } - - gp operator[](std::size_t i) const { return slot_v_[i]; } - gp & operator[](std::size_t i) { return slot_v_[i]; } - - // 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; - - /** LocalEnv policy is that variable can be established once only. - * For example function arguments must all have distinct names. - **/ - virtual gp * establish_var(bp v) final override; - - // inherited from Object.. - virtual TaggedPtr self_tp() const final override; - virtual void display(std::ostream & os) const final override; - virtual std::size_t _shallow_size() const final override; - virtual Object * _shallow_copy(gc::IAlloc * mm) const final override; - virtual std::size_t _forward_children(gc::IAlloc * /*gc*/) final override; - - private: - /** parent stack frame **/ - gp parent_; - /** origin symbol table. records variable names and bindings. - * for a binding path p with leaf slot index j = p.j_slot_: - * @c slot_v_[j] holds value associated with variable @c symtab_->argv_[j] - **/ - rp symtab_; - /** environment contents **/ - obj::CVector> slot_v_; - }; - } /*namespace scm*/ -} /*namespace xo*/ - -/* end LocalEnv.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/Schematika.hpp b/.xo-interpreter/include/xo/interpreter/Schematika.hpp deleted file mode 100644 index 0c02d974..00000000 --- a/.xo-interpreter/include/xo/interpreter/Schematika.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/** @file Schematika.hpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#pragma once - -#include "xo/alloc/GC.hpp" - -namespace xo { - namespace scm { - /** @class Schematika - * @brief schematika interpreter state - **/ - class Schematika { - public: - class Impl; - - struct Config { - /** true to enable welcome message **/ - bool welcome_flag_ = true; - /** number of command history items to preserve **/ - std::size_t history_size = 100; - /** on startup: load command history from this file; - persist last @ref history_size commands to the same file - **/ - std::string history_file = "scm_history.txt"; - /** when true enable console logging for repl internals **/ - bool debug_flag = false; - - /** garbage collector configuration **/ - gc::Config gc_config_; - - /** control schematika vsm logging **/ - log_level vsm_log_level_; - }; - - using IAlloc = xo::gc::IAlloc; - - public: - ~Schematika(); - - /** create instance with configuration @p cfg **/ - static Schematika make(const Config & cfg); - - /** interactive read-eval-print loop. - * Uses replxx to read from stdin. - * If stdin is interactive, accepts line editing commands: - * - ctrl-a goto beginning of line - * - ctrl-e goto end of line - * - ctrl-k delete to end of line - * - meta- backwards delete word - * - meta-p| retrieve previous command from history - * - meta-n| retrieve next command from history - * - / page through history faster - * - ctrl-s forward history search - * - ctrl-r backward history search - **/ - void interactive_repl(); - - private: - explicit Schematika(const Config & cfg); - - private: - up p_impl_; - }; - } -} - -/* end Schematika.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/SchematikaError.hpp b/.xo-interpreter/include/xo/interpreter/SchematikaError.hpp deleted file mode 100644 index 6baabad3..00000000 --- a/.xo-interpreter/include/xo/interpreter/SchematikaError.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/** @file SchematikaError.hpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#pragma once - -#include - -namespace xo { - namespace scm { - class SchematikaError { - public: - SchematikaError() = default; - explicit SchematikaError(std::string x) : what_{std::move(x)} {} - - const std::string & what() const { return what_; } - - bool is_error() const { return !what_.empty(); } - bool is_not_an_error() const { return what_.empty(); } - - private: - std::string what_; - }; - } -} - -/* end SchematikaError.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp b/.xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp deleted file mode 100644 index a8a182d9..00000000 --- a/.xo-interpreter/include/xo/interpreter/VirtualSchematikaMachine.hpp +++ /dev/null @@ -1,187 +0,0 @@ -/** @file VirtualSchematikaMachine.hpp **/ - -#pragma once - -#include "VsmInstr.hpp" -#include "VsmStackFrame.hpp" -#include "SchematikaError.hpp" -#include "GlobalEnv.hpp" -#include "xo/expression/Expression.hpp" -#include "xo/object/ObjectConverter.hpp" -#include "xo/alloc/Object.hpp" - -namespace xo { - namespace scm { - /** @brief state that may be shared across VirtualSchematikaMachine instances **/ - struct VirtualSchematikaMachineFlyweight { - explicit VirtualSchematikaMachineFlyweight(gc::IAlloc * mm, - gp env, - log_level log_level); - - /** memory allocator for interpreter operation. **/ - gc::IAlloc * object_mm_ = nullptr; - /** global environment **/ - gp toplevel_env_; - /** convert TaggedPtr->Object **/ - xo::obj::ObjectConverter object_converter_; - /** control logging level. higher values -> more logging **/ - log_level log_level_; - }; - - /** @class VirtualSchematikaMachine - * @brief Virtual machine implementing a Schematika interpreter - * - **/ - class VirtualSchematikaMachine { - public: - using IAlloc = xo::gc::IAlloc; - - public: - 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. - * conversely when value is nullptr, error gives details of original - * error. - * - * Evaluate schematika expression @p expr in environment @p env - **/ - std::pair, SchematikaError> eval(bp expr, gp env); - - /** evaluate expression @p expr in toplevel environment **/ - std::pair, SchematikaError> toplevel_eval(bp expr); - - private: - /** Not moveable or copyable. - * One constraint is member variables added to flyweight_.object_mm_ - * as GC roots, with no provision for unwinding later. - **/ - VirtualSchematikaMachine(const VirtualSchematikaMachine &) = delete; - VirtualSchematikaMachine(VirtualSchematikaMachine &&) = delete; - - /** borrow calling thread to run schematika machine - * indefinitely, or until null continuation - **/ - void run(); - - /** execute vsm instruction in program counter. - * Note: may possibly be able to replace with just opcode - * - * Registers: - * - expr_ input, caller saves - * - env_ input, caller saves - * - cont_ input, caller saves - * - stack_ input, caller saves - * - value_ output - * - error_ output - * - **/ - void execute_one(); - - /* design note: - * - eval_xxx_op() methods are primary VSM transitions, - * in the sense that they begin a sequence of transitions to interpret a - * particular kind of expression - * - do_xxx_op() methods represent secondary VSM transitions, - * that continue an instruction sequence that was initiated by a preceding - * eval_xxx_op() method - */ - - /** interpret literal constant expression **/ - void eval_constant_op(); - - /** interpreter literal primitive expression - * (these appear implicitly as result of builtin operators like {+, ==, ..}) - **/ - void eval_primitive_op(); - - /** execute define expression (finished in do_complete_assign_op()) **/ - void eval_define_op(); - /** execute assign expression (finishes in do_complete_assign_op()) **/ - void eval_assign_op(); - /** continue after establishing value fo rhs of define exprsssion **/ - void do_complete_assign_op(); - - /** interpret variable expression **/ - void eval_variable_op(); - - /** interpret if-expression **/ - void eval_ifexpr_op(); - /** continue after establish value of test expression **/ - void do_complete_ifexpr_op(); - - /** interpret sequence **/ - void eval_sequence_op(); - /** continue after establishing value for a sequence element **/ - void do_complete_sequence_op(); - - /** interpret apply-expression (i.e. function call) **/ - void eval_apply_op(); - /** continue assembling args for a function call; - * transition to (interpretation of) called function once all arguments - * are evaluated. - **/ - void do_complete_evalargs_op(); - - /** execute function application, given actuals in top stack frame **/ - void apply_op(); - - /** goto error state with message @p err **/ - void report_error(const std::string & err); - - /** implementation class; contains instruction implementations **/ - friend struct VsmOps; - - private: - /** program counter. - * (Perhaps replace with VsmInstr::Opcode ?) - **/ - const VsmInstr * pc_ = nullptr; - - /** register to hold Schematika expression to drive @ref execute_one. - * - * caller saves! - **/ - rp expr_; - /** holds bindings for all schematika variables, to drive @ref execute_one. - * execute_one will not save this - * - * caller saves! - **/ - gp env_; - - /** vsm stack. callee saves! - **/ - gp stack_; - - /** non-error result value from eval() / apply() - * - * output register: caller must save - **/ - gp value_; - - /** error result value from eval() / apply() - * - * output regisetr: caller must save - **/ - SchematikaError error_; - - /** continuation - * (Perhaps replace with VsmInstr::Opcode ?) - * - * input register: callee saves! - **/ - const VsmInstr * cont_ = nullptr; - - /** possibly-shared data **/ - VirtualSchematikaMachineFlyweight flyweight_; - }; - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end VirtualSchematikaMachine.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/VsmInstr.hpp b/.xo-interpreter/include/xo/interpreter/VsmInstr.hpp deleted file mode 100644 index a1539bd0..00000000 --- a/.xo-interpreter/include/xo/interpreter/VsmInstr.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/** @file VsmInstr.hpp **/ - -#pragma once - -#include - -namespace xo { - namespace scm { - class VirtualSchematikaMachine; // see VirtualSchematikaMachine.hpp - - /** @class VmInstr - * @brief Represent a particular vritual schematika machine instruction - * - * A vsm instruction acts on a virtual schematika machine instance. - **/ - class VsmInstr - { - public: - enum class Opcode { - /** Halt virtual schematika machine **/ - halt, - - /** Evaluate a schematika expression. - * See VirtualSchematikaMachine::eval() - **/ - eval, - - /** assign to variable + continue - * - * stack: frame with: - * [0] lhs : variable to assign - **/ - complete_assign, - - /** execute ifexpr branch, given - * result of test expression has been established - **/ - complete_ifexpr, - - /** execute remainder of expression sequence - **/ - complete_sequence, - - /** execute remainder of argument sequence evaluation; - * subsidiary to marshalling a function call - **/ - complete_evalargs, - - /** Call a function. Arguments have been evaluated - * and are in top stack frame, in order, - * starting with target function itself - **/ - apply, - - /** choose branch of if-expression + continue - * - * stack: frame with - * [0] ifexpr : original if-expression - **/ - N_Opcode - }; - - //using ActionFn = void (*)(VirtualSchematikaMachine * vm); - - public: - VsmInstr(Opcode opcode, std::string_view name); - - Opcode opcode() const { return opcode_; } - - private: - /** unique opcode for this instruction **/ - Opcode opcode_; - /** **/ - std::string_view name_; - //ActionFn action_; - }; - } -} - -/* end VsmInstr.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp b/.xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp deleted file mode 100644 index 0fc0dee7..00000000 --- a/.xo-interpreter/include/xo/interpreter/VsmStackFrame.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/** @file VsmStackFrame.hpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#pragma once - -#include "VsmInstr.hpp" -#include "xo/object/CVector.hpp" -#include "xo/alloc/Object.hpp" - -namespace xo { - namespace scm { - /** @class VsmStackFrame - * @brief Virtual Schematika Machine stack frame - * - * Intending to use the "cheney on the MTA" strategy, - * i.e. allocate frames using GC's bump allocator. - * - * Parallels LocalEnv, but VSM implementation isn't reflected - **/ - class VsmStackFrame : public Object { - public: - VsmStackFrame(gc::IAlloc * mm, gp p, std::size_t n, const VsmInstr * cont); - - /** create frame using allocator @p mm, - * with parent @p p and exactly @p n_slot object pointers. - **/ - static gp make(gc::IAlloc * mm, - gp p, - std::size_t n_slot, - const VsmInstr * cont); - - /** create new stack frame using allocator @p mm, - * with parent frame @p p; new frame contains values @p s0 - **/ - static gp push1(gc::IAlloc * mm, - gp p, - gp s0, - const VsmInstr * cont); - - /** create new stack frame using allocator @p mm, - * with parent frame @p p; new frame contains values @p s0, @p s1 - **/ - static gp push2(gc::IAlloc * mm, - gp p, - gp s0, - gp s1, - const VsmInstr * cont); - - - /** reflect VsmStackFrame object representation **/ - static void reflect_self(); - - gp parent() const { return parent_; } - std::size_t size() const { return slot_v_.size(); } - const obj::CVector> & argv() const { return slot_v_; } - const VsmInstr * continuation() const { return cont_; } - - gp operator[](std::size_t i) const { return slot_v_[i]; } - gp & operator[](std::size_t i) { return slot_v_[i]; } - - // inherited from Object.. - virtual TaggedPtr self_tp() const final override; - virtual void display(std::ostream & os) const final override; - virtual std::size_t _shallow_size() const final override; - virtual Object * _shallow_copy(gc::IAlloc *) const final override; - virtual std::size_t _forward_children(gc::IAlloc *) final override; - - private: - /** parent stack frame **/ - gp parent_; - - /** stored state **/ - obj::CVector> slot_v_; - - /** proceed to this continuation when popping this frame **/ - const VsmInstr * cont_ = nullptr; - }; - } /*namespace scm*/ -} /*namespace xo*/ - -/* end VsmStackFrame.hpp */ diff --git a/.xo-interpreter/include/xo/interpreter/init_interpreter.hpp b/.xo-interpreter/include/xo/interpreter/init_interpreter.hpp deleted file mode 100644 index 91e4828c..00000000 --- a/.xo-interpreter/include/xo/interpreter/init_interpreter.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/** @file init_interpreter.hpp - * - * author: Roland Conybeare, Nov 2025 - **/ - -#pragma once - -#include "xo/subsys/Subsystem.hpp" - -namespace xo { - /* tag to represent the interpreter/ subsystem in ordered initialization */ - enum S_interpreter_tag {}; - - template<> - struct InitSubsys { - static void init(); - static InitEvidence require(); - }; -} - -/* end init_interpreter.hpp */ diff --git a/.xo-interpreter/src/interpreter/BuiltinPrimitives.cpp b/.xo-interpreter/src/interpreter/BuiltinPrimitives.cpp deleted file mode 100644 index bead7c87..00000000 --- a/.xo-interpreter/src/interpreter/BuiltinPrimitives.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/** @file BuiltinPrimitives.cpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#include "BuiltinPrimitives.hpp" -#include "Integer.hpp" -#include "Primitive.hpp" -#include "xo/expression/PrimitiveExpr.hpp" -#include "xo/object/ObjectConversion.hpp" -#include "xo/reflect/Reflect.hpp" -#include - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::TaggedPtr; - using xo::reflect::TypeDescr; - - namespace scm { - int64_t - add64(int64_t x, int64_t y) - { - return x + y; - } - - void - BuiltinPrimitives::install(gc::IAlloc * mm, gp env) - { - scope log(XO_DEBUG(true)); - - // add(x,y) - { - gp rhs = xo::obj::make_primitive(mm, "add", add64); - - TypeDescr td = Reflect::require_function(); - - rp lhs = Variable::make("add", td); - gp * addr = env->establish_var(lhs.borrow()); - - *addr = rhs; - } - - // i64 comparisons - - // @cmp_eq2_i64 - install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_eq2_i64(), env); - - // @cmp_ne2_i64 - install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_ne2_i64(), env); - - // @cmp_lt2_i64 - install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_lt2_i64(), env); - - // @cmp_le2_i64 - install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_le2_i64(), env); - - // @cmp_gt2_i64 - install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_gt2_i64(), env); - - // @cmp_ge2_i64 - install_pm(mm, PrimitiveExpr_cmp_i64::make_cmp_ge2_i64(), env); - - // i64 arithmetic - - // @add2_i64 - install_pm(mm, PrimitiveExpr_i64::make_add2_i64(), env); - - // @sub2_i64 - install_pm(mm, PrimitiveExpr_i64::make_sub2_i64(), env); - - // @mul2_i64 - install_pm(mm, PrimitiveExpr_i64::make_mul2_i64(), env); - - // @div2_i64 - install_pm(mm, PrimitiveExpr_i64::make_div2_i64(), env); - - // ---------------------------------------------------------------- - - // @add2_f64 - install_pm(mm, PrimitiveExpr_f64::make_add2_f64(), env); - - // @sub2_f64 - install_pm(mm, PrimitiveExpr_f64::make_sub2_f64(), env); - - // @mul2_f64 - install_pm(mm, PrimitiveExpr_f64::make_mul2_f64(), env); - - // @div2_f64 - install_pm(mm, PrimitiveExpr_f64::make_div2_f64(), env); - } - } -} - -/* end BuiltinPrimitives.cpp */ diff --git a/.xo-interpreter/src/interpreter/CMakeLists.txt b/.xo-interpreter/src/interpreter/CMakeLists.txt deleted file mode 100644 index 912d4a93..00000000 --- a/.xo-interpreter/src/interpreter/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# interpreter/CMakeLists.txt - -set(SELF_LIB xo_interpreter) -set(SELF_SRCS - init_interpreter.cpp - Schematika.cpp - BuiltinPrimitives.cpp - LocalEnv.cpp - GlobalEnv.cpp - VirtualSchematikaMachine.cpp - VsmInstr.cpp - VsmStackFrame.cpp - ExpressionBoxed.cpp -) - -find_package(Threads REQUIRED) - -xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) -xo_dependency(${SELF_LIB} xo_object) -xo_dependency(${SELF_LIB} xo_expression) -xo_dependency(${SELF_LIB} xo_reader) -xo_external_target_dependency(${SELF_LIB} replxx replxx::replxx) -target_link_libraries(${SELF_LIB} PUBLIC Threads::Threads) -xo_headeronly_dependency(${SELF_LIB} subsys) diff --git a/.xo-interpreter/src/interpreter/ExpressionBoxed.cpp b/.xo-interpreter/src/interpreter/ExpressionBoxed.cpp deleted file mode 100644 index 2d72ef33..00000000 --- a/.xo-interpreter/src/interpreter/ExpressionBoxed.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** @file ExpressionBoxed.cpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#include "ExpressionBoxed.hpp" -#include "xo/reflect/Reflect.hpp" - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::TaggedPtr; - - namespace scm { - ExpressionBoxed::ExpressionBoxed(bp c) : contents_{c.promote()} - {} - - gp - ExpressionBoxed::make(gc::IAlloc * mm, - bp c) - { - return new (MMPtr(mm)) ExpressionBoxed(c); - } - - - TaggedPtr - ExpressionBoxed::self_tp() const - { - return Reflect::make_tp(const_cast(this)); - } - - void - ExpressionBoxed::display(std::ostream & os) const - { - os << contents_; - } - - std::size_t - ExpressionBoxed::_shallow_size() const - { - return sizeof(ExpressionBoxed); - } - - Object * - ExpressionBoxed::_shallow_copy(gc::IAlloc * mm) const - { - Cpof cpof(mm, this); - - return new (cpof) ExpressionBoxed(*this); - } - - std::size_t - ExpressionBoxed::_forward_children(gc::IAlloc *) - { - return _shallow_size(); - } - } /*namespace scm*/ -} /*namespace xo*/ - -/* end ExpressionBoxed.cpp */ diff --git a/.xo-interpreter/src/interpreter/GlobalEnv.cpp b/.xo-interpreter/src/interpreter/GlobalEnv.cpp deleted file mode 100644 index 736af083..00000000 --- a/.xo-interpreter/src/interpreter/GlobalEnv.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/** @file GlobalEnv.cpp **/ - -#include "GlobalEnv.hpp" -#include "xo/reflect/Reflect.hpp" - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::TaggedPtr; - - namespace scm { - gp - GlobalEnv::make_empty(gc::IAlloc * mm, const rp & symtab) - { - /* by design: GlobalEnv and GlobalEnv.slot_map_ are heap-allocated */ - - return new GlobalEnv(mm, symtab); - } - - GlobalEnv::GlobalEnv(const GlobalEnv & x) - : mm_{x.mm_}, - symtab_{x.symtab_}, - slot_map_{std::make_unique(*x.slot_map_)} - { - } - - GlobalEnv::GlobalEnv(gc::IAlloc * mm, - const rp & symtab) : mm_{mm}, - symtab_{symtab}, - slot_map_{std::make_unique()} - {} - - bool - GlobalEnv::local_contains_var(const std::string & vname) const - { - return symtab_->lookup_local(vname).get(); - } - - gp * - GlobalEnv::lookup_slot(const std::string & vname) - { - scope log(XO_DEBUG(true), xtag("name", vname)); - - assert(slot_map_.get()); - - auto ix = slot_map_->find(vname); - - if (ix == slot_map_->end()) { - return nullptr; - } else { - log && log("binding found", xtag("vname", vname)); - return &(ix->second); - } - } - - gp * - GlobalEnv::establish_var(bp var) - { - scope log(XO_DEBUG(true), xtag("name", var->name()), xtag("type", var->valuetype())); - - // Warning: altering declared type for an already-existing variable - // invalidates any type checking that relied on that variable. - // - // Ignoring this problem for now. - // - // Actual solution might look like: - // - keep track of which functions/defs depend on each global variable. - // - invalidate any jit / types for such variables. - // - maybe use seqno's to track - // - re-check / re-complie - // - need to admit invalid states. - // suppose have mutually recursive functions f(), g() - // want ability to modify type signatures separately - // - // Alternatives: - // - forbid changing type of an already-established variable - // Actually: can't even change values if we intend supporting dependent types - // - quietly number variables so new definitions shadow old ones but don't - // affect previously-encountered expressions - - this->symtab_->require_global(var->name(), var); - - gp &slot = (*this->slot_map_)[var->name()]; - - /* discard any pre-existing value, we're redefining a variable */ - slot = gp(); - - return &slot; - } - - TaggedPtr - GlobalEnv::self_tp() const - { - return Reflect::make_tp(const_cast(this)); - } - - void - GlobalEnv::display(std::ostream & os) const - { - os << "size()) << ">"; - } - - std::size_t - GlobalEnv::_shallow_size() const - { - return sizeof(GlobalEnv); - } - - Object * - GlobalEnv::_shallow_copy(gc::IAlloc * mm) const - { - Cpof cpof(mm, this); - - return new (cpof) GlobalEnv(*this); - } - - std::size_t - GlobalEnv::_forward_children(gc::IAlloc * gc) - { - for (auto & ix : *slot_map_) { - Object::_forward_inplace(ix.second, gc); - } - return _shallow_size(); - } - } /*namespace scm*/ -} /*namespace xo*/ - -/* end GlobalEnv.cpp */ diff --git a/.xo-interpreter/src/interpreter/LocalEnv.cpp b/.xo-interpreter/src/interpreter/LocalEnv.cpp deleted file mode 100644 index 8085f126..00000000 --- a/.xo-interpreter/src/interpreter/LocalEnv.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/** @file LocalEnv.cpp **/ - -#include "LocalEnv.hpp" -#include "xo/reflect/Reflect.hpp" -#include "xo/reflect/StructReflector.hpp" -#include - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::StructReflector; - using xo::reflect::TypeDescrW; - using xo::reflect::TaggedPtr; - using xo::reflect::TypeDescrExtra; - using xo::reflect::EstablishTypeDescr; - using xo::reflect::StlVectorTdx; - using xo::print::quot; - - namespace scm { - namespace { - std::size_t - slot_array_size(std::size_t n) { - return n * sizeof(gp); - } - } - - gp - LocalEnv::make(gc::IAlloc * mm, - gp p, - const rp & s, - std::size_t n) - { - if (s) { - assert(static_cast(n) == s->n_arg()); - } - - return new (MMPtr(mm)) LocalEnv(mm, p, s, n); - } - - LocalEnv::LocalEnv(gc::IAlloc * mm, - gp p, - const rp & s, - std::size_t n) : parent_{p}, - symtab_{s}, - slot_v_{mm, n} - {} - - bool - LocalEnv::local_contains_var(const std::string & vname) const - { - assert(symtab_.get()); - - return symtab_->lookup_local(vname); - } - - gp * - LocalEnv::lookup_slot(const std::string & vname) - { - binding_path b = symtab_->lookup_local_binding(vname); - - if (b.i_link_ == 0) { - assert((b.j_slot_ >= 0) && (static_cast(b.j_slot_) < slot_v_.size())); - - return &(slot_v_[b.j_slot_]); - } - - if (parent_.get()) { - return parent_->lookup_slot(vname); - } - - return nullptr; - } - - gp * - LocalEnv::establish_var(bp v) - { - assert(v); - - throw std::runtime_error(tostr("LocalEnv::establish_var:" - " inserting new variables not supported for LocalEnv", - xtag("v.name", v->name()))); - } - - TaggedPtr - LocalEnv::self_tp() const - { - return Reflect::make_tp(const_cast(this)); - } - - void - LocalEnv::display(std::ostream & os) const - { - os << ""; - } - - std::size_t - LocalEnv::_shallow_size() const - { - std::size_t retval = sizeof(LocalEnv); - - retval += gc::IAlloc::with_padding(slot_array_size(slot_v_.size())); - - return retval; - } - - Object * - LocalEnv::_shallow_copy(gc::IAlloc * mm) const - { - Cpof cpof(mm, this); - - size_t z = this->size(); - - LocalEnv * copy = new (cpof) LocalEnv(cpof.mm_, parent_, symtab_, z); - - void * v_dest = copy->slot_v_.v_; - - if (slot_v_.v_) { - ::memcpy(v_dest, slot_v_.v_, slot_array_size(z)); - } - -#ifdef OBSOLETE - for (size_t i = 0, n = n_slot_; i < n; ++i) { - copy->v_[i] = v_[i]; - } -#endif - - return copy; - } - - std::size_t - LocalEnv::_forward_children(gc::IAlloc * gc) - { - static_assert(decltype(symtab_)::is_gc_ptr == false); - - Object::_forward_inplace(parent_, gc); - // Object::_forward_inplace(symtab_); // not a gp yet - for (std::size_t i = 0, n = slot_v_.size(); i < n; ++i) { - Object::_forward_inplace((*this)[i], gc); - } - - return _shallow_size(); - } - - void - LocalEnv::reflect_self() - { - StructReflector sr; - - if (sr.is_incomplete()) { - /* reflect CVector> - * - * note: placement here works b/c CVector not used anywhere else - */ - using VectorType = obj::CVector>; - - /* custom reflection for array of Object pointers. - * Can use StlVectorTdx here, treating CVector as a vector - * via .size() and .operator[] members - */ - std::unique_ptr tdx1 - = std::make_unique>(); - TypeDescrW td1 - = EstablishTypeDescr::establish(); - td1->assign_tdextra(Reflect::get_final_invoker(), - std::move(tdx1)); - - REFLECT_MEMBER(sr, parent); - REFLECT_MEMBER(sr, slot_v); - } - } - } /*namespace scm*/ -} /*namespace xo*/ - -/* end LocalEnv.cpp */ diff --git a/.xo-interpreter/src/interpreter/Schematika.cpp b/.xo-interpreter/src/interpreter/Schematika.cpp deleted file mode 100644 index 039b2e67..00000000 --- a/.xo-interpreter/src/interpreter/Schematika.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/** @file Schematika.cpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#include "Schematika.hpp" -#include "VirtualSchematikaMachine.hpp" -#include "BuiltinPrimitives.hpp" -#include "GlobalEnv.hpp" -#include "xo/reader/reader.hpp" -#include -#include -#include // for STDIN_FILENO on OSX - -namespace xo { - using xo::gc::IAlloc; - using xo::gc::GC; - using xo::print::ppconfig; - using xo::print::ppstate_standalone; - using replxx::Replxx; - using namespace std; - - namespace scm { - - class Schematika::Impl { - public: - /** note: choosing to have Schemtika::Impl - * rather than VirtualSchematikaMachine to own allocator - * to preserve option to share it - **/ - Impl(const Config & config, up mm, gp toplevel_env); - ~Impl(); - - /** create instance + allocator **/ - static up make(const Config & cfg); - - /** borrow calling thread to run interactive read-eval-print loop; - * input from stdin, output to stdout. - **/ - void interactive_repl(); - - 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, - std::string & input); - - private: - /** configuration **/ - Config config_; - /** ownership for memory allocator / garbage collector; - * @ref vsm_ holds naked pointer, so this could in principle be nullptr - * in case want to maintain allocator ownership from outside. - * - * note: must appear before @ref vsm_, so latter gets destroyed first - **/ - up mm_; - /** schematika interpreter **/ - VirtualSchematikaMachine vsm_; - }; - - Schematika::Impl::Impl(const Config & config, up mm, gp toplevel_env) : - config_{config}, - mm_{std::move(mm)}, - vsm_{mm_.get(), toplevel_env, config.vsm_log_level_} - { - - } - - Schematika::Impl::~Impl() = default; - - up - Schematika::Impl::make(const Config & cfg) - { - up mm = GC::make(cfg.gc_config_); - rp symtab = GlobalSymtab::make_empty(); - gp env = GlobalEnv::make_empty(mm.get(), symtab); - - /* also see VirtualSchematikaMachineFlyweight::Impl::Impl, - * for BuiltinPrimitives::install_interpreter_conversions() - */ - BuiltinPrimitives::install(mm.get(), env); - - return std::make_unique(cfg, std::move(mm), env); - } - - void - Schematika::Impl::welcome(std::ostream & os) - { - using namespace std; - - os << "read-eval-print loop for schematika expressions" << endl; - os << " ctrl-a/ctrl-e beginning/end of line" << endl; - os << " ctrl-u delete entire line" << endl; - os << " ctrl-k delete to end of line" << endl; - os << " meta- backward delete word" << endl; - os << " |meta-p previous command from history" << endl; - os << " |meta-n next command from history" << endl; - os << " / page through history faster" << endl; - os << " ctrl-s/ctrl-r forward/backward history search" << endl; - os << endl; - } - - // similar helper in exprreplxx.cpp - // - bool - Schematika::Impl::replxx_getline(bool interactive, - std::size_t parser_stack_size, - replxx::Replxx & rx, - std::string & input) - { - using namespace std; - - char const * prompt = ""; - - if (interactive) { - if (parser_stack_size <= 1) - prompt = "> "; - else - prompt = ". "; - } - - /* input_cstr: next line of input from replxx library */ - const char * input_cstr = rx.input(prompt); - - bool retval = (input_cstr != nullptr); - - if (retval) { - /* got new input */ - input = input_cstr; - } - - rx.history_add(input); - - input.push_back('\n'); - - return retval; - } - - void - Schematika::Impl::interactive_repl() - { - scope log(XO_DEBUG(true)); - - using span_type = xo::scm::span; - - bool interactive = isatty(STDIN_FILENO); - - Replxx rx; - rx.set_max_history_size(config_.history_size); - rx.history_load(config_.history_file); - // rx.bind_key_internal(Replxx::KEY::control('p'), "history_previous"); - // rx.bind_key_internal(Replxx::KEY::control('n'), "history_next"); - - reader rdr(vsm_.toplevel_env()->symtab(), config_.debug_flag); - rdr.begin_interactive_session(); - - string input_str; - - bool eof = false; - - span_type input; - std::size_t parser_stack_size = 0; - - if (config_.welcome_flag_) - welcome(cerr); - - while (replxx_getline(interactive, parser_stack_size, rx, input_str)) { - input = span_type::from_string(input_str); - - while (!input.empty()) { - /** - * Three cases here: - * 1. available input is invalid (does not conform to schematika syntax). - * 1a. expr=nullptr - * 1b. consumed reads all available input - * 1c. psz=0 - * 1d. error.is_error(); details including exact location where parsing failed. - * 1e. parser reset to top level. - * 2. available input represents prefix of a possibly-valid expression - * 2a. expr=nullptr; - * 2b. consumed reads all available input - * 2c. psz reflects nesting level after reading available input. - * 2d. error.is_not_an_error() - * 3. available input completes at least one expression - * 3a. expr contains first completed top-level expression - * 3b. consumed reports portion of input up to end of expr - * 3c. psz=0 - * 3d. error.is_not_an_error() - * - * expr :: rp if non-null: the next expression from input - * consumed :: span extent of input read up to next Expression - * psz :: size_t parser stack size - * error :: reader_error error details on parsing failure - **/ - auto [expr, consumed, psz, error] = rdr.read_expr(input, eof); - - if (expr) { - /** configuration for pretty-printing **/ - ppconfig ppc; - ppstate_standalone pps(&cout, 0, &ppc); - - //pps.prettyn(expr); - - // TODO: - auto [ value, scm_error ] = this->vsm_.toplevel_eval(expr); - - if (scm_error.is_error()) { - /* print error */ - - cout << "scm error: " << scm_error.what() << endl; - cout << "top-level expression: " << expr << endl; - } else { - /* print value */ - - cout << "scm result:" << endl; - cout << value << endl; - //pps.pretty(value); - } - - } else if (error.is_error()) { - cout << "parsing error (detected in " << error.src_function() << "): " << endl << endl; - error.report(cout); - - /* discard stashed remainder of input line - * (for nicely-formatted errors) - */ - rdr.reset_to_idle_toplevel(); - break; - } - - input = input.after_prefix(consumed); - parser_stack_size = psz; - } - - /* here: input.empty() or error encountered */ - - cerr << endl; - } - - auto [expr, _1, _2, error] = rdr.read_expr(input, true /*eof*/); - - if (expr) { - ppconfig ppc; - ppstate_standalone pps(&cout, 0, &ppc); - - pps.prettyn>(rp(expr)); - } else if (error.is_error()) { - cout << "parsing error (detected in " << error.src_function() << "): " << endl; - error.report(cout); - } - - rx.history_save("repl_history.txt"); - } - - // ----- Schematika ----- - - Schematika::Schematika(const Config & cfg) : p_impl_{Impl::make(cfg)} - {} - - Schematika::~Schematika() - {} - - Schematika - Schematika::make(const Config & cfg) - { - return Schematika(cfg); - } - - void - Schematika::interactive_repl() - { - p_impl_->interactive_repl(); - } - } -} - -/* end Schematika.cpp */ diff --git a/.xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp b/.xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp deleted file mode 100644 index 25f620b0..00000000 --- a/.xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp +++ /dev/null @@ -1,865 +0,0 @@ -/** @file VirtualSchematikaMachine.cpp **/ - -#include "VirtualSchematikaMachine.hpp" -#include "VsmInstr.hpp" -#include "BuiltinPrimitives.hpp" -#include "ExpressionBoxed.hpp" -#include "xo/expression/Constant.hpp" -#include "xo/expression/PrimitiveExprInterface.hpp" -#include "xo/expression/DefineExpr.hpp" -#include "xo/expression/AssignExpr.hpp" -#include "xo/expression/Variable.hpp" -#include "xo/expression/IfExpr.hpp" -#include "xo/expression/Sequence.hpp" -#include "xo/expression/Apply.hpp" -#include "xo/object/Procedure.hpp" -#include "xo/object/Primitive.hpp" -#include "xo/object/Integer.hpp" -#include "xo/object/Boolean.hpp" -#include "xo/alloc/GC.hpp" - -/** continue after completing a VSM instruction; - * achieve by jumping to continuation. - **/ -#define VSM_CONTINUE() this->pc_ = this->cont_; return; - -/** report error and terminate VSM execution - **/ -#define VSM_ERROR(msg) report_error(msg); return; - - - -namespace xo { - using xo::gc::GC; - using xo::obj::Procedure; - using xo::obj::Integer; - using xo::obj::Boolean; - - namespace scm { - struct VsmOps { - /** halt virtual scheme machine. - * This will cause innermost run() to return to its caller - **/ - static VsmInstr halt_op; - - /** evaluate an expression. - * - opcode is Opcode::eval - * - expression in register @ref expr_ - **/ - static VsmInstr eval_op; - - /** assign variable after evaluating rhs of a define-expression or assign-expression - * - opcode is Opcode::complete_assign - * - top stack frame contains {lhs, cont} - **/ - static VsmInstr complete_assign_op; - - /** choose branch of if-expr after evaluating test condition. - * - opcode is Opcode::complete_ifexpr - * - top stack frame contains {ifexpr, cont} - **/ - static VsmInstr complete_ifexpr_op; - - /** proceed to next element of sequence-expr. - * - opcode is Opcode::complete_sequence - * - top stack frame contains {seq, next, cont} - */ - static VsmInstr complete_sequence_op; - - /** proceed to next argument in apply-expr - * - opcode is Opcode::eval_collect_args - * - top stack frame contains {apply, targetarg, cont} - */ - static VsmInstr complete_evalargs_op; - - /** call a procedure, where evaluated arguments (including target function) - * are in top stack frame. - * - opcode is Opcode::apply - * - top stack frame contains evaluated arguments. - **/ - static VsmInstr apply_op; - }; - - VsmInstr - VsmOps::halt_op{VsmInstr::Opcode::halt, "halt"}; - - VsmInstr - VsmOps::eval_op{VsmInstr::Opcode::eval, "eval"}; - - VsmInstr - VsmOps::complete_assign_op{VsmInstr::Opcode::complete_assign, "complete-assign"}; - - VsmInstr - VsmOps::complete_ifexpr_op{VsmInstr::Opcode::complete_ifexpr, "complete-ifexpr"}; - - VsmInstr - VsmOps::complete_sequence_op{VsmInstr::Opcode::complete_sequence, "complete-sequence"}; - - VsmInstr - VsmOps::complete_evalargs_op{VsmInstr::Opcode::complete_evalargs, "complete-evalargs"}; - - VsmInstr - VsmOps::apply_op{VsmInstr::Opcode::apply, "apply"}; - - // ----- VirtualSchematikaMachineFlyweight ----- - - VirtualSchematikaMachineFlyweight::VirtualSchematikaMachineFlyweight(gc::IAlloc * mm, - gp env, - log_level ll) : - object_mm_{mm}, - toplevel_env_{env}, - log_level_{ll} - { - } - - // ----- VirtualSchematikaMachine ----- - - VirtualSchematikaMachine::VirtualSchematikaMachine(gc::IAlloc * mm, - 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 - gc::GC * gc = GC::from(mm); - - if (gc) { - assert((gc->gc_in_progress() == false) && "cannot add roots while GC running"); - - gc->add_gc_root_dwim(&env_); - gc->add_gc_root_dwim(&value_); - } else { - // Want to support VSM with arena-allocator-only; - // if only for unit testing. - } - - // TODO: install builtin primitives here - } - - VirtualSchematikaMachine::~VirtualSchematikaMachine() - { - gc::GC * gc = GC::from(flyweight_.object_mm_); - - if (gc) { - assert((gc->gc_in_progress() == false) && "cannot remove roots while GC running"); - - gc->remove_gc_root_dwim(&env_); - gc->remove_gc_root_dwim(&value_); - } else { - // nothing to do in arena-only mode - } - } - - std::pair, - SchematikaError> - VirtualSchematikaMachine::toplevel_eval(bp expr) - { - return this->eval(expr, this->env_); - } - - std::pair, - SchematikaError> - 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; - this->stack_ = nullptr; - this->value_ = nullptr; - this->error_ = SchematikaError(); - this->cont_ = &VsmOps::halt_op; - - this->run(); - - return std::make_pair(this->value_, this->error_); - } - - void - VirtualSchematikaMachine::run() - { - while(pc_) - this->execute_one(); - } - - void - VirtualSchematikaMachine::execute_one() - { - scope log(XO_DEBUG(true)); - log && log(xtag("pc", pc_), xtag("cont", cont_)); - log && log(xtag("stack", stack_)); - - using Opcode = VsmInstr::Opcode; - - switch (pc_->opcode()) { - - case Opcode::halt: - { - this->pc_ = nullptr; - this->cont_ = nullptr; - break; - } - - case Opcode::eval: - { - log && log("Opcode::eval"); - - /* generally speaking: opcode will be 1:1 with extypes */ - - switch (expr_->extype()) { - case exprtype::constant: - log && log("eval -> constant"); - this->eval_constant_op(); - break; - - case exprtype::primitive: - log && log("eval -> primitive"); - this->eval_primitive_op(); - break; - - case exprtype::define: - log && log("eval -> define"); - this->eval_define_op(); - break; - - case exprtype::assign: - log && log("eval -> assign"); - this->eval_assign_op(); - break; - - case exprtype::variable: - log && log("eval -> variable"); - this->eval_variable_op(); - break; - - case exprtype::ifexpr: - log && log("eval -> ifexpr"); - this->eval_ifexpr_op(); - break; - - case exprtype::sequence: - log && log("eval -> sequence"); - this->eval_sequence_op(); - break; - - case exprtype::apply: - log && log("eval -> apply"); - this->eval_apply_op(); - break; - - case exprtype::invalid: - - case exprtype::lambda: - case exprtype::convert: - case exprtype::n_expr: - this->pc_ = nullptr; - this->value_ = nullptr; - this->error_ = SchematikaError(tostr("execute_vsm: not implemented", - xtag("extype", expr_->extype()))); - this->cont_ = nullptr; - break; - } - } - break; - - case Opcode::complete_assign: - this->do_complete_assign_op(); - break; - - case Opcode::complete_ifexpr: - this->do_complete_ifexpr_op(); - break; - - case Opcode::complete_sequence: - this->do_complete_sequence_op(); - break; - - case Opcode::complete_evalargs: - this->do_complete_evalargs_op(); - break; - - case Opcode::apply: - this->apply_op(); - break; - - case Opcode::N_Opcode: - assert(false); - break; - } - } - - void - VirtualSchematikaMachine::report_error(const std::string & err) - { - /* error short-circuits vsm operation */ - - this->pc_ = nullptr; - this->value_ = nullptr; - this->error_ = SchematikaError(err); - this->cont_ = nullptr; - } - - void - VirtualSchematikaMachine::eval_constant_op() - { - using xo::scm::ConstantInterface; - - scope log(XO_DEBUG(true)); - - bp expr = ConstantInterface::from(expr_); - - assert(expr); - - this->value_ = flyweight_.object_converter_.tp_to_object(flyweight_.object_mm_, - expr->value_tp(), - false); - if (this->value_.ptr()) { - log && log("got object: ", xtag("value", value_)); - - VSM_CONTINUE(); - } else { - /* see ObjectConverter::ctor to add more builtin types - * - * generally conversion for a type Foo will appear in Foo.hpp - * see - * xo/object/Boolean.hpp - * xo/object/Integer.hpp - * xo/object/Float.hpp - * xo/object/String.hpp - */ - - VSM_ERROR(tostr("constant_op: unable to convert native value to object", - xtag("id", expr->value_tp().td()->id()), - xtag("short_name", expr->value_tp().td()->short_name()))); - } - } - - void - VirtualSchematikaMachine::eval_primitive_op() - { - using xo::obj::Primitive; - using xo::reflect::TaggedPtr; - - scope log(XO_DEBUG(true)); - - bp expr = PrimitiveExprInterface::from(expr_); - - const gp * slot = env_->lookup_slot(expr->name()); - - if (slot) { - this->value_ = *slot; - this->pc_ = cont_; - } else { - std::string err = tostr("no binding for primitive", xtag("name", expr->name())); - - this->value_ = nullptr; - this->error_ = SchematikaError(err); - - /* note: poor man's exception */ - this->pc_ = nullptr; - this->cont_ = nullptr; - } - } - - void - VirtualSchematikaMachine::eval_define_op() - { - using xo::scm::DefineExpr; - - scope log(XO_DEBUG(true)); - - auto mm = flyweight_.object_mm_; - - bp expr = DefineExpr::from(expr_); - - assert(expr); - assert(env_.get()); - - // note: expecting nested define to have expanded iteself into - // applying a lambda - - // note: establish lhs_var first, to allow for recursion, for example: - // def fact(n: i64) { if (n == 0) then 1; else n * fact(n-1); } - - /** remembers promised variable type **/ - this->env_->establish_var(expr->lhs_variable()); - - /** must promote rp -> gp **/ - gp lhs_0 = ExpressionBoxed::make(mm, expr->lhs_variable()); - - this->pc_ = &VsmOps::eval_op; - this->expr_ = expr->rhs(); - - /* when control arrives at .cont_, will have: - * .value_ -> result of evaluating expr->rhs() - */ - this->stack_ = VsmStackFrame::push1(mm, this->stack_, lhs_0, cont_); - - /* .stack_: - * frame - * [0] = lhs_0 (boxed lhs Variable) - * .. - */ - - this->cont_ = &VsmOps::complete_assign_op; - } - - void - VirtualSchematikaMachine::eval_assign_op() - { - using xo::scm::AssignExpr; - - scope log(XO_DEBUG(true)); - - auto mm = flyweight_.object_mm_; - - bp assign = AssignExpr::from(expr_); - - assert(assign.get()); - assert(env_.get()); - - assert(assign->lhs().get()); - assert(assign->rhs().get()); - - /* verify slot exists, before we evaluate rhs */ - gp * slot = env_->lookup_slot(assign->lhs()->name()); - - if (slot) { - /** must promote rp -> gp **/ - gp lhs = ExpressionBoxed::make(mm, assign->lhs()); - - this->pc_ = &VsmOps::eval_op; - this->expr_ = assign->rhs(); - - /* when control arrives at .cont_, will have: - * .value_ -> result of evaluating assign->rhs() - */ - this->stack_ = VsmStackFrame::push1(mm, this->stack_, lhs, cont_); - - /* .stack_: - * frame - * [0] = lhs (boxed lhs Variable) - * .. - */ - - this->cont_ = &VsmOps::complete_assign_op; - } else { - std::string err = tostr("no binding for lhs of assignment", xtag("name", assign->lhs()->name())); - - this->value_ = nullptr; - this->error_ = SchematikaError(err); - - /* note: poor man's exception */ - this->pc_ = nullptr; - this->cont_ = nullptr; - } - } - - void - VirtualSchematikaMachine::do_complete_assign_op() - { - scope log(XO_DEBUG(true)); - - /* - * - value: contains result of evaluating rhs of define - * - stack: top frame has 1 slot, holds variable to receive assignment - */ - assert(value_.get()); - assert(stack_.get()); - assert(env_.get()); - - gp sp0 = this->stack_; - - bp var = Variable::from(ExpressionBoxed::from((*sp0)[0])->contents()); - - assert(var.get()); - - gp * slot = this->env_->establish_var(var); - assert(slot); - - *slot = this->value_; - - //this->value_ = this->value_; // preserve value from rhs of defexpr - - this->stack_ = sp0->parent(); - this->pc_ = this->cont_ = sp0->continuation(); - } - - void - VirtualSchematikaMachine::eval_variable_op() - { - using xo::scm::Variable; - - scope log(XO_DEBUG(true)); - - bp var = Variable::from(expr_); - - assert(var.get()); - assert(env_.get()); - - const gp * slot = env_->lookup_slot(var->name()); - - if (slot) { - this->value_ = *slot; - this->pc_ = cont_; - } else { - /* Unknown variable error will often be recognized in expression parser, - * in such cases this path won't be used. - * - * In interactive environment will need some kind of support for modifying - * code (e.g. replacing top-level functions/variables), and in particular, - * replacements may have different type signature. - * It's possible that allowing for such replacements winds up giving up - * typesafety guarantees. In that case this path may get activated after - * all. - */ - - std::string err = tostr("no binding for variable", xtag("name", var->name())); - - this->value_ = nullptr; - this->error_ = SchematikaError(err); - - /* note: poor man's exception */ - this->pc_ = nullptr; - this->cont_ = nullptr; - } - } - - void - VirtualSchematikaMachine::eval_ifexpr_op() - { - using xo::scm::IfExpr; - - scope log(XO_DEBUG(true)); - - gc::IAlloc * mm = flyweight_.object_mm_; - - /** must promote bp -> gp **/ - gp ifexpr_boxed = ExpressionBoxed::make(mm, expr_); - bp ifexpr = IfExpr::from(expr_); - - assert(ifexpr.get()); - assert(env_.get()); - - this->pc_ = &VsmOps::eval_op; - this->expr_ = ifexpr->test(); - - - /* when control arrives at .cont_ will have: - * .value_ -> result of evaluating ifexpr->test() - */ - this->stack_ = VsmStackFrame::push1(mm, this->stack_, ifexpr_boxed, cont_); - - /* .stack_: - * frame - * [0] = ifexpr (boxed expression) - */ - - this->cont_ = &VsmOps::complete_ifexpr_op; - } - - void - VirtualSchematikaMachine::do_complete_ifexpr_op() - { - using xo::scm::IfExpr; - - scope log(XO_DEBUG(true)); - - /* - * - value: contains result of evaluating test condition of if-expr - * - stack: top frame has 1 slot, holds (boxed) if-expr itself - */ - assert(value_.get()); - assert(stack_.get()); - assert(env_.get()); - - gp test_value = gp::from(value_); - - if (test_value.get()) { - gp sp0 = this->stack_; - - bp ifexpr = IfExpr::from(ExpressionBoxed::from((*sp0)[0])->contents()); - - assert(ifexpr.get()); - - this->pc_ = &VsmOps::eval_op; - - if (test_value->value()) { - this->expr_ = ifexpr->when_true(); - } else { - if (ifexpr->when_false()) { - this->expr_ = ifexpr->when_false(); - } else { - /* 1-sided if-expr; evaluate to false */ - this->expr_ = Constant::make(false); - } - } - - this->stack_ = sp0->parent(); - this->cont_ = sp0->continuation(); - } else { - std::string err = tostr("expect boolean value for result of if-expr test", xtag("value", test_value)); - - this->value_ = nullptr; - this->error_ = SchematikaError(err); - - /* note: poor man's exception */ - this->pc_ = nullptr; - this->cont_ = nullptr; - } - } - - void - VirtualSchematikaMachine::eval_sequence_op() - { - using xo::scm::Sequence; - - scope log(XO_DEBUG(true)); - - gc::IAlloc * mm = flyweight_.object_mm_; - - /** must promote bp -> gp **/ - gp seq_boxed = ExpressionBoxed::make(mm, expr_); - bp seq = Sequence::from(expr_); - - assert(seq.get()); - assert(env_.get()); - - this->pc_ = &VsmOps::eval_op; - - if (seq->size() == 0) { - /* for 0-size sequence, invent an expression */ - this->expr_ = Constant::make(false); - } else { - this->expr_ = (*seq)[0]; - } - - if (seq->size() > 1) { - /* remainder */ - - gp next = Integer::make(mm, 1); - - /* when control arrives at .cont_ will have: - * .value_ -> result of evaluating last expr in seq - */ - this->stack_ = VsmStackFrame::push2(mm, stack_, seq_boxed, next, cont_); - - /* .stack_: - * frame - * [0] = seq (boxed sequence) - * [1] = next (index of next seq member to evaluate) - * .. - */ - - this->cont_ = &VsmOps::complete_sequence_op; - } else { - /* sequence completes when expr_ evaluated - * -> proceed with o.g. cont_ - */ - } - } - - void - VirtualSchematikaMachine::do_complete_sequence_op() - { - using xo::scm::Sequence; - - scope log(XO_DEBUG(true)); - - /* - stack: top frame has 2 slots: - * [0] : seq (boxed Sequence) - * [1] : next (index of next seq element to eval - */ - - assert(value_.get()); - assert(stack_.get()); - - gp sp0 = this->stack_; - - assert(sp0->size() == 2); - - bp seq = Sequence::from(ExpressionBoxed::from((*sp0)[0])->contents()); - gp next_obj = Integer::from((*sp0)[1]); - size_t i_next = next_obj->value(); - - assert(i_next < seq->size()); - - this->pc_ = &VsmOps::eval_op; - this->expr_ = (*seq)[i_next]; - - if (i_next + 1 == seq->size()) { - /* last member of sequence -> tail call optimization */ - this->stack_ = sp0->parent(); - this->cont_ = sp0->continuation(); - } else { - /* we can modify next_obj in place, - * since it's unique to frame sp0 - */ - next_obj->assign_value(i_next + 1); - this->cont_ = &VsmOps::complete_sequence_op; - } - } - - void - VirtualSchematikaMachine::eval_apply_op() - { - /* strategy: - * 1. calling sequence will involve two stack frames. - * 1a. the outer frame will hold 'final evaluated arguments' - * to the called function. When control transfers to that - * function, this frame will be at the top of stack_ - * 1b. innert frame will be used by eval_apply_op() and - * helper do_eval_collect_args() to evaluate function - * arguments, and populate the outer frame. - */ - - using xo::scm::Apply; - - scope log(XO_DEBUG(true)); - - gc::IAlloc * mm = flyweight_.object_mm_; - - /** must promote bp -> gp **/ - gp apply_boxed = ExpressionBoxed::make(mm, expr_); - bp apply = Apply::from(expr_); - - assert(apply.get()); - - size_t n = apply->n_arg() + 1; - - /* reminder: argument 0 refers to the function being called */ - gp targetarg = Integer::make(mm, 0); - - /* outer frame */ - gp argstack = VsmStackFrame::make(mm, stack_, n, cont_); - - /* scratch frame during call sequence. - * probably collect->cont_ will not be used? - */ - gp collect = VsmStackFrame::push2(mm, - argstack, - apply_boxed, - targetarg, - &VsmOps::complete_evalargs_op); - - this->pc_ = &VsmOps::eval_op; - this->expr_ = apply->fn(); - this->stack_ = collect; - this->cont_ = &VsmOps::complete_evalargs_op; - } - - void - VirtualSchematikaMachine::do_complete_evalargs_op() - { - using xo::scm::Apply; - - scope log(XO_DEBUG(true)); - - /* - stack: top frame has 2 slots - * [0] : apply (boxed Apply) - * [1] : targetarg index of next evaluated argument to deliver. - * (to corresponding slot in 2nd frame) - * - 2nd frame has n slots, where n = #of arguments at this site - * [0] : actual #0 - * .. - * [targetarg-1] : actual #{targetarg-1} - */ - - assert(value_.get()); - assert(stack_.get()); - - gp sp0 = this->stack_; - - assert(sp0.get()); - assert(sp0->size() == 2); - - bp apply = Apply::from(ExpressionBoxed::from((*sp0)[0])->contents()); - assert(apply.get()); - gp targetarg_obj = Integer::from((*stack_)[1]); - size_t targetarg = targetarg_obj->value(); - - /* note: apply->n_arg() doesn't count function itself */ - assert(targetarg < apply->n_arg() + 1); - - gp argstack = sp0->parent(); - - assert(argstack.get()); - - /* storing actual parameter in its correct position in call stackframe */ - (*argstack)[targetarg] = value_; - - ++targetarg; - - if (targetarg < apply->n_arg() + 1) { - /* - * arguments 0 .. #targetarg-1 already present in argstack - * arguments #targetarg .. #n still need to be evaluated - */ - - /* ok to update in place, since Integer in sp0 is unique */ - targetarg_obj->assign_value(targetarg); - - rp targetexpr = apply->lookup_arg(targetarg - 1); - - this->pc_ = &VsmOps::eval_op; - this->expr_ = targetexpr; - assert(this->stack_.get() == sp0.get()); - this->cont_ = &VsmOps::complete_evalargs_op; - } else { - /* all args evaluated: proceed to invoke evaluated function */ - - this->pc_ = &VsmOps::apply_op; - this->expr_ = nullptr; - this->stack_ = argstack; - /* unnecessary - will actually be set by apply_op() */ - this->cont_ = argstack->continuation(); - } - } - - void - VirtualSchematikaMachine::apply_op() - { - scope log(XO_DEBUG(true)); - - auto mm = flyweight_.object_mm_; - - // NOTE: Closures will have special handling. - // Could alternatively forward the whole problem - // (along with VSM state) to procedure implementation - - /* stack: top frame has n slots for procedure with n canonical args */ - - gp sp0 = stack_; - - assert(sp0->size() > 0); - - gp fn = Procedure::from((*sp0)[0]); - - if (fn->n_args() + 1 != sp0->size()) { - throw std::runtime_error(tostr("VirtualSchematikaMachine::apply_op:" - " argument mismatch in apply" - ": k arguments supplied where n expected", - xtag("k", sp0->size() - 1), - xtag("n", fn->n_args()))); - } - - /* todo: - * check function signature? - * should have been guaranteed by expression parser, - * but complications in interactive session when variables redefined. - */ - - gp retval = fn->apply_nocheck(mm, sp0->argv()); - - this->pc_ = this->cont_; - this->stack_ = sp0->parent(); - this->value_ = retval; - } - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end VirtualSchematikaMachine.cpp */ diff --git a/.xo-interpreter/src/interpreter/VsmInstr.cpp b/.xo-interpreter/src/interpreter/VsmInstr.cpp deleted file mode 100644 index 3ca138d9..00000000 --- a/.xo-interpreter/src/interpreter/VsmInstr.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/** @file VsmInstr.cpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#include "VsmInstr.hpp" - -namespace xo { - namespace scm { - VsmInstr::VsmInstr(Opcode opcode, - std::string_view name) : opcode_{opcode}, name_{name} - {} - } -} - -/* end VsmInstr.cpp */ diff --git a/.xo-interpreter/src/interpreter/VsmStackFrame.cpp b/.xo-interpreter/src/interpreter/VsmStackFrame.cpp deleted file mode 100644 index 9bca575e..00000000 --- a/.xo-interpreter/src/interpreter/VsmStackFrame.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/** @file VsmStackFrame.cpp - * - * @author Roland Conybeare, Nov 2025 - **/ - -#include "VsmStackFrame.hpp" -#include "xo/reflect/Reflect.hpp" -#include "xo/reflect/StructReflector.hpp" - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::StructReflector; - using xo::reflect::TypeDescrW; - using xo::reflect::TaggedPtr; - using xo::reflect::TypeDescrExtra; - using xo::reflect::EstablishTypeDescr; - using xo::reflect::StlVectorTdx; - - namespace scm { - namespace { - // TOOD: move into CVector - - std::size_t - slot_array_size(std::size_t n) { - return n * sizeof(gp); - } - } - - VsmStackFrame::VsmStackFrame(gc::IAlloc * mm, - gp p, - std::size_t n, - const VsmInstr * cont) : parent_{p}, - slot_v_{mm, n}, - cont_{cont} - {} - - gp - VsmStackFrame::make(gc::IAlloc * mm, - gp p, - std::size_t n, - const VsmInstr * cont) - { - gp retval = new (MMPtr(mm)) VsmStackFrame(mm, p, n, cont); - - for (std::size_t i = 0; i < n; ++i) - (*retval)[i] = nullptr; - - return retval; - } - - gp - VsmStackFrame::push1(gc::IAlloc * mm, - gp p, - gp s0, - const VsmInstr * cont) - { - gp retval = new (MMPtr(mm)) VsmStackFrame(mm, p, 1, cont); - - (*retval)[0] = s0; - - return retval; - } - - gp - VsmStackFrame::push2(gc::IAlloc * mm, - gp p, - gp s0, - gp s1, - const VsmInstr * cont) - { - gp retval = new (MMPtr(mm)) VsmStackFrame(mm, p, 2, cont); - - (*retval)[0] = s0; - (*retval)[1] = s1; - - return retval; - } - - TaggedPtr - VsmStackFrame::self_tp() const - { - return Reflect::make_tp(const_cast(this)); - } - - void - VsmStackFrame::display(std::ostream & os) const - { - os << ""; - } - - std::size_t - VsmStackFrame::_shallow_size() const - { - std::size_t retval = sizeof(VsmStackFrame); - - retval += gc::IAlloc::with_padding(slot_array_size(slot_v_.size())); - - return retval; - } - - Object * - VsmStackFrame::_shallow_copy(gc::IAlloc * mm) const - { - Cpof cpof(mm, this); - - size_t n = this->size(); - - VsmStackFrame * copy = new (cpof) VsmStackFrame(cpof.mm_, parent_, n, cont_); - - void * v_dest = copy->slot_v_.v_; - - if (slot_v_.v_) { - ::memcpy(v_dest, slot_v_.v_, slot_array_size(n)); - } - -#ifdef OBSOLETE - for (size_t i = 0, n = n_slot_; i < n; ++i) { - copy->v_[i] = v_[i]; - } -#endif - return copy; - } - - std::size_t - VsmStackFrame::_forward_children(gc::IAlloc * gc) - { - Object::_forward_inplace(parent_, gc); - - for (std::size_t i = 0, n = slot_v_.size(); i < n; ++i) { - Object::_forward_inplace((*this)[i], gc); - } - - return _shallow_size(); - } - - void - VsmStackFrame::reflect_self() - { - StructReflector sr; - - if (sr.is_incomplete() ) { - /* reflect CVector>. - * duplicates similar code in LocalEnv::reflect_self() - */ - using VectorType = obj::CVector>; - - /* custom reflection for array of Object pointers. - * Can use StlVectorTdx here, treating CVector as a vector - * via .size() and .operator[] members - */ - std::unique_ptr tdx1 - = std::make_unique>(); - TypeDescrW td1 - = EstablishTypeDescr::establish(); - td1->assign_tdextra(Reflect::get_final_invoker(), - std::move(tdx1)); - - REFLECT_MEMBER(sr, parent); - REFLECT_MEMBER(sr, slot_v); - } - } - } /*namespace scm*/ -} /*namespace xo*/ - -/* end VsmStackFrame.cpp */ diff --git a/.xo-interpreter/src/interpreter/init_interpreter.cpp b/.xo-interpreter/src/interpreter/init_interpreter.cpp deleted file mode 100644 index eaa0bffe..00000000 --- a/.xo-interpreter/src/interpreter/init_interpreter.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/** @file init_interpreter.cpp - * - * author: Roland Conybeare, Nov 2025 - */ - -#include "init_interpreter.hpp" -#include "LocalEnv.hpp" -#include "xo/subsys/Subsystem.hpp" - -namespace xo { - using xo::scm::LocalEnv; - - void - InitSubsys::init() - { - LocalEnv::reflect_self(); - } - - InitEvidence - InitSubsys::require() - { - return Subsystem::provide("interpreter", &init); - } - -} /*namespace xo*/ - -/* end init_interpreter.cpp */ diff --git a/.xo-interpreter/utest/CMakeLists.txt b/.xo-interpreter/utest/CMakeLists.txt deleted file mode 100644 index 01cef051..00000000 --- a/.xo-interpreter/utest/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# build unittest interpreter/utest - -set(UTEST_EXE utest.interpreter) -set(UTEST_SRCS - interpreter_utest_main.cpp - LocalEnv.test.cpp -) - -xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) -xo_self_dependency(${UTEST_EXE} xo_interpreter) -xo_dependency(${UTEST_EXE} xo_object) -xo_external_target_dependency(${UTEST_EXE} Catch2 Catch2::Catch2) diff --git a/.xo-interpreter/utest/LocalEnv.test.cpp b/.xo-interpreter/utest/LocalEnv.test.cpp deleted file mode 100644 index 084d5a4d..00000000 --- a/.xo-interpreter/utest/LocalEnv.test.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/** @file LocalEnv.test.cpp **/ - -#include "xo/interpreter/init_interpreter.hpp" -#include "xo/interpreter/LocalEnv.hpp" -#include "xo/object/Integer.hpp" -#include "xo/alloc/GC.hpp" -#include -#include -#include - -namespace xo { - using xo::scm::LocalEnv; - using xo::obj::Integer; - using xo::gc::GC; - using xo::gc::ArenaAlloc; - using xo::gc::generation; - using xo::gc::generation_result; - using xo::reflect::TaggedPtr; - - namespace ut { - static InitEvidence s_init = (InitSubsys::require()); - - namespace { - struct Testcase_LocalEnv { - Testcase_LocalEnv(const std::vector & contents) : contents_{contents} {} - - /* build xo::obj::Integer for each contents_[i], store in F[i] for new LocalEnv F */ - std::vector contents_; - }; - - std::vector - s_testcase_v = { - Testcase_LocalEnv({}), - Testcase_LocalEnv({}), - Testcase_LocalEnv({111}), - Testcase_LocalEnv({111, 222}), - }; - } - - TEST_CASE("LocalEnv", "[LocalEnv][interpreter]") - { - Subsystem::initialize_all(); - - constexpr bool c_debug_flag = false; - - for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) { - scope log(XO_DEBUG(c_debug_flag), xtag("test", "LocalEnv2"), xtag("i_tc", i_tc)); - - const Testcase_LocalEnv & tc = s_testcase_v[i_tc]; - - up alloc = ArenaAlloc::make("utest", 16384, c_debug_flag); - REQUIRE(alloc.get()); - Object::mm = alloc.get(); - - std::size_t n = tc.contents_.size(); - gp frame = LocalEnv::make(alloc.get(), nullptr /*parent*/, nullptr /*symtab*/, n); - - TaggedPtr tp = frame->self_tp(); - - REQUIRE(tp.is_struct()); - } - } - - TEST_CASE("LocalEnv2", "[LocalEnv][gc][interpreter]") - { - Subsystem::initialize_all(); - - constexpr bool c_debug_flag = false; - - try { - for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) { - scope log(XO_DEBUG(c_debug_flag), xtag("test", "LocalEnv2"), xtag("i_tc", i_tc)); - - const Testcase_LocalEnv & tc = s_testcase_v[i_tc]; - - up gc = GC::make( - {.initial_nursery_z_ = 16384, - .initial_tenured_z_ = 32768, - .incr_gc_threshold_ = 4096, - .full_gc_threshold_ = 4096, - .object_stats_flag_ = true, - .debug_flag_ = c_debug_flag, - }); - - REQUIRE(gc.get()); - - /* use gc for all Object allocs */ - GC * mm = gc.get(); - Object::mm = mm; - - std::size_t n = tc.contents_.size(); - - gp x = Integer::make(gc.get(), 42); - gc->add_gc_root(reinterpret_cast(&x)); - REQUIRE(gc->tospace_generation_of(x.ptr()) == generation_result::nursery); - - gp frame = LocalEnv::make(gc.get(), nullptr /*parent*/, nullptr /*symtab*/, n); - LocalEnv ** frame_pp = frame.ptr_address(); - gc->add_gc_root(reinterpret_cast(frame_pp)); - - /* verifying allocated in N1 */ - REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery); - - for (std::size_t i = 0; i < n; ++i) - (*frame)[i] = Integer::make(mm, tc.contents_.at(i)); - - std::size_t expected_alloc_z = frame->_shallow_size(); - REQUIRE(expected_alloc_z >= sizeof(LocalEnv) + n * sizeof(gp)); - - gc->request_gc(generation::nursery); // <<<<<<<<< GC here <<<<<<<<< - - REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1); - REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0); - - /* verify Integer x preserved across gc */ - REQUIRE(gc->tospace_generation_of(x.ptr()) == generation_result::nursery); - - /* verify LocalEnv preserved across gc */ - REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery); - REQUIRE(frame->size() == n); - for (std::size_t i = 0; i < n; ++i) { - //REQUIRE(Integer::from(frame->lookup(i)).ptr()); - //REQUIRE(Integer::from(frame->lookup(i))->value() == tc.contents_.at(i)); - } - } - } catch (std::exception & ex) { - std::cerr << "exception: " << ex.what() << std::endl; - REQUIRE(false); - } - } - } -} - -/* end LocalEnv.test.cpp */ diff --git a/.xo-interpreter/utest/interpreter_utest_main.cpp b/.xo-interpreter/utest/interpreter_utest_main.cpp deleted file mode 100644 index e385f9b4..00000000 --- a/.xo-interpreter/utest/interpreter_utest_main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/** @file interpreter_utest_main.cpp **/ - -#define CATCH_CONFIG_MAIN -#include "catch2/catch.hpp" - -/* end interpreter_utest_main.cpp */