From 5d2ee35fe67825b259642f5ee65408f4b0621f1f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 31 Jul 2024 23:37:51 +1000 Subject: [PATCH 001/191] parser: initial implementation [wip - only handles 'def' expr --- .gitignore | 8 + CMakeLists.txt | 27 ++ cmake/xo-bootstrap-macros.cmake | 35 ++ cmake/xo_parserConfig.cmake.in | 8 + include/xo/parser/parser.hpp | 454 +++++++++++++++++++++ src/parser/CMakeLists.txt | 11 + src/parser/parser.cpp | 690 ++++++++++++++++++++++++++++++++ utest/CMakeLists.txt | 16 + utest/parser.test.cpp | 199 +++++++++ utest/parser_utest_main.cpp | 6 + 10 files changed, 1454 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 cmake/xo-bootstrap-macros.cmake create mode 100644 cmake/xo_parserConfig.cmake.in create mode 100644 include/xo/parser/parser.hpp create mode 100644 src/parser/CMakeLists.txt create mode 100644 src/parser/parser.cpp create mode 100644 utest/CMakeLists.txt create mode 100644 utest/parser.test.cpp create mode 100644 utest/parser_utest_main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3d3a7826 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# emacs workspace config +.projectile +# clangd working space (see emacs+lsp) +.cache +# typical cmake build directory (source-tree-nephew) +.build* +# symlink to builddir/compile_commands.json; should be set manually in dev sandbox +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..84eccb39 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +# xo-parser/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_parser 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") +add_definitions(${PROJECT_CXX_FLAGS}) + +# ---------------------------------------------------------------- + +add_subdirectory(src/parser) +add_subdirectory(utest) + +# ---------------------------------------------------------------- +# provide find_package() support + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) diff --git a/cmake/xo-bootstrap-macros.cmake b/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..aba31169 --- /dev/null +++ b/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,35 @@ +# ---------------------------------------------------------------- +# 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 (NOT XO_SUBMODULE_BUILD) + 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/cmake/xo_parserConfig.cmake.in b/cmake/xo_parserConfig.cmake.in new file mode 100644 index 00000000..6eadeb07 --- /dev/null +++ b/cmake/xo_parserConfig.cmake.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(xo_expression) +find_dependency(xo_tokenizer) +#find_dependency(subsys) +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp new file mode 100644 index 00000000..92b8e046 --- /dev/null +++ b/include/xo/parser/parser.hpp @@ -0,0 +1,454 @@ +/* file parser.hpp + * + * author: Roland Conybeare, Jul 2024 + */ + +#pragma once + +#include "xo/expression/Expression.hpp" +#include "xo/tokenizer/token.hpp" +#include +#include + +namespace xo { + namespace scm { + // ----- exprir ----- + + enum class exprirtype { + invalid = -1, + + empty, + symbol, + expression, + + n_exprirtype + }; + + extern const char * + exprirtype_descr(exprirtype x); + + inline std::ostream & + operator<< (std::ostream & os, + exprirtype x) + { + os << exprirtype_descr(x); + return os; + } + + /** intermediate representation for some part of an expression + * + * Examples: + * 1. a variable name (but without type information) + **/ + class exprir { + public: + using Expression = xo::ast::Expression; + + public: + exprir() = default; + exprir(exprirtype xir_type, + const std::string & x) + : xir_type_{xir_type}, symbol_name_{x} {} + exprir(exprirtype xir_type, + rp expr) + : xir_type_{xir_type}, expr_{std::move(expr)} {} + + exprirtype xir_type() const { return xir_type_; } + const std::string & symbol_name() const { return symbol_name_; } + const rp & expr() const { return expr_; } + + void print(std::ostream & os) const; + + private: + /** IR type code **/ + exprirtype xir_type_ = exprirtype::invalid; + /** xir_type=symbol: a symbol (type or variable) name **/ + std::string symbol_name_; + /** xir_type=expression: a completed expression **/ + rp expr_; + }; + + inline std::ostream & + operator<< (std::ostream & os, const exprir & x) { + x.print(os); + return os; + } + + enum class exprstatetype { + invalid = -1, + + /** toplevel of some translation unit **/ + expect_toplevel_expression_sequence, + + def_0, + def_1, + def_2, + def_3, + def_4, + + expect_rhs_expression, + expect_symbol, + + n_exprstatetype + }; + + extern const char * + exprstatetype_descr(exprstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, exprstatetype x) { + os << exprstatetype_descr(x); + return os; + } + + enum class expractiontype { + invalid = -1, + + push1, + push2, + keep, + emit, + pop, + + n_expractiontype + }; + + extern const char * + expractiontype_descr(expractiontype x); + + inline std::ostream & + operator<< (std::ostream & os, expractiontype x) { + os << expractiontype_descr(x); + return os; + } + + /** an action associated with parser response to an incoming lexical + **/ + class expraction { + public: + expraction() = default; + expraction(expractiontype action_type, + const exprir & expr_ir, + exprstatetype push_exs1, + exprstatetype push_exs2) + : action_type_{action_type}, expr_ir_{expr_ir}, + push_exs1_{push_exs1}, push_exs2_{push_exs2} + {} + + static expraction keep(); + static expraction emit(const exprir & ir); + static expraction push2(exprstatetype s1, exprstatetype s2); + + expractiontype action_type() const { return action_type_; } + const exprir & expr_ir() const { return expr_ir_; } + exprstatetype push_exs1() const { return push_exs1_; } + exprstatetype push_exs2() const { return push_exs2_; } + + void print(std::ostream & os) const; + + private: + /** + * push1: push new exprstate built from push_exs1_ + * push2: push new exprstate built from push_exs1_, + * followed by push_exs2_ + * keep: keep current exprstate (which will have updated inplace) + * pop: drop exprstate, report exprir to parent + **/ + expractiontype action_type_ = expractiontype::invalid; + /** + * intermediate representation (pass to enclosing stack state) + **/ + exprir expr_ir_; + /** with action_type push1 or push2, + * parser will push exprstate with this type + **/ + exprstatetype push_exs1_ = exprstatetype::invalid; + /** with action_type push2, + * parser will push exprstate with this type + * (after pushing exprstate built from push_exs1_) + **/ + exprstatetype push_exs2_ = exprstatetype::invalid; + }; + + inline std::ostream & + operator<< (std::ostream & os, + const expraction & x) + { + x.print(os); + return os; + } + + /** state associated with a partially-parsed expression. + **/ + class exprstate { + public: + using exprtype = xo::ast::exprtype; + using token_type = token; + + public: + exprstate() = default; + exprstate(exprstatetype exs_type) : exs_type_{exs_type} {} + + static exprstate expect_toplevel_expression_sequence() { + return exprstate(exprstatetype::expect_toplevel_expression_sequence); + } + static exprstate def_0() { + return exprstate(exprstatetype::def_0); + } + static exprstate expect_symbol() { + return exprstate(exprstatetype::expect_symbol); + } + + exprstatetype exs_type() const { return exs_type_; } + + /** true iff this parsing state admits a 'def' keyword + * as next token + **/ + bool admits_definition() const; + /** true iff this parsing state admits a symbol as next token **/ + bool admits_symbol() const; + /** true iff this parsing state admits a colon as next token **/ + bool admits_colon() const; + /** true iff this parsing state admits a singleassign '=' as next token **/ + bool admits_singleassign() const; + /** true iff this parsing state admits a 64-bit floating point literal token **/ + bool admits_f64() const; + + /** update exprstate in response to incoming token @p tk, + * forward instructions to parent parser + **/ + expraction on_input(const token_type & tk); + /** update exprstate in response to IR (intermediate representation) + * from nested parsing task + **/ + expraction on_exprir(const exprir & ir); + + /** print human-readable representation on @p os **/ + void print(std::ostream & os) const; + + private: + expraction on_def(); + expraction on_symbol(const token_type & tk); + expraction on_colon(); + expraction on_singleassign(); + expraction on_f64(const token_type & tk); + + private: + /** + * def foo : f64 = 1 + * ^ ^ ^ ^ ^ ^ ^ + * | | | | | | (done) + * | | | | | def_4:expect_rhs_expression + * | | | | def_3 + * | | | def_2:expect_symbol + * | | def_1 + * | def_0:expect_symbol + * expect_toplevel_expression_sequence + * + * def_0:expect_symbol: got 'def' keyword, symbol to follow + * def_1: got symbol name + * def_2:expect_symbol got (optional) colon, type name to follow + * def_3: got symbol type + * def_4:expect_rhs_expression got (optional) equal sign, value to follow + * (done): definition complete, pop exprstate from stack + * + **/ + exprstatetype exs_type_; + + /** e.g. foo in + * def foo : f64 = 1 + **/ + std::string def_lhs_symbol_; + /** e.g. f64 in + * def foo : f64 = 1 + **/ + std::string def_lhs_type_; + }; /*exprstate*/ + + inline std::ostream & + operator<< (std::ostream & os, const exprstate & x) { + x.print(os); + return os; + } + + /** schematica parser + * + * Examples: + * + * decltype point + * + * // forward declarations + * decl pi : f64 + * decl fib(n : i32) -> i32 + * + * def pi = 3.14159265 // constant. = is single assignment + * + * def fib(n : i32) -> i32 { + * // nested defs ok + * def aux(n : i32, s1 : i32, s2 : i32) -> i32 { + * // or: + * // (n == 0) ? s1 : aux(n - 1, s1 + s2, s1) + * // + * if (n == 0) { + * s1 + * } else { + * aux(n - 1, s1 + s2, s1) + * } + * + * // or: + * // if (n == 0) ? s1 : aux(n - 1, s1 + s2, s1) + * } + * + * aux(n=n, s1=1, s2=0) + * } + * + * def anotherfib = lambda(n : i32) { fib(n) } + * + * def any : object + * def l : list = '() + * + * deftype point :: {x : f64, y : f64} + * deftype polar :: {arg : f64, mag : f64} + * + * def polar2rect(pt : polar) -> point { + * point(x = pt.mag * cos(arg), + * y = pt.mag * sin(arg)) + * } + * + * Grammar: + * toplevel-program = expression* + * type-decl = decltype $typename [<$tp1 .. $tpn>] + * expression = define-expr + * | literal-expr + * | variable-expr + * | apply-expr + * | if-expr + * | lambda-expr + * | block + * + * define-expr = type-decl + * | type-def + * | variable-def + * | function-decl + * | function-def + * + * type-def = deftype $typename [<$tp1 .. $tpn>] :: type-def-rhs + * type-def-rhs = object + * | bool + * | i128 | i64 | i32 | i16 | i8 + * | f128 | f64 | f32 | f16 + * | struct $typename { ($membername(i) : $typename(i))* } + * [end $typename] + * | tuple $typename { $typename(1), .., $typename(n) } + * [end $typename] + * | copytype $typename + * | subtype $typename { ($member(i) : $typename(i))* } + * + * variable-def = decl $varname [: $typename] [= expression] + * function-decl = decl $functionname($varname(1) : $typename(1), + * .., + * $varname(n) : $typename(n)) -> $typename[ret] + * function-def = def $functionname($varname(1) : $typename(1), + * .., + * $varname(n) : $typename(n)) [-> $typename[ret]] + * body-expr + * [ end $functionname ] + * literal-expr = integer-literal + * | fp-literal + * | string-literal + * | symbol-literal + * | struct-literal + * + * variable-expr = $varname + * apply-expr = fn-expr(arg-expr(1), .., arg-expr(n)) + * fn-expr = expression + * arg-expr(i) = expression + * + * if-expr = if (test-expr) then-block else else-block + * | (test-expr) ? then-expr : else-expr + * test-expr = expression + * then-block = block + * else-block = block + * + * block = { (definition | expression)* } + * + * lambda-expr = lambda ($paramname(1) : $type(1), + * .., + * $paramname(n) : $type(n)) body-expr + * body-expr = expression + **/ + class parser { + public: + using Expression = xo::ast::Expression; + using token_type = exprstate::token_type; // token; + + public: + /** create parser in initial state; + * parser is ready to receive tokens via @ref include_token + **/ + parser() = default; + + /** for diagnostics: number of entries in parser stack **/ + std::size_t stack_size() const { return stack_.size(); } + /** for diagnostics: exprstatetype at level @p i + * (taken relative to top of stack) + * + * @pre 0 <= i < stack_size + **/ + exprstatetype i_exstype(std::size_t i) const { + std::size_t z = stack_.size(); + + if (i < z) { + return stack_[(z - 1) - i].exs_type(); + } + + /* out of bounds */ + return exprstatetype::invalid; + } + + /** put parser into state for beginning of a translation unit + * (i.e. input stream) + **/ + void begin_translation_unit(); + + /** include next token @p tk and increment parser state. + * + * @param tk next input token + * @return parsed expression, if @p tk completes an expression. + * otherwise nullptr + **/ + rp include_token(const token_type & tk); + + /** print human-readable representation on stream @p os **/ + void print(std::ostream & os) const; + + private: + exprstate & top_exprstate(); + void push_exprstate(const exprstate & exs); + void pop_exprstate(); + + private: + /** state recording state associated with enclosing expressions. + * + * Note: at least asof c++23, the std::stack api doesn't support access + * to members other than the top. + * + * for stack with N elements (N = stack_.size()): + * - bottom of stack is stack_[0] + * - top of stack is stack_[N-1] + **/ + std::vector stack_; + + }; /*parser*/ + + inline std::ostream & + operator<< (std::ostream & os, + const parser & x) { + x.print(os); + return os; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end parser.hpp */ diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt new file mode 100644 index 00000000..2af43636 --- /dev/null +++ b/src/parser/CMakeLists.txt @@ -0,0 +1,11 @@ +# parser/CMakeLists.txt + +set(SELF_LIB xo_parser) +set(SELF_SRCS + parser.cpp) + +xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) +xo_dependency(${SELF_LIB} xo_expression) +xo_dependency(${SELF_LIB} xo_tokenizer) + +# end CMakeLists.txt diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp new file mode 100644 index 00000000..ab6404fd --- /dev/null +++ b/src/parser/parser.cpp @@ -0,0 +1,690 @@ +/* file parser.cpp + * + * author: Roland Conybeare + */ + +#include "parser.hpp" +#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/Constant.hpp" +#include +#include + +namespace xo { + using xo::ast::Expression; + using xo::ast::DefineExpr; + using xo::ast::Constant; + + namespace scm { + const char * + exprirtype_descr(exprirtype x) { + switch(x) { + case exprirtype::invalid: + return "?invalid"; + case exprirtype::empty: + return "empty"; + case exprirtype::symbol: + return "symbol"; + case exprirtype::expression: + return "expression"; + case exprirtype::n_exprirtype: + break; + } + + return "???exprirtype"; + } + + void + exprir::print(std::ostream & os) const { + os << ""; + } + + const char * + exprstatetype_descr(exprstatetype x) { + switch(x) { + case exprstatetype::invalid: + return "?invalid"; + case exprstatetype::expect_toplevel_expression_sequence: + return "expect_toplevel_expression_sequence"; + case exprstatetype::def_0: + return "def_0"; + case exprstatetype::def_1: + return "def_1"; + case exprstatetype::def_2: + return "def_2"; + case exprstatetype::def_3: + return "def_3"; + case exprstatetype::def_4: + return "def_4"; + case exprstatetype::expect_rhs_expression: + return "expect_rhs_expression"; + case exprstatetype::expect_symbol: + return "expect_symbol"; + case exprstatetype::n_exprstatetype: + break; + } + + return "???"; + } + + const char * + expractiontype_descr(expractiontype x) { + switch(x) { + case expractiontype::invalid: + return "?invalid"; + case expractiontype::push1: + return "push1"; + case expractiontype::push2: + return "push2"; + case expractiontype::keep: + return "keep"; + case expractiontype::emit: + return "emit"; + case expractiontype::pop: + return "pop"; + case expractiontype::n_expractiontype: + break; + } + + return "???"; + } + + expraction + expraction::keep() { + return expraction(expractiontype::keep, + exprir(), + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + } + + expraction + expraction::emit(const exprir & ir) { + return expraction(expractiontype::emit, + ir, + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + } + + expraction + expraction::push2(exprstatetype s1, + exprstatetype s2) { + return expraction(expractiontype::push2, + exprir(), + s1, + s2); + } + + void + expraction::print(std::ostream & os) const { + os << ""; + } + + bool + exprstate::admits_definition() const { + switch(exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + return true; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + /* note for def_4: + * rhs could certainly be a function body that contains + * nested defines; but then immediately-enclosing-exprstate + * would be a block + */ + return false; + case exprstatetype::expect_rhs_expression: + return false; + case exprstatetype::expect_symbol: + return false; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + } + + bool + exprstate::admits_symbol() const { + switch(exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + return false; + + case exprstatetype::expect_rhs_expression: + /* treat symbol as variable name */ + return true; + + case exprstatetype::expect_symbol: + return true; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + } + + bool + exprstate::admits_colon() const { + switch(exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + return false; + + case exprstatetype::def_1: + return true; + + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::expect_rhs_expression: + /* rhs-expressions (or expressions for that matter) + * may not begin with a colon + */ + case exprstatetype::expect_symbol: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + } + + bool + exprstate::admits_singleassign() const { + switch(exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + return false; + + case exprstatetype::def_3: + return true; + + case exprstatetype::def_4: + case exprstatetype::expect_rhs_expression: + /* rhs-expressions (or expressions for that matter) + * may not begin with singleassign '=' + */ + case exprstatetype::expect_symbol: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + } + + bool + exprstate::admits_f64() const { + switch(exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + return false; + + case exprstatetype::expect_rhs_expression: + return true; + + case exprstatetype::expect_symbol: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + } + + expraction + exprstate::on_def() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_def"; + + /* lots of illegal states */ + if (!this->admits_definition()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected keyword 'def' for parsing state", + xtag("state", *this))); + } + + /* keyword 'def' introduces a definition: + * def pi : f64 = 3.14159265 + * def sq(x : f64) -> f64 { (x * x) } + */ + return expraction::push2(exprstatetype::def_0, + /* todo: replace: + * expect_symbol_or_function_signature() + */ + exprstatetype::expect_symbol); + } + + expraction + exprstate::on_symbol(const token_type & tk) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_symbol"; + + if (!this->admits_symbol()) { + throw std::runtime_error + (tostr(self_name, + ": unexpected symbol-token for parsing state", + xtag("symbol", tk), + xtag("state", *this))); + } + + switch(this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + throw std::runtime_error + (tostr(self_name, + ": unexpected symbol-token at top-level", + " (expecting decl|def)", + xtag("symbol", tk))); + break; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + /* unreachable */ + assert(false); + return expraction(); + + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + return expraction(expractiontype::pop, + exprir(exprirtype::symbol, tk.text()), + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return expraction(); + } + } + + expraction + exprstate::on_colon() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_colon"; + + /* lots of illegal states */ + if (!this->admits_colon()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected colon for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::def_1) { + this->exs_type_ = exprstatetype::def_2; + + return expraction(expractiontype::push1, + exprir(), + exprstatetype::expect_symbol, + exprstatetype::invalid /*not used*/); + } else { + assert(false); + return expraction(); + } + } + + expraction + exprstate::on_singleassign() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_singleassign"; + + if (!this->admits_singleassign()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected equals for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::def_3) { + this->exs_type_ = exprstatetype::def_4; + + return expraction(expractiontype::push1, + exprir(), + exprstatetype::expect_rhs_expression, + exprstatetype::invalid /*not used*/); + } else { + assert(false); + return expraction(); + } + } + + expraction + exprstate::on_f64(const token_type & tk) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_f64"; + + if (!this->admits_f64()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected floating-point literal for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expect_rhs_expression) { + return expraction(expractiontype::pop, + exprir(exprirtype::expression, + Constant::make(tk.f64_value())), + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + } else { + assert(false); + return expraction(); + } + } + + expraction + exprstate::on_input(const token_type & tk) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + log && log(xtag("tk", tk)); + log && log(xtag("state", *this)); + + switch(tk.tk_type()) { + + case tokentype::tk_def: + return this->on_def(); + + case tokentype::tk_i64: + assert(false); + return expraction(); + + case tokentype::tk_f64: + return this->on_f64(tk); + + case tokentype::tk_string: + assert(false); + return expraction(); + + case tokentype::tk_symbol: + return this->on_symbol(tk); + + case tokentype::tk_leftparen: + + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_dot: + case tokentype::tk_comma: + assert(false); + return expraction(); + + case tokentype::tk_colon: + return this->on_colon(); + + case tokentype::tk_doublecolon: + case tokentype::tk_semicolon: + assert(false); + return expraction(); + + case tokentype::tk_singleassign: + return this->on_singleassign(); + + case tokentype::tk_assign: + case tokentype::tk_yields: + + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_if: + case tokentype::tk_let: + + case tokentype::tk_in: + case tokentype::tk_end: + assert(false); + return expraction(); + + case tokentype::tk_invalid: + case tokentype::n_tokentype: + assert(false); + return expraction(); + } + + assert(false); + return expraction(); + } + + expraction + exprstate::on_exprir(const exprir & ir) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + log && log(xtag("ir", ir)); + log && log(xtag("state", *this)); + + switch(this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* toplevel expression sequence accepts an + * arbitrary number of expressions. + * + * parser::include_token() returns + */ + + if (ir.xir_type() == exprirtype::expression) + return expraction::emit(ir); + + /* NOT IMPLEMENTED */ + assert(false); + return expraction(); + case exprstatetype::def_0: + this->exs_type_ = exprstatetype::def_1; + this->def_lhs_symbol_ = ir.symbol_name(); + + return expraction::keep(); + case exprstatetype::def_1: + /* NOT IMPLEMENTED */ + assert(false); + return expraction(); + case exprstatetype::def_2: + this->exs_type_ = exprstatetype::def_3; + this->def_lhs_type_ = ir.symbol_name(); + + return expraction::keep(); + case exprstatetype::def_3: + /* NOT IMPLEMENTED */ + assert(false); + return expraction(); + case exprstatetype::def_4: + /* have all the ingredients to create an expression + * representing a definition + * + * 1. if ir_type is a symbol, interpret as variable name. + * Need to be able to locate variable by type + * 2. if ir_type is an expression, adopt as rhs + */ + if (ir.xir_type() == exprirtype::expression) { + /* TODO: do something with def_lhs_type */ + + rp rhs_value = ir.expr(); + rp def + = DefineExpr::make(this->def_lhs_symbol_, + rhs_value); + + return expraction(expractiontype::pop, + exprir(exprirtype::expression, def), + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + } else { + assert(false); + return expraction(); + } + + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + /* unreachable + * (this exprstate issues pop instruction from exprstate::on_input() + */ + assert(false); + return expraction(); + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return expraction(); + } + } + + void + exprstate::print(std::ostream & os) const { + os << ""; + } + + // ----- parser ----- + + exprstate & + parser::top_exprstate() { + std::size_t z = stack_.size(); + + if (z == 0) { + throw std::runtime_error + ("parser::top_exprstate: unexpected empty stack"); + } + + return stack_[z-1]; + } + + void + parser::push_exprstate(const exprstate & exs) { + std::size_t z = stack_.size(); + + stack_.resize(z+1); + + stack_[z] = exs; + } + + void + parser::pop_exprstate() { + std::size_t z = stack_.size(); + + if (z > 0) + stack_.resize(z-1); + } + + void + parser::begin_translation_unit() { + this->push_exprstate + (exprstate::expect_toplevel_expression_sequence()); + } + + rp + parser::include_token(const token_type & tk) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + if (stack_.empty()) { + throw std::runtime_error(tostr("parser::include_token", + ": parser not expecting input" + "(call parser.begin_translation_unit()..?)", + xtag("token", tk))); + } + + /* stack_ is non-empty */ + expraction action = this->top_exprstate().on_input(tk); + + /* loop until reach parsing state that requires more input */ + for (;;) { + log && log(xtag("action", action)); + + switch(action.action_type()) { + case expractiontype::keep: + return nullptr; + + case expractiontype::emit: + return action.expr_ir().expr(); + + case expractiontype::pop: + this->pop_exprstate(); + + if (stack_.empty()) { + throw std::runtime_error(tostr("parser::include_token", + ": pop leaves empty stack")); + } + + action = this->top_exprstate().on_exprir(action.expr_ir()); + break; + + case expractiontype::push1: + this->push_exprstate(action.push_exs1()); + return nullptr; + + case expractiontype::push2: + this->push_exprstate(action.push_exs1()); + this->push_exprstate(action.push_exs2()); + return nullptr; + + case expractiontype::invalid: + case expractiontype::n_expractiontype: + /* unreachable */ + assert(false); + return nullptr; + } + } + } /*include_token*/ + + void + parser::print(std::ostream & os) const { + os << "" << std::endl; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end parser.cpp */ diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt new file mode 100644 index 00000000..d70b7d4d --- /dev/null +++ b/utest/CMakeLists.txt @@ -0,0 +1,16 @@ +# xo-parser/utest/CMakeLists.txt + +set(UTEST_EXE utest.parser) +set(UTEST_SRCS + parser_utest_main.cpp + parser.test.cpp) + +if (ENABLE_TESTING) + xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) + xo_self_dependency(${UTEST_EXE} xo_parser) + #xo_dependency(${UTEST_EXE} xo_ratio) + #xo_dependency(${UTEST_EXE} xo_reflectutil) + xo_external_target_dependency(${UTEST_EXE} Catch2 Catch2::Catch2) +endif() + +# end CMakeLists.txt diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp new file mode 100644 index 00000000..d5be7db7 --- /dev/null +++ b/utest/parser.test.cpp @@ -0,0 +1,199 @@ +/* file parser.test.cpp + * + * author: Roland Conybeare + */ + +#include "xo/parser/parser.hpp" +#include + +namespace xo { + using parser_type = xo::scm::parser; + using token_type = parser_type::token_type; + using xo::scm::exprstatetype; + using std::cerr; + using std::endl; + + //using xo::ast::Expression; + + namespace ut { + TEST_CASE("parser", "[parser]") { + parser_type parser; + + parser.begin_translation_unit(); + + REQUIRE(parser.stack_size() == 1); + REQUIRE(parser.i_exstype(0) + == exprstatetype::expect_toplevel_expression_sequence); + + /* input: + * def + */ + { + auto r1 = parser.include_token(token_type::def()); + REQUIRE(r1.get() == nullptr); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_0 + * expect_symbol + */ + CHECK(parser.stack_size() == 3); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::expect_symbol); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) == exprstatetype::def_0); + if (parser.stack_size() > 2) + CHECK(parser.i_exstype(2) + == exprstatetype::expect_toplevel_expression_sequence); + } + + /* input: + * def foo + * ^ ^ + * 0 1 + */ + { + auto r2 = parser.include_token(token_type::symbol_token("foo")); + + cerr << "parser state after [def foo]" << endl; + cerr << parser << endl; + + REQUIRE(r2.get() == nullptr); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_1 + */ + CHECK(parser.stack_size() == 2); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::def_1); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) + == exprstatetype::expect_toplevel_expression_sequence); + + } + + /* input: + * def foo : + * ^ ^ + * 0 1 + */ + { + auto r3 = parser.include_token(token_type::colon()); + + cerr << "parser state after [def foo :]" << endl; + cerr << parser << endl; + + REQUIRE(r3.get() == nullptr); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_2 + * expect_symbol + */ + CHECK(parser.stack_size() == 3); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::expect_symbol); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) == exprstatetype::def_2); + if (parser.stack_size() > 2) + CHECK(parser.i_exstype(2) + == exprstatetype::expect_toplevel_expression_sequence); + } + + /* input: + * def foo : footype + * ^ ^ + * 0 1 + */ + { + auto r4 = parser.include_token(token_type::symbol_token("footype")); + + cerr << "parser state after [def foo : footype]" << endl; + cerr << parser << endl; + + REQUIRE(r4.get() == nullptr); + + CHECK(parser.stack_size() == 2); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_3 + */ + CHECK(parser.stack_size() == 2); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::def_3); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) + == exprstatetype::expect_toplevel_expression_sequence); + + /* expecting either: + * = rhs-expression + * new-expression + */ + } + + /* input: + * def foo : footype = + * ^ ^ + * 0 1 + */ + { + auto r5 = parser.include_token(token_type::singleassign()); + + cerr << "parser state after [def foo : footype =]" << endl; + cerr << parser << endl; + + REQUIRE(r5.get() == nullptr); + + CHECK(parser.stack_size() == 3); + + /* stack should be + * + * expect_toplevel_expression_sequence + * def_4 + * expect_expression + */ + CHECK(parser.stack_size() == 3); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::expect_rhs_expression); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) == exprstatetype::def_4); + if (parser.stack_size() > 2) + CHECK(parser.i_exstype(2) + == exprstatetype::expect_toplevel_expression_sequence); + } + + /* input: + * def foo : footype = 3.14159265 + * ^ ^ + * 0 1 + */ + { + auto r6 = parser.include_token(token_type::f64_token("3.14159265")); + + cerr << "parser state after [def foo : footype = 3.14159265]" << endl; + cerr << parser << endl; + + REQUIRE(r6.get() != nullptr); + + CHECK(parser.stack_size() == 1); + + /* stack should be + * + * expect_toplevel_expression_sequence + */ + CHECK(parser.stack_size() == 1); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) + == exprstatetype::expect_toplevel_expression_sequence); + } + } /*TEST_CASE(parser)*/ + } /*namespace ut*/ +} /*namespace xo*/ + +/* end parser.test.cpp */ diff --git a/utest/parser_utest_main.cpp b/utest/parser_utest_main.cpp new file mode 100644 index 00000000..d1013151 --- /dev/null +++ b/utest/parser_utest_main.cpp @@ -0,0 +1,6 @@ +/* file parser_utest_main.cpp */ + +#define CATCH_CONFIG_MAIN +#include + +/* end parser_utest_main.cpp */ From 4132a66165529704b9d4b24c7b27b662b0c71856 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 09:44:52 +1000 Subject: [PATCH 002/191] xo-parser: + expect_type + exprir::td_ etc. --- include/xo/parser/parser.hpp | 14 ++++++-- src/parser/parser.cpp | 64 +++++++++++++++++++++++++++++++----- utest/parser.test.cpp | 28 ++++++++-------- 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 92b8e046..e5e87194 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -20,6 +20,7 @@ namespace xo { empty, symbol, expression, + typedescr, n_exprirtype }; @@ -43,6 +44,7 @@ namespace xo { class exprir { public: using Expression = xo::ast::Expression; + using TypeDescr = xo::reflect::TypeDescr; public: exprir() = default; @@ -52,10 +54,14 @@ namespace xo { exprir(exprirtype xir_type, rp expr) : xir_type_{xir_type}, expr_{std::move(expr)} {} + exprir(exprirtype xir_type, + TypeDescr td) + : xir_type_{xir_type}, td_{td} {} exprirtype xir_type() const { return xir_type_; } const std::string & symbol_name() const { return symbol_name_; } const rp & expr() const { return expr_; } + TypeDescr td() const { return td_; } void print(std::ostream & os) const; @@ -66,6 +72,8 @@ namespace xo { std::string symbol_name_; /** xir_type=expression: a completed expression **/ rp expr_; + /** xir_type=typedescr: object identifying/describing a datatype **/ + TypeDescr td_ = nullptr; }; inline std::ostream & @@ -88,6 +96,7 @@ namespace xo { expect_rhs_expression, expect_symbol, + expect_type, n_exprstatetype }; @@ -184,6 +193,7 @@ namespace xo { public: using exprtype = xo::ast::exprtype; using token_type = token; + using TypeDescr = xo::reflect::TypeDescr; public: exprstate() = default; @@ -240,7 +250,7 @@ namespace xo { * | | | | | | (done) * | | | | | def_4:expect_rhs_expression * | | | | def_3 - * | | | def_2:expect_symbol + * | | | def_2:expect_type * | | def_1 * | def_0:expect_symbol * expect_toplevel_expression_sequence @@ -262,7 +272,7 @@ namespace xo { /** e.g. f64 in * def foo : f64 = 1 **/ - std::string def_lhs_type_; + TypeDescr def_lhs_td_ = nullptr; }; /*exprstate*/ inline std::ostream & diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index ab6404fd..9bd6b8f6 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -6,13 +6,15 @@ #include "parser.hpp" #include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" -#include +//#include #include namespace xo { using xo::ast::Expression; using xo::ast::DefineExpr; using xo::ast::Constant; + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; namespace scm { const char * @@ -26,6 +28,8 @@ namespace xo { return "symbol"; case exprirtype::expression: return "expression"; + case exprirtype::typedescr: + return "typedescr"; case exprirtype::n_exprirtype: break; } @@ -38,8 +42,10 @@ namespace xo { os << ""; + << xtag("expr", expr_); + if (td_) + os << xtag("td", td_->short_name()); + os << ">"; } const char * @@ -63,6 +69,8 @@ namespace xo { return "expect_rhs_expression"; case exprstatetype::expect_symbol: return "expect_symbol"; + case exprstatetype::expect_type: + return "expect_type"; case exprstatetype::n_exprstatetype: break; } @@ -147,6 +155,7 @@ namespace xo { case exprstatetype::expect_rhs_expression: return false; case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: @@ -173,6 +182,10 @@ namespace xo { case exprstatetype::expect_symbol: return true; + case exprstatetype::expect_type: + /* treat symbol as typename */ + return true; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -198,6 +211,7 @@ namespace xo { * may not begin with a colon */ case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: @@ -225,6 +239,7 @@ namespace xo { * may not begin with singleassign '=' */ case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: @@ -249,6 +264,7 @@ namespace xo { return true; case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: @@ -324,6 +340,36 @@ namespace xo { exprstatetype::invalid /*not used*/, exprstatetype::invalid /*not used*/); + case exprstatetype::expect_type: { + TypeDescr td = nullptr; + + /* TODO: replace with typetable lookup */ + + if (tk.text() == "f64") + td = Reflect::require(); + else if(tk.text() == "f32") + td = Reflect::require(); + else if(tk.text() == "i16") + td = Reflect::require(); + else if(tk.text() == "i32") + td = Reflect::require(); + else if(tk.text() == "i64") + td = Reflect::require(); + + if (!td) { + throw std::runtime_error + (tostr(self_name, + ": unknown type name", + " (expecting f64|f32|i16|i32|i64)", + xtag("typename", tk.text()))); + } + + return expraction(expractiontype::pop, + exprir(exprirtype::typedescr, td), + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + } + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -352,7 +398,7 @@ namespace xo { return expraction(expractiontype::push1, exprir(), - exprstatetype::expect_symbol, + exprstatetype::expect_type, exprstatetype::invalid /*not used*/); } else { assert(false); @@ -520,7 +566,7 @@ namespace xo { return expraction(); case exprstatetype::def_2: this->exs_type_ = exprstatetype::def_3; - this->def_lhs_type_ = ir.symbol_name(); + this->def_lhs_td_ = ir.td(); return expraction::keep(); case exprstatetype::def_3: @@ -553,6 +599,7 @@ namespace xo { } case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: case exprstatetype::expect_symbol: /* unreachable * (this exprstate issues pop instruction from exprstate::on_input() @@ -571,9 +618,10 @@ namespace xo { exprstate::print(std::ostream & os) const { os << ""; + << xtag("def_lhs_symbol", def_lhs_symbol_); + if (def_lhs_td_) + os << xtag("def_lhs_td", def_lhs_td_->short_name()); + os << ">"; } // ----- parser ----- diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp index d5be7db7..e656d9de 100644 --- a/utest/parser.test.cpp +++ b/utest/parser.test.cpp @@ -96,7 +96,7 @@ namespace xo { */ CHECK(parser.stack_size() == 3); if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::expect_symbol); + CHECK(parser.i_exstype(0) == exprstatetype::expect_type); if (parser.stack_size() > 1) CHECK(parser.i_exstype(1) == exprstatetype::def_2); if (parser.stack_size() > 2) @@ -105,14 +105,14 @@ namespace xo { } /* input: - * def foo : footype - * ^ ^ - * 0 1 + * def foo : f64 + * ^ ^ + * 0 1 */ { - auto r4 = parser.include_token(token_type::symbol_token("footype")); + auto r4 = parser.include_token(token_type::symbol_token("f64")); - cerr << "parser state after [def foo : footype]" << endl; + cerr << "parser state after [def foo : f64]" << endl; cerr << parser << endl; REQUIRE(r4.get() == nullptr); @@ -138,14 +138,14 @@ namespace xo { } /* input: - * def foo : footype = - * ^ ^ - * 0 1 + * def foo : f64 = + * ^ ^ + * 0 1 */ { auto r5 = parser.include_token(token_type::singleassign()); - cerr << "parser state after [def foo : footype =]" << endl; + cerr << "parser state after [def foo : f64 =]" << endl; cerr << parser << endl; REQUIRE(r5.get() == nullptr); @@ -169,14 +169,14 @@ namespace xo { } /* input: - * def foo : footype = 3.14159265 - * ^ ^ - * 0 1 + * def foo : f64 = 3.14159265 + * ^ ^ + * 0 1 */ { auto r6 = parser.include_token(token_type::f64_token("3.14159265")); - cerr << "parser state after [def foo : footype = 3.14159265]" << endl; + cerr << "parser state after [def foo : f64 = 3.14159265]" << endl; cerr << parser << endl; REQUIRE(r6.get() != nullptr); From 32b3998094a1242853f2aedc5441b295e30c0883 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:04:10 +1000 Subject: [PATCH 003/191] xo-parser: use ConvertExpr for 'def foo : sometype...' --- src/parser/parser.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 9bd6b8f6..9851a987 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -6,12 +6,14 @@ #include "parser.hpp" #include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" +#include "xo/expression/ConvertExpr.hpp" //#include #include namespace xo { using xo::ast::Expression; using xo::ast::DefineExpr; + using xo::ast::ConvertExpr; using xo::ast::Constant; using xo::reflect::Reflect; using xo::reflect::TypeDescr; @@ -582,12 +584,15 @@ namespace xo { * 2. if ir_type is an expression, adopt as rhs */ if (ir.xir_type() == exprirtype::expression) { - /* TODO: do something with def_lhs_type */ + /* TODO: do something with def_lhs_td */ rp rhs_value = ir.expr(); - rp def - = DefineExpr::make(this->def_lhs_symbol_, - rhs_value); + + if (def_lhs_td_) + rhs_value = ConvertExpr::make(def_lhs_td_, rhs_value); + + rp def = DefineExpr::make(this->def_lhs_symbol_, + rhs_value); return expraction(expractiontype::pop, exprir(exprirtype::expression, def), From 2f7176b1022bd16eb2833ae6e315cbd5f4466f79 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:31:42 +1000 Subject: [PATCH 004/191] xo-parser: + expraction::pop() & apply --- include/xo/parser/parser.hpp | 1 + src/parser/parser.cpp | 30 +++++++++++++----------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index e5e87194..11a3a2e2 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -147,6 +147,7 @@ namespace xo { static expraction keep(); static expraction emit(const exprir & ir); static expraction push2(exprstatetype s1, exprstatetype s2); + static expraction pop(const exprir & ir); expractiontype action_type() const { return action_type_; } const exprir & expr_ir() const { return expr_ir_; } diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 9851a987..312b38f0 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -127,6 +127,14 @@ namespace xo { s2); } + expraction + expraction::pop(const exprir & ir) { + return expraction(expractiontype::pop, + ir, + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + } + void expraction::print(std::ostream & os) const { os << "exs_type_ == exprstatetype::expect_rhs_expression) { - return expraction(expractiontype::pop, - exprir(exprirtype::expression, - Constant::make(tk.f64_value())), - exprstatetype::invalid /*not used*/, - exprstatetype::invalid /*not used*/); + return expraction::pop(exprir(exprirtype::expression, + Constant::make(tk.f64_value()))); } else { assert(false); return expraction(); @@ -594,10 +593,7 @@ namespace xo { rp def = DefineExpr::make(this->def_lhs_symbol_, rhs_value); - return expraction(expractiontype::pop, - exprir(exprirtype::expression, def), - exprstatetype::invalid /*not used*/, - exprstatetype::invalid /*not used*/); + return expraction::pop(exprir(exprirtype::expression, def)); } else { assert(false); return expraction(); From a5bd857efdd17a434823e9df854e55551d176ce4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:32:23 +1000 Subject: [PATCH 005/191] xo-parser: refactor: xtract exprstatestack from parser --- include/xo/parser/parser.hpp | 52 +++++++++++++++++++++++++++++------- src/parser/parser.cpp | 52 +++++++++++++++++++++++------------- 2 files changed, 76 insertions(+), 28 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 11a3a2e2..b81b5ff3 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -282,6 +282,45 @@ namespace xo { return os; } + /** @class exprstatestack + * @brief A stack of exprstate objects + **/ + class exprstatestack { + public: + exprstatestack() {} + + bool empty() const { return stack_.empty(); } + std::size_t size() const { return stack_.size(); } + + exprstate & top_exprstate(); + void push_exprstate(const exprstate & exs); + void pop_exprstate(); + + /** relative to top-of-stack. + * 0 -> top (last in), z-1 -> bottom (first in) + **/ + exprstate & operator[](std::size_t i) { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + const exprstate & operator[](std::size_t i) const { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + void print (std::ostream & os) const; + + private: + std::vector stack_; + }; + /** schematica parser * * Examples: @@ -400,17 +439,17 @@ namespace xo { parser() = default; /** for diagnostics: number of entries in parser stack **/ - std::size_t stack_size() const { return stack_.size(); } + std::size_t stack_size() const { return xs_stack_.size(); } /** for diagnostics: exprstatetype at level @p i * (taken relative to top of stack) * * @pre 0 <= i < stack_size **/ exprstatetype i_exstype(std::size_t i) const { - std::size_t z = stack_.size(); + std::size_t z = xs_stack_.size(); if (i < z) { - return stack_[(z - 1) - i].exs_type(); + return xs_stack_[i].exs_type(); } /* out of bounds */ @@ -433,11 +472,6 @@ namespace xo { /** print human-readable representation on stream @p os **/ void print(std::ostream & os) const; - private: - exprstate & top_exprstate(); - void push_exprstate(const exprstate & exs); - void pop_exprstate(); - private: /** state recording state associated with enclosing expressions. * @@ -448,7 +482,7 @@ namespace xo { * - bottom of stack is stack_[0] * - top of stack is stack_[N-1] **/ - std::vector stack_; + exprstatestack xs_stack_; }; /*parser*/ diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 312b38f0..a4f93b70 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -625,10 +625,10 @@ namespace xo { os << ">"; } - // ----- parser ----- + // ----- exprstatestack ----- exprstate & - parser::top_exprstate() { + exprstatestack::top_exprstate() { std::size_t z = stack_.size(); if (z == 0) { @@ -640,7 +640,7 @@ namespace xo { } void - parser::push_exprstate(const exprstate & exs) { + exprstatestack::push_exprstate(const exprstate & exs) { std::size_t z = stack_.size(); stack_.resize(z+1); @@ -649,16 +649,33 @@ namespace xo { } void - parser::pop_exprstate() { + exprstatestack::pop_exprstate() { std::size_t z = stack_.size(); if (z > 0) stack_.resize(z-1); } + void + exprstatestack::print(std::ostream & os) const { + os << "" << std::endl; + } + + // ----- parser ----- + void parser::begin_translation_unit() { - this->push_exprstate + xs_stack_.push_exprstate (exprstate::expect_toplevel_expression_sequence()); } @@ -668,7 +685,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - if (stack_.empty()) { + if (xs_stack_.empty()) { throw std::runtime_error(tostr("parser::include_token", ": parser not expecting input" "(call parser.begin_translation_unit()..?)", @@ -676,7 +693,7 @@ namespace xo { } /* stack_ is non-empty */ - expraction action = this->top_exprstate().on_input(tk); + expraction action = xs_stack_.top_exprstate().on_input(tk); /* loop until reach parsing state that requires more input */ for (;;) { @@ -690,23 +707,25 @@ namespace xo { return action.expr_ir().expr(); case expractiontype::pop: - this->pop_exprstate(); + xs_stack_.pop_exprstate(); - if (stack_.empty()) { + if (xs_stack_.empty()) { throw std::runtime_error(tostr("parser::include_token", ": pop leaves empty stack")); } - action = this->top_exprstate().on_exprir(action.expr_ir()); + action = (xs_stack_ + .top_exprstate() + .on_exprir(action.expr_ir())); break; case expractiontype::push1: - this->push_exprstate(action.push_exs1()); + xs_stack_.push_exprstate(action.push_exs1()); return nullptr; case expractiontype::push2: - this->push_exprstate(action.push_exs1()); - this->push_exprstate(action.push_exs2()); + xs_stack_.push_exprstate(action.push_exs1()); + xs_stack_.push_exprstate(action.push_exs2()); return nullptr; case expractiontype::invalid: @@ -721,14 +740,9 @@ namespace xo { void parser::print(std::ostream & os) const { os << "" << std::endl; } From 6affaf9dedaec5b550c9e5f7728160fc7872761e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:37:54 +1000 Subject: [PATCH 006/191] xo-parser: refactor: + xs_stack arg to exprstate input methods --- include/xo/parser/parser.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index b81b5ff3..287d8256 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -188,6 +188,8 @@ namespace xo { return os; } + class exprstatestack; + /** state associated with a partially-parsed expression. **/ class exprstate { @@ -228,11 +230,11 @@ namespace xo { /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser **/ - expraction on_input(const token_type & tk); + expraction on_input(const token_type & tk, exprstatestack * p_stack); /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ - expraction on_exprir(const exprir & ir); + expraction on_exprir(const exprir & ir, exprstatestack * p_stack); /** print human-readable representation on @p os **/ void print(std::ostream & os) const; From 847f8744b34c7cd7fcde931512c0d1d1569a1ab0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:41:55 +1000 Subject: [PATCH 007/191] xo-parser: refactor: explicit stack eliminates push2 actiontype --- include/xo/parser/parser.hpp | 5 +++-- src/parser/parser.cpp | 35 ++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 287d8256..43f80d39 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -114,7 +114,6 @@ namespace xo { invalid = -1, push1, - push2, keep, emit, pop, @@ -146,7 +145,9 @@ namespace xo { static expraction keep(); static expraction emit(const exprir & ir); +#ifdef OBSOLETE static expraction push2(exprstatetype s1, exprstatetype s2); +#endif static expraction pop(const exprir & ir); expractiontype action_type() const { return action_type_; } @@ -240,7 +241,7 @@ namespace xo { void print(std::ostream & os) const; private: - expraction on_def(); + expraction on_def(exprstatestack * p_stack); expraction on_symbol(const token_type & tk); expraction on_colon(); expraction on_singleassign(); diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index a4f93b70..56f06f20 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -87,8 +87,6 @@ namespace xo { return "?invalid"; case expractiontype::push1: return "push1"; - case expractiontype::push2: - return "push2"; case expractiontype::keep: return "keep"; case expractiontype::emit: @@ -118,6 +116,7 @@ namespace xo { exprstatetype::invalid /*not used*/); } +#ifdef OBSOLETE expraction expraction::push2(exprstatetype s1, exprstatetype s2) { @@ -126,6 +125,7 @@ namespace xo { s1, s2); } +#endif expraction expraction::pop(const exprir & ir) { @@ -285,7 +285,7 @@ namespace xo { } expraction - exprstate::on_def() { + exprstate::on_def(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -299,15 +299,17 @@ namespace xo { xtag("state", *this))); } + p_stack->push_exprstate(exprstatetype::def_0); + /* todo: replace: + * expect_symbol_or_function_signature() + */ + p_stack->push_exprstate(exprstatetype::expect_symbol); + /* keyword 'def' introduces a definition: * def pi : f64 = 3.14159265 * def sq(x : f64) -> f64 { (x * x) } */ - return expraction::push2(exprstatetype::def_0, - /* todo: replace: - * expect_symbol_or_function_signature() - */ - exprstatetype::expect_symbol); + return expraction::keep(); } expraction @@ -461,7 +463,9 @@ namespace xo { } expraction - exprstate::on_input(const token_type & tk) { + exprstate::on_input(const token_type & tk, + exprstatestack * p_stack) + { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); log && log(xtag("tk", tk)); @@ -470,7 +474,7 @@ namespace xo { switch(tk.tk_type()) { case tokentype::tk_def: - return this->on_def(); + return this->on_def(p_stack); case tokentype::tk_i64: assert(false); @@ -536,7 +540,9 @@ namespace xo { } expraction - exprstate::on_exprir(const exprir & ir) { + exprstate::on_exprir(const exprir & ir, + exprstatestack * /*p_stack*/) + { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); log && log(xtag("ir", ir)); @@ -693,7 +699,7 @@ namespace xo { } /* stack_ is non-empty */ - expraction action = xs_stack_.top_exprstate().on_input(tk); + expraction action = xs_stack_.top_exprstate().on_input(tk, &xs_stack_); /* loop until reach parsing state that requires more input */ for (;;) { @@ -716,17 +722,20 @@ namespace xo { action = (xs_stack_ .top_exprstate() - .on_exprir(action.expr_ir())); + .on_exprir(action.expr_ir(), + &xs_stack_)); break; case expractiontype::push1: xs_stack_.push_exprstate(action.push_exs1()); return nullptr; +#ifdef OBSOLETE case expractiontype::push2: xs_stack_.push_exprstate(action.push_exs1()); xs_stack_.push_exprstate(action.push_exs2()); return nullptr; +#endif case expractiontype::invalid: case expractiontype::n_expractiontype: From 00eaa55cc9bf2b46757a1d9d4aae671aeafdcb45 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:43:33 +1000 Subject: [PATCH 008/191] xo-parser: pref: + exprstatestack arg to exprstate::on_symbol() --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 43f80d39..ba903311 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -242,7 +242,7 @@ namespace xo { private: expraction on_def(exprstatestack * p_stack); - expraction on_symbol(const token_type & tk); + expraction on_symbol(const token_type & tk, exprstatestack * p_stack); expraction on_colon(); expraction on_singleassign(); expraction on_f64(const token_type & tk); diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 56f06f20..0bf2c8a6 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -313,7 +313,9 @@ namespace xo { } expraction - exprstate::on_symbol(const token_type & tk) { + exprstate::on_symbol(const token_type & tk, + exprstatestack * /*p_stack*/) + { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -488,7 +490,7 @@ namespace xo { return expraction(); case tokentype::tk_symbol: - return this->on_symbol(tk); + return this->on_symbol(tk, p_stack); case tokentype::tk_leftparen: From cdd40a20c78872f966650c191e5c2e6445db3e8f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:44:59 +1000 Subject: [PATCH 009/191] xo-parser: prep: + exprstatestack arg to exprstate::on_colon() --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index ba903311..6b474ff5 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -243,7 +243,7 @@ namespace xo { private: expraction on_def(exprstatestack * p_stack); expraction on_symbol(const token_type & tk, exprstatestack * p_stack); - expraction on_colon(); + expraction on_colon(exprstatestack * p_stack); expraction on_singleassign(); expraction on_f64(const token_type & tk); diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 0bf2c8a6..0b1436cd 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -387,7 +387,7 @@ namespace xo { } expraction - exprstate::on_colon() { + exprstate::on_colon(exprstatestack * /*p_stack*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -508,7 +508,7 @@ namespace xo { return expraction(); case tokentype::tk_colon: - return this->on_colon(); + return this->on_colon(p_stack); case tokentype::tk_doublecolon: case tokentype::tk_semicolon: From 59837c47f0f355f18c54c10aaec5a61557161779 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:45:52 +1000 Subject: [PATCH 010/191] xo-parser: prep: + exprstatestack arg to exprstate::on_singleassign() --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 6b474ff5..39d768d8 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -244,7 +244,7 @@ namespace xo { expraction on_def(exprstatestack * p_stack); expraction on_symbol(const token_type & tk, exprstatestack * p_stack); expraction on_colon(exprstatestack * p_stack); - expraction on_singleassign(); + expraction on_singleassign(exprstatestack * p_stack); expraction on_f64(const token_type & tk); private: diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 0b1436cd..7302bd3b 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -415,7 +415,7 @@ namespace xo { } expraction - exprstate::on_singleassign() { + exprstate::on_singleassign(exprstatestack * /*p_stack*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -516,7 +516,7 @@ namespace xo { return expraction(); case tokentype::tk_singleassign: - return this->on_singleassign(); + return this->on_singleassign(p_stack); case tokentype::tk_assign: case tokentype::tk_yields: From 6b53afe6e66bb9f98b6276b31fce80167d07140e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:47:07 +1000 Subject: [PATCH 011/191] xo-parser: prep: + exprstatestack arg to exprstate::on_f64() --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 39d768d8..a85f3a16 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -245,7 +245,7 @@ namespace xo { expraction on_symbol(const token_type & tk, exprstatestack * p_stack); expraction on_colon(exprstatestack * p_stack); expraction on_singleassign(exprstatestack * p_stack); - expraction on_f64(const token_type & tk); + expraction on_f64(const token_type & tk, exprstatestack * p_stack); private: /** diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 7302bd3b..0bbe0167 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -442,7 +442,9 @@ namespace xo { } expraction - exprstate::on_f64(const token_type & tk) { + exprstate::on_f64(const token_type & tk, + exprstatestack * /*p_stack*/) + { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -483,7 +485,7 @@ namespace xo { return expraction(); case tokentype::tk_f64: - return this->on_f64(tk); + return this->on_f64(tk, p_stack); case tokentype::tk_string: assert(false); From 8bc91d3b830a4f2d35d6781459e6c4464bd2cd38 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:50:14 +1000 Subject: [PATCH 012/191] xo-parser: refactor: explicit stack eliminates expractiontype::push1 --- include/xo/parser/parser.hpp | 1 - src/parser/parser.cpp | 22 +++++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index a85f3a16..8e878099 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -113,7 +113,6 @@ namespace xo { enum class expractiontype { invalid = -1, - push1, keep, emit, pop, diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 0bbe0167..c01cda37 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -85,8 +85,6 @@ namespace xo { switch(x) { case expractiontype::invalid: return "?invalid"; - case expractiontype::push1: - return "push1"; case expractiontype::keep: return "keep"; case expractiontype::emit: @@ -387,7 +385,7 @@ namespace xo { } expraction - exprstate::on_colon(exprstatestack * /*p_stack*/) { + exprstate::on_colon(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -404,10 +402,9 @@ namespace xo { if (this->exs_type_ == exprstatetype::def_1) { this->exs_type_ = exprstatetype::def_2; - return expraction(expractiontype::push1, - exprir(), - exprstatetype::expect_type, - exprstatetype::invalid /*not used*/); + p_stack->push_exprstate(exprstatetype::expect_type); + + return expraction::keep(); } else { assert(false); return expraction(); @@ -415,7 +412,7 @@ namespace xo { } expraction - exprstate::on_singleassign(exprstatestack * /*p_stack*/) { + exprstate::on_singleassign(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -431,10 +428,9 @@ namespace xo { if (this->exs_type_ == exprstatetype::def_3) { this->exs_type_ = exprstatetype::def_4; - return expraction(expractiontype::push1, - exprir(), - exprstatetype::expect_rhs_expression, - exprstatetype::invalid /*not used*/); + p_stack->push_exprstate(exprstatetype::expect_rhs_expression); + + return expraction::keep(); } else { assert(false); return expraction(); @@ -730,11 +726,11 @@ namespace xo { &xs_stack_)); break; +#ifdef OBSOLETE case expractiontype::push1: xs_stack_.push_exprstate(action.push_exs1()); return nullptr; -#ifdef OBSOLETE case expractiontype::push2: xs_stack_.push_exprstate(action.push_exs1()); xs_stack_.push_exprstate(action.push_exs2()); From c7c6bc888af142012a99e572ac6f6af5f3a9409c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 10:52:41 +1000 Subject: [PATCH 013/191] xo-parser: simplify: drop expraction:: push_exs1, push_exs2 --- include/xo/parser/parser.hpp | 21 ++------------------- src/parser/parser.cpp | 25 +++---------------------- 2 files changed, 5 insertions(+), 41 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 8e878099..838b4cec 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -135,24 +135,16 @@ namespace xo { public: expraction() = default; expraction(expractiontype action_type, - const exprir & expr_ir, - exprstatetype push_exs1, - exprstatetype push_exs2) - : action_type_{action_type}, expr_ir_{expr_ir}, - push_exs1_{push_exs1}, push_exs2_{push_exs2} + const exprir & expr_ir) + : action_type_{action_type}, expr_ir_{expr_ir} {} static expraction keep(); static expraction emit(const exprir & ir); -#ifdef OBSOLETE - static expraction push2(exprstatetype s1, exprstatetype s2); -#endif static expraction pop(const exprir & ir); expractiontype action_type() const { return action_type_; } const exprir & expr_ir() const { return expr_ir_; } - exprstatetype push_exs1() const { return push_exs1_; } - exprstatetype push_exs2() const { return push_exs2_; } void print(std::ostream & os) const; @@ -169,15 +161,6 @@ namespace xo { * intermediate representation (pass to enclosing stack state) **/ exprir expr_ir_; - /** with action_type push1 or push2, - * parser will push exprstate with this type - **/ - exprstatetype push_exs1_ = exprstatetype::invalid; - /** with action_type push2, - * parser will push exprstate with this type - * (after pushing exprstate built from push_exs1_) - **/ - exprstatetype push_exs2_ = exprstatetype::invalid; }; inline std::ostream & diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index c01cda37..ea5c372a 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -101,36 +101,19 @@ namespace xo { expraction expraction::keep() { return expraction(expractiontype::keep, - exprir(), - exprstatetype::invalid /*not used*/, - exprstatetype::invalid /*not used*/); + exprir()); } expraction expraction::emit(const exprir & ir) { return expraction(expractiontype::emit, - ir, - exprstatetype::invalid /*not used*/, - exprstatetype::invalid /*not used*/); + ir); } -#ifdef OBSOLETE - expraction - expraction::push2(exprstatetype s1, - exprstatetype s2) { - return expraction(expractiontype::push2, - exprir(), - s1, - s2); - } -#endif - expraction expraction::pop(const exprir & ir) { return expraction(expractiontype::pop, - ir, - exprstatetype::invalid /*not used*/, - exprstatetype::invalid /*not used*/); + ir); } void @@ -138,8 +121,6 @@ namespace xo { os << ""; } From 010f15641e1507d797391d80a5c719db4ab7b488 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 12:45:20 +1000 Subject: [PATCH 014/191] xo-parser: refactor: bypass exprir arg to pop exprstateaction --- include/xo/parser/parser.hpp | 7 ++--- src/parser/parser.cpp | 50 ++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 838b4cec..fc735bcd 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -134,14 +134,15 @@ namespace xo { class expraction { public: expraction() = default; - expraction(expractiontype action_type, - const exprir & expr_ir) + explicit expraction(expractiontype action_type, + const exprir & expr_ir) : action_type_{action_type}, expr_ir_{expr_ir} {} static expraction keep(); static expraction emit(const exprir & ir); - static expraction pop(const exprir & ir); + //static expraction pop(const exprir & ir); + static expraction pop(); expractiontype action_type() const { return action_type_; } const exprir & expr_ir() const { return expr_ir_; } diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index ea5c372a..b4d6ae45 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -110,11 +110,19 @@ namespace xo { ir); } +#ifdef OBSOLETE expraction expraction::pop(const exprir & ir) { return expraction(expractiontype::pop, ir); } +#endif + + expraction + expraction::pop() { + return expraction(expractiontype::pop, + exprir()); + } void expraction::print(std::ostream & os) const { @@ -293,7 +301,7 @@ namespace xo { expraction exprstate::on_symbol(const token_type & tk, - exprstatestack * /*p_stack*/) + exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -328,7 +336,12 @@ namespace xo { case exprstatetype::expect_rhs_expression: case exprstatetype::expect_symbol: - return expraction::pop(exprir(exprirtype::symbol, tk.text())); + /* have to do pop first */ + + p_stack->pop_exprstate(); + return p_stack->top_exprstate().on_exprir + (exprir(exprirtype::symbol, tk.text()), p_stack); + //return expraction::pop(exprir(exprirtype::symbol, tk.text())); case exprstatetype::expect_type: { TypeDescr td = nullptr; @@ -354,7 +367,10 @@ namespace xo { xtag("typename", tk.text()))); } - return expraction::pop(exprir(exprirtype::typedescr, td)); + p_stack->pop_exprstate(); + return p_stack->top_exprstate().on_exprir + (exprir(exprirtype::typedescr, td), p_stack); + //return expraction::pop(exprir(exprirtype::typedescr, td)); } case exprstatetype::invalid: @@ -420,7 +436,7 @@ namespace xo { expraction exprstate::on_f64(const token_type & tk, - exprstatestack * /*p_stack*/) + exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -435,8 +451,12 @@ namespace xo { } if (this->exs_type_ == exprstatetype::expect_rhs_expression) { - return expraction::pop(exprir(exprirtype::expression, - Constant::make(tk.f64_value()))); + p_stack->pop_exprstate(); + + return p_stack->top_exprstate() + .on_exprir(exprir(exprirtype::expression, + Constant::make(tk.f64_value())), + p_stack); } else { assert(false); return expraction(); @@ -522,7 +542,7 @@ namespace xo { expraction exprstate::on_exprir(const exprir & ir, - exprstatestack * /*p_stack*/) + exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -580,7 +600,10 @@ namespace xo { rp def = DefineExpr::make(this->def_lhs_symbol_, rhs_value); - return expraction::pop(exprir(exprirtype::expression, def)); + p_stack->pop_exprstate(); + return p_stack->top_exprstate() + .on_exprir(exprir(exprirtype::expression, def), + p_stack); } else { assert(false); return expraction(); @@ -707,17 +730,6 @@ namespace xo { &xs_stack_)); break; -#ifdef OBSOLETE - case expractiontype::push1: - xs_stack_.push_exprstate(action.push_exs1()); - return nullptr; - - case expractiontype::push2: - xs_stack_.push_exprstate(action.push_exs1()); - xs_stack_.push_exprstate(action.push_exs2()); - return nullptr; -#endif - case expractiontype::invalid: case expractiontype::n_expractiontype: /* unreachable */ From 942de7335c0f6dc0fd3249c2aa7df06d101d4588 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 12:48:01 +1000 Subject: [PATCH 015/191] xo-parser: refactor: drop unused expractiontype::pop --- include/xo/parser/parser.hpp | 5 +++-- src/parser/parser.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index fc735bcd..ce328bbd 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -115,7 +115,7 @@ namespace xo { keep, emit, - pop, + //pop, n_expractiontype }; @@ -141,8 +141,9 @@ namespace xo { static expraction keep(); static expraction emit(const exprir & ir); - //static expraction pop(const exprir & ir); +#ifdef OBSOLETE static expraction pop(); +#endif expractiontype action_type() const { return action_type_; } const exprir & expr_ir() const { return expr_ir_; } diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index b4d6ae45..b770218b 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -89,8 +89,8 @@ namespace xo { return "keep"; case expractiontype::emit: return "emit"; - case expractiontype::pop: - return "pop"; + //case expractiontype::pop: + //return "pop"; case expractiontype::n_expractiontype: break; } @@ -118,11 +118,13 @@ namespace xo { } #endif +#ifdef OBSOLETE expraction expraction::pop() { return expraction(expractiontype::pop, exprir()); } +#endif void expraction::print(std::ostream & os) const { @@ -716,6 +718,7 @@ namespace xo { case expractiontype::emit: return action.expr_ir().expr(); +#ifdef OBSOLETE case expractiontype::pop: xs_stack_.pop_exprstate(); @@ -729,6 +732,7 @@ namespace xo { .on_exprir(action.expr_ir(), &xs_stack_)); break; +#endif case expractiontype::invalid: case expractiontype::n_expractiontype: From 03f11ab70a59e57d10853c771daa22c3d910a32b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 12:55:43 +1000 Subject: [PATCH 016/191] xo-parser: progress: + arg to rcv parsed expr -> simplify exprir --- include/xo/parser/parser.hpp | 13 ++++-- src/parser/parser.cpp | 77 +++++++++++++++++------------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index ce328bbd..193d1cc5 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -179,6 +179,7 @@ namespace xo { **/ class exprstate { public: + using Expression = xo::ast::Expression; using exprtype = xo::ast::exprtype; using token_type = token; using TypeDescr = xo::reflect::TypeDescr; @@ -215,21 +216,25 @@ namespace xo { /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser **/ - expraction on_input(const token_type & tk, exprstatestack * p_stack); + expraction on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ - expraction on_exprir(const exprir & ir, exprstatestack * p_stack); + expraction on_exprir(const exprir & ir, exprstatestack * p_stack, rp * p_emit_expr); /** print human-readable representation on @p os **/ void print(std::ostream & os) const; private: expraction on_def(exprstatestack * p_stack); - expraction on_symbol(const token_type & tk, exprstatestack * p_stack); + expraction on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); expraction on_colon(exprstatestack * p_stack); expraction on_singleassign(exprstatestack * p_stack); - expraction on_f64(const token_type & tk, exprstatestack * p_stack); + expraction on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); private: /** diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index b770218b..4a0f37f5 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -303,7 +303,8 @@ namespace xo { expraction exprstate::on_symbol(const token_type & tk, - exprstatestack * p_stack) + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -342,7 +343,7 @@ namespace xo { p_stack->pop_exprstate(); return p_stack->top_exprstate().on_exprir - (exprir(exprirtype::symbol, tk.text()), p_stack); + (exprir(exprirtype::symbol, tk.text()), p_stack, p_emit_expr); //return expraction::pop(exprir(exprirtype::symbol, tk.text())); case exprstatetype::expect_type: { @@ -371,7 +372,7 @@ namespace xo { p_stack->pop_exprstate(); return p_stack->top_exprstate().on_exprir - (exprir(exprirtype::typedescr, td), p_stack); + (exprir(exprirtype::typedescr, td), p_stack, p_emit_expr); //return expraction::pop(exprir(exprirtype::typedescr, td)); } @@ -438,7 +439,8 @@ namespace xo { expraction exprstate::on_f64(const token_type & tk, - exprstatestack * p_stack) + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -458,7 +460,8 @@ namespace xo { return p_stack->top_exprstate() .on_exprir(exprir(exprirtype::expression, Constant::make(tk.f64_value())), - p_stack); + p_stack, + p_emit_expr); } else { assert(false); return expraction(); @@ -467,7 +470,8 @@ namespace xo { expraction exprstate::on_input(const token_type & tk, - exprstatestack * p_stack) + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -484,14 +488,14 @@ namespace xo { return expraction(); case tokentype::tk_f64: - return this->on_f64(tk, p_stack); + return this->on_f64(tk, p_stack, p_emit_expr); case tokentype::tk_string: assert(false); return expraction(); case tokentype::tk_symbol: - return this->on_symbol(tk, p_stack); + return this->on_symbol(tk, p_stack, p_emit_expr); case tokentype::tk_leftparen: @@ -544,7 +548,8 @@ namespace xo { expraction exprstate::on_exprir(const exprir & ir, - exprstatestack * p_stack) + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -559,8 +564,10 @@ namespace xo { * parser::include_token() returns */ - if (ir.xir_type() == exprirtype::expression) - return expraction::emit(ir); + if (ir.xir_type() == exprirtype::expression) { + *p_emit_expr = ir.expr(); + return expraction::keep(); + } /* NOT IMPLEMENTED */ assert(false); @@ -605,7 +612,7 @@ namespace xo { p_stack->pop_exprstate(); return p_stack->top_exprstate() .on_exprir(exprir(exprirtype::expression, def), - p_stack); + p_stack, p_emit_expr); } else { assert(false); return expraction(); @@ -691,7 +698,7 @@ namespace xo { (exprstate::expect_toplevel_expression_sequence()); } - rp + rp parser::include_token(const token_type & tk) { constexpr bool c_debug_flag = true; @@ -705,42 +712,30 @@ namespace xo { } /* stack_ is non-empty */ - expraction action = xs_stack_.top_exprstate().on_input(tk, &xs_stack_); - /* loop until reach parsing state that requires more input */ - for (;;) { - log && log(xtag("action", action)); + rp retval; - switch(action.action_type()) { - case expractiontype::keep: - return nullptr; + expraction action = xs_stack_.top_exprstate().on_input(tk, &xs_stack_, &retval); - case expractiontype::emit: - return action.expr_ir().expr(); + log && log(xtag("action", action)); + + return retval; #ifdef OBSOLETE - case expractiontype::pop: - xs_stack_.pop_exprstate(); + switch(action.action_type()) { + case expractiontype::keep: + return nullptr; - if (xs_stack_.empty()) { - throw std::runtime_error(tostr("parser::include_token", - ": pop leaves empty stack")); - } + case expractiontype::emit: + //return action.expr_ir().expr(); - action = (xs_stack_ - .top_exprstate() - .on_exprir(action.expr_ir(), - &xs_stack_)); - break; -#endif - - case expractiontype::invalid: - case expractiontype::n_expractiontype: - /* unreachable */ - assert(false); - return nullptr; - } + case expractiontype::invalid: + case expractiontype::n_expractiontype: + /* unreachable */ + assert(false); + return nullptr; } +#endif } /*include_token*/ void From e013082442505f9a1631dd7827264ad417a0b66a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 12:57:42 +1000 Subject: [PATCH 017/191] xo-parser: drop expractiontype::emit --- include/xo/parser/parser.hpp | 5 ++--- src/parser/parser.cpp | 20 +------------------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 193d1cc5..bbb0a584 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -114,7 +114,7 @@ namespace xo { invalid = -1, keep, - emit, + //emit, //pop, n_expractiontype @@ -140,9 +140,8 @@ namespace xo { {} static expraction keep(); - static expraction emit(const exprir & ir); #ifdef OBSOLETE - static expraction pop(); + static expraction emit(const exprir & ir); #endif expractiontype action_type() const { return action_type_; } diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 4a0f37f5..3a0eaaf9 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -87,10 +87,6 @@ namespace xo { return "?invalid"; case expractiontype::keep: return "keep"; - case expractiontype::emit: - return "emit"; - //case expractiontype::pop: - //return "pop"; case expractiontype::n_expractiontype: break; } @@ -104,26 +100,12 @@ namespace xo { exprir()); } +#ifdef OBSOLETE expraction expraction::emit(const exprir & ir) { return expraction(expractiontype::emit, ir); } - -#ifdef OBSOLETE - expraction - expraction::pop(const exprir & ir) { - return expraction(expractiontype::pop, - ir); - } -#endif - -#ifdef OBSOLETE - expraction - expraction::pop() { - return expraction(expractiontype::pop, - exprir()); - } #endif void From 04d3961d24ae6bc733f82f5634f39c812ecedaa1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 12:59:52 +1000 Subject: [PATCH 018/191] xo-parser: simplify: drop expraction.expr_ir_ --- include/xo/parser/parser.hpp | 19 +++++++++++++------ src/parser/parser.cpp | 12 +----------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index bbb0a584..4fd65ec5 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -134,18 +134,23 @@ namespace xo { class expraction { public: expraction() = default; - explicit expraction(expractiontype action_type, - const exprir & expr_ir) - : action_type_{action_type}, expr_ir_{expr_ir} + explicit expraction(expractiontype action_type +#ifdef OBSOLETE + const exprir & expr_ir +#endif + ) + : action_type_{action_type} +#ifdef OBSOLETE + , expr_ir_{expr_ir} +#endif {} static expraction keep(); -#ifdef OBSOLETE - static expraction emit(const exprir & ir); -#endif expractiontype action_type() const { return action_type_; } +#ifdef OBSOLETE const exprir & expr_ir() const { return expr_ir_; } +#endif void print(std::ostream & os) const; @@ -158,10 +163,12 @@ namespace xo { * pop: drop exprstate, report exprir to parent **/ expractiontype action_type_ = expractiontype::invalid; +#ifdef OBSOLETE /** * intermediate representation (pass to enclosing stack state) **/ exprir expr_ir_; +#endif }; inline std::ostream & diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 3a0eaaf9..ad87f680 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -96,23 +96,13 @@ namespace xo { expraction expraction::keep() { - return expraction(expractiontype::keep, - exprir()); + return expraction(expractiontype::keep); } -#ifdef OBSOLETE - expraction - expraction::emit(const exprir & ir) { - return expraction(expractiontype::emit, - ir); - } -#endif - void expraction::print(std::ostream & os) const { os << ""; } From f1b83ec8053b02e8516c0c89a7761865b5d5ba9b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:01:48 +1000 Subject: [PATCH 019/191] xo-parser: progress: exprstate::on_input() drop expraction retval --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 49 +++++++++++++----------------------- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 4fd65ec5..e087424f 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -222,7 +222,7 @@ namespace xo { /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser **/ - expraction on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); + void on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index ad87f680..aac8aa50 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -440,7 +440,7 @@ namespace xo { } } - expraction + void exprstate::on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) @@ -453,21 +453,24 @@ namespace xo { switch(tk.tk_type()) { case tokentype::tk_def: - return this->on_def(p_stack); + this->on_def(p_stack); + return; case tokentype::tk_i64: assert(false); - return expraction(); + return; case tokentype::tk_f64: - return this->on_f64(tk, p_stack, p_emit_expr); + this->on_f64(tk, p_stack, p_emit_expr); + return; case tokentype::tk_string: assert(false); - return expraction(); + return; case tokentype::tk_symbol: - return this->on_symbol(tk, p_stack, p_emit_expr); + this->on_symbol(tk, p_stack, p_emit_expr); + return; case tokentype::tk_leftparen: @@ -482,18 +485,20 @@ namespace xo { case tokentype::tk_dot: case tokentype::tk_comma: assert(false); - return expraction(); + return; case tokentype::tk_colon: - return this->on_colon(p_stack); + this->on_colon(p_stack); + return; case tokentype::tk_doublecolon: case tokentype::tk_semicolon: assert(false); - return expraction(); + return; case tokentype::tk_singleassign: - return this->on_singleassign(p_stack); + this->on_singleassign(p_stack); + return; case tokentype::tk_assign: case tokentype::tk_yields: @@ -506,16 +511,15 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: assert(false); - return expraction(); + return; case tokentype::tk_invalid: case tokentype::n_tokentype: assert(false); - return expraction(); + return; } assert(false); - return expraction(); } expraction @@ -687,27 +691,10 @@ namespace xo { rp retval; - expraction action = xs_stack_.top_exprstate().on_input(tk, &xs_stack_, &retval); + xs_stack_.top_exprstate().on_input(tk, &xs_stack_, &retval); - log && log(xtag("action", action)); return retval; - -#ifdef OBSOLETE - switch(action.action_type()) { - case expractiontype::keep: - return nullptr; - - case expractiontype::emit: - //return action.expr_ir().expr(); - - case expractiontype::invalid: - case expractiontype::n_expractiontype: - /* unreachable */ - assert(false); - return nullptr; - } -#endif } /*include_token*/ void From 5281ccb3f50ed4dd74192aab612570abb279964c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:04:58 +1000 Subject: [PATCH 020/191] xo-parser: simplify: exprstate::on_f64() drop retval --- include/xo/parser/parser.hpp | 6 +++--- src/parser/parser.cpp | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index e087424f..1b349b88 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -238,9 +238,9 @@ namespace xo { rp * p_emit_expr); expraction on_colon(exprstatestack * p_stack); expraction on_singleassign(exprstatestack * p_stack); - expraction on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + void on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); private: /** diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index aac8aa50..e49645f4 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -409,7 +409,7 @@ namespace xo { } } - expraction + void exprstate::on_f64(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) @@ -429,14 +429,13 @@ namespace xo { if (this->exs_type_ == exprstatetype::expect_rhs_expression) { p_stack->pop_exprstate(); - return p_stack->top_exprstate() + p_stack->top_exprstate() .on_exprir(exprir(exprirtype::expression, Constant::make(tk.f64_value())), p_stack, p_emit_expr); } else { assert(false); - return expraction(); } } From 880606908b205585ac2727c171c8ddc53b71effb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:05:58 +1000 Subject: [PATCH 021/191] xo-parser: simplify: exprstate::on_colon drop retval --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 1b349b88..99117193 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -236,7 +236,7 @@ namespace xo { expraction on_symbol(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); - expraction on_colon(exprstatestack * p_stack); + void on_colon(exprstatestack * p_stack); expraction on_singleassign(exprstatestack * p_stack); void on_f64(const token_type & tk, exprstatestack * p_stack, diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index e49645f4..98baccfc 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -356,7 +356,7 @@ namespace xo { } } - expraction + void exprstate::on_colon(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -375,11 +375,8 @@ namespace xo { this->exs_type_ = exprstatetype::def_2; p_stack->push_exprstate(exprstatetype::expect_type); - - return expraction::keep(); } else { assert(false); - return expraction(); } } From 909101cd8de8b1879e1852c9c24511fae7a68202 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:07:33 +1000 Subject: [PATCH 022/191] xo-parser: simplify: exprstate::on_singleassign drop retval --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 99117193..4d45f6e7 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -237,7 +237,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr); void on_colon(exprstatestack * p_stack); - expraction on_singleassign(exprstatestack * p_stack); + void on_singleassign(exprstatestack * p_stack); void on_f64(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 98baccfc..a1ee3ae2 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -380,7 +380,7 @@ namespace xo { } } - expraction + void exprstate::on_singleassign(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -398,11 +398,8 @@ namespace xo { this->exs_type_ = exprstatetype::def_4; p_stack->push_exprstate(exprstatetype::expect_rhs_expression); - - return expraction::keep(); } else { assert(false); - return expraction(); } } From 129b5d9258aeb12c8d80a4df7d0ee60c47f40e58 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:08:54 +1000 Subject: [PATCH 023/191] xo-parser: simplify: exprstate::on_def drop retval --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 4d45f6e7..a01b1da2 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -232,7 +232,7 @@ namespace xo { void print(std::ostream & os) const; private: - expraction on_def(exprstatestack * p_stack); + void on_def(exprstatestack * p_stack); expraction on_symbol(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index a1ee3ae2..905abfea 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -245,7 +245,7 @@ namespace xo { } } - expraction + void exprstate::on_def(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -270,7 +270,6 @@ namespace xo { * def pi : f64 = 3.14159265 * def sq(x : f64) -> f64 { (x * x) } */ - return expraction::keep(); } expraction From 77ec1c7ead6e58ddd82c97dbc600dd86a7cf4696 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:11:27 +1000 Subject: [PATCH 024/191] xo-parser: simplify: exprstate::on_symbol drop retval --- include/xo/parser/parser.hpp | 6 +++--- src/parser/parser.cpp | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index a01b1da2..b26ad942 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -233,9 +233,9 @@ namespace xo { private: void on_def(exprstatestack * p_stack); - expraction on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + void on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); void on_colon(exprstatestack * p_stack); void on_singleassign(exprstatestack * p_stack); void on_f64(const token_type & tk, diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 905abfea..7db6e821 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -272,7 +272,7 @@ namespace xo { */ } - expraction + void exprstate::on_symbol(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) @@ -306,16 +306,17 @@ namespace xo { case exprstatetype::def_4: /* unreachable */ assert(false); - return expraction(); + return; case exprstatetype::expect_rhs_expression: case exprstatetype::expect_symbol: /* have to do pop first */ p_stack->pop_exprstate(); - return p_stack->top_exprstate().on_exprir + p_stack->top_exprstate().on_exprir (exprir(exprirtype::symbol, tk.text()), p_stack, p_emit_expr); //return expraction::pop(exprir(exprirtype::symbol, tk.text())); + return; case exprstatetype::expect_type: { TypeDescr td = nullptr; @@ -342,16 +343,17 @@ namespace xo { } p_stack->pop_exprstate(); - return p_stack->top_exprstate().on_exprir + p_stack->top_exprstate().on_exprir (exprir(exprirtype::typedescr, td), p_stack, p_emit_expr); //return expraction::pop(exprir(exprirtype::typedescr, td)); + return; } case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ assert(false); - return expraction(); + return; } } From cd83b6bed9be01aa48c7cc5e5b6b30ca04b1cf7b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:13:12 +1000 Subject: [PATCH 025/191] xo-parser: simplify: exprstate::on_exprir drop retval --- include/xo/parser/parser.hpp | 2 +- src/parser/parser.cpp | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index b26ad942..7056e1ee 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -226,7 +226,7 @@ namespace xo { /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ - expraction on_exprir(const exprir & ir, exprstatestack * p_stack, rp * p_emit_expr); + void on_exprir(const exprir & ir, exprstatestack * p_stack, rp * p_emit_expr); /** print human-readable representation on @p os **/ void print(std::ostream & os) const; diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 7db6e821..7eb20b29 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -516,7 +516,7 @@ namespace xo { assert(false); } - expraction + void exprstate::on_exprir(const exprir & ir, exprstatestack * p_stack, rp * p_emit_expr) @@ -536,30 +536,30 @@ namespace xo { if (ir.xir_type() == exprirtype::expression) { *p_emit_expr = ir.expr(); - return expraction::keep(); + return; } /* NOT IMPLEMENTED */ assert(false); - return expraction(); + return; case exprstatetype::def_0: this->exs_type_ = exprstatetype::def_1; this->def_lhs_symbol_ = ir.symbol_name(); - return expraction::keep(); + return; case exprstatetype::def_1: /* NOT IMPLEMENTED */ assert(false); - return expraction(); + return; case exprstatetype::def_2: this->exs_type_ = exprstatetype::def_3; this->def_lhs_td_ = ir.td(); - return expraction::keep(); + return; case exprstatetype::def_3: /* NOT IMPLEMENTED */ assert(false); - return expraction(); + return; case exprstatetype::def_4: /* have all the ingredients to create an expression * representing a definition @@ -585,7 +585,7 @@ namespace xo { p_stack, p_emit_expr); } else { assert(false); - return expraction(); + return; } case exprstatetype::expect_rhs_expression: @@ -595,12 +595,12 @@ namespace xo { * (this exprstate issues pop instruction from exprstate::on_input() */ assert(false); - return expraction(); + return; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ assert(false); - return expraction(); + return; } } From 514a2cb687b66c9df369c8fde18d328780035b8b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:23:16 +1000 Subject: [PATCH 026/191] xo-parser: simplify: + exprstate::on_expr split from on_exprir() --- include/xo/parser/parser.hpp | 4 ++ src/parser/parser.cpp | 77 +++++++++++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 7056e1ee..6e703376 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -223,6 +223,10 @@ namespace xo { * forward instructions to parent parser **/ void on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate in response to a successfully-parsed subexpression **/ + void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr); /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 7eb20b29..b3e27701 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -313,8 +313,7 @@ namespace xo { /* have to do pop first */ p_stack->pop_exprstate(); - p_stack->top_exprstate().on_exprir - (exprir(exprirtype::symbol, tk.text()), p_stack, p_emit_expr); + p_stack->top_exprstate().on_exprir(exprir(exprirtype::symbol, tk.text()), p_stack, p_emit_expr); //return expraction::pop(exprir(exprirtype::symbol, tk.text())); return; @@ -424,11 +423,9 @@ namespace xo { if (this->exs_type_ == exprstatetype::expect_rhs_expression) { p_stack->pop_exprstate(); - p_stack->top_exprstate() - .on_exprir(exprir(exprirtype::expression, - Constant::make(tk.f64_value())), - p_stack, - p_emit_expr); + p_stack->top_exprstate().on_expr(Constant::make(tk.f64_value()), + p_stack, + p_emit_expr); } else { assert(false); } @@ -516,6 +513,67 @@ namespace xo { assert(false); } + void + exprstate::on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) + { + switch(this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* toplevel expression sequence accepts an + * arbitrary number of expressions. + * + * parser::include_token() returns + */ + + *p_emit_expr = expr.get(); + return; + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + /* NOT IMPLEMENTED */ + assert(false); + return; + case exprstatetype::def_4: { + /* have all the ingredients to create an expression + * representing a definition + * + * 1. if ir_type is a symbol, interpret as variable name. + * Need to be able to locate variable by type + * 2. if ir_type is an expression, adopt as rhs + */ + rp rhs_value = expr.get(); + + if (def_lhs_td_) + rhs_value = ConvertExpr::make(def_lhs_td_, rhs_value); + + rp def = DefineExpr::make(this->def_lhs_symbol_, + rhs_value); + + p_stack->pop_exprstate(); + p_stack->top_exprstate().on_expr(def, + p_stack, + p_emit_expr); + return; + } + + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + /* unreachable + * (this exprstate issues pop instruction from exprstate::on_input() + */ + assert(false); + return; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } + void exprstate::on_exprir(const exprir & ir, exprstatestack * p_stack, @@ -580,9 +638,8 @@ namespace xo { rhs_value); p_stack->pop_exprstate(); - return p_stack->top_exprstate() - .on_exprir(exprir(exprirtype::expression, def), - p_stack, p_emit_expr); + return p_stack->top_exprstate().on_expr(def, + p_stack, p_emit_expr); } else { assert(false); return; From 216eea9d2c59338aff782a3a07d068d2e179c94d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:26:18 +1000 Subject: [PATCH 027/191] xo-parser: simplify: drop exprir.expr --- include/xo/parser/parser.hpp | 7 ------ src/parser/parser.cpp | 41 +++++------------------------------- 2 files changed, 5 insertions(+), 43 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 6e703376..db6ea524 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -19,7 +19,6 @@ namespace xo { empty, symbol, - expression, typedescr, n_exprirtype @@ -51,16 +50,12 @@ namespace xo { exprir(exprirtype xir_type, const std::string & x) : xir_type_{xir_type}, symbol_name_{x} {} - exprir(exprirtype xir_type, - rp expr) - : xir_type_{xir_type}, expr_{std::move(expr)} {} exprir(exprirtype xir_type, TypeDescr td) : xir_type_{xir_type}, td_{td} {} exprirtype xir_type() const { return xir_type_; } const std::string & symbol_name() const { return symbol_name_; } - const rp & expr() const { return expr_; } TypeDescr td() const { return td_; } void print(std::ostream & os) const; @@ -70,8 +65,6 @@ namespace xo { exprirtype xir_type_ = exprirtype::invalid; /** xir_type=symbol: a symbol (type or variable) name **/ std::string symbol_name_; - /** xir_type=expression: a completed expression **/ - rp expr_; /** xir_type=typedescr: object identifying/describing a datatype **/ TypeDescr td_ = nullptr; }; diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index b3e27701..8772e7fd 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -28,8 +28,6 @@ namespace xo { return "empty"; case exprirtype::symbol: return "symbol"; - case exprirtype::expression: - return "expression"; case exprirtype::typedescr: return "typedescr"; case exprirtype::n_exprirtype: @@ -43,8 +41,7 @@ namespace xo { exprir::print(std::ostream & os) const { os << "short_name()); os << ">"; @@ -576,8 +573,8 @@ namespace xo { void exprstate::on_exprir(const exprir & ir, - exprstatestack * p_stack, - rp * p_emit_expr) + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -592,11 +589,6 @@ namespace xo { * parser::include_token() returns */ - if (ir.xir_type() == exprirtype::expression) { - *p_emit_expr = ir.expr(); - return; - } - /* NOT IMPLEMENTED */ assert(false); return; @@ -619,31 +611,8 @@ namespace xo { assert(false); return; case exprstatetype::def_4: - /* have all the ingredients to create an expression - * representing a definition - * - * 1. if ir_type is a symbol, interpret as variable name. - * Need to be able to locate variable by type - * 2. if ir_type is an expression, adopt as rhs - */ - if (ir.xir_type() == exprirtype::expression) { - /* TODO: do something with def_lhs_td */ - - rp rhs_value = ir.expr(); - - if (def_lhs_td_) - rhs_value = ConvertExpr::make(def_lhs_td_, rhs_value); - - rp def = DefineExpr::make(this->def_lhs_symbol_, - rhs_value); - - p_stack->pop_exprstate(); - return p_stack->top_exprstate().on_expr(def, - p_stack, p_emit_expr); - } else { - assert(false); - return; - } + assert(false); + return; case exprstatetype::expect_rhs_expression: case exprstatetype::expect_type: From 44fdba132c3efd0a5b1a157bb7946cb245e77e57 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:32:15 +1000 Subject: [PATCH 028/191] xo-parser: refactor: exprstate::on_symbol splits symbol from exprir --- include/xo/parser/parser.hpp | 10 ++++++- src/parser/parser.cpp | 54 ++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index db6ea524..57d4b319 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -47,15 +47,17 @@ namespace xo { public: exprir() = default; +#ifdef OBSOLETE exprir(exprirtype xir_type, const std::string & x) : xir_type_{xir_type}, symbol_name_{x} {} +#endif exprir(exprirtype xir_type, TypeDescr td) : xir_type_{xir_type}, td_{td} {} exprirtype xir_type() const { return xir_type_; } - const std::string & symbol_name() const { return symbol_name_; } + //const std::string & symbol_name() const { return symbol_name_; } TypeDescr td() const { return td_; } void print(std::ostream & os) const; @@ -63,8 +65,10 @@ namespace xo { private: /** IR type code **/ exprirtype xir_type_ = exprirtype::invalid; +#ifdef OBSOLETE /** xir_type=symbol: a symbol (type or variable) name **/ std::string symbol_name_; +#endif /** xir_type=typedescr: object identifying/describing a datatype **/ TypeDescr td_ = nullptr; }; @@ -220,6 +224,10 @@ namespace xo { void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate when expecting a symbol **/ + void on_symbol(const std::string & symbol, + exprstatestack * p_stack, + rp * p_emit_expr); /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 8772e7fd..600c7191 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -40,8 +40,8 @@ namespace xo { void exprir::print(std::ostream & os) const { os << "short_name()); os << ">"; @@ -310,8 +310,8 @@ namespace xo { /* have to do pop first */ p_stack->pop_exprstate(); - p_stack->top_exprstate().on_exprir(exprir(exprirtype::symbol, tk.text()), p_stack, p_emit_expr); - //return expraction::pop(exprir(exprirtype::symbol, tk.text())); + p_stack->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); return; case exprstatetype::expect_type: { @@ -572,15 +572,10 @@ namespace xo { } void - exprstate::on_exprir(const exprir & ir, + exprstate::on_symbol(const std::string & symbol_name, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - log && log(xtag("ir", ir)); - log && log(xtag("state", *this)); - switch(this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: /* toplevel expression sequence accepts an @@ -594,9 +589,46 @@ namespace xo { return; case exprstatetype::def_0: this->exs_type_ = exprstatetype::def_1; - this->def_lhs_symbol_ = ir.symbol_name(); + this->def_lhs_symbol_ = symbol_name; return; + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + /* unreachable + * (this exprstate issues pop instruction from exprstate::on_input() + */ + assert(false); + return; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } + + void + exprstate::on_exprir(const exprir & ir, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + log && log(xtag("ir", ir)); + log && log(xtag("state", *this)); + + switch(this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: case exprstatetype::def_1: /* NOT IMPLEMENTED */ assert(false); From 18f32805257f15cee9f1118727303538c2b9c1e7 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:37:08 +1000 Subject: [PATCH 029/191] xo-parser: simplify: drop exprir::td --- include/xo/parser/parser.hpp | 40 +++++------------------- src/parser/parser.cpp | 59 ++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 57d4b319..a9dbc198 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -47,30 +47,18 @@ namespace xo { public: exprir() = default; -#ifdef OBSOLETE - exprir(exprirtype xir_type, - const std::string & x) - : xir_type_{xir_type}, symbol_name_{x} {} -#endif - exprir(exprirtype xir_type, - TypeDescr td) - : xir_type_{xir_type}, td_{td} {} + explicit exprir(exprirtype xir_type) + : xir_type_{xir_type} {} exprirtype xir_type() const { return xir_type_; } //const std::string & symbol_name() const { return symbol_name_; } - TypeDescr td() const { return td_; } + //TypeDescr td() const { return td_; } void print(std::ostream & os) const; private: /** IR type code **/ exprirtype xir_type_ = exprirtype::invalid; -#ifdef OBSOLETE - /** xir_type=symbol: a symbol (type or variable) name **/ - std::string symbol_name_; -#endif - /** xir_type=typedescr: object identifying/describing a datatype **/ - TypeDescr td_ = nullptr; }; inline std::ostream & @@ -131,23 +119,13 @@ namespace xo { class expraction { public: expraction() = default; - explicit expraction(expractiontype action_type -#ifdef OBSOLETE - const exprir & expr_ir -#endif - ) + explicit expraction(expractiontype action_type) : action_type_{action_type} -#ifdef OBSOLETE - , expr_ir_{expr_ir} -#endif {} static expraction keep(); expractiontype action_type() const { return action_type_; } -#ifdef OBSOLETE - const exprir & expr_ir() const { return expr_ir_; } -#endif void print(std::ostream & os) const; @@ -160,12 +138,6 @@ namespace xo { * pop: drop exprstate, report exprir to parent **/ expractiontype action_type_ = expractiontype::invalid; -#ifdef OBSOLETE - /** - * intermediate representation (pass to enclosing stack state) - **/ - exprir expr_ir_; -#endif }; inline std::ostream & @@ -228,6 +200,10 @@ namespace xo { void on_symbol(const std::string & symbol, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate when expeccting a typedescr **/ + void on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr); /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 600c7191..9eaba07c 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -41,9 +41,6 @@ namespace xo { exprir::print(std::ostream & os) const { os << "short_name()); os << ">"; } @@ -339,9 +336,7 @@ namespace xo { } p_stack->pop_exprstate(); - p_stack->top_exprstate().on_exprir - (exprir(exprirtype::typedescr, td), p_stack, p_emit_expr); - //return expraction::pop(exprir(exprirtype::typedescr, td)); + p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); return; } @@ -353,6 +348,47 @@ namespace xo { } } + void + exprstate::on_typedescr(TypeDescr td, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + switch(this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::def_2: + this->exs_type_ = exprstatetype::def_3; + this->def_lhs_td_ = td; + + return; + case exprstatetype::def_3: + case exprstatetype::def_4: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + /* unreachable + * (this exprstate issues pop instruction from exprstate::on_input() + */ + assert(false); + return; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } + void exprstate::on_colon(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; @@ -630,19 +666,10 @@ namespace xo { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::def_0: case exprstatetype::def_1: - /* NOT IMPLEMENTED */ - assert(false); - return; case exprstatetype::def_2: - this->exs_type_ = exprstatetype::def_3; - this->def_lhs_td_ = ir.td(); - - return; case exprstatetype::def_3: - /* NOT IMPLEMENTED */ - assert(false); - return; case exprstatetype::def_4: + /* NOT IMPLEMENTED */ assert(false); return; From 325d1f65476358116a16b7329ef02749c3a78e4b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:38:56 +1000 Subject: [PATCH 030/191] xo-parser: simplify: drop unused exprir type --- include/xo/parser/parser.hpp | 4 ++++ src/parser/parser.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index a9dbc198..deafa708 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -12,6 +12,7 @@ namespace xo { namespace scm { +#ifdef OBSOLETE // ----- exprir ----- enum class exprirtype { @@ -66,6 +67,7 @@ namespace xo { x.print(os); return os; } +#endif enum class exprstatetype { invalid = -1, @@ -204,10 +206,12 @@ namespace xo { void on_typedescr(TypeDescr td, exprstatestack * p_stack, rp * p_emit_expr); +#ifdef OBSOLETE /** update exprstate in response to IR (intermediate representation) * from nested parsing task **/ void on_exprir(const exprir & ir, exprstatestack * p_stack, rp * p_emit_expr); +#endif /** print human-readable representation on @p os **/ void print(std::ostream & os) const; diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 9eaba07c..0fbe7946 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -19,6 +19,7 @@ namespace xo { using xo::reflect::TypeDescr; namespace scm { +#ifdef OBSOLETE const char * exprirtype_descr(exprirtype x) { switch(x) { @@ -43,6 +44,7 @@ namespace xo { << xtag("type", xir_type_); os << ">"; } +#endif const char * exprstatetype_descr(exprstatetype x) { @@ -652,6 +654,7 @@ namespace xo { } } +#ifdef OBSOLETE void exprstate::on_exprir(const exprir & ir, exprstatestack * /*p_stack*/, @@ -688,6 +691,7 @@ namespace xo { return; } } +#endif void exprstate::print(std::ostream & os) const { From 992de108ca2c26cf6a3cdfc2e74bb661f4bf1222 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:40:09 +1000 Subject: [PATCH 031/191] xo-parser: simplify: drop unused expraction --- include/xo/parser/parser.hpp | 2 ++ src/parser/parser.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index deafa708..ebf2f7d6 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -97,6 +97,7 @@ namespace xo { return os; } +#ifdef OBSOLETE enum class expractiontype { invalid = -1, @@ -149,6 +150,7 @@ namespace xo { x.print(os); return os; } +#endif class exprstatestack; diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 0fbe7946..6813ba8e 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -76,6 +76,7 @@ namespace xo { return "???"; } +#ifdef OBSOLETE const char * expractiontype_descr(expractiontype x) { switch(x) { @@ -101,6 +102,7 @@ namespace xo { os << xtag("type", action_type_); os << ">"; } +#endif bool exprstate::admits_definition() const { From 7d6941fe3f3264a814022d3d4dcbd9df1c09f2bd Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 13:41:01 +1000 Subject: [PATCH 032/191] xo-parser: tidy: delete excluded code --- include/xo/parser/parser.hpp | 119 ----------------------------------- 1 file changed, 119 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index ebf2f7d6..a750affc 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -12,63 +12,6 @@ namespace xo { namespace scm { -#ifdef OBSOLETE - // ----- exprir ----- - - enum class exprirtype { - invalid = -1, - - empty, - symbol, - typedescr, - - n_exprirtype - }; - - extern const char * - exprirtype_descr(exprirtype x); - - inline std::ostream & - operator<< (std::ostream & os, - exprirtype x) - { - os << exprirtype_descr(x); - return os; - } - - /** intermediate representation for some part of an expression - * - * Examples: - * 1. a variable name (but without type information) - **/ - class exprir { - public: - using Expression = xo::ast::Expression; - using TypeDescr = xo::reflect::TypeDescr; - - public: - exprir() = default; - explicit exprir(exprirtype xir_type) - : xir_type_{xir_type} {} - - exprirtype xir_type() const { return xir_type_; } - //const std::string & symbol_name() const { return symbol_name_; } - //TypeDescr td() const { return td_; } - - void print(std::ostream & os) const; - - private: - /** IR type code **/ - exprirtype xir_type_ = exprirtype::invalid; - }; - - inline std::ostream & - operator<< (std::ostream & os, const exprir & x) { - x.print(os); - return os; - } -#endif - enum class exprstatetype { invalid = -1, @@ -97,61 +40,6 @@ namespace xo { return os; } -#ifdef OBSOLETE - enum class expractiontype { - invalid = -1, - - keep, - //emit, - //pop, - - n_expractiontype - }; - - extern const char * - expractiontype_descr(expractiontype x); - - inline std::ostream & - operator<< (std::ostream & os, expractiontype x) { - os << expractiontype_descr(x); - return os; - } - - /** an action associated with parser response to an incoming lexical - **/ - class expraction { - public: - expraction() = default; - explicit expraction(expractiontype action_type) - : action_type_{action_type} - {} - - static expraction keep(); - - expractiontype action_type() const { return action_type_; } - - void print(std::ostream & os) const; - - private: - /** - * push1: push new exprstate built from push_exs1_ - * push2: push new exprstate built from push_exs1_, - * followed by push_exs2_ - * keep: keep current exprstate (which will have updated inplace) - * pop: drop exprstate, report exprir to parent - **/ - expractiontype action_type_ = expractiontype::invalid; - }; - - inline std::ostream & - operator<< (std::ostream & os, - const expraction & x) - { - x.print(os); - return os; - } -#endif - class exprstatestack; /** state associated with a partially-parsed expression. @@ -208,13 +96,6 @@ namespace xo { void on_typedescr(TypeDescr td, exprstatestack * p_stack, rp * p_emit_expr); -#ifdef OBSOLETE - /** update exprstate in response to IR (intermediate representation) - * from nested parsing task - **/ - void on_exprir(const exprir & ir, exprstatestack * p_stack, rp * p_emit_expr); -#endif - /** print human-readable representation on @p os **/ void print(std::ostream & os) const; From 4e9b41645f76539393a859fe28313ad6b3de029f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 15:34:47 +1000 Subject: [PATCH 033/191] xo-parser: scaffolding eliminates exprstate::def_lhs_symbol --- include/xo/parser/parser.hpp | 12 +++++++- src/parser/parser.cpp | 60 ++++++++++-------------------------- 2 files changed, 27 insertions(+), 45 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index a750affc..ccba5080 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -6,6 +6,7 @@ #pragma once #include "xo/expression/Expression.hpp" +#include "xo/expression/DefineExpr.hpp" #include "xo/tokenizer/token.hpp" #include #include @@ -47,13 +48,17 @@ namespace xo { class exprstate { public: using Expression = xo::ast::Expression; + using DefineExprAccess = xo::ast::DefineExprAccess; using exprtype = xo::ast::exprtype; using token_type = token; using TypeDescr = xo::reflect::TypeDescr; public: exprstate() = default; - exprstate(exprstatetype exs_type) : exs_type_{exs_type} {} + exprstate(exprstatetype exs_type, + rp def_expr = nullptr) + : exs_type_{exs_type}, + def_expr_{std::move(def_expr)} {} static exprstate expect_toplevel_expression_sequence() { return exprstate(exprstatetype::expect_toplevel_expression_sequence); @@ -132,10 +137,15 @@ namespace xo { **/ exprstatetype exs_type_; + /** scaffold a define-expression here **/ + rp def_expr_; + +#ifdef OBSOLETE /** e.g. foo in * def foo : f64 = 1 **/ std::string def_lhs_symbol_; +#endif /** e.g. f64 in * def foo : f64 = 1 **/ diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 6813ba8e..e78728d9 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -258,7 +258,9 @@ namespace xo { xtag("state", *this))); } - p_stack->push_exprstate(exprstatetype::def_0); + p_stack->push_exprstate(exprstate(exprstatetype::def_0, + DefineExprAccess::make_empty())); + /* todo: replace: * expect_symbol_or_function_signature() */ @@ -367,6 +369,7 @@ namespace xo { case exprstatetype::def_2: this->exs_type_ = exprstatetype::def_3; + this->def_lhs_td_ = td; return; @@ -585,11 +588,18 @@ namespace xo { if (def_lhs_td_) rhs_value = ConvertExpr::make(def_lhs_td_, rhs_value); + rp def_expr = this->def_expr_; + + def_expr->assign_rhs(rhs_value); + +#ifdef OBSOLETE rp def = DefineExpr::make(this->def_lhs_symbol_, rhs_value); +#endif - p_stack->pop_exprstate(); - p_stack->top_exprstate().on_expr(def, + p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(def_expr, p_stack, p_emit_expr); return; @@ -629,7 +639,8 @@ namespace xo { return; case exprstatetype::def_0: this->exs_type_ = exprstatetype::def_1; - this->def_lhs_symbol_ = symbol_name; + this->def_expr_->assign_lhs_name(symbol_name); + //this->def_lhs_symbol_ = symbol_name; return; case exprstatetype::def_1: @@ -656,50 +667,11 @@ namespace xo { } } -#ifdef OBSOLETE - void - exprstate::on_exprir(const exprir & ir, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - log && log(xtag("ir", ir)); - log && log(xtag("state", *this)); - - switch(this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - /* NOT IMPLEMENTED */ - assert(false); - return; - - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - /* unreachable - * (this exprstate issues pop instruction from exprstate::on_input() - */ - assert(false); - return; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } - } -#endif - void exprstate::print(std::ostream & os) const { os << "short_name()); os << ">"; From c4c140af36069e981cac28af0279e4ad4a3d6aa2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 16:39:01 +1000 Subject: [PATCH 034/191] xo-parser: simplify: ConvertExprAccess replaces exprstate.def_lhs_td --- include/xo/parser/parser.hpp | 9 ++++----- src/parser/parser.cpp | 27 ++++++++++++--------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index ccba5080..75dd22dd 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -7,6 +7,7 @@ #include "xo/expression/Expression.hpp" #include "xo/expression/DefineExpr.hpp" +#include "xo/expression/ConvertExpr.hpp" #include "xo/tokenizer/token.hpp" #include #include @@ -49,6 +50,7 @@ namespace xo { public: using Expression = xo::ast::Expression; using DefineExprAccess = xo::ast::DefineExprAccess; + using ConvertExprAccess = xo::ast::ConvertExprAccess; using exprtype = xo::ast::exprtype; using token_type = token; using TypeDescr = xo::reflect::TypeDescr; @@ -139,17 +141,14 @@ namespace xo { /** scaffold a define-expression here **/ rp def_expr_; + rp cvt_expr_; #ifdef OBSOLETE - /** e.g. foo in - * def foo : f64 = 1 - **/ - std::string def_lhs_symbol_; -#endif /** e.g. f64 in * def foo : f64 = 1 **/ TypeDescr def_lhs_td_ = nullptr; +#endif }; /*exprstate*/ inline std::ostream & diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index e78728d9..eef5f821 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -369,10 +369,13 @@ namespace xo { case exprstatetype::def_2: this->exs_type_ = exprstatetype::def_3; - - this->def_lhs_td_ = td; + this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, + nullptr /*source_expr*/); + this->def_expr_->assign_rhs(this->cvt_expr_); + //this->def_lhs_td_ = td; return; + case exprstatetype::def_3: case exprstatetype::def_4: /* NOT IMPLEMENTED */ @@ -585,17 +588,12 @@ namespace xo { */ rp rhs_value = expr.get(); - if (def_lhs_td_) - rhs_value = ConvertExpr::make(def_lhs_td_, rhs_value); + if (this->cvt_expr_) + this->cvt_expr_->assign_arg(rhs_value); + else + this->def_expr_->assign_rhs(rhs_value);; - rp def_expr = this->def_expr_; - - def_expr->assign_rhs(rhs_value); - -#ifdef OBSOLETE - rp def = DefineExpr::make(this->def_lhs_symbol_, - rhs_value); -#endif + rp def_expr = this->def_expr_; p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ @@ -671,9 +669,8 @@ namespace xo { exprstate::print(std::ostream & os) const { os << "short_name()); + << xtag("def_expr", def_expr_) + << xtag("cvt_expr", cvt_expr_); os << ">"; } From 4df9192586cb1b24678a0b3cb31f3ee4b7d84484 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 16:56:08 +1000 Subject: [PATCH 035/191] xo-parser: feature: def may omit explicit type --- include/xo/parser/parser.hpp | 10 +++------- src/parser/parser.cpp | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 75dd22dd..e4e8943a 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -141,14 +141,10 @@ namespace xo { /** scaffold a define-expression here **/ rp def_expr_; - rp cvt_expr_; - -#ifdef OBSOLETE - /** e.g. f64 in - * def foo : f64 = 1 + /** scafford a convert-expression here. + * May be nested within a def_expr **/ - TypeDescr def_lhs_td_ = nullptr; -#endif + rp cvt_expr_; }; /*exprstate*/ inline std::ostream & diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index eef5f821..79c9b73f 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -194,8 +194,27 @@ namespace xo { exprstate::admits_singleassign() const { switch(exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: + + /* + * def foo = 1 + * def foo : f64 = 1 + * ^ ^ ^ ^ ^ ^ ^ + * | | | | | | (done) + * | | | | | def_4:expect_rhs_expression + * | | | | def_3 + * | | | def_2:expect_type + * | | def_1 + * | def_0:expect_symbol + * expect_toplevel_expression_sequence + * + * note that we skip from def_1 -> def_4 if '=' instead of ':' + */ case exprstatetype::def_0: + return false; + case exprstatetype::def_1: + return true; + case exprstatetype::def_2: return false; @@ -203,6 +222,7 @@ namespace xo { return true; case exprstatetype::def_4: + case exprstatetype::expect_rhs_expression: /* rhs-expressions (or expressions for that matter) * may not begin with singleassign '=' @@ -437,7 +457,9 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::def_3) { + if ((this->exs_type_ == exprstatetype::def_1) + || (this->exs_type_ == exprstatetype::def_3)) + { this->exs_type_ = exprstatetype::def_4; p_stack->push_exprstate(exprstatetype::expect_rhs_expression); From 32057efb5a79bcb4581cc4ea2840d082083c8474 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 16:56:34 +1000 Subject: [PATCH 036/191] xo-parser: utest: unit test for def with/without explicit type --- utest/parser.test.cpp | 333 ++++++++++++++++++++++-------------------- 1 file changed, 178 insertions(+), 155 deletions(-) diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp index e656d9de..8397f903 100644 --- a/utest/parser.test.cpp +++ b/utest/parser.test.cpp @@ -17,180 +17,203 @@ namespace xo { namespace ut { TEST_CASE("parser", "[parser]") { - parser_type parser; + for (std::size_t i_tc = 0; i_tc < 2; ++i_tc) { + parser_type parser; - parser.begin_translation_unit(); + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("i_tc", i_tc)); - REQUIRE(parser.stack_size() == 1); - REQUIRE(parser.i_exstype(0) - == exprstatetype::expect_toplevel_expression_sequence); + parser.begin_translation_unit(); - /* input: - * def - */ - { - auto r1 = parser.include_token(token_type::def()); - REQUIRE(r1.get() == nullptr); + REQUIRE(parser.stack_size() == 1); + REQUIRE(parser.i_exstype(0) + == exprstatetype::expect_toplevel_expression_sequence); - /* stack should be: + /* input: + * def + */ + { + auto r1 = parser.include_token(token_type::def()); + REQUIRE(r1.get() == nullptr); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_0 + * expect_symbol + */ + CHECK(parser.stack_size() == 3); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::expect_symbol); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) == exprstatetype::def_0); + if (parser.stack_size() > 2) + CHECK(parser.i_exstype(2) + == exprstatetype::expect_toplevel_expression_sequence); + } + + /* input: + * def foo + * ^ ^ + * 0 1 + */ + { + auto r2 = parser.include_token(token_type::symbol_token("foo")); + + cerr << "parser state after [def foo]" << endl; + cerr << parser << endl; + + REQUIRE(r2.get() == nullptr); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_1 + */ + CHECK(parser.stack_size() == 2); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::def_1); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) + == exprstatetype::expect_toplevel_expression_sequence); + + } + + if (i_tc == 0) { + ; + } else if (i_tc == 1) { + /* input: + * def foo : + * ^ ^ + * 0 1 + */ + { + auto r3 = parser.include_token(token_type::colon()); + + cerr << "parser state after [def foo :]" << endl; + cerr << parser << endl; + + REQUIRE(r3.get() == nullptr); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_2 + * expect_symbol + */ + CHECK(parser.stack_size() == 3); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::expect_type); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) == exprstatetype::def_2); + if (parser.stack_size() > 2) + CHECK(parser.i_exstype(2) + == exprstatetype::expect_toplevel_expression_sequence); + } + + /* input: + * def foo : f64 + * ^ ^ + * 0 1 + */ + { + auto r4 = parser.include_token(token_type::symbol_token("f64")); + + cerr << "parser state after [def foo : f64]" << endl; + cerr << parser << endl; + + REQUIRE(r4.get() == nullptr); + + CHECK(parser.stack_size() == 2); + + /* stack should be: + * + * expect_toplevel_expression_sequence + * def_3 + */ + CHECK(parser.stack_size() == 2); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::def_3); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) + == exprstatetype::expect_toplevel_expression_sequence); + + /* expecting either: + * = rhs-expression + * new-expression + */ + } + } + + /* input: * - * expect_toplevel_expression_sequence - * def_0 - * expect_symbol - */ - CHECK(parser.stack_size() == 3); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::expect_symbol); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) == exprstatetype::def_0); - if (parser.stack_size() > 2) - CHECK(parser.i_exstype(2) - == exprstatetype::expect_toplevel_expression_sequence); - } - - /* input: - * def foo - * ^ ^ - * 0 1 - */ - { - auto r2 = parser.include_token(token_type::symbol_token("foo")); - - cerr << "parser state after [def foo]" << endl; - cerr << parser << endl; - - REQUIRE(r2.get() == nullptr); - - /* stack should be: + * i_tc==0: + * def foo = + * ^ ^ + * 0 1 * - * expect_toplevel_expression_sequence - * def_1 + * i_tc==1: + * def foo : f64 = + * ^ ^ + * 0 1 */ - CHECK(parser.stack_size() == 2); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::def_1); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) - == exprstatetype::expect_toplevel_expression_sequence); + { + auto r5 = parser.include_token(token_type::singleassign()); - } + cerr << "parser state after [def foo : f64 =]" << endl; + cerr << parser << endl; - /* input: - * def foo : - * ^ ^ - * 0 1 - */ - { - auto r3 = parser.include_token(token_type::colon()); + REQUIRE(r5.get() == nullptr); - cerr << "parser state after [def foo :]" << endl; - cerr << parser << endl; + CHECK(parser.stack_size() == 3); - REQUIRE(r3.get() == nullptr); + /* stack should be + * + * expect_toplevel_expression_sequence + * def_4 + * expect_expression + */ + CHECK(parser.stack_size() == 3); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::expect_rhs_expression); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) == exprstatetype::def_4); + if (parser.stack_size() > 2) + CHECK(parser.i_exstype(2) + == exprstatetype::expect_toplevel_expression_sequence); + } - /* stack should be: + /* input: * - * expect_toplevel_expression_sequence - * def_2 - * expect_symbol - */ - CHECK(parser.stack_size() == 3); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::expect_type); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) == exprstatetype::def_2); - if (parser.stack_size() > 2) - CHECK(parser.i_exstype(2) - == exprstatetype::expect_toplevel_expression_sequence); - } - - /* input: - * def foo : f64 - * ^ ^ - * 0 1 - */ - { - auto r4 = parser.include_token(token_type::symbol_token("f64")); - - cerr << "parser state after [def foo : f64]" << endl; - cerr << parser << endl; - - REQUIRE(r4.get() == nullptr); - - CHECK(parser.stack_size() == 2); - - /* stack should be: + * i_tc==0: + * def foo = 3.14159265 + * ^ ^ + * 0 1 * - * expect_toplevel_expression_sequence - * def_3 + * i_tc==1: + * def foo : f64 = 3.14159265 + * ^ ^ + * 0 1 */ - CHECK(parser.stack_size() == 2); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::def_3); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) - == exprstatetype::expect_toplevel_expression_sequence); + { + auto r6 = parser.include_token(token_type::f64_token("3.14159265")); - /* expecting either: - * = rhs-expression - * new-expression - */ - } + cerr << "parser state after [def foo : f64 = 3.14159265]" << endl; + cerr << parser << endl; - /* input: - * def foo : f64 = - * ^ ^ - * 0 1 - */ - { - auto r5 = parser.include_token(token_type::singleassign()); + REQUIRE(r6.get() != nullptr); - cerr << "parser state after [def foo : f64 =]" << endl; - cerr << parser << endl; + CHECK(parser.stack_size() == 1); - REQUIRE(r5.get() == nullptr); - - CHECK(parser.stack_size() == 3); - - /* stack should be - * - * expect_toplevel_expression_sequence - * def_4 - * expect_expression - */ - CHECK(parser.stack_size() == 3); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::expect_rhs_expression); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) == exprstatetype::def_4); - if (parser.stack_size() > 2) - CHECK(parser.i_exstype(2) - == exprstatetype::expect_toplevel_expression_sequence); - } - - /* input: - * def foo : f64 = 3.14159265 - * ^ ^ - * 0 1 - */ - { - auto r6 = parser.include_token(token_type::f64_token("3.14159265")); - - cerr << "parser state after [def foo : f64 = 3.14159265]" << endl; - cerr << parser << endl; - - REQUIRE(r6.get() != nullptr); - - CHECK(parser.stack_size() == 1); - - /* stack should be - * - * expect_toplevel_expression_sequence - */ - CHECK(parser.stack_size() == 1); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) - == exprstatetype::expect_toplevel_expression_sequence); + /* stack should be + * + * expect_toplevel_expression_sequence + */ + CHECK(parser.stack_size() == 1); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) + == exprstatetype::expect_toplevel_expression_sequence); + } } } /*TEST_CASE(parser)*/ } /*namespace ut*/ From 179215e6516fc4d7cf9839b2b0dc8389e76b743c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 5 Aug 2024 14:54:17 -0400 Subject: [PATCH 037/191] xo-parser: drop unused exprirtype debris --- src/parser/parser.cpp | 55 ------------------------------------------- 1 file changed, 55 deletions(-) diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 79c9b73f..8a60bbbd 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -19,33 +19,6 @@ namespace xo { using xo::reflect::TypeDescr; namespace scm { -#ifdef OBSOLETE - const char * - exprirtype_descr(exprirtype x) { - switch(x) { - case exprirtype::invalid: - return "?invalid"; - case exprirtype::empty: - return "empty"; - case exprirtype::symbol: - return "symbol"; - case exprirtype::typedescr: - return "typedescr"; - case exprirtype::n_exprirtype: - break; - } - - return "???exprirtype"; - } - - void - exprir::print(std::ostream & os) const { - os << ""; - } -#endif - const char * exprstatetype_descr(exprstatetype x) { switch(x) { @@ -76,34 +49,6 @@ namespace xo { return "???"; } -#ifdef OBSOLETE - const char * - expractiontype_descr(expractiontype x) { - switch(x) { - case expractiontype::invalid: - return "?invalid"; - case expractiontype::keep: - return "keep"; - case expractiontype::n_expractiontype: - break; - } - - return "???"; - } - - expraction - expraction::keep() { - return expraction(expractiontype::keep); - } - - void - expraction::print(std::ostream & os) const { - os << ""; - } -#endif - bool exprstate::admits_definition() const { switch(exs_type_) { From 99c1ebc7fb4ad93b0c73488b839544ae6cafca93 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 04:40:56 -0400 Subject: [PATCH 038/191] xo-reader: + reader.hpp --- include/xo/parser/reader.hpp | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 include/xo/parser/reader.hpp diff --git a/include/xo/parser/reader.hpp b/include/xo/parser/reader.hpp new file mode 100644 index 00000000..39dcd6b8 --- /dev/null +++ b/include/xo/parser/reader.hpp @@ -0,0 +1,56 @@ +/* file reader.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "parser.hpp" +#include "xo/tokenizer/tokenizer.hpp" + +namespace xo { + namespace scm { + /** + * Use: + * @code + * reader rdr; + * + * bool eof = false; + * while (!eof) { + * auto input = ins.read_some(); + * // eof: true if no more input will be forthcoming from this stream + * eof = ins.eof(); + * + * for (auto rem = input; ; !rem.empty()) { + * // res: (parsed-expr, used) + * auto res = rdr.read_expr(rem, eof); + * + * if (res.first) { + * // do something with res.first (parsed expr) + * ... + * } + * + * rem = rem.suffix_after(res.second); + * } + * } + * + * // expect !rdr.has_prefix() + * + * @endcode + **/ + class reader { + public: + reader() = default; + + private: + /** tokenizer: text -> tokens **/ + tokenizer tokenizer_; + + /** parser: tokens -> expressions (TODO: reanme ->reader) **/ + parser parser_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end Repl.hpp */ From f58502c8a83406081ab5c5e1ac790295824f2f5e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 04:41:50 -0400 Subject: [PATCH 039/191] xo-reader: trivial: comment tidy --- include/xo/parser/parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index e4e8943a..4245c2c3 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -286,7 +286,7 @@ namespace xo { * arg-expr(i) = expression * * if-expr = if (test-expr) then-block else else-block - * | (test-expr) ? then-expr : else-expr + * | ((test-expr) ? then-expr : else-expr) * test-expr = expression * then-block = block * else-block = block From a4848044ea9165c60441120d8caccf6ed6009d50 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 09:42:38 -0400 Subject: [PATCH 040/191] xo-parser: feat: + parser.has_incomplete_expr() --- include/xo/parser/parser.hpp | 6 ++++++ src/parser/parser.cpp | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index e4e8943a..deabaab8 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -327,6 +327,12 @@ namespace xo { return exprstatetype::invalid; } + /** true iff parser contains state for an incomplete expression. + * For this to be true, parser must have consumed at least one token + * since end of last toplevel expression + **/ + bool has_incomplete_expr() const; + /** put parser into state for beginning of a translation unit * (i.e. input stream) **/ diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 8a60bbbd..71da1798 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -689,6 +689,11 @@ namespace xo { // ----- parser ----- + bool + parser::has_incomplete_expr() const { + return !xs_stack_.empty(); + } + void parser::begin_translation_unit() { xs_stack_.push_exprstate From 07ba966e083f7f4d20d7615db04288a842b2a09d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 09:42:53 -0400 Subject: [PATCH 041/191] xo-parser: appease g++: return statement after switch --- src/parser/parser.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 71da1798..9327f893 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -76,6 +76,8 @@ namespace xo { /* unreachable */ return false; } + + return false; } bool @@ -105,6 +107,8 @@ namespace xo { /* unreachable */ return false; } + + return false; } bool @@ -133,6 +137,8 @@ namespace xo { /* unreachable */ return false; } + + return false; } bool @@ -181,6 +187,8 @@ namespace xo { /* unreachable */ return false; } + + return false; } bool @@ -206,6 +214,8 @@ namespace xo { /* unreachable */ return false; } + + return false; } void From 7e311ab0cbbfbec84843a814d1637ce0c39a57e1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 09:43:32 -0400 Subject: [PATCH 042/191] xo-parser: + reader class (tokenizer -> parser pipeline) --- include/xo/parser/reader.hpp | 41 +++++++++++++++++--- src/parser/CMakeLists.txt | 3 +- src/parser/reader.cpp | 75 ++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 src/parser/reader.cpp diff --git a/include/xo/parser/reader.hpp b/include/xo/parser/reader.hpp index 39dcd6b8..b36489d6 100644 --- a/include/xo/parser/reader.hpp +++ b/include/xo/parser/reader.hpp @@ -6,10 +6,27 @@ #pragma once #include "parser.hpp" +#include "xo/expression/Expression.hpp" #include "xo/tokenizer/tokenizer.hpp" namespace xo { namespace scm { + /** @class parse_result + * @brief Result object returned from reader::read_expr + **/ + struct reader_result { + using Expression = xo::ast::Expression; + using span_type = span; + + /** parsed schematica expression **/ + rp expr_; + /** span giving text input consumed to construct expr, + * including any leading whitespace. + * This is the span returned in result of tokenizer::scan() + **/ + span_type rem_; + }; + /** * Use: * @code @@ -21,7 +38,7 @@ namespace xo { * // eof: true if no more input will be forthcoming from this stream * eof = ins.eof(); * - * for (auto rem = input; ; !rem.empty()) { + * for (auto rem = input; !rem.empty();) { * // res: (parsed-expr, used) * auto res = rdr.read_expr(rem, eof); * @@ -39,18 +56,32 @@ namespace xo { * @endcode **/ class reader { + public: + using tokenizer_type = tokenizer; + using span_type = tokenizer_type::span_type; + public: reader() = default; + /** Try to read one expression from @p input. + * Return struct containing parsed expression + * and span of characters comprising that expression + * + * @param input Supply this input span of chars + * @param eof. True if input stream supplying @p input + * reports end-of-file immediately after the last char + * in @p input. + **/ + reader_result read_expr(const span_type & input, bool eof); + private: /** tokenizer: text -> tokens **/ - tokenizer tokenizer_; + tokenizer_type tokenizer_; - /** parser: tokens -> expressions (TODO: reanme ->reader) **/ + /** parser: tokens -> expressions **/ parser parser_; }; } /*namespace scm*/ } /*namespace xo*/ - -/* end Repl.hpp */ +/* end reader.hpp */ diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt index 2af43636..a97b50fa 100644 --- a/src/parser/CMakeLists.txt +++ b/src/parser/CMakeLists.txt @@ -2,7 +2,8 @@ set(SELF_LIB xo_parser) set(SELF_SRCS - parser.cpp) + parser.cpp + reader.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/parser/reader.cpp b/src/parser/reader.cpp new file mode 100644 index 00000000..84d00b30 --- /dev/null +++ b/src/parser/reader.cpp @@ -0,0 +1,75 @@ +/* @file reader.cpp */ + +#include "reader.hpp" + +namespace xo { + namespace scm { + reader_result + reader::read_expr(const span_type & input_arg, bool eof) + { + span_type input = input_arg; + + /* input text-span consumed by this call. + * Always comprises some number (possibly 0) + * of complete tokens, along with any leading + * whitespace + */ + span_type expr_span = input.prefix(0ul); + + while (!input.empty()) { + /* read one token from input */ + auto sr = this->tokenizer_.scan2(input, eof); + const auto & tk = sr.first; + const span_type & used_span = sr.second; + + input = input.after_prefix(used_span); + expr_span += used_span; + + if (tk.is_valid()) { + /* forward just-read token to parser */ + auto expr = this->parser_.include_token(tk); + + if (expr) { + /* token completes an expression -> victory */ + return reader_result(expr, expr_span); + } else { + /* token did not complete an expression + * (e.g. token for '[') + * + * input span may contain more tokens -> iterate + */ + input = input.after_prefix(used_span); + } + } else { + assert(input.empty()); + + /* no more tokens in input */ + break; + } + } + + /* control here: either + * 1. input.empty (perhaps ate some whitespace, ok) + * 2. missing or incomplete token (ok unless eof) + */ + if (eof) { + if (parser_.has_incomplete_expr()) { + throw std::runtime_error + ("reader::read_expr" + ": eof reached with incomplete expression"); + } + + if (tokenizer_.has_prefix()) { + throw std::runtime_error + ("reader::read_expr" + ": unintelligible input recognized at eof"); + } + } + + return reader_result(nullptr, expr_span); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end reader.cpp */ From 0fdef0f3173f5fbf0f2209486387b06ffdf13aea Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 10:11:36 -0400 Subject: [PATCH 043/191] xo-reader: tidy: + begin/end translation unit methods --- include/xo/parser/reader.hpp | 17 +++++++++++++++++ src/parser/reader.cpp | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/xo/parser/reader.hpp b/include/xo/parser/reader.hpp index b36489d6..4009f722 100644 --- a/include/xo/parser/reader.hpp +++ b/include/xo/parser/reader.hpp @@ -31,6 +31,7 @@ namespace xo { * Use: * @code * reader rdr; + * rdr.begin_translation_unit() * * bool eof = false; * while (!eof) { @@ -63,6 +64,22 @@ namespace xo { public: reader() = default; + /** call once before calling .read_expr(): + * 1. with new reader + * 2. if last read_expr() call had eof=true + **/ + void begin_translation_unit(); + + /** counterpart to .begin_translation_unit(), + * provided for symmetry's sake + * + * Equivalent to: + * @code + * read_expr(span_type(nullptr, nullptr), true); + * @endcode + **/ + reader_result end_translation_unit(); + /** Try to read one expression from @p input. * Return struct containing parsed expression * and span of characters comprising that expression diff --git a/src/parser/reader.cpp b/src/parser/reader.cpp index 84d00b30..c24ebf94 100644 --- a/src/parser/reader.cpp +++ b/src/parser/reader.cpp @@ -4,6 +4,16 @@ namespace xo { namespace scm { + void + reader::begin_translation_unit() { + parser_.begin_translation_unit(); + } + + reader_result + reader::end_translation_unit() { + return this->read_expr(span_type(nullptr, nullptr), true /*eof*/); + } + reader_result reader::read_expr(const span_type & input_arg, bool eof) { From f00c390e37f3d90022ad439721e0d6e2a91d9028 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 10:19:33 -0400 Subject: [PATCH 044/191] xo-reader: naming: xo_parser->xo_reader --- CMakeLists.txt | 6 +++--- .../{xo_parserConfig.cmake.in => xo_readerConfig.cmake.in} | 0 include/xo/{parser => reader}/parser.hpp | 0 include/xo/{parser => reader}/reader.hpp | 0 src/{parser => reader}/CMakeLists.txt | 2 +- src/{parser => reader}/parser.cpp | 0 src/{parser => reader}/reader.cpp | 0 utest/CMakeLists.txt | 6 +++--- utest/parser.test.cpp | 2 +- utest/{parser_utest_main.cpp => reader_utest_main.cpp} | 0 10 files changed, 8 insertions(+), 8 deletions(-) rename cmake/{xo_parserConfig.cmake.in => xo_readerConfig.cmake.in} (100%) rename include/xo/{parser => reader}/parser.hpp (100%) rename include/xo/{parser => reader}/reader.hpp (100%) rename src/{parser => reader}/CMakeLists.txt (91%) rename src/{parser => reader}/parser.cpp (100%) rename src/{parser => reader}/reader.cpp (100%) rename utest/{parser_utest_main.cpp => reader_utest_main.cpp} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84eccb39..7748dc4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ -# xo-parser/CMakeLists.txt +# xo-reader/CMakeLists.txt cmake_minimum_required(VERSION 3.10) -project(xo_parser VERSION 0.1) +project(xo_reader VERSION 0.1) include(GNUInstallDirs) include(cmake/xo-bootstrap-macros.cmake) @@ -18,7 +18,7 @@ add_definitions(${PROJECT_CXX_FLAGS}) # ---------------------------------------------------------------- -add_subdirectory(src/parser) +add_subdirectory(src/reader) add_subdirectory(utest) # ---------------------------------------------------------------- diff --git a/cmake/xo_parserConfig.cmake.in b/cmake/xo_readerConfig.cmake.in similarity index 100% rename from cmake/xo_parserConfig.cmake.in rename to cmake/xo_readerConfig.cmake.in diff --git a/include/xo/parser/parser.hpp b/include/xo/reader/parser.hpp similarity index 100% rename from include/xo/parser/parser.hpp rename to include/xo/reader/parser.hpp diff --git a/include/xo/parser/reader.hpp b/include/xo/reader/reader.hpp similarity index 100% rename from include/xo/parser/reader.hpp rename to include/xo/reader/reader.hpp diff --git a/src/parser/CMakeLists.txt b/src/reader/CMakeLists.txt similarity index 91% rename from src/parser/CMakeLists.txt rename to src/reader/CMakeLists.txt index a97b50fa..687ae4e1 100644 --- a/src/parser/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -1,6 +1,6 @@ # parser/CMakeLists.txt -set(SELF_LIB xo_parser) +set(SELF_LIB xo_reader) set(SELF_SRCS parser.cpp reader.cpp) diff --git a/src/parser/parser.cpp b/src/reader/parser.cpp similarity index 100% rename from src/parser/parser.cpp rename to src/reader/parser.cpp diff --git a/src/parser/reader.cpp b/src/reader/reader.cpp similarity index 100% rename from src/parser/reader.cpp rename to src/reader/reader.cpp diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt index d70b7d4d..d1e00b46 100644 --- a/utest/CMakeLists.txt +++ b/utest/CMakeLists.txt @@ -1,13 +1,13 @@ -# xo-parser/utest/CMakeLists.txt +# xo-reader/utest/CMakeLists.txt set(UTEST_EXE utest.parser) set(UTEST_SRCS - parser_utest_main.cpp + reader_utest_main.cpp parser.test.cpp) if (ENABLE_TESTING) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) - xo_self_dependency(${UTEST_EXE} xo_parser) + xo_self_dependency(${UTEST_EXE} xo_reader) #xo_dependency(${UTEST_EXE} xo_ratio) #xo_dependency(${UTEST_EXE} xo_reflectutil) xo_external_target_dependency(${UTEST_EXE} Catch2 Catch2::Catch2) diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp index 8397f903..aa230c7a 100644 --- a/utest/parser.test.cpp +++ b/utest/parser.test.cpp @@ -3,7 +3,7 @@ * author: Roland Conybeare */ -#include "xo/parser/parser.hpp" +#include "xo/reader/parser.hpp" #include namespace xo { diff --git a/utest/parser_utest_main.cpp b/utest/reader_utest_main.cpp similarity index 100% rename from utest/parser_utest_main.cpp rename to utest/reader_utest_main.cpp From 91545c973259fa80e6fcbca56b8085a0e57038dd Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 10:52:27 -0400 Subject: [PATCH 045/191] xo-reader: lint: drop unused defs --- src/reader/parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 9327f893..b4a9eaf9 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -12,8 +12,8 @@ namespace xo { using xo::ast::Expression; - using xo::ast::DefineExpr; - using xo::ast::ConvertExpr; + //using xo::ast::DefineExpr; + //using xo::ast::ConvertExpr; using xo::ast::Constant; using xo::reflect::Reflect; using xo::reflect::TypeDescr; From f591d9703ecca00a1a547222542d3d52b0158e58 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 10:52:47 -0400 Subject: [PATCH 046/191] xo-reader: tidy: fix utest exe name --- utest/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt index d1e00b46..b209a9c9 100644 --- a/utest/CMakeLists.txt +++ b/utest/CMakeLists.txt @@ -1,6 +1,6 @@ # xo-reader/utest/CMakeLists.txt -set(UTEST_EXE utest.parser) +set(UTEST_EXE utest.reader) set(UTEST_SRCS reader_utest_main.cpp parser.test.cpp) From 876489700f12ee608b977e959046728e56a172de Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 10:53:04 -0400 Subject: [PATCH 047/191] xo-reader: + utest for reader [failing!] --- utest/CMakeLists.txt | 3 ++- utest/reader.test.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 utest/reader.test.cpp diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt index b209a9c9..1f876ca1 100644 --- a/utest/CMakeLists.txt +++ b/utest/CMakeLists.txt @@ -3,7 +3,8 @@ set(UTEST_EXE utest.reader) set(UTEST_SRCS reader_utest_main.cpp - parser.test.cpp) + parser.test.cpp + reader.test.cpp) if (ENABLE_TESTING) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp new file mode 100644 index 00000000..376dbf05 --- /dev/null +++ b/utest/reader.test.cpp @@ -0,0 +1,38 @@ +/* @file reader.test.cpp */ + +#include "xo/reader/reader.hpp" +#include + +namespace xo { + using xo::scm::reader; + + namespace ut { + TEST_CASE("reader", "[reader]") { + for (std::size_t i_tc = 0; i_tc < 1; ++i_tc) { + reader rdr; + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("utest", "reader"), xtag("i_tc", i_tc)); + + rdr.begin_translation_unit(); + + try { + auto rr = rdr.read_expr(reader::span_type::from_cstr("def foo : f64 = 3.14159265"), + true /*eof*/); + + REQUIRE(rr.expr_.get()); + REQUIRE(rr.rem_.empty()); + } catch (std::exception & ex) { + log && log(ex.what()); + + INFO(ex.what()); + + REQUIRE(false); + } + } + } + } /*namespace ut*/ +} /*namespace xo*/ + +/* end reader.test.cpp */ From 37268113fbdc55648f446e305647bdc3ae448386 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 6 Aug 2024 23:09:05 -0400 Subject: [PATCH 048/191] xo-parser: prep: semicolon expr separator, prep for infix ops --- include/xo/reader/parser.hpp | 92 ++++++++--- include/xo/reader/reader.hpp | 3 + src/reader/parser.cpp | 306 +++++++++++++++++++++++++++++++---- src/reader/reader.cpp | 15 +- utest/parser.test.cpp | 38 ++++- utest/reader.test.cpp | 15 +- 6 files changed, 409 insertions(+), 60 deletions(-) diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index 5888c9f9..2c26a8e9 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -30,6 +30,8 @@ namespace xo { expect_symbol, expect_type, + expr_progress, + n_exprstatetype }; @@ -58,18 +60,29 @@ namespace xo { public: exprstate() = default; exprstate(exprstatetype exs_type, - rp def_expr = nullptr) + rp candidate_expr, + rp def_expr) : exs_type_{exs_type}, + gen_expr_{std::move(candidate_expr)}, def_expr_{std::move(def_expr)} {} static exprstate expect_toplevel_expression_sequence() { - return exprstate(exprstatetype::expect_toplevel_expression_sequence); + return exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr); } - static exprstate def_0() { - return exprstate(exprstatetype::def_0); + static exprstate expect_rhs_expression() { + return exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr); } static exprstate expect_symbol() { - return exprstate(exprstatetype::expect_symbol); + return exprstate(exprstatetype::expect_symbol, nullptr, nullptr); + } + static exprstate expect_type() { + return exprstate(exprstatetype::expect_type, nullptr, nullptr); + } + static exprstate make_expr_progress(rp expr) { + return exprstate(exprstatetype::expr_progress, expr, nullptr); + } + static exprstate def_0(rp def_expr) { + return exprstate(exprstatetype::def_0, nullptr, def_expr); } exprstatetype exs_type() const { return exs_type_; } @@ -82,8 +95,14 @@ namespace xo { bool admits_symbol() const; /** true iff this parsing state admits a colon as next token **/ bool admits_colon() const; + /** true iff this parsing state admits a semicolon as next token **/ + bool admits_semicolon() const; /** true iff this parsing state admits a singleassign '=' as next token **/ bool admits_singleassign() const; +#ifdef NOT_YET + /** true iff this parsing state admits a leftparen '(' as next token **/ + bool admits_leftparen() const; +#endif /** true iff this parsing state admits a 64-bit floating point literal token **/ bool admits_f64() const; @@ -112,16 +131,23 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr); void on_colon(exprstatestack * p_stack); + void on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr); void on_singleassign(exprstatestack * p_stack); +#ifdef NOT_YET + void on_leftparen(exprstatestack * p_stack, + rp * p_emit_expr); +#endif void on_f64(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); private: /** - * def foo : f64 = 1 - * ^ ^ ^ ^ ^ ^ ^ - * | | | | | | (done) + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | (done) + * | | | | | | ?? * | | | | | def_4:expect_rhs_expression * | | | | def_3 * | | | def_2:expect_type @@ -139,6 +165,8 @@ namespace xo { **/ exprstatetype exs_type_; + /** generic expression **/ + rp gen_expr_; /** scaffold a define-expression here **/ rp def_expr_; /** scafford a convert-expression here. @@ -199,10 +227,10 @@ namespace xo { * decltype point * * // forward declarations - * decl pi : f64 - * decl fib(n : i32) -> i32 + * decl pi : f64; + * decl fib(n : i32) -> i32; * - * def pi = 3.14159265 // constant. = is single assignment + * def pi = 3.14159265; // constant. = is single assignment * * def fib(n : i32) -> i32 { * // nested defs ok @@ -211,33 +239,37 @@ namespace xo { * // (n == 0) ? s1 : aux(n - 1, s1 + s2, s1) * // * if (n == 0) { - * s1 + * s1; * } else { - * aux(n - 1, s1 + s2, s1) + * aux(n - 1, s1 + s2, s1); * } * * // or: * // if (n == 0) ? s1 : aux(n - 1, s1 + s2, s1) * } * - * aux(n=n, s1=1, s2=0) + * aux(n=n, s1=1, s2=0); * } * - * def anotherfib = lambda(n : i32) { fib(n) } + * def x := "fu"; // non-constant + * x += "bar"; * - * def any : object - * def l : list = '() + * def anotherfib = lambda(n : i32) { fib(n) }; * - * deftype point :: {x : f64, y : f64} - * deftype polar :: {arg : f64, mag : f64} + * def any : object; + * def l : list = '(); + * + * deftype point :: {x : f64, y : f64}; + * deftype polar :: {arg : f64, mag : f64}; * * def polar2rect(pt : polar) -> point { * point(x = pt.mag * cos(arg), - * y = pt.mag * sin(arg)) + * y = pt.mag * sin(arg)); * } * * Grammar: - * toplevel-program = expression* + * toplevel-program = $expression(1); ..; $expression(n) + * * type-decl = decltype $typename [<$tp1 .. $tpn>] * expression = define-expr * | literal-expr @@ -245,6 +277,7 @@ namespace xo { * | apply-expr * | if-expr * | lambda-expr + * | arithmetic-expr * | block * * define-expr = type-decl @@ -297,6 +330,23 @@ namespace xo { * .., * $paramname(n) : $type(n)) body-expr * body-expr = expression + * + * arithmetic-expr = expression binop expression + * + * binop = + + * | - + * | * + * | / + * | | + * | & + * | ^ + * | == + * | != + * | < + * | <= + * | => + * | > + * **/ class parser { public: diff --git a/include/xo/reader/reader.hpp b/include/xo/reader/reader.hpp index 4009f722..28e0b3a6 100644 --- a/include/xo/reader/reader.hpp +++ b/include/xo/reader/reader.hpp @@ -18,6 +18,9 @@ namespace xo { using Expression = xo::ast::Expression; using span_type = span; + reader_result(rp expr, span_type rem) + : expr_{std::move(expr)}, rem_{rem} {} + /** parsed schematica expression **/ rp expr_; /** span giving text input consumed to construct expr, diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index b4a9eaf9..b5b7dcd6 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -21,7 +21,7 @@ namespace xo { namespace scm { const char * exprstatetype_descr(exprstatetype x) { - switch(x) { + switch (x) { case exprstatetype::invalid: return "?invalid"; case exprstatetype::expect_toplevel_expression_sequence: @@ -42,6 +42,8 @@ namespace xo { return "expect_symbol"; case exprstatetype::expect_type: return "expect_type"; + case exprstatetype::expr_progress: + return "expr_progress"; case exprstatetype::n_exprstatetype: break; } @@ -51,7 +53,7 @@ namespace xo { bool exprstate::admits_definition() const { - switch(exs_type_) { + switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: return true; @@ -71,6 +73,8 @@ namespace xo { case exprstatetype::expect_symbol: case exprstatetype::expect_type: return false; + case exprstatetype::expr_progress: + return false; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -82,7 +86,7 @@ namespace xo { bool exprstate::admits_symbol() const { - switch(exs_type_) { + switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::def_0: case exprstatetype::def_1: @@ -102,6 +106,9 @@ namespace xo { /* treat symbol as typename */ return true; + case exprstatetype::expr_progress: + return false; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -113,7 +120,7 @@ namespace xo { bool exprstate::admits_colon() const { - switch(exs_type_) { + switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::def_0: return false; @@ -132,6 +139,9 @@ namespace xo { case exprstatetype::expect_type: return false; + case exprstatetype::expr_progress: + return false; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -141,14 +151,37 @@ namespace xo { return false; } + bool + exprstate::admits_semicolon() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + return false; + case exprstatetype::expr_progress: + return true; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + return false; + } + + return false; + } + bool exprstate::admits_singleassign() const { - switch(exs_type_) { + switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: /* - * def foo = 1 - * def foo : f64 = 1 + * def foo = 1 ; + * def foo : f64 = 1 ; * ^ ^ ^ ^ ^ ^ ^ * | | | | | | (done) * | | | | | def_4:expect_rhs_expression @@ -182,6 +215,9 @@ namespace xo { case exprstatetype::expect_type: return false; + case exprstatetype::expr_progress: + return false; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -193,7 +229,7 @@ namespace xo { bool exprstate::admits_f64() const { - switch(exs_type_) { + switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::def_0: case exprstatetype::def_1: @@ -209,6 +245,9 @@ namespace xo { case exprstatetype::expect_type: return false; + case exprstatetype::expr_progress: + return false; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -218,6 +257,61 @@ namespace xo { return false; } +#ifdef NOT_YET + bool + exprstate::admits_leftparen() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* input like + * (function(blah...)) + * not allowed at toplevel; + * creates ambiguity e.g. consider + * x := foo + * (bar) + * + * is rhs 'foo' or 'foo(bar)' + */ + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + /* input like + * def foo : f64 = ( + * ^ ^ ^ ^ ^ + * | | | | def_4 + * | | | def_3 + * | | def_2 + * | def_1 + * def_0 + * + * not allowed or relies on pushing another state + */ + return false; + + case exprstatetype::expect_rhs_expression: + /* can always begin non-toplevel expression with '(' */ + return true; + + case exprstatetype::expect_type: + return false; + + case exprstatetype::expect_symbol: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } +#endif + void exprstate::on_def(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; @@ -233,13 +327,13 @@ namespace xo { xtag("state", *this))); } - p_stack->push_exprstate(exprstate(exprstatetype::def_0, - DefineExprAccess::make_empty())); + p_stack->push_exprstate + (exprstate::def_0(DefineExprAccess::make_empty())); /* todo: replace: * expect_symbol_or_function_signature() */ - p_stack->push_exprstate(exprstatetype::expect_symbol); + p_stack->push_exprstate(exprstate::expect_symbol()); /* keyword 'def' introduces a definition: * def pi : f64 = 3.14159265 @@ -255,6 +349,8 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); + constexpr const char * self_name = "exprstate::on_symbol"; if (!this->admits_symbol()) { @@ -265,7 +361,7 @@ namespace xo { xtag("state", *this))); } - switch(this->exs_type_) { + switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: throw std::runtime_error (tostr(self_name, @@ -284,13 +380,44 @@ namespace xo { return; case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - /* have to do pop first */ + { + /* various possibilities when looking for rhs expression: + * + * x := y // (1) + * x := f(a) // (2) + * x := f(a,b) // (3) + * + * need lookahead token following symbol to distinguish + * between (1) (symbol completes rhs expression) + * and {(2), (3)} (symbol is function call) + */ + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ +#ifdef NOT_YET + p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, + Variable::make(name, type))); +#endif + +#ifdef LATER + p_stack->pop_exprstate(); + p_stack->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); +#endif + return; + } + + case exprstatetype::expect_symbol: + { + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ p_stack->pop_exprstate(); p_stack->top_exprstate().on_symbol(tk.text(), p_stack, p_emit_expr); return; + } case exprstatetype::expect_type: { TypeDescr td = nullptr; @@ -321,20 +448,27 @@ namespace xo { return; } + case exprstatetype::expr_progress: + /* illegal input, e.g. + * foo bar + */ + assert(false); + return; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ assert(false); return; } - } + } /*on_symbol*/ void exprstate::on_typedescr(TypeDescr td, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { - switch(this->exs_type_) { + switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::def_0: case exprstatetype::def_1: @@ -366,6 +500,10 @@ namespace xo { assert(false); return; + case exprstatetype::expr_progress: + assert(false); + return; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -392,7 +530,36 @@ namespace xo { if (this->exs_type_ == exprstatetype::def_1) { this->exs_type_ = exprstatetype::def_2; - p_stack->push_exprstate(exprstatetype::expect_type); + p_stack->push_exprstate(exprstate::expect_type()); + } else { + assert(false); + } + } + + void + exprstate::on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_semicolon"; + + if (!this->admits_semicolon()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected semicolon for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expr_progress) { + rp expr = this->gen_expr_; + + p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); } else { assert(false); } @@ -417,16 +584,51 @@ namespace xo { { this->exs_type_ = exprstatetype::def_4; - p_stack->push_exprstate(exprstatetype::expect_rhs_expression); + p_stack->push_exprstate(exprstate::expect_rhs_expression()); } else { assert(false); } } +#ifdef OBSOLETE + /** + consider input: + + x := y(foo()) + + Is that an assignment x:=y followed by function call (foo()) ? + Or assignment with rhs calling a function y() with argument foo() + + policy: forbid parenthesis as beginning of a toplevel expression + **/ + + void + exprstate::on_leftparen(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + if (!this->admits_leftparen()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected leftparen '(' for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expect_rhs_expression) { + /* push lparen_0 to remember to look for subsequent rightparen */ + p_stack->push_exprstate(exprstatetype::lparen_0); + + p_stack->push_exprstate(exprstatetype::expect_rhs_expression); + } + } +#endif + void exprstate::on_f64(const token_type & tk, exprstatestack * p_stack, - rp * p_emit_expr) + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -441,11 +643,9 @@ namespace xo { } if (this->exs_type_ == exprstatetype::expect_rhs_expression) { - p_stack->pop_exprstate(); - - p_stack->top_exprstate().on_expr(Constant::make(tk.f64_value()), - p_stack, - p_emit_expr); + p_stack->push_exprstate + (exprstate::make_expr_progress + (Constant::make(tk.f64_value()))); } else { assert(false); } @@ -461,7 +661,7 @@ namespace xo { log && log(xtag("tk", tk)); log && log(xtag("state", *this)); - switch(tk.tk_type()) { + switch (tk.tk_type()) { case tokentype::tk_def: this->on_def(p_stack); @@ -503,10 +703,13 @@ namespace xo { return; case tokentype::tk_doublecolon: - case tokentype::tk_semicolon: assert(false); return; + case tokentype::tk_semicolon: + this->on_semicolon(p_stack, p_emit_expr); + return; + case tokentype::tk_singleassign: this->on_singleassign(p_stack); return; @@ -538,7 +741,13 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) { - switch(this->exs_type_) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr)); + + switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: /* toplevel expression sequence accepts an * arbitrary number of expressions. @@ -546,7 +755,7 @@ namespace xo { * parser::include_token() returns */ - *p_emit_expr = expr.get(); + *p_emit_expr = expr.promote(); return; case exprstatetype::def_0: case exprstatetype::def_1: @@ -580,7 +789,17 @@ namespace xo { return; } - case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_rhs_expression: { + + p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + + return; + } + case exprstatetype::expect_type: case exprstatetype::expect_symbol: /* unreachable @@ -588,13 +807,18 @@ namespace xo { */ assert(false); return; + case exprstatetype::expr_progress: + /* consecutive expressions isn't legal + */ + assert(false); + return; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ assert(false); return; } - } + } /*on_expr*/ void exprstate::on_symbol(const std::string & symbol_name, @@ -634,6 +858,9 @@ namespace xo { */ assert(false); return; + case exprstatetype::expr_progress: + assert(false); + return; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -645,9 +872,11 @@ namespace xo { void exprstate::print(std::ostream & os) const { os << ""; } @@ -667,6 +896,10 @@ namespace xo { void exprstatestack::push_exprstate(const exprstate & exs) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("exs", exs)); + std::size_t z = stack_.size(); stack_.resize(z+1); @@ -676,6 +909,10 @@ namespace xo { void exprstatestack::pop_exprstate() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("top.exstype", top_exprstate().exs_type())); + std::size_t z = stack_.size(); if (z > 0) @@ -714,7 +951,7 @@ namespace xo { parser::include_token(const token_type & tk) { constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(c_debug_flag), xtag("tk", tk)); if (xs_stack_.empty()) { throw std::runtime_error(tostr("parser::include_token", @@ -729,6 +966,7 @@ namespace xo { xs_stack_.top_exprstate().on_input(tk, &xs_stack_, &retval); + log && log(xtag("retval", retval)); return retval; } /*include_token*/ diff --git a/src/reader/reader.cpp b/src/reader/reader.cpp index c24ebf94..d08b9552 100644 --- a/src/reader/reader.cpp +++ b/src/reader/reader.cpp @@ -17,6 +17,9 @@ namespace xo { reader_result reader::read_expr(const span_type & input_arg, bool eof) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + span_type input = input_arg; /* input text-span consumed by this call. @@ -32,7 +35,13 @@ namespace xo { const auto & tk = sr.first; const span_type & used_span = sr.second; + log && log(xtag("used_span", used_span)); + log && log(xtag("input.pre", input)); + input = input.after_prefix(used_span); + + log && log(xtag("expr_span.pre", expr_span)); + expr_span += used_span; if (tk.is_valid()) { @@ -40,6 +49,9 @@ namespace xo { auto expr = this->parser_.include_token(tk); if (expr) { + log && log(xtag("outcome", "victory!"), + xtag("expr", expr)); + /* token completes an expression -> victory */ return reader_result(expr, expr_span); } else { @@ -48,7 +60,6 @@ namespace xo { * * input span may contain more tokens -> iterate */ - input = input.after_prefix(used_span); } } else { assert(input.empty()); @@ -76,6 +87,8 @@ namespace xo { } } + log && log(xtag("outcome", "noop")); + return reader_result(nullptr, expr_span); } diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp index aa230c7a..58910bda 100644 --- a/utest/parser.test.cpp +++ b/utest/parser.test.cpp @@ -201,7 +201,43 @@ namespace xo { cerr << "parser state after [def foo : f64 = 3.14159265]" << endl; cerr << parser << endl; - REQUIRE(r6.get() != nullptr); + REQUIRE(r6.get() == nullptr); + + /* stack should be + * + * expect_toplevel_expression_sequence + */ + CHECK(parser.stack_size() == 4); + if (parser.stack_size() > 0) + CHECK(parser.i_exstype(0) == exprstatetype::expr_progress); + if (parser.stack_size() > 1) + CHECK(parser.i_exstype(1) == exprstatetype::expect_rhs_expression); + if (parser.stack_size() > 2) + CHECK(parser.i_exstype(2) == exprstatetype::def_4); + if (parser.stack_size() > 3) + CHECK(parser.i_exstype(3) + == exprstatetype::expect_toplevel_expression_sequence); + } + + /* input: + * + * i_tc==0: + * def foo = 3.14159265 ; + * ^ ^ + * 0 1 + * + * i_tc==1: + * def foo : f64 = 3.14159265 ; + * ^ ^ + * 0 1 + */ + { + auto r7 = parser.include_token(token_type::semicolon()); + + cerr << "parser state after [def foo : f64 = 3.14159265;]" << endl; + cerr << parser << endl; + + REQUIRE(r7.get() != nullptr); CHECK(parser.stack_size() == 1); diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp index 376dbf05..eff43622 100644 --- a/utest/reader.test.cpp +++ b/utest/reader.test.cpp @@ -18,11 +18,20 @@ namespace xo { rdr.begin_translation_unit(); try { - auto rr = rdr.read_expr(reader::span_type::from_cstr("def foo : f64 = 3.14159265"), - true /*eof*/); + auto input + = reader::span_type::from_cstr("def foo : f64 = 3.14159265;"); + auto rr + = rdr.read_expr(input, true /*eof*/); REQUIRE(rr.expr_.get()); - REQUIRE(rr.rem_.empty()); + + log && log(xtag("expr", rr.expr_)); + + input = input.after_prefix(rr.rem_); + + log && log(xtag("post.input", input)); + + REQUIRE(input.empty()); } catch (std::exception & ex) { log && log(ex.what()); From 6ff2ac97b0f4764899ada6fe5416f7313eaaab72 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 7 Aug 2024 11:52:20 -0400 Subject: [PATCH 049/191] xo-reader: feat: handle parenthesized expressions --- include/xo/reader/parser.hpp | 41 +++++- src/reader/parser.cpp | 247 +++++++++++++++++++++++++++++++---- utest/reader.test.cpp | 25 +++- 3 files changed, 278 insertions(+), 35 deletions(-) diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index 2c26a8e9..715bc23f 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -25,6 +25,12 @@ namespace xo { def_2, def_3, def_4, + def_5, + + /* lparen_0: look for expression; capture + advance to lparen_1 */ + lparen_0, + /* lparen_1: expect rightparen */ + lparen_1, expect_rhs_expression, expect_symbol, @@ -46,6 +52,17 @@ namespace xo { class exprstatestack; +#ifdef NOT_YET + class exprstateaux { + public: + }; + + class lparen_xsa : public exprstateaux { + public: + private: + }; +#endif + /** state associated with a partially-parsed expression. **/ class exprstate { @@ -84,6 +101,9 @@ namespace xo { static exprstate def_0(rp def_expr) { return exprstate(exprstatetype::def_0, nullptr, def_expr); } + static exprstate lparen_0() { + return exprstate(exprstatetype::lparen_0, nullptr, nullptr); + } exprstatetype exs_type() const { return exs_type_; } @@ -99,10 +119,10 @@ namespace xo { bool admits_semicolon() const; /** true iff this parsing state admits a singleassign '=' as next token **/ bool admits_singleassign() const; -#ifdef NOT_YET /** true iff this parsing state admits a leftparen '(' as next token **/ bool admits_leftparen() const; -#endif + /** truee iff this parsing state admits a rightparen ')' as next token **/ + bool admits_rightparen() const; /** true iff this parsing state admits a 64-bit floating point literal token **/ bool admits_f64() const; @@ -134,10 +154,10 @@ namespace xo { void on_semicolon(exprstatestack * p_stack, rp * p_emit_expr); void on_singleassign(exprstatestack * p_stack); -#ifdef NOT_YET void on_leftparen(exprstatestack * p_stack, rp * p_emit_expr); -#endif + void on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr); void on_f64(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); @@ -147,7 +167,7 @@ namespace xo { * def foo : f64 = 1 ; * ^ ^ ^ ^ ^ ^ ^ ^ * | | | | | | | (done) - * | | | | | | ?? + * | | | | | | def_4:expect_rhs_expression:expr_progress * | | | | | def_4:expect_rhs_expression * | | | | def_3 * | | | def_2:expect_type @@ -173,6 +193,11 @@ namespace xo { * May be nested within a def_expr **/ rp cvt_expr_; + +#ifdef NOT_YET + /* polymorphic state here */ + std::unique_ptr state_; +#endif }; /*exprstate*/ inline std::ostream & @@ -220,6 +245,12 @@ namespace xo { std::vector stack_; }; + inline std::ostream & + operator<< (std::ostream & os, const exprstatestack & x) { + x.print(os); + return os; + } + /** schematica parser * * Examples: diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index b5b7dcd6..a03199ad 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -36,6 +36,12 @@ namespace xo { return "def_3"; case exprstatetype::def_4: return "def_4"; + case exprstatetype::def_5: + return "def_5"; + case exprstatetype::lparen_0: + return "lparen_0"; + case exprstatetype::lparen_1: + return "lparen_1"; case exprstatetype::expect_rhs_expression: return "expect_rhs_expression"; case exprstatetype::expect_symbol: @@ -62,12 +68,15 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: /* note for def_4: * rhs could certainly be a function body that contains * nested defines; but then immediately-enclosing-exprstate * would be a block */ return false; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: return false; case exprstatetype::expect_symbol: @@ -93,8 +102,11 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: return false; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: /* treat symbol as variable name */ return true; @@ -131,6 +143,9 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: /* rhs-expressions (or expressions for that matter) * may not begin with a colon @@ -160,6 +175,11 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + return false; + case exprstatetype::def_5: + return true; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: case exprstatetype::expect_symbol: case exprstatetype::expect_type: @@ -206,7 +226,10 @@ namespace xo { return true; case exprstatetype::def_4: + case exprstatetype::def_5: + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: /* rhs-expressions (or expressions for that matter) * may not begin with singleassign '=' @@ -236,6 +259,13 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: + return false; + + case exprstatetype::lparen_0: + return true; + + case exprstatetype::lparen_1: return false; case exprstatetype::expect_rhs_expression: @@ -257,7 +287,6 @@ namespace xo { return false; } -#ifdef NOT_YET bool exprstate::admits_leftparen() const { switch (exs_type_) { @@ -278,6 +307,7 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: /* input like * def foo : f64 = ( * ^ ^ ^ ^ ^ @@ -291,6 +321,12 @@ namespace xo { */ return false; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + /* unreachable */ + assert(false); + return false; + case exprstatetype::expect_rhs_expression: /* can always begin non-toplevel expression with '(' */ return true; @@ -301,6 +337,53 @@ namespace xo { case exprstatetype::expect_symbol: return false; + case exprstatetype::expr_progress: + /* todo: will parse as function call */ + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + + bool + exprstate::admits_rightparen() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + return false; + + case exprstatetype::lparen_0: + /* unreachable -- will have pushed expect_rhs_expression */ + assert(false); + return false; + + case exprstatetype::lparen_1: + return true; + + case exprstatetype::expect_rhs_expression: + return false; + + case exprstatetype::expect_type: + return false; + + case exprstatetype::expect_symbol: + return false; + + case exprstatetype::expr_progress: + /* satisfies expression form */ + return true; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -310,7 +393,6 @@ namespace xo { return false; } -#endif void exprstate::on_def(exprstatestack * p_stack) { @@ -375,10 +457,22 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: /* unreachable */ assert(false); return; + case exprstatetype::lparen_0: + /* todo: variable reference */ + assert(false); + break; + + case exprstatetype::lparen_1: + /* unreachable */ + + assert(false); + break; + case exprstatetype::expect_rhs_expression: { /* various possibilities when looking for rhs expression: @@ -468,6 +562,8 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { + /* returning type description to somethign that wants it */ + switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::def_0: @@ -487,10 +583,16 @@ namespace xo { case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: /* NOT IMPLEMENTED */ assert(false); return; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + assert(false); + return; + case exprstatetype::expect_rhs_expression: case exprstatetype::expect_type: case exprstatetype::expect_symbol: @@ -557,6 +659,30 @@ namespace xo { p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + /* control here on input like: + * (1.234; + * + * a. '(' sets up stack [lparen_0:expect_rhs_expression] + * (see exprstate::on_leftparen()) + * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] + * (see exprstate::on_f64()) + * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] + * deliver expresssion to expect_rhs_expression.on_expr() + * (see exprstate::on_expr()) + * d. expr_rhs_expression forwards expression to [lparen_0] + * e. lparen_0 advances to [lparen_1] + * f. now deliver semicolon; [lparen_1] rejects + */ + + p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); + } else if (this->exs_type_ == exprstatetype::def_5) { + rp expr = this->def_expr_; + + p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); @@ -590,25 +716,15 @@ namespace xo { } } -#ifdef OBSOLETE - /** - consider input: - - x := y(foo()) - - Is that an assignment x:=y followed by function call (foo()) ? - Or assignment with rhs calling a function y() with argument foo() - - policy: forbid parenthesis as beginning of a toplevel expression - **/ - void exprstate::on_leftparen(exprstatestack * p_stack, - rp * p_emit_expr) + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + constexpr const char * self_name = "exprstate::on_leftparen"; + if (!this->admits_leftparen()) { throw std::runtime_error(tostr(self_name, @@ -617,13 +733,64 @@ namespace xo { } if (this->exs_type_ == exprstatetype::expect_rhs_expression) { - /* push lparen_0 to remember to look for subsequent rightparen */ - p_stack->push_exprstate(exprstatetype::lparen_0); - - p_stack->push_exprstate(exprstatetype::expect_rhs_expression); + /* push lparen_0 to remember to look for subsequent rightparen. */ + p_stack->push_exprstate(exprstate::lparen_0()); + p_stack->push_exprstate(exprstate::expect_rhs_expression()); + } + } + + void + exprstate::on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_rightparen"; + + if (!this->admits_rightparen()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected rightparen ')' for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expr_progress) { + /* stack may be something like: + * + * lparen_0 + * expect_rhs_expression + * expr_progress + * <-- rightparen + * + * 1. rightparen completes expression-in-progress + * 2. rightparen must then match innermost waiting lparen_0 + */ + + /* right paren confirms stack expression */ + rp expr = this->gen_expr_; + + p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + if (p_stack->empty()) { + throw std::runtime_error(tostr(self_name, + ": expected non-empty parsing stack")); + } + + log && log(xtag("stack", *p_stack)); + + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + + /* now deliver rightparen */ + p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); + } else if (this->exs_type_ == exprstatetype::lparen_1) { + rp expr = this->gen_expr_; + + p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); } } -#endif void exprstate::on_f64(const token_type & tk, @@ -643,6 +810,10 @@ namespace xo { } if (this->exs_type_ == exprstatetype::expect_rhs_expression) { + /* e.g. + * def pi = 3.14159265; + * \---tk---/ + */ p_stack->push_exprstate (exprstate::make_expr_progress (Constant::make(tk.f64_value()))); @@ -684,8 +855,13 @@ namespace xo { return; case tokentype::tk_leftparen: + this->on_leftparen(p_stack, p_emit_expr); + return; case tokentype::tk_rightparen: + this->on_rightparen(p_stack, p_emit_expr); + return; + case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: case tokentype::tk_leftbrace: @@ -772,7 +948,7 @@ namespace xo { * Need to be able to locate variable by type * 2. if ir_type is an expression, adopt as rhs */ - rp rhs_value = expr.get(); + rp rhs_value = expr.promote(); if (this->cvt_expr_) this->cvt_expr_->assign_arg(rhs_value); @@ -781,11 +957,25 @@ namespace xo { rp def_expr = this->def_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + this->exs_type_ = exprstatetype::def_5; + return; + } - p_stack->top_exprstate().on_expr(def_expr, - p_stack, - p_emit_expr); + case exprstatetype::def_5: + assert(false); + return; + + case exprstatetype::lparen_0: { + this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ + p_stack->push_exprstate(exprstate::make_expr_progress(expr.promote())); + + return; + } + + case exprstatetype::lparen_1: { + this->gen_expr_ = expr.promote(); + + /* expect immediate incoming call, this time to on_rightparen() */ return; } @@ -846,6 +1036,13 @@ namespace xo { case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: + case exprstatetype::def_5: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: /* NOT IMPLEMENTED */ assert(false); return; diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp index eff43622..8aff0011 100644 --- a/utest/reader.test.cpp +++ b/utest/reader.test.cpp @@ -7,19 +7,34 @@ namespace xo { using xo::scm::reader; namespace ut { + namespace { + struct test_case { + const char * text_; + }; + + std::vector s_testcase_v = { + {"def foo : f64 = 3.14159265;"}, + {"def foo : f64 = (3.14159265);"} + }; + } + TEST_CASE("reader", "[reader]") { - for (std::size_t i_tc = 0; i_tc < 1; ++i_tc) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("utest", "reader")); + + 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; - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag), - xtag("utest", "reader"), xtag("i_tc", i_tc)); + scope log(XO_ENTER2(always, c_debug_flag, "reader.testcase"), + xtag("i_tc", i_tc)); rdr.begin_translation_unit(); try { auto input - = reader::span_type::from_cstr("def foo : f64 = 3.14159265;"); + = reader::span_type::from_cstr(tc.text_); auto rr = rdr.read_expr(input, true /*eof*/); From 6bc28cbfdf1bd6b208322fab8ff8f75dc7a578f9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 7 Aug 2024 16:01:05 -0400 Subject: [PATCH 050/191] xo-reader: refactor: exprstatestack holds ptrs to exprstates --- include/xo/reader/parser.hpp | 46 ++++++++++++++++++++---------------- src/reader/parser.cpp | 36 +++++++++++++++++----------- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index 715bc23f..ebdf2076 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -83,26 +83,26 @@ namespace xo { gen_expr_{std::move(candidate_expr)}, def_expr_{std::move(def_expr)} {} - static exprstate expect_toplevel_expression_sequence() { - return exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr); + static std::unique_ptr expect_toplevel_expression_sequence() { + return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr)); } - static exprstate expect_rhs_expression() { - return exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr); + static std::unique_ptr expect_rhs_expression() { + return std::make_unique(exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr)); } - static exprstate expect_symbol() { - return exprstate(exprstatetype::expect_symbol, nullptr, nullptr); + static std::unique_ptr expect_symbol() { + return std::make_unique(exprstate(exprstatetype::expect_symbol, nullptr, nullptr)); } - static exprstate expect_type() { - return exprstate(exprstatetype::expect_type, nullptr, nullptr); + static std::unique_ptr expect_type() { + return std::make_unique(exprstate(exprstatetype::expect_type, nullptr, nullptr)); } - static exprstate make_expr_progress(rp expr) { - return exprstate(exprstatetype::expr_progress, expr, nullptr); + static std::unique_ptr make_expr_progress(rp expr) { + return std::make_unique(exprstate(exprstatetype::expr_progress, expr, nullptr)); } - static exprstate def_0(rp def_expr) { - return exprstate(exprstatetype::def_0, nullptr, def_expr); + static std::unique_ptr def_0(rp def_expr) { + return std::make_unique(exprstate(exprstatetype::def_0, nullptr, def_expr)); } - static exprstate lparen_0() { - return exprstate(exprstatetype::lparen_0, nullptr, nullptr); + static std::unique_ptr lparen_0() { + return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr, nullptr)); } exprstatetype exs_type() const { return exs_type_; } @@ -217,13 +217,13 @@ namespace xo { std::size_t size() const { return stack_.size(); } exprstate & top_exprstate(); - void push_exprstate(const exprstate & exs); - void pop_exprstate(); + void push_exprstate(std::unique_ptr exs); + std::unique_ptr pop_exprstate(); /** relative to top-of-stack. * 0 -> top (last in), z-1 -> bottom (first in) **/ - exprstate & operator[](std::size_t i) { + std::unique_ptr & operator[](std::size_t i) { std::size_t z = stack_.size(); assert(i < z); @@ -231,7 +231,7 @@ namespace xo { return stack_[z - i - 1]; } - const exprstate & operator[](std::size_t i) const { + const std::unique_ptr & operator[](std::size_t i) const { std::size_t z = stack_.size(); assert(i < z); @@ -242,7 +242,7 @@ namespace xo { void print (std::ostream & os) const; private: - std::vector stack_; + std::vector> stack_; }; inline std::ostream & @@ -251,6 +251,12 @@ namespace xo { return os; } + inline std::ostream & + operator<< (std::ostream & os, const exprstatestack * x) { + x->print(os); + return os; + } + /** schematica parser * * Examples: @@ -401,7 +407,7 @@ namespace xo { std::size_t z = xs_stack_.size(); if (i < z) { - return xs_stack_[i].exs_type(); + return xs_stack_[i]->exs_type(); } /* out of bounds */ diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index a03199ad..6cef967b 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -507,7 +507,8 @@ namespace xo { /* have to do pop first, before sending symbol to * the o.g. symbol-requester */ - p_stack->pop_exprstate(); + std::unique_ptr self = p_stack->pop_exprstate(); + p_stack->top_exprstate().on_symbol(tk.text(), p_stack, p_emit_expr); return; @@ -537,7 +538,7 @@ namespace xo { xtag("typename", tk.text()))); } - p_stack->pop_exprstate(); + std::unique_ptr self = p_stack->pop_exprstate(); p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); return; } @@ -657,7 +658,7 @@ namespace xo { if (this->exs_type_ == exprstatetype::expr_progress) { rp expr = this->gen_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, @@ -681,7 +682,7 @@ namespace xo { } else if (this->exs_type_ == exprstatetype::def_5) { rp expr = this->def_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, @@ -770,14 +771,14 @@ namespace xo { /* right paren confirms stack expression */ rp expr = this->gen_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ if (p_stack->empty()) { throw std::runtime_error(tostr(self_name, ": expected non-empty parsing stack")); } - log && log(xtag("stack", *p_stack)); + log && log(xtag("stack", p_stack)); p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); @@ -786,7 +787,7 @@ namespace xo { } else if (this->exs_type_ == exprstatetype::lparen_1) { rp expr = this->gen_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); } @@ -981,7 +982,7 @@ namespace xo { case exprstatetype::expect_rhs_expression: { - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, @@ -1088,23 +1089,23 @@ namespace xo { ("parser::top_exprstate: unexpected empty stack"); } - return stack_[z-1]; + return *(stack_[z-1]); } void - exprstatestack::push_exprstate(const exprstate & exs) { + exprstatestack::push_exprstate(std::unique_ptr exs) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), - xtag("exs", exs)); + xtag("exs", *exs)); std::size_t z = stack_.size(); stack_.resize(z+1); - stack_[z] = exs; + stack_[z] = std::move(exs); } - void + std::unique_ptr exprstatestack::pop_exprstate() { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), @@ -1112,8 +1113,15 @@ namespace xo { std::size_t z = stack_.size(); - if (z > 0) + if (z > 0) { + std::unique_ptr top = std::move(stack_[z-1]); + stack_.resize(z-1); + + return top; + } else { + return nullptr; + } } void From e58f1ac62df933bb5be50b51c04a7a1ef19fc9bc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 7 Aug 2024 16:05:21 -0400 Subject: [PATCH 051/191] xo-reader: prep: virtual-ize exprstate methods --- include/xo/reader/parser.hpp | 76 +++++++++++++++++------------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index ebdf2076..587b1173 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -82,6 +82,7 @@ namespace xo { : exs_type_{exs_type}, gen_expr_{std::move(candidate_expr)}, def_expr_{std::move(def_expr)} {} + virtual ~exprstate() = default; static std::unique_ptr expect_toplevel_expression_sequence() { return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr)); @@ -110,59 +111,59 @@ namespace xo { /** true iff this parsing state admits a 'def' keyword * as next token **/ - bool admits_definition() const; + virtual bool admits_definition() const; /** true iff this parsing state admits a symbol as next token **/ - bool admits_symbol() const; + virtual bool admits_symbol() const; /** true iff this parsing state admits a colon as next token **/ - bool admits_colon() const; + virtual bool admits_colon() const; /** true iff this parsing state admits a semicolon as next token **/ - bool admits_semicolon() const; + virtual bool admits_semicolon() const; /** true iff this parsing state admits a singleassign '=' as next token **/ - bool admits_singleassign() const; + virtual bool admits_singleassign() const; /** true iff this parsing state admits a leftparen '(' as next token **/ - bool admits_leftparen() const; + virtual bool admits_leftparen() const; /** truee iff this parsing state admits a rightparen ')' as next token **/ - bool admits_rightparen() const; + virtual bool admits_rightparen() const; /** true iff this parsing state admits a 64-bit floating point literal token **/ - bool admits_f64() const; + virtual bool admits_f64() const; /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser **/ void on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); /** update exprstate in response to a successfully-parsed subexpression **/ - void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr); + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr); /** update exprstate when expecting a symbol **/ - void on_symbol(const std::string & symbol, - exprstatestack * p_stack, - rp * p_emit_expr); + virtual void on_symbol(const std::string & symbol, + exprstatestack * p_stack, + rp * p_emit_expr); /** update exprstate when expeccting a typedescr **/ - void on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr); + virtual void on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr); /** print human-readable representation on @p os **/ - void print(std::ostream & os) const; + virtual void print(std::ostream & os) const; - private: - void on_def(exprstatestack * p_stack); - void on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); - void on_colon(exprstatestack * p_stack); - void on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr); - void on_singleassign(exprstatestack * p_stack); - void on_leftparen(exprstatestack * p_stack, - rp * p_emit_expr); - void on_rightparen(exprstatestack * p_stack, - rp * p_emit_expr); - void on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + protected: + virtual void on_def(exprstatestack * p_stack); + virtual void on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_colon(exprstatestack * p_stack); + virtual void on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_singleassign(exprstatestack * p_stack); + virtual void on_leftparen(exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); - private: + protected: /** * def foo : f64 = 1 ; * ^ ^ ^ ^ ^ ^ ^ ^ @@ -193,11 +194,6 @@ namespace xo { * May be nested within a def_expr **/ rp cvt_expr_; - -#ifdef NOT_YET - /* polymorphic state here */ - std::unique_ptr state_; -#endif }; /*exprstate*/ inline std::ostream & From 739d8efe8276d1768196b24dd59e447dd321542b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 7 Aug 2024 16:08:03 -0400 Subject: [PATCH 052/191] xo-reader: reorg: exprstate to own .hpp file --- include/xo/reader/exprstate.hpp | 259 ++++++++++++++++++++++++++++++++ include/xo/reader/parser.hpp | 245 +----------------------------- 2 files changed, 260 insertions(+), 244 deletions(-) create mode 100644 include/xo/reader/exprstate.hpp diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp new file mode 100644 index 00000000..0a59c233 --- /dev/null +++ b/include/xo/reader/exprstate.hpp @@ -0,0 +1,259 @@ +/** @file exprstate.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "xo/expression/Expression.hpp" +#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/ConvertExpr.hpp" +#include "xo/tokenizer/token.hpp" +#include +//#include + +namespace xo { + namespace scm { + enum class exprstatetype { + invalid = -1, + + /** toplevel of some translation unit **/ + expect_toplevel_expression_sequence, + + def_0, + def_1, + def_2, + def_3, + def_4, + def_5, + + /* lparen_0: look for expression; capture + advance to lparen_1 */ + lparen_0, + /* lparen_1: expect rightparen */ + lparen_1, + + expect_rhs_expression, + expect_symbol, + expect_type, + + expr_progress, + + n_exprstatetype + }; + + extern const char * + exprstatetype_descr(exprstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, exprstatetype x) { + os << exprstatetype_descr(x); + return os; + } + + class exprstatestack; + +#ifdef NOT_YET + class exprstateaux { + public: + }; + + class lparen_xsa : public exprstateaux { + public: + private: + }; +#endif + + /** state associated with a partially-parsed expression. + **/ + class exprstate { + public: + using Expression = xo::ast::Expression; + using DefineExprAccess = xo::ast::DefineExprAccess; + using ConvertExprAccess = xo::ast::ConvertExprAccess; + using exprtype = xo::ast::exprtype; + using token_type = token; + using TypeDescr = xo::reflect::TypeDescr; + + public: + exprstate() = default; + exprstate(exprstatetype exs_type, + rp candidate_expr, + rp def_expr) + : exs_type_{exs_type}, + gen_expr_{std::move(candidate_expr)}, + def_expr_{std::move(def_expr)} {} + virtual ~exprstate() = default; + + static std::unique_ptr expect_toplevel_expression_sequence() { + return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr)); + } + static std::unique_ptr expect_rhs_expression() { + return std::make_unique(exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr)); + } + static std::unique_ptr expect_symbol() { + return std::make_unique(exprstate(exprstatetype::expect_symbol, nullptr, nullptr)); + } + static std::unique_ptr expect_type() { + return std::make_unique(exprstate(exprstatetype::expect_type, nullptr, nullptr)); + } + static std::unique_ptr make_expr_progress(rp expr) { + return std::make_unique(exprstate(exprstatetype::expr_progress, expr, nullptr)); + } + static std::unique_ptr def_0(rp def_expr) { + return std::make_unique(exprstate(exprstatetype::def_0, nullptr, def_expr)); + } + static std::unique_ptr lparen_0() { + return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr, nullptr)); + } + + exprstatetype exs_type() const { return exs_type_; } + + /** true iff this parsing state admits a 'def' keyword + * as next token + **/ + virtual bool admits_definition() const; + /** true iff this parsing state admits a symbol as next token **/ + virtual bool admits_symbol() const; + /** true iff this parsing state admits a colon as next token **/ + virtual bool admits_colon() const; + /** true iff this parsing state admits a semicolon as next token **/ + virtual bool admits_semicolon() const; + /** true iff this parsing state admits a singleassign '=' as next token **/ + virtual bool admits_singleassign() const; + /** true iff this parsing state admits a leftparen '(' as next token **/ + virtual bool admits_leftparen() const; + /** truee iff this parsing state admits a rightparen ')' as next token **/ + virtual bool admits_rightparen() const; + /** true iff this parsing state admits a 64-bit floating point literal token **/ + virtual bool admits_f64() const; + + /** update exprstate in response to incoming token @p tk, + * forward instructions to parent parser + **/ + void on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate in response to a successfully-parsed subexpression **/ + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr); + /** update exprstate when expecting a symbol **/ + virtual void on_symbol(const std::string & symbol, + exprstatestack * p_stack, + rp * p_emit_expr); + /** update exprstate when expeccting a typedescr **/ + virtual void on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr); + /** print human-readable representation on @p os **/ + virtual void print(std::ostream & os) const; + + protected: + virtual void on_def(exprstatestack * p_stack); + virtual void on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_colon(exprstatestack * p_stack); + virtual void on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_singleassign(exprstatestack * p_stack); + virtual void on_leftparen(exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr); + virtual void on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); + + protected: + /** + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | (done) + * | | | | | | def_4:expect_rhs_expression:expr_progress + * | | | | | def_4:expect_rhs_expression + * | | | | def_3 + * | | | def_2:expect_type + * | | def_1 + * | def_0:expect_symbol + * expect_toplevel_expression_sequence + * + * def_0:expect_symbol: got 'def' keyword, symbol to follow + * def_1: got symbol name + * def_2:expect_symbol got (optional) colon, type name to follow + * def_3: got symbol type + * def_4:expect_rhs_expression got (optional) equal sign, value to follow + * (done): definition complete, pop exprstate from stack + * + **/ + exprstatetype exs_type_; + + /** generic expression **/ + rp gen_expr_; + /** scaffold a define-expression here **/ + rp def_expr_; + /** scafford a convert-expression here. + * May be nested within a def_expr + **/ + rp cvt_expr_; + }; /*exprstate*/ + + inline std::ostream & + operator<< (std::ostream & os, const exprstate & x) { + x.print(os); + return os; + } + + /** @class exprstatestack + * @brief A stack of exprstate objects + **/ + class exprstatestack { + public: + exprstatestack() {} + + bool empty() const { return stack_.empty(); } + std::size_t size() const { return stack_.size(); } + + exprstate & top_exprstate(); + void push_exprstate(std::unique_ptr exs); + std::unique_ptr pop_exprstate(); + + /** relative to top-of-stack. + * 0 -> top (last in), z-1 -> bottom (first in) + **/ + std::unique_ptr & operator[](std::size_t i) { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + const std::unique_ptr & operator[](std::size_t i) const { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + void print (std::ostream & os) const; + + private: + std::vector> stack_; + }; + + inline std::ostream & + operator<< (std::ostream & os, const exprstatestack & x) { + x.print(os); + return os; + } + + inline std::ostream & + operator<< (std::ostream & os, const exprstatestack * x) { + x->print(os); + return os; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end exprstate.hpp **/ diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index 587b1173..fb760081 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -5,254 +5,11 @@ #pragma once -#include "xo/expression/Expression.hpp" -#include "xo/expression/DefineExpr.hpp" -#include "xo/expression/ConvertExpr.hpp" -#include "xo/tokenizer/token.hpp" -#include +#include "exprstate.hpp" #include namespace xo { namespace scm { - enum class exprstatetype { - invalid = -1, - - /** toplevel of some translation unit **/ - expect_toplevel_expression_sequence, - - def_0, - def_1, - def_2, - def_3, - def_4, - def_5, - - /* lparen_0: look for expression; capture + advance to lparen_1 */ - lparen_0, - /* lparen_1: expect rightparen */ - lparen_1, - - expect_rhs_expression, - expect_symbol, - expect_type, - - expr_progress, - - n_exprstatetype - }; - - extern const char * - exprstatetype_descr(exprstatetype x); - - inline std::ostream & - operator<< (std::ostream & os, exprstatetype x) { - os << exprstatetype_descr(x); - return os; - } - - class exprstatestack; - -#ifdef NOT_YET - class exprstateaux { - public: - }; - - class lparen_xsa : public exprstateaux { - public: - private: - }; -#endif - - /** state associated with a partially-parsed expression. - **/ - class exprstate { - public: - using Expression = xo::ast::Expression; - using DefineExprAccess = xo::ast::DefineExprAccess; - using ConvertExprAccess = xo::ast::ConvertExprAccess; - using exprtype = xo::ast::exprtype; - using token_type = token; - using TypeDescr = xo::reflect::TypeDescr; - - public: - exprstate() = default; - exprstate(exprstatetype exs_type, - rp candidate_expr, - rp def_expr) - : exs_type_{exs_type}, - gen_expr_{std::move(candidate_expr)}, - def_expr_{std::move(def_expr)} {} - virtual ~exprstate() = default; - - static std::unique_ptr expect_toplevel_expression_sequence() { - return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr)); - } - static std::unique_ptr expect_rhs_expression() { - return std::make_unique(exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr)); - } - static std::unique_ptr expect_symbol() { - return std::make_unique(exprstate(exprstatetype::expect_symbol, nullptr, nullptr)); - } - static std::unique_ptr expect_type() { - return std::make_unique(exprstate(exprstatetype::expect_type, nullptr, nullptr)); - } - static std::unique_ptr make_expr_progress(rp expr) { - return std::make_unique(exprstate(exprstatetype::expr_progress, expr, nullptr)); - } - static std::unique_ptr def_0(rp def_expr) { - return std::make_unique(exprstate(exprstatetype::def_0, nullptr, def_expr)); - } - static std::unique_ptr lparen_0() { - return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr, nullptr)); - } - - exprstatetype exs_type() const { return exs_type_; } - - /** true iff this parsing state admits a 'def' keyword - * as next token - **/ - virtual bool admits_definition() const; - /** true iff this parsing state admits a symbol as next token **/ - virtual bool admits_symbol() const; - /** true iff this parsing state admits a colon as next token **/ - virtual bool admits_colon() const; - /** true iff this parsing state admits a semicolon as next token **/ - virtual bool admits_semicolon() const; - /** true iff this parsing state admits a singleassign '=' as next token **/ - virtual bool admits_singleassign() const; - /** true iff this parsing state admits a leftparen '(' as next token **/ - virtual bool admits_leftparen() const; - /** truee iff this parsing state admits a rightparen ')' as next token **/ - virtual bool admits_rightparen() const; - /** true iff this parsing state admits a 64-bit floating point literal token **/ - virtual bool admits_f64() const; - - /** update exprstate in response to incoming token @p tk, - * forward instructions to parent parser - **/ - void on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); - /** update exprstate in response to a successfully-parsed subexpression **/ - virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr); - /** update exprstate when expecting a symbol **/ - virtual void on_symbol(const std::string & symbol, - exprstatestack * p_stack, - rp * p_emit_expr); - /** update exprstate when expeccting a typedescr **/ - virtual void on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr); - /** print human-readable representation on @p os **/ - virtual void print(std::ostream & os) const; - - protected: - virtual void on_def(exprstatestack * p_stack); - virtual void on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); - virtual void on_colon(exprstatestack * p_stack); - virtual void on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr); - virtual void on_singleassign(exprstatestack * p_stack); - virtual void on_leftparen(exprstatestack * p_stack, - rp * p_emit_expr); - virtual void on_rightparen(exprstatestack * p_stack, - rp * p_emit_expr); - virtual void on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); - - protected: - /** - * def foo : f64 = 1 ; - * ^ ^ ^ ^ ^ ^ ^ ^ - * | | | | | | | (done) - * | | | | | | def_4:expect_rhs_expression:expr_progress - * | | | | | def_4:expect_rhs_expression - * | | | | def_3 - * | | | def_2:expect_type - * | | def_1 - * | def_0:expect_symbol - * expect_toplevel_expression_sequence - * - * def_0:expect_symbol: got 'def' keyword, symbol to follow - * def_1: got symbol name - * def_2:expect_symbol got (optional) colon, type name to follow - * def_3: got symbol type - * def_4:expect_rhs_expression got (optional) equal sign, value to follow - * (done): definition complete, pop exprstate from stack - * - **/ - exprstatetype exs_type_; - - /** generic expression **/ - rp gen_expr_; - /** scaffold a define-expression here **/ - rp def_expr_; - /** scafford a convert-expression here. - * May be nested within a def_expr - **/ - rp cvt_expr_; - }; /*exprstate*/ - - inline std::ostream & - operator<< (std::ostream & os, const exprstate & x) { - x.print(os); - return os; - } - - /** @class exprstatestack - * @brief A stack of exprstate objects - **/ - class exprstatestack { - public: - exprstatestack() {} - - bool empty() const { return stack_.empty(); } - std::size_t size() const { return stack_.size(); } - - exprstate & top_exprstate(); - void push_exprstate(std::unique_ptr exs); - std::unique_ptr pop_exprstate(); - - /** relative to top-of-stack. - * 0 -> top (last in), z-1 -> bottom (first in) - **/ - std::unique_ptr & operator[](std::size_t i) { - std::size_t z = stack_.size(); - - assert(i < z); - - return stack_[z - i - 1]; - } - - const std::unique_ptr & operator[](std::size_t i) const { - std::size_t z = stack_.size(); - - assert(i < z); - - return stack_[z - i - 1]; - } - - void print (std::ostream & os) const; - - private: - std::vector> stack_; - }; - - inline std::ostream & - operator<< (std::ostream & os, const exprstatestack & x) { - x.print(os); - return os; - } - - inline std::ostream & - operator<< (std::ostream & os, const exprstatestack * x) { - x->print(os); - return os; - } - /** schematica parser * * Examples: From c4b58bb29889c23aeea2aaee5cb157bfafdebdf7 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 7 Aug 2024 16:28:39 -0400 Subject: [PATCH 053/191] xo-reader: refactor: move def on_expr() to define_xs subtype --- include/xo/reader/define_xs.hpp | 52 ++++++++++++++++++++++++ include/xo/reader/exprstate.hpp | 24 ----------- src/reader/CMakeLists.txt | 4 +- src/reader/define_xs.cpp | 71 +++++++++++++++++++++++++++++++++ src/reader/exprstate.cpp | 15 +++++++ src/reader/parser.cpp | 29 ++------------ 6 files changed, 145 insertions(+), 50 deletions(-) create mode 100644 include/xo/reader/define_xs.hpp create mode 100644 src/reader/define_xs.cpp create mode 100644 src/reader/exprstate.cpp diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp new file mode 100644 index 00000000..43cd445c --- /dev/null +++ b/include/xo/reader/define_xs.hpp @@ -0,0 +1,52 @@ +/** @file define_xs.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "exprstate.hpp" +//#include + +namespace xo { + namespace scm { + /** @class define_xs + * @brief state to provide parsing of a define-expression + **/ + class define_xs : public exprstate { + public: + define_xs(rp def_expr); + virtual ~define_xs() = default; + + static std::unique_ptr def_0(rp def_expr); + + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) override; + private: + /** + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | (done) + * | | | | | | def_4:expect_rhs_expression:expr_progress + * | | | | | def_4:expect_rhs_expression + * | | | | def_3 + * | | | def_2:expect_type + * | | def_1 + * | def_0:expect_symbol + * expect_toplevel_expression_sequence + * + * def_0:expect_symbol: got 'def' keyword, symbol to follow + * def_1: got symbol name + * def_2:expect_symbol got (optional) colon, type name to follow + * def_3: got symbol type + * def_4:expect_rhs_expression got (optional) equal sign, value to follow + * (done): definition complete, pop exprstate from stack + * + **/ + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end define_xs.hpp **/ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 0a59c233..461ecddf 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -99,9 +99,6 @@ namespace xo { static std::unique_ptr make_expr_progress(rp expr) { return std::make_unique(exprstate(exprstatetype::expr_progress, expr, nullptr)); } - static std::unique_ptr def_0(rp def_expr) { - return std::make_unique(exprstate(exprstatetype::def_0, nullptr, def_expr)); - } static std::unique_ptr lparen_0() { return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr, nullptr)); } @@ -164,26 +161,6 @@ namespace xo { rp * p_emit_expr); protected: - /** - * def foo : f64 = 1 ; - * ^ ^ ^ ^ ^ ^ ^ ^ - * | | | | | | | (done) - * | | | | | | def_4:expect_rhs_expression:expr_progress - * | | | | | def_4:expect_rhs_expression - * | | | | def_3 - * | | | def_2:expect_type - * | | def_1 - * | def_0:expect_symbol - * expect_toplevel_expression_sequence - * - * def_0:expect_symbol: got 'def' keyword, symbol to follow - * def_1: got symbol name - * def_2:expect_symbol got (optional) colon, type name to follow - * def_3: got symbol type - * def_4:expect_rhs_expression got (optional) equal sign, value to follow - * (done): definition complete, pop exprstate from stack - * - **/ exprstatetype exs_type_; /** generic expression **/ @@ -255,5 +232,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ - /** end exprstate.hpp **/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 687ae4e1..8896040e 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -3,7 +3,9 @@ set(SELF_LIB xo_reader) set(SELF_SRCS parser.cpp - reader.cpp) + reader.cpp + exprstate.cpp + define_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp new file mode 100644 index 00000000..57526378 --- /dev/null +++ b/src/reader/define_xs.cpp @@ -0,0 +1,71 @@ +/* @file define_xs.cpp */ + +#include "define_xs.hpp" + +namespace xo { + namespace scm { + define_xs::define_xs(rp def_expr) + : exprstate(exprstatetype::def_0, + nullptr /*gen_expr*/, + def_expr) + {} + + void + define_xs::on_expr(ref::brw expr, + exprstatestack * /* p_stack */, + rp * /* p_emit_expr */) + { + switch (this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + assert(false); + return; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + /* NOT IMPLEMENTED */ + assert(false); + return; + case exprstatetype::def_4: { + /* have all the ingredients to create an expression + * representing a definition + * + * 1. if ir_type is a symbol, interpret as variable name. + * Need to be able to locate variable by type + * 2. if ir_type is an expression, adopt as rhs + */ + rp rhs_value = expr.promote(); + + if (this->cvt_expr_) + this->cvt_expr_->assign_arg(rhs_value); + else + this->def_expr_->assign_rhs(rhs_value);; + + rp def_expr = this->def_expr_; + + this->exs_type_ = exprstatetype::def_5; + return; + } + + case exprstatetype::def_5: + assert(false); + return; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end define_xs.cpp */ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp new file mode 100644 index 00000000..c6b2ef36 --- /dev/null +++ b/src/reader/exprstate.cpp @@ -0,0 +1,15 @@ +/* @file exprstate.cpp */ + +#include "exprstate.hpp" +#include "define_xs.hpp" + +namespace xo { + namespace scm { + std::unique_ptr + define_xs::def_0(rp def_expr) { + return std::make_unique(define_xs(def_expr)); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end exprstate.cpp */ diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 6cef967b..63d19f93 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -4,6 +4,7 @@ */ #include "parser.hpp" +#include "define_xs.hpp" #include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" #include "xo/expression/ConvertExpr.hpp" @@ -410,7 +411,7 @@ namespace xo { } p_stack->push_exprstate - (exprstate::def_0(DefineExprAccess::make_empty())); + (define_xs::def_0(DefineExprAccess::make_empty())); /* todo: replace: * expect_symbol_or_function_signature() @@ -938,31 +939,9 @@ namespace xo { case exprstatetype::def_1: case exprstatetype::def_2: case exprstatetype::def_3: - /* NOT IMPLEMENTED */ - assert(false); - return; - case exprstatetype::def_4: { - /* have all the ingredients to create an expression - * representing a definition - * - * 1. if ir_type is a symbol, interpret as variable name. - * Need to be able to locate variable by type - * 2. if ir_type is an expression, adopt as rhs - */ - rp rhs_value = expr.promote(); - - if (this->cvt_expr_) - this->cvt_expr_->assign_arg(rhs_value); - else - this->def_expr_->assign_rhs(rhs_value);; - - rp def_expr = this->def_expr_; - - this->exs_type_ = exprstatetype::def_5; - return; - } - + case exprstatetype::def_4: case exprstatetype::def_5: + /* unreachable. see define_xs::on_expr() */ assert(false); return; From 3a1db8ca022c109af74fe5754675ead482f3dcd7 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 7 Aug 2024 16:32:32 -0400 Subject: [PATCH 054/191] xo-reader: refactor: move defexpr on_symbol to dedicated define_xs --- include/xo/reader/define_xs.hpp | 4 ++++ src/reader/define_xs.cpp | 39 +++++++++++++++++++++++++++++++++ src/reader/parser.cpp | 9 ++------ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 43cd445c..c872a58b 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -23,6 +23,10 @@ namespace xo { virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; + virtual void on_symbol(const std::string & symbol_name, + exprstatestack * p_stack, + rp * p_emit_expr) override; + private: /** * def foo : f64 = 1 ; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 57526378..09148c9e 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -65,6 +65,45 @@ namespace xo { return; } } + + void + define_xs::on_symbol(const std::string & symbol_name, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + switch (this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return; + case exprstatetype::def_0: + this->exs_type_ = exprstatetype::def_1; + this->def_expr_->assign_lhs_name(symbol_name); + //this->def_lhs_symbol_ = symbol_name; + + return; + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 63d19f93..8e0df1ef 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -991,7 +991,7 @@ namespace xo { } /*on_expr*/ void - exprstate::on_symbol(const std::string & symbol_name, + exprstate::on_symbol(const std::string & /*symbol_name*/, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -1007,17 +1007,12 @@ namespace xo { assert(false); return; case exprstatetype::def_0: - this->exs_type_ = exprstatetype::def_1; - this->def_expr_->assign_lhs_name(symbol_name); - //this->def_lhs_symbol_ = symbol_name; - - return; case exprstatetype::def_1: case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: case exprstatetype::def_5: - /* NOT IMPLEMENTED */ + /* unreachable */ assert(false); return; From 3f949dd3e4eea3492b21090a35eeed513688db95 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 7 Aug 2024 16:36:46 -0400 Subject: [PATCH 055/191] xo-reader: refactor: specialize admits_definition() for define_xs --- include/xo/reader/define_xs.hpp | 2 ++ src/reader/define_xs.cpp | 37 +++++++++++++++++++++++++++++++++ src/reader/parser.cpp | 6 +----- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index c872a58b..41bf90d4 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -20,6 +20,8 @@ namespace xo { static std::unique_ptr def_0(rp def_expr); + virtual bool admits_definition() const override; + // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 09148c9e..5da374ad 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -10,6 +10,43 @@ namespace xo { def_expr) {} + bool + define_xs::admits_definition() const + { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* note for def_4: + * rhs could certainly be a function body that contains + * nested defines; but then immediately-enclosing-exprstate + * would be a block + */ + return false; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + void define_xs::on_expr(ref::brw expr, exprstatestack * /* p_stack */, diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 8e0df1ef..e5700bdd 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -70,11 +70,7 @@ namespace xo { case exprstatetype::def_3: case exprstatetype::def_4: case exprstatetype::def_5: - /* note for def_4: - * rhs could certainly be a function body that contains - * nested defines; but then immediately-enclosing-exprstate - * would be a block - */ + /* unreachable */ return false; case exprstatetype::lparen_0: case exprstatetype::lparen_1: From 8b77fa9e99625e27d9ca1a61931dc9c350e31187 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 11:31:52 -0400 Subject: [PATCH 056/191] xo-reader: refactor: mv admits_symbol de- expr work -> define_xs --- include/xo/reader/define_xs.hpp | 1 + src/reader/define_xs.cpp | 32 ++++++++++++++++++++++++++++++++ src/reader/parser.cpp | 4 ++++ 3 files changed, 37 insertions(+) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 41bf90d4..162bd62a 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -21,6 +21,7 @@ namespace xo { static std::unique_ptr def_0(rp def_expr); virtual bool admits_definition() const override; + virtual bool admits_symbol() const override; // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 5da374ad..6fa1bc45 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -47,6 +47,38 @@ namespace xo { return false; } + bool + define_xs::admits_symbol() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + return false; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + void define_xs::on_expr(ref::brw expr, exprstatestack * /* p_stack */, diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index e5700bdd..f503932c 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -94,12 +94,16 @@ namespace xo { exprstate::admits_symbol() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: + return false; + case exprstatetype::def_0: case exprstatetype::def_1: case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: case exprstatetype::def_5: + /* unreachable */ + assert(false); return false; case exprstatetype::lparen_0: From ca33241ce209f2fd63b39ea14ea2fa62a49f4d6f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 11:40:51 -0400 Subject: [PATCH 057/191] xo-reader: refactor: mv admits_colon -> define_xs --- include/xo/reader/define_xs.hpp | 2 ++ src/reader/define_xs.cpp | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 162bd62a..b41454e3 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -22,6 +22,8 @@ namespace xo { virtual bool admits_definition() const override; virtual bool admits_symbol() const override; + virtual bool admits_colon() const override; + // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 6fa1bc45..5c760e5e 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -79,6 +79,42 @@ namespace xo { return false; } + bool + define_xs::admits_colon() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::def_0: + return false; + + case exprstatetype::def_1: + return true; + + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + return false; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + void define_xs::on_expr(ref::brw expr, exprstatestack * /* p_stack */, From 452c224110806c04f894c6be73cc4f0ba4c5731b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 11:41:27 -0400 Subject: [PATCH 058/191] xo-reader: refactor: mv admits_semicolon for defexpr -> define_xs --- include/xo/reader/define_xs.hpp | 1 + src/reader/define_xs.cpp | 31 +++++++++++++++++++++++++++++++ src/reader/parser.cpp | 1 + 3 files changed, 33 insertions(+) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index b41454e3..4cd4a297 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -23,6 +23,7 @@ namespace xo { virtual bool admits_definition() const override; virtual bool admits_symbol() const override; virtual bool admits_colon() const override; + virtual bool admits_semicolon() const override; // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 5c760e5e..85efffea 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -115,6 +115,37 @@ namespace xo { return false; } + bool + define_xs::admits_semicolon() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return false; + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + return false; + case exprstatetype::def_5: + return true; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + void define_xs::on_expr(ref::brw expr, exprstatestack * /* p_stack */, diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index f503932c..db116b48 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -71,6 +71,7 @@ namespace xo { case exprstatetype::def_4: case exprstatetype::def_5: /* unreachable */ + assert(false); return false; case exprstatetype::lparen_0: case exprstatetype::lparen_1: From 762aa0016a1daa5d2ac9d6bccb912741151ab012 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 12:16:59 -0400 Subject: [PATCH 059/191] xo-reader: refactor: mv admits_singleassign -> define_xs --- include/xo/reader/define_xs.hpp | 1 + src/reader/define_xs.cpp | 54 +++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 4cd4a297..2f3e0879 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -24,6 +24,7 @@ namespace xo { virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; + virtual bool admits_singleassign() const override; // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 85efffea..449eaeb6 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -146,6 +146,60 @@ namespace xo { return false; } + bool + define_xs::admits_singleassign() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return false; + + /* + * def foo = 1 ; + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ + * | | | | | | (done) + * | | | | | def_4:expect_rhs_expression + * | | | | def_3 + * | | | def_2:expect_type + * | | def_1 + * | def_0:expect_symbol + * expect_toplevel_expression_sequence + * + * note that we skip from def_1 -> def_4 if '=' instead of ':' + */ + case exprstatetype::def_0: + return false; + + case exprstatetype::def_1: + return true; + + case exprstatetype::def_2: + return false; + + case exprstatetype::def_3: + return true; + + case exprstatetype::def_4: + case exprstatetype::def_5: + return false; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + /* unreachable */ + assert(false); + return false; + } + + return false; + } void define_xs::on_expr(ref::brw expr, exprstatestack * /* p_stack */, From e544491ef7241d8e757da72fbae09e74b521b538 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 12:54:50 -0400 Subject: [PATCH 060/191] xo-reader: refactor: mv admits_xxxparen -> define_xs --- include/xo/reader/define_xs.hpp | 2 + src/reader/define_xs.cpp | 76 +++++++++++++++++++++++++++++++++ src/reader/parser.cpp | 17 +++----- 3 files changed, 84 insertions(+), 11 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 2f3e0879..8b9d1512 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -25,6 +25,8 @@ namespace xo { virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; + virtual bool admits_leftparen() const override; + virtual bool admits_rightparen() const override; // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 449eaeb6..239abb0f 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -200,6 +200,82 @@ namespace xo { return false; } + + bool + define_xs::admits_leftparen() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* input like + * def foo : f64 = ( + * ^ ^ ^ ^ ^ + * | | | | def_4 + * | | | def_3 + * | | def_2 + * | def_1 + * def_0 + * + * not allowed or relies on pushing another state + */ + return false; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + + bool + define_xs::admits_rightparen() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + return false; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + void define_xs::on_expr(ref::brw expr, exprstatestack * /* p_stack */, diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index db116b48..d777fa6b 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -310,17 +310,8 @@ namespace xo { case exprstatetype::def_3: case exprstatetype::def_4: case exprstatetype::def_5: - /* input like - * def foo : f64 = ( - * ^ ^ ^ ^ ^ - * | | | | def_4 - * | | | def_3 - * | | def_2 - * | def_1 - * def_0 - * - * not allowed or relies on pushing another state - */ + /* unreachable */ + assert(false); return false; case exprstatetype::lparen_0: @@ -357,12 +348,16 @@ namespace xo { exprstate::admits_rightparen() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: + return false; + case exprstatetype::def_0: case exprstatetype::def_1: case exprstatetype::def_2: case exprstatetype::def_3: case exprstatetype::def_4: case exprstatetype::def_5: + /* unreachable */ + assert(false); return false; case exprstatetype::lparen_0: From 190a0fa7199f039fa5c7bc904cab99efa4403dbb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 13:18:58 -0400 Subject: [PATCH 061/191] xo-reader: tidy: mv exprstate impl -> exprstate.cpp --- src/reader/define_xs.cpp | 5 + src/reader/exprstate.cpp | 1098 +++++++++++++++++++++++++++++++++++++- src/reader/parser.cpp | 1093 +------------------------------------ 3 files changed, 1102 insertions(+), 1094 deletions(-) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 239abb0f..e4df8cea 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -4,6 +4,11 @@ namespace xo { namespace scm { + std::unique_ptr + define_xs::def_0(rp def_expr) { + return std::make_unique(define_xs(def_expr)); + } + define_xs::define_xs(rp def_expr) : exprstate(exprstatetype::def_0, nullptr /*gen_expr*/, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index c6b2ef36..f58be6bd 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -2,12 +2,1104 @@ #include "exprstate.hpp" #include "define_xs.hpp" +//#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/Constant.hpp" +//#include "xo/expression/ConvertExpr.hpp" +#include "xo/reflect/Reflect.hpp" namespace xo { + using xo::ast::Constant; + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; + namespace scm { - std::unique_ptr - define_xs::def_0(rp def_expr) { - return std::make_unique(define_xs(def_expr)); + const char * + exprstatetype_descr(exprstatetype x) { + switch (x) { + case exprstatetype::invalid: + return "?invalid"; + case exprstatetype::expect_toplevel_expression_sequence: + return "expect_toplevel_expression_sequence"; + case exprstatetype::def_0: + return "def_0"; + case exprstatetype::def_1: + return "def_1"; + case exprstatetype::def_2: + return "def_2"; + case exprstatetype::def_3: + return "def_3"; + case exprstatetype::def_4: + return "def_4"; + case exprstatetype::def_5: + return "def_5"; + case exprstatetype::lparen_0: + return "lparen_0"; + case exprstatetype::lparen_1: + return "lparen_1"; + case exprstatetype::expect_rhs_expression: + return "expect_rhs_expression"; + case exprstatetype::expect_symbol: + return "expect_symbol"; + case exprstatetype::expect_type: + return "expect_type"; + case exprstatetype::expr_progress: + return "expr_progress"; + case exprstatetype::n_exprstatetype: + break; + } + + return "???"; + } + + bool + exprstate::admits_definition() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + return true; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* unreachable */ + assert(false); + return false; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + return false; + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + return false; + case exprstatetype::expr_progress: + return false; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + + return false; + } + + bool + exprstate::admits_symbol() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + /* treat symbol as variable name */ + return true; + + case exprstatetype::expect_symbol: + return true; + + case exprstatetype::expect_type: + /* treat symbol as typename */ + return true; + + case exprstatetype::expr_progress: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + + return false; + } + + bool + exprstate::admits_colon() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + return false; + + case exprstatetype::def_1: + return true; + + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + /* rhs-expressions (or expressions for that matter) + * may not begin with a colon + */ + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + return false; + + case exprstatetype::expr_progress: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + + return false; + } + + bool + exprstate::admits_semicolon() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + return false; + case exprstatetype::def_5: + return true; + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + return false; + case exprstatetype::expr_progress: + return true; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + return false; + } + + return false; + } + + bool + exprstate::admits_singleassign() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + + /* + * def foo = 1 ; + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ + * | | | | | | (done) + * | | | | | def_4:expect_rhs_expression + * | | | | def_3 + * | | | def_2:expect_type + * | | def_1 + * | def_0:expect_symbol + * expect_toplevel_expression_sequence + * + * note that we skip from def_1 -> def_4 if '=' instead of ':' + */ + case exprstatetype::def_0: + return false; + + case exprstatetype::def_1: + return true; + + case exprstatetype::def_2: + return false; + + case exprstatetype::def_3: + return true; + + case exprstatetype::def_4: + case exprstatetype::def_5: + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + /* rhs-expressions (or expressions for that matter) + * may not begin with singleassign '=' + */ + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + return false; + + case exprstatetype::expr_progress: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + + return false; + } + + bool + exprstate::admits_f64() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + return false; + + case exprstatetype::lparen_0: + return true; + + case exprstatetype::lparen_1: + return false; + + case exprstatetype::expect_rhs_expression: + return true; + + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + return false; + + case exprstatetype::expr_progress: + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + + return false; + } + + bool + exprstate::admits_leftparen() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* input like + * (function(blah...)) + * not allowed at toplevel; + * creates ambiguity e.g. consider + * x := foo + * (bar) + * + * is rhs 'foo' or 'foo(bar)' + */ + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::expect_rhs_expression: + /* can always begin non-toplevel expression with '(' */ + return true; + + case exprstatetype::expect_type: + return false; + + case exprstatetype::expect_symbol: + return false; + + case exprstatetype::expr_progress: + /* todo: will parse as function call */ + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + + bool + exprstate::admits_rightparen() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + return false; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::lparen_0: + /* unreachable -- will have pushed expect_rhs_expression */ + assert(false); + return false; + + case exprstatetype::lparen_1: + return true; + + case exprstatetype::expect_rhs_expression: + return false; + + case exprstatetype::expect_type: + return false; + + case exprstatetype::expect_symbol: + return false; + + case exprstatetype::expr_progress: + /* satisfies expression form */ + return true; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + + void + exprstate::on_def(exprstatestack * p_stack) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_def"; + + /* lots of illegal states */ + if (!this->admits_definition()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected keyword 'def' for parsing state", + xtag("state", *this))); + } + + p_stack->push_exprstate + (define_xs::def_0(DefineExprAccess::make_empty())); + + /* todo: replace: + * expect_symbol_or_function_signature() + */ + p_stack->push_exprstate(exprstate::expect_symbol()); + + /* keyword 'def' introduces a definition: + * def pi : f64 = 3.14159265 + * def sq(x : f64) -> f64 { (x * x) } + */ + } + + void + exprstate::on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); + + constexpr const char * self_name = "exprstate::on_symbol"; + + if (!this->admits_symbol()) { + throw std::runtime_error + (tostr(self_name, + ": unexpected symbol-token for parsing state", + xtag("symbol", tk), + xtag("state", *this))); + } + + switch (this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + throw std::runtime_error + (tostr(self_name, + ": unexpected symbol-token at top-level", + " (expecting decl|def)", + xtag("symbol", tk))); + break; + + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* unreachable */ + assert(false); + return; + + case exprstatetype::lparen_0: + /* todo: variable reference */ + assert(false); + break; + + case exprstatetype::lparen_1: + /* unreachable */ + + assert(false); + break; + + case exprstatetype::expect_rhs_expression: + { + /* various possibilities when looking for rhs expression: + * + * x := y // (1) + * x := f(a) // (2) + * x := f(a,b) // (3) + * + * need lookahead token following symbol to distinguish + * between (1) (symbol completes rhs expression) + * and {(2), (3)} (symbol is function call) + */ + + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ +#ifdef NOT_YET + p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, + Variable::make(name, type))); +#endif + +#ifdef LATER + p_stack->pop_exprstate(); + p_stack->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); +#endif + return; + } + + case exprstatetype::expect_symbol: + { + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ + std::unique_ptr self = p_stack->pop_exprstate(); + + p_stack->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); + return; + } + + case exprstatetype::expect_type: { + TypeDescr td = nullptr; + + /* TODO: replace with typetable lookup */ + + if (tk.text() == "f64") + td = Reflect::require(); + else if(tk.text() == "f32") + td = Reflect::require(); + else if(tk.text() == "i16") + td = Reflect::require(); + else if(tk.text() == "i32") + td = Reflect::require(); + else if(tk.text() == "i64") + td = Reflect::require(); + + if (!td) { + throw std::runtime_error + (tostr(self_name, + ": unknown type name", + " (expecting f64|f32|i16|i32|i64)", + xtag("typename", tk.text()))); + } + + std::unique_ptr self = p_stack->pop_exprstate(); + p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); + return; + } + + case exprstatetype::expr_progress: + /* illegal input, e.g. + * foo bar + */ + assert(false); + return; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } /*on_symbol*/ + + void + exprstate::on_typedescr(TypeDescr td, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* returning type description to somethign that wants it */ + + switch (this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: + case exprstatetype::def_1: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::def_2: + this->exs_type_ = exprstatetype::def_3; + this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, + nullptr /*source_expr*/); + this->def_expr_->assign_rhs(this->cvt_expr_); + //this->def_lhs_td_ = td; + + return; + + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + assert(false); + return; + + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + /* unreachable + * (this exprstate issues pop instruction from exprstate::on_input() + */ + assert(false); + return; + + case exprstatetype::expr_progress: + assert(false); + return; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } + + void + exprstate::on_colon(exprstatestack * p_stack) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_colon"; + + /* lots of illegal states */ + if (!this->admits_colon()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected colon for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::def_1) { + this->exs_type_ = exprstatetype::def_2; + + p_stack->push_exprstate(exprstate::expect_type()); + } else { + assert(false); + } + } + + void + exprstate::on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_semicolon"; + + if (!this->admits_semicolon()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected semicolon for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expr_progress) { + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + /* control here on input like: + * (1.234; + * + * a. '(' sets up stack [lparen_0:expect_rhs_expression] + * (see exprstate::on_leftparen()) + * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] + * (see exprstate::on_f64()) + * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] + * deliver expresssion to expect_rhs_expression.on_expr() + * (see exprstate::on_expr()) + * d. expr_rhs_expression forwards expression to [lparen_0] + * e. lparen_0 advances to [lparen_1] + * f. now deliver semicolon; [lparen_1] rejects + */ + + p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); + } else if (this->exs_type_ == exprstatetype::def_5) { + rp expr = this->def_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + } else { + assert(false); + } + } + + void + exprstate::on_singleassign(exprstatestack * p_stack) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_singleassign"; + + if (!this->admits_singleassign()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected equals for parsing state", + xtag("state", *this))); + } + + if ((this->exs_type_ == exprstatetype::def_1) + || (this->exs_type_ == exprstatetype::def_3)) + { + this->exs_type_ = exprstatetype::def_4; + + p_stack->push_exprstate(exprstate::expect_rhs_expression()); + } else { + assert(false); + } + } + + void + exprstate::on_leftparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_leftparen"; + + if (!this->admits_leftparen()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected leftparen '(' for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expect_rhs_expression) { + /* push lparen_0 to remember to look for subsequent rightparen. */ + p_stack->push_exprstate(exprstate::lparen_0()); + p_stack->push_exprstate(exprstate::expect_rhs_expression()); + } + } + + void + exprstate::on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_rightparen"; + + if (!this->admits_rightparen()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected rightparen ')' for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expr_progress) { + /* stack may be something like: + * + * lparen_0 + * expect_rhs_expression + * expr_progress + * <-- rightparen + * + * 1. rightparen completes expression-in-progress + * 2. rightparen must then match innermost waiting lparen_0 + */ + + /* right paren confirms stack expression */ + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + if (p_stack->empty()) { + throw std::runtime_error(tostr(self_name, + ": expected non-empty parsing stack")); + } + + log && log(xtag("stack", p_stack)); + + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + + /* now deliver rightparen */ + p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); + } else if (this->exs_type_ == exprstatetype::lparen_1) { + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + } + } + + void + exprstate::on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_f64"; + + if (!this->admits_f64()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected floating-point literal for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::expect_rhs_expression) { + /* e.g. + * def pi = 3.14159265; + * \---tk---/ + */ + p_stack->push_exprstate + (exprstate::make_expr_progress + (Constant::make(tk.f64_value()))); + } else { + assert(false); + } + } + + void + exprstate::on_input(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + log && log(xtag("tk", tk)); + log && log(xtag("state", *this)); + + switch (tk.tk_type()) { + + case tokentype::tk_def: + this->on_def(p_stack); + return; + + case tokentype::tk_i64: + assert(false); + return; + + case tokentype::tk_f64: + this->on_f64(tk, p_stack, p_emit_expr); + return; + + case tokentype::tk_string: + assert(false); + return; + + case tokentype::tk_symbol: + this->on_symbol(tk, p_stack, p_emit_expr); + return; + + case tokentype::tk_leftparen: + this->on_leftparen(p_stack, p_emit_expr); + return; + + case tokentype::tk_rightparen: + this->on_rightparen(p_stack, p_emit_expr); + return; + + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_dot: + case tokentype::tk_comma: + assert(false); + return; + + case tokentype::tk_colon: + this->on_colon(p_stack); + return; + + case tokentype::tk_doublecolon: + assert(false); + return; + + case tokentype::tk_semicolon: + this->on_semicolon(p_stack, p_emit_expr); + return; + + case tokentype::tk_singleassign: + this->on_singleassign(p_stack); + return; + + case tokentype::tk_assign: + case tokentype::tk_yields: + + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_if: + case tokentype::tk_let: + + case tokentype::tk_in: + case tokentype::tk_end: + assert(false); + return; + + case tokentype::tk_invalid: + case tokentype::n_tokentype: + assert(false); + return; + } + + assert(false); + } + + void + exprstate::on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr)); + + switch (this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* toplevel expression sequence accepts an + * arbitrary number of expressions. + * + * parser::include_token() returns + */ + + *p_emit_expr = expr.promote(); + return; + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* unreachable. see define_xs::on_expr() */ + assert(false); + return; + + case exprstatetype::lparen_0: { + this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ + p_stack->push_exprstate(exprstate::make_expr_progress(expr.promote())); + + return; + } + + case exprstatetype::lparen_1: { + this->gen_expr_ = expr.promote(); + + /* expect immediate incoming call, this time to on_rightparen() */ + return; + } + + case exprstatetype::expect_rhs_expression: { + + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + + return; + } + + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + /* unreachable + * (this exprstate issues pop instruction from exprstate::on_input() + */ + assert(false); + return; + case exprstatetype::expr_progress: + /* consecutive expressions isn't legal + */ + assert(false); + return; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } /*on_expr*/ + + void + exprstate::on_symbol(const std::string & /*symbol_name*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + switch(this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* toplevel expression sequence accepts an + * arbitrary number of expressions. + * + * parser::include_token() returns + */ + + /* NOT IMPLEMENTED */ + assert(false); + return; + case exprstatetype::def_0: + case exprstatetype::def_1: + case exprstatetype::def_2: + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* unreachable */ + assert(false); + return; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + /* unreachable + * (this exprstate issues pop instruction from exprstate::on_input() + */ + assert(false); + return; + case exprstatetype::expr_progress: + assert(false); + return; + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } + + void + exprstate::print(std::ostream & os) const { + os << ""; + } + + // ----- exprstatestack ----- + + exprstate & + exprstatestack::top_exprstate() { + std::size_t z = stack_.size(); + + if (z == 0) { + throw std::runtime_error + ("parser::top_exprstate: unexpected empty stack"); + } + + return *(stack_[z-1]); + } + + void + exprstatestack::push_exprstate(std::unique_ptr exs) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("exs", *exs)); + + std::size_t z = stack_.size(); + + stack_.resize(z+1); + + stack_[z] = std::move(exs); + } + + std::unique_ptr + exprstatestack::pop_exprstate() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("top.exstype", top_exprstate().exs_type())); + + std::size_t z = stack_.size(); + + if (z > 0) { + std::unique_ptr top = std::move(stack_[z-1]); + + stack_.resize(z-1); + + return top; + } else { + return nullptr; + } + } + + void + exprstatestack::print(std::ostream & os) const { + os << "" << std::endl; } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index d777fa6b..f056eeac 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -15,1100 +15,11 @@ namespace xo { using xo::ast::Expression; //using xo::ast::DefineExpr; //using xo::ast::ConvertExpr; - using xo::ast::Constant; - using xo::reflect::Reflect; + //using xo::ast::Constant; + //using xo::reflect::Reflect; using xo::reflect::TypeDescr; namespace scm { - const char * - exprstatetype_descr(exprstatetype x) { - switch (x) { - case exprstatetype::invalid: - return "?invalid"; - case exprstatetype::expect_toplevel_expression_sequence: - return "expect_toplevel_expression_sequence"; - case exprstatetype::def_0: - return "def_0"; - case exprstatetype::def_1: - return "def_1"; - case exprstatetype::def_2: - return "def_2"; - case exprstatetype::def_3: - return "def_3"; - case exprstatetype::def_4: - return "def_4"; - case exprstatetype::def_5: - return "def_5"; - case exprstatetype::lparen_0: - return "lparen_0"; - case exprstatetype::lparen_1: - return "lparen_1"; - case exprstatetype::expect_rhs_expression: - return "expect_rhs_expression"; - case exprstatetype::expect_symbol: - return "expect_symbol"; - case exprstatetype::expect_type: - return "expect_type"; - case exprstatetype::expr_progress: - return "expr_progress"; - case exprstatetype::n_exprstatetype: - break; - } - - return "???"; - } - - bool - exprstate::admits_definition() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - return true; - - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ - assert(false); - return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - return false; - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - case exprstatetype::expr_progress: - return false; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } - - bool - exprstate::admits_symbol() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - return false; - - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - /* treat symbol as variable name */ - return true; - - case exprstatetype::expect_symbol: - return true; - - case exprstatetype::expect_type: - /* treat symbol as typename */ - return true; - - case exprstatetype::expr_progress: - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } - - bool - exprstate::admits_colon() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - return false; - - case exprstatetype::def_1: - return true; - - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - /* rhs-expressions (or expressions for that matter) - * may not begin with a colon - */ - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - - case exprstatetype::expr_progress: - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } - - bool - exprstate::admits_semicolon() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - return false; - case exprstatetype::def_5: - return true; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - case exprstatetype::expr_progress: - return true; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - return false; - } - - return false; - } - - bool - exprstate::admits_singleassign() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - - /* - * def foo = 1 ; - * def foo : f64 = 1 ; - * ^ ^ ^ ^ ^ ^ ^ - * | | | | | | (done) - * | | | | | def_4:expect_rhs_expression - * | | | | def_3 - * | | | def_2:expect_type - * | | def_1 - * | def_0:expect_symbol - * expect_toplevel_expression_sequence - * - * note that we skip from def_1 -> def_4 if '=' instead of ':' - */ - case exprstatetype::def_0: - return false; - - case exprstatetype::def_1: - return true; - - case exprstatetype::def_2: - return false; - - case exprstatetype::def_3: - return true; - - case exprstatetype::def_4: - case exprstatetype::def_5: - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - /* rhs-expressions (or expressions for that matter) - * may not begin with singleassign '=' - */ - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - - case exprstatetype::expr_progress: - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } - - bool - exprstate::admits_f64() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - return false; - - case exprstatetype::lparen_0: - return true; - - case exprstatetype::lparen_1: - return false; - - case exprstatetype::expect_rhs_expression: - return true; - - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - - case exprstatetype::expr_progress: - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } - - bool - exprstate::admits_leftparen() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* input like - * (function(blah...)) - * not allowed at toplevel; - * creates ambiguity e.g. consider - * x := foo - * (bar) - * - * is rhs 'foo' or 'foo(bar)' - */ - return false; - - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::expect_rhs_expression: - /* can always begin non-toplevel expression with '(' */ - return true; - - case exprstatetype::expect_type: - return false; - - case exprstatetype::expect_symbol: - return false; - - case exprstatetype::expr_progress: - /* todo: will parse as function call */ - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } - - bool - exprstate::admits_rightparen() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - return false; - - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::lparen_0: - /* unreachable -- will have pushed expect_rhs_expression */ - assert(false); - return false; - - case exprstatetype::lparen_1: - return true; - - case exprstatetype::expect_rhs_expression: - return false; - - case exprstatetype::expect_type: - return false; - - case exprstatetype::expect_symbol: - return false; - - case exprstatetype::expr_progress: - /* satisfies expression form */ - return true; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } - - void - exprstate::on_def(exprstatestack * p_stack) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_def"; - - /* lots of illegal states */ - if (!this->admits_definition()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected keyword 'def' for parsing state", - xtag("state", *this))); - } - - p_stack->push_exprstate - (define_xs::def_0(DefineExprAccess::make_empty())); - - /* todo: replace: - * expect_symbol_or_function_signature() - */ - p_stack->push_exprstate(exprstate::expect_symbol()); - - /* keyword 'def' introduces a definition: - * def pi : f64 = 3.14159265 - * def sq(x : f64) -> f64 { (x * x) } - */ - } - - void - exprstate::on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); - - constexpr const char * self_name = "exprstate::on_symbol"; - - if (!this->admits_symbol()) { - throw std::runtime_error - (tostr(self_name, - ": unexpected symbol-token for parsing state", - xtag("symbol", tk), - xtag("state", *this))); - } - - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - throw std::runtime_error - (tostr(self_name, - ": unexpected symbol-token at top-level", - " (expecting decl|def)", - xtag("symbol", tk))); - break; - - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ - assert(false); - return; - - case exprstatetype::lparen_0: - /* todo: variable reference */ - assert(false); - break; - - case exprstatetype::lparen_1: - /* unreachable */ - - assert(false); - break; - - case exprstatetype::expect_rhs_expression: - { - /* various possibilities when looking for rhs expression: - * - * x := y // (1) - * x := f(a) // (2) - * x := f(a,b) // (3) - * - * need lookahead token following symbol to distinguish - * between (1) (symbol completes rhs expression) - * and {(2), (3)} (symbol is function call) - */ - - /* have to do pop first, before sending symbol to - * the o.g. symbol-requester - */ -#ifdef NOT_YET - p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, - Variable::make(name, type))); -#endif - -#ifdef LATER - p_stack->pop_exprstate(); - p_stack->top_exprstate().on_symbol(tk.text(), - p_stack, p_emit_expr); -#endif - return; - } - - case exprstatetype::expect_symbol: - { - /* have to do pop first, before sending symbol to - * the o.g. symbol-requester - */ - std::unique_ptr self = p_stack->pop_exprstate(); - - p_stack->top_exprstate().on_symbol(tk.text(), - p_stack, p_emit_expr); - return; - } - - case exprstatetype::expect_type: { - TypeDescr td = nullptr; - - /* TODO: replace with typetable lookup */ - - if (tk.text() == "f64") - td = Reflect::require(); - else if(tk.text() == "f32") - td = Reflect::require(); - else if(tk.text() == "i16") - td = Reflect::require(); - else if(tk.text() == "i32") - td = Reflect::require(); - else if(tk.text() == "i64") - td = Reflect::require(); - - if (!td) { - throw std::runtime_error - (tostr(self_name, - ": unknown type name", - " (expecting f64|f32|i16|i32|i64)", - xtag("typename", tk.text()))); - } - - std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); - return; - } - - case exprstatetype::expr_progress: - /* illegal input, e.g. - * foo bar - */ - assert(false); - return; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } - } /*on_symbol*/ - - void - exprstate::on_typedescr(TypeDescr td, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) - { - /* returning type description to somethign that wants it */ - - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - case exprstatetype::def_1: - /* NOT IMPLEMENTED */ - assert(false); - return; - - case exprstatetype::def_2: - this->exs_type_ = exprstatetype::def_3; - this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, - nullptr /*source_expr*/); - this->def_expr_->assign_rhs(this->cvt_expr_); - //this->def_lhs_td_ = td; - - return; - - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* NOT IMPLEMENTED */ - assert(false); - return; - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - assert(false); - return; - - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - /* unreachable - * (this exprstate issues pop instruction from exprstate::on_input() - */ - assert(false); - return; - - case exprstatetype::expr_progress: - assert(false); - return; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } - } - - void - exprstate::on_colon(exprstatestack * p_stack) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_colon"; - - /* lots of illegal states */ - if (!this->admits_colon()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected colon for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::def_1) { - this->exs_type_ = exprstatetype::def_2; - - p_stack->push_exprstate(exprstate::expect_type()); - } else { - assert(false); - } - } - - void - exprstate::on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_semicolon"; - - if (!this->admits_semicolon()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected semicolon for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::expr_progress) { - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); - /* control here on input like: - * (1.234; - * - * a. '(' sets up stack [lparen_0:expect_rhs_expression] - * (see exprstate::on_leftparen()) - * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] - * (see exprstate::on_f64()) - * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] - * deliver expresssion to expect_rhs_expression.on_expr() - * (see exprstate::on_expr()) - * d. expr_rhs_expression forwards expression to [lparen_0] - * e. lparen_0 advances to [lparen_1] - * f. now deliver semicolon; [lparen_1] rejects - */ - - p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); - } else if (this->exs_type_ == exprstatetype::def_5) { - rp expr = this->def_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); - } else { - assert(false); - } - } - - void - exprstate::on_singleassign(exprstatestack * p_stack) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_singleassign"; - - if (!this->admits_singleassign()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected equals for parsing state", - xtag("state", *this))); - } - - if ((this->exs_type_ == exprstatetype::def_1) - || (this->exs_type_ == exprstatetype::def_3)) - { - this->exs_type_ = exprstatetype::def_4; - - p_stack->push_exprstate(exprstate::expect_rhs_expression()); - } else { - assert(false); - } - } - - void - exprstate::on_leftparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_leftparen"; - - if (!this->admits_leftparen()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected leftparen '(' for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::expect_rhs_expression) { - /* push lparen_0 to remember to look for subsequent rightparen. */ - p_stack->push_exprstate(exprstate::lparen_0()); - p_stack->push_exprstate(exprstate::expect_rhs_expression()); - } - } - - void - exprstate::on_rightparen(exprstatestack * p_stack, - rp * p_emit_expr) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_rightparen"; - - if (!this->admits_rightparen()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected rightparen ')' for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::expr_progress) { - /* stack may be something like: - * - * lparen_0 - * expect_rhs_expression - * expr_progress - * <-- rightparen - * - * 1. rightparen completes expression-in-progress - * 2. rightparen must then match innermost waiting lparen_0 - */ - - /* right paren confirms stack expression */ - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - if (p_stack->empty()) { - throw std::runtime_error(tostr(self_name, - ": expected non-empty parsing stack")); - } - - log && log(xtag("stack", p_stack)); - - p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); - - /* now deliver rightparen */ - p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); - } else if (this->exs_type_ == exprstatetype::lparen_1) { - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); - } - } - - void - exprstate::on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_f64"; - - if (!this->admits_f64()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected floating-point literal for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::expect_rhs_expression) { - /* e.g. - * def pi = 3.14159265; - * \---tk---/ - */ - p_stack->push_exprstate - (exprstate::make_expr_progress - (Constant::make(tk.f64_value()))); - } else { - assert(false); - } - } - - void - exprstate::on_input(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - log && log(xtag("tk", tk)); - log && log(xtag("state", *this)); - - switch (tk.tk_type()) { - - case tokentype::tk_def: - this->on_def(p_stack); - return; - - case tokentype::tk_i64: - assert(false); - return; - - case tokentype::tk_f64: - this->on_f64(tk, p_stack, p_emit_expr); - return; - - case tokentype::tk_string: - assert(false); - return; - - case tokentype::tk_symbol: - this->on_symbol(tk, p_stack, p_emit_expr); - return; - - case tokentype::tk_leftparen: - this->on_leftparen(p_stack, p_emit_expr); - return; - - case tokentype::tk_rightparen: - this->on_rightparen(p_stack, p_emit_expr); - return; - - case tokentype::tk_leftbracket: - case tokentype::tk_rightbracket: - case tokentype::tk_leftbrace: - case tokentype::tk_rightbrace: - - case tokentype::tk_leftangle: - case tokentype::tk_rightangle: - case tokentype::tk_dot: - case tokentype::tk_comma: - assert(false); - return; - - case tokentype::tk_colon: - this->on_colon(p_stack); - return; - - case tokentype::tk_doublecolon: - assert(false); - return; - - case tokentype::tk_semicolon: - this->on_semicolon(p_stack, p_emit_expr); - return; - - case tokentype::tk_singleassign: - this->on_singleassign(p_stack); - return; - - case tokentype::tk_assign: - case tokentype::tk_yields: - - case tokentype::tk_type: - case tokentype::tk_lambda: - case tokentype::tk_if: - case tokentype::tk_let: - - case tokentype::tk_in: - case tokentype::tk_end: - assert(false); - return; - - case tokentype::tk_invalid: - case tokentype::n_tokentype: - assert(false); - return; - } - - assert(false); - } - - void - exprstate::on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - log && log(xtag("exstype", this->exs_type_), - xtag("expr", expr)); - - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* toplevel expression sequence accepts an - * arbitrary number of expressions. - * - * parser::include_token() returns - */ - - *p_emit_expr = expr.promote(); - return; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable. see define_xs::on_expr() */ - assert(false); - return; - - case exprstatetype::lparen_0: { - this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ - p_stack->push_exprstate(exprstate::make_expr_progress(expr.promote())); - - return; - } - - case exprstatetype::lparen_1: { - this->gen_expr_ = expr.promote(); - - /* expect immediate incoming call, this time to on_rightparen() */ - return; - } - - case exprstatetype::expect_rhs_expression: { - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); - - return; - } - - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - /* unreachable - * (this exprstate issues pop instruction from exprstate::on_input() - */ - assert(false); - return; - case exprstatetype::expr_progress: - /* consecutive expressions isn't legal - */ - assert(false); - return; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } - } /*on_expr*/ - - void - exprstate::on_symbol(const std::string & /*symbol_name*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) - { - switch(this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* toplevel expression sequence accepts an - * arbitrary number of expressions. - * - * parser::include_token() returns - */ - - /* NOT IMPLEMENTED */ - assert(false); - return; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ - assert(false); - return; - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - /* NOT IMPLEMENTED */ - assert(false); - return; - - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - /* unreachable - * (this exprstate issues pop instruction from exprstate::on_input() - */ - assert(false); - return; - case exprstatetype::expr_progress: - assert(false); - return; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } - } - - void - exprstate::print(std::ostream & os) const { - os << ""; - } - - // ----- exprstatestack ----- - - exprstate & - exprstatestack::top_exprstate() { - std::size_t z = stack_.size(); - - if (z == 0) { - throw std::runtime_error - ("parser::top_exprstate: unexpected empty stack"); - } - - return *(stack_[z-1]); - } - - void - exprstatestack::push_exprstate(std::unique_ptr exs) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag), - xtag("exs", *exs)); - - std::size_t z = stack_.size(); - - stack_.resize(z+1); - - stack_[z] = std::move(exs); - } - - std::unique_ptr - exprstatestack::pop_exprstate() { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag), - xtag("top.exstype", top_exprstate().exs_type())); - - std::size_t z = stack_.size(); - - if (z > 0) { - std::unique_ptr top = std::move(stack_[z-1]); - - stack_.resize(z-1); - - return top; - } else { - return nullptr; - } - } - - void - exprstatestack::print(std::ostream & os) const { - os << "" << std::endl; - } - // ----- parser ----- bool From b6a94bb61c840bdb600663d4b1faf7eadb432588 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 13:25:56 -0400 Subject: [PATCH 062/191] xo-reader: refactor: mv on_typedescr def-expr impl -> define_xs --- include/xo/reader/define_xs.hpp | 3 +++ src/reader/define_xs.cpp | 48 +++++++++++++++++++++++++++++++++ src/reader/exprstate.cpp | 17 +++--------- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 8b9d1512..88e07237 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -35,6 +35,9 @@ namespace xo { virtual void on_symbol(const std::string & symbol_name, exprstatestack * p_stack, rp * p_emit_expr) override; + virtual void on_typedescr(TypeDescr td, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) override; private: /** diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index e4df8cea..f1ce7669 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -375,6 +375,54 @@ namespace xo { return; } } + + void + define_xs::on_typedescr(TypeDescr td, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + switch (this->exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + /* unreachable */ + assert(false); + return; + + case exprstatetype::def_0: + case exprstatetype::def_1: + /* NOT IMPLEMENTED (ill-formed program) */ + assert(false); + return; + + case exprstatetype::def_2: + this->exs_type_ = exprstatetype::def_3; + this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, + nullptr /*source_expr*/); + this->def_expr_->assign_rhs(this->cvt_expr_); + //this->def_lhs_td_ = td; + + return; + + case exprstatetype::def_3: + case exprstatetype::def_4: + case exprstatetype::def_5: + /* NOT IMPLEMENTED */ + assert(false); + return; + + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: + case exprstatetype::expect_symbol: + case exprstatetype::expr_progress: + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + assert(false); + return; + } + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index f58be6bd..2b4b777e 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -549,7 +549,7 @@ namespace xo { } /*on_symbol*/ void - exprstate::on_typedescr(TypeDescr td, + exprstate::on_typedescr(TypeDescr /*td*/, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -557,25 +557,14 @@ namespace xo { switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: + case exprstatetype::def_0: case exprstatetype::def_1: - /* NOT IMPLEMENTED */ - assert(false); - return; - case exprstatetype::def_2: - this->exs_type_ = exprstatetype::def_3; - this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, - nullptr /*source_expr*/); - this->def_expr_->assign_rhs(this->cvt_expr_); - //this->def_lhs_td_ = td; - - return; - case exprstatetype::def_3: case exprstatetype::def_4: case exprstatetype::def_5: - /* NOT IMPLEMENTED */ + /* unreachable */ assert(false); return; From a3b8f778f28a458417a199b0c8a8d3ce34b262be Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 13:32:02 -0400 Subject: [PATCH 063/191] xo-reader: refactor: move on_colon() for def-expr to define_xs.cpp --- include/xo/reader/define_xs.hpp | 1 + src/reader/define_xs.cpp | 24 ++++++++++++++++++++++++ src/reader/exprstate.cpp | 10 ++-------- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 88e07237..d3ca7b39 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -38,6 +38,7 @@ namespace xo { virtual void on_typedescr(TypeDescr td, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; + virtual void on_colon(exprstatestack * p_stack) override; private: /** diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index f1ce7669..7c0ed3bd 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -423,6 +423,30 @@ namespace xo { } } + void + define_xs::on_colon(exprstatestack * p_stack) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_colon"; + + /* lots of illegal states */ + if (!this->admits_colon()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected colon for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::def_1) { + this->exs_type_ = exprstatetype::def_2; + + p_stack->push_exprstate(exprstate::expect_type()); + } else { + assert(false); + } + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 2b4b777e..d4079646 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -595,7 +595,7 @@ namespace xo { } void - exprstate::on_colon(exprstatestack * p_stack) { + exprstate::on_colon(exprstatestack * /*p_stack*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -609,13 +609,7 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::def_1) { - this->exs_type_ = exprstatetype::def_2; - - p_stack->push_exprstate(exprstate::expect_type()); - } else { - assert(false); - } + assert(false); } void From 149536b182f86086ac36dec0b24ca801714d86df Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 14:16:12 -0400 Subject: [PATCH 064/191] xo-reader: refactor: mv on_semicolon for def-expr to define_xs --- include/xo/reader/define_xs.hpp | 2 ++ src/reader/define_xs.cpp | 28 ++++++++++++++++++++++++++++ src/reader/exprstate.cpp | 8 -------- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index d3ca7b39..b83ada71 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -39,6 +39,8 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; virtual void on_colon(exprstatestack * p_stack) override; + virtual void on_semicolon(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; private: /** diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 7c0ed3bd..d5513bf2 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -447,6 +447,34 @@ namespace xo { } } + void + define_xs::on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_semicolon"; + + if (!this->admits_semicolon()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected semicolon for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::def_5) { + rp expr = this->def_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + } else { + assert(false); + } + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index d4079646..77a376c3 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -652,14 +652,6 @@ namespace xo { */ p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); - } else if (this->exs_type_ == exprstatetype::def_5) { - rp expr = this->def_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); } else { assert(false); } From 5c14ff988469acf616038c0781b8e62c2f38db10 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 14:22:48 -0400 Subject: [PATCH 065/191] xo-reader: refactor: mv on_singleassign def-expr -> define_xs --- include/xo/reader/define_xs.hpp | 1 + src/reader/define_xs.cpp | 26 ++++++++++++++++++++++++++ src/reader/exprstate.cpp | 12 ++---------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index b83ada71..e32d47a8 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -41,6 +41,7 @@ namespace xo { virtual void on_colon(exprstatestack * p_stack) override; virtual void on_semicolon(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; + virtual void on_singleassign(exprstatestack * p_stack) override; private: /** diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index d5513bf2..df468503 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -475,6 +475,32 @@ namespace xo { assert(false); } } + + void + define_xs::on_singleassign(exprstatestack * p_stack) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_singleassign"; + + if (!this->admits_singleassign()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected equals for parsing state", + xtag("state", *this))); + } + + if ((this->exs_type_ == exprstatetype::def_1) + || (this->exs_type_ == exprstatetype::def_3)) + { + this->exs_type_ = exprstatetype::def_4; + + p_stack->push_exprstate(exprstate::expect_rhs_expression()); + } else { + assert(false); + } + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 77a376c3..a0e9b0c7 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -658,7 +658,7 @@ namespace xo { } void - exprstate::on_singleassign(exprstatestack * p_stack) { + exprstate::on_singleassign(exprstatestack * /*p_stack*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -671,15 +671,7 @@ namespace xo { xtag("state", *this))); } - if ((this->exs_type_ == exprstatetype::def_1) - || (this->exs_type_ == exprstatetype::def_3)) - { - this->exs_type_ = exprstatetype::def_4; - - p_stack->push_exprstate(exprstate::expect_rhs_expression()); - } else { - assert(false); - } + assert(false); } void From 1a6908043b60b97807ea43a37c9b41e4331734cf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 14:27:01 -0400 Subject: [PATCH 066/191] xo-reader: refactor: mv def-expr on_leftparen (noop) -> define_xs --- include/xo/reader/define_xs.hpp | 2 ++ src/reader/define_xs.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index e32d47a8..f1e0e2c7 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -42,6 +42,8 @@ namespace xo { virtual void on_semicolon(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_singleassign(exprstatestack * p_stack) override; + virtual void on_leftparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; private: /** diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index df468503..4c5b3cb4 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -501,6 +501,25 @@ namespace xo { assert(false); } } + + void + define_xs::on_leftparen(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_leftparen"; + + if (!this->admits_leftparen()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected leftparen '(' for parsing state", + xtag("state", *this))); + } + + assert(false); /* inserting this during refactor...? */ + } } /*namespace scm*/ } /*namespace xo*/ From 3a0a455b2c711e6a6d7436593691c03e3cff0019 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 14:37:56 -0400 Subject: [PATCH 067/191] xo-reader: refactor: mv defexpr on_rightparen(), on_f64() -> define_xs --- include/xo/reader/define_xs.hpp | 5 +++++ include/xo/reader/exprstate.hpp | 1 + src/reader/define_xs.cpp | 39 +++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index f1e0e2c7..de1fb44d 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -44,6 +44,11 @@ namespace xo { virtual void on_singleassign(exprstatestack * p_stack) override; virtual void on_leftparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; + virtual void on_rightparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; private: /** diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 461ecddf..75a955ce 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -128,6 +128,7 @@ namespace xo { * forward instructions to parent parser **/ void on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 4c5b3cb4..f5859c23 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -520,6 +520,45 @@ namespace xo { assert(false); /* inserting this during refactor...? */ } + + void + define_xs::on_rightparen(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_rightparen"; + + if (!this->admits_rightparen()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected rightparen ')' for parsing state", + xtag("state", *this))); + } + + assert(false); /* inserting this during refactor..? */ + } + + void + define_xs::on_f64(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_f64"; + + if (!this->admits_f64()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected floating-point literal for parsing state", + xtag("state", *this))); + } + + assert(false); + } } /*namespace scm*/ } /*namespace xo*/ From fccff550011b9645573e1cdb48c000e881d65e23 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 15:11:50 -0400 Subject: [PATCH 068/191] xo-reader: refactor: splitoff defexpr state machine from exprstate --- include/xo/reader/define_xs.hpp | 17 ++ include/xo/reader/exprstate.hpp | 5 + include/xo/reader/parser.hpp | 11 ++ src/reader/define_xs.cpp | 311 +++++++++++--------------------- src/reader/exprstate.cpp | 133 +++----------- utest/parser.test.cpp | 45 +++-- 6 files changed, 203 insertions(+), 319 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index de1fb44d..0f872007 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -10,6 +10,19 @@ namespace xo { namespace scm { + enum class defexprstatetype { + invalid = -1, + + def_0, + def_1, + def_2, + def_3, + def_4, + def_5, + + n_defexprstatetype, + }; + /** @class define_xs * @brief state to provide parsing of a define-expression **/ @@ -18,8 +31,11 @@ namespace xo { define_xs(rp def_expr); virtual ~define_xs() = default; + static const define_xs * from(const exprstate * x) { return dynamic_cast(x); } static std::unique_ptr def_0(rp def_expr); + defexprstatetype defxs_type() const { return defxs_type_; } + virtual bool admits_definition() const override; virtual bool admits_symbol() const override; virtual bool admits_colon() const override; @@ -71,6 +87,7 @@ namespace xo { * (done): definition complete, pop exprstate from stack * **/ + defexprstatetype defxs_type_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 75a955ce..ea37b934 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -20,12 +20,15 @@ namespace xo { /** toplevel of some translation unit **/ expect_toplevel_expression_sequence, + defexpr, +#ifdef OBSOLETE def_0, def_1, def_2, def_3, def_4, def_5, +#endif /* lparen_0: look for expression; capture + advance to lparen_1 */ lparen_0, @@ -63,6 +66,8 @@ namespace xo { }; #endif + class define_xs; + /** state associated with a partially-parsed expression. **/ class exprstate { diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index fb760081..3211fd0c 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -167,6 +167,17 @@ namespace xo { return exprstatetype::invalid; } + exprstate const * i_exstate(std::size_t i) const { + std::size_t z = xs_stack_.size(); + + if (i < z) { + return xs_stack_[i].get(); + } + + /* out of bounds */ + return nullptr; + } + /** true iff parser contains state for an incomplete expression. * For this to be true, parser must have consumed at least one token * since end of last toplevel expression diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index f5859c23..15ff0130 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -10,40 +10,31 @@ namespace xo { } define_xs::define_xs(rp def_expr) - : exprstate(exprstatetype::def_0, + : exprstate(exprstatetype::defexpr, nullptr /*gen_expr*/, - def_expr) + def_expr), + defxs_type_{defexprstatetype::def_0} {} bool define_xs::admits_definition() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); - return false; + switch (defxs_type_) { - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + case defexprstatetype::def_0: + case defexprstatetype::def_1: + case defexprstatetype::def_2: + case defexprstatetype::def_3: + case defexprstatetype::def_4: + case defexprstatetype::def_5: /* note for def_4: * rhs could certainly be a function body that contains * nested defines; but then immediately-enclosing-exprstate * would be a block */ return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return false; @@ -54,28 +45,18 @@ namespace xo { bool define_xs::admits_symbol() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); + switch (defxs_type_) { + + case defexprstatetype::def_0: + case defexprstatetype::def_1: + case defexprstatetype::def_2: + case defexprstatetype::def_3: + case defexprstatetype::def_4: + case defexprstatetype::def_5: return false; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - return false; - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return false; @@ -86,32 +67,22 @@ namespace xo { bool define_xs::admits_colon() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); + switch (defxs_type_) { + + case defexprstatetype::def_0: return false; - case exprstatetype::def_0: - return false; - - case exprstatetype::def_1: + case defexprstatetype::def_1: return true; - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + case defexprstatetype::def_2: + case defexprstatetype::def_3: + case defexprstatetype::def_4: + case defexprstatetype::def_5: return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return false; @@ -122,27 +93,19 @@ namespace xo { bool define_xs::admits_semicolon() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); + switch (defxs_type_) { + + case defexprstatetype::def_0: + case defexprstatetype::def_1: + case defexprstatetype::def_2: + case defexprstatetype::def_3: + case defexprstatetype::def_4: return false; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - return false; - case exprstatetype::def_5: + case defexprstatetype::def_5: return true; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return false; @@ -153,11 +116,7 @@ namespace xo { bool define_xs::admits_singleassign() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); - return false; + switch (defxs_type_) { /* * def foo = 1 ; @@ -173,31 +132,24 @@ namespace xo { * * note that we skip from def_1 -> def_4 if '=' instead of ':' */ - case exprstatetype::def_0: + case defexprstatetype::def_0: return false; - case exprstatetype::def_1: + case defexprstatetype::def_1: return true; - case exprstatetype::def_2: + case defexprstatetype::def_2: return false; - case exprstatetype::def_3: + case defexprstatetype::def_3: return true; - case exprstatetype::def_4: - case exprstatetype::def_5: + case defexprstatetype::def_4: + case defexprstatetype::def_5: return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return false; @@ -208,18 +160,14 @@ namespace xo { bool define_xs::admits_leftparen() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); - return false; + switch (defxs_type_) { - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + case defexprstatetype::def_0: + case defexprstatetype::def_1: + case defexprstatetype::def_2: + case defexprstatetype::def_3: + case defexprstatetype::def_4: + case defexprstatetype::def_5: /* input like * def foo : f64 = ( * ^ ^ ^ ^ ^ @@ -233,14 +181,8 @@ namespace xo { */ return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return false; @@ -251,28 +193,18 @@ namespace xo { bool define_xs::admits_rightparen() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); + switch (defxs_type_) { + + case defexprstatetype::def_0: + case defexprstatetype::def_1: + case defexprstatetype::def_2: + case defexprstatetype::def_3: + case defexprstatetype::def_4: + case defexprstatetype::def_5: return false; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - return false; - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return false; @@ -286,19 +218,16 @@ namespace xo { exprstatestack * /* p_stack */, rp * /* p_emit_expr */) { - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - assert(false); - return; + switch (this->defxs_type_) { - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: + case defexprstatetype::def_0: + case defexprstatetype::def_1: + case defexprstatetype::def_2: + case defexprstatetype::def_3: /* NOT IMPLEMENTED */ assert(false); return; - case exprstatetype::def_4: { + case defexprstatetype::def_4: { /* have all the ingredients to create an expression * representing a definition * @@ -315,22 +244,16 @@ namespace xo { rp def_expr = this->def_expr_; - this->exs_type_ = exprstatetype::def_5; + this->defxs_type_ = defexprstatetype::def_5; return; } - case exprstatetype::def_5: + case defexprstatetype::def_5: assert(false); return; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return; @@ -342,34 +265,24 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); - return; - case exprstatetype::def_0: - this->exs_type_ = exprstatetype::def_1; + switch (this->defxs_type_) { + case defexprstatetype::def_0: + this->defxs_type_ = defexprstatetype::def_1; this->def_expr_->assign_lhs_name(symbol_name); //this->def_lhs_symbol_ = symbol_name; return; - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + case defexprstatetype::def_1: + case defexprstatetype::def_2: + case defexprstatetype::def_3: + case defexprstatetype::def_4: + case defexprstatetype::def_5: /* NOT IMPLEMENTED */ assert(false); return; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return; @@ -381,20 +294,16 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* unreachable */ - assert(false); - return; + switch (this->defxs_type_) { - case exprstatetype::def_0: - case exprstatetype::def_1: + case defexprstatetype::def_0: + case defexprstatetype::def_1: /* NOT IMPLEMENTED (ill-formed program) */ assert(false); return; - case exprstatetype::def_2: - this->exs_type_ = exprstatetype::def_3; + case defexprstatetype::def_2: + this->defxs_type_ = defexprstatetype::def_3; this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, nullptr /*source_expr*/); this->def_expr_->assign_rhs(this->cvt_expr_); @@ -402,21 +311,15 @@ namespace xo { return; - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + case defexprstatetype::def_3: + case defexprstatetype::def_4: + case defexprstatetype::def_5: /* NOT IMPLEMENTED */ assert(false); return; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: + case defexprstatetype::invalid: + case defexprstatetype::n_defexprstatetype: /* unreachable */ assert(false); return; @@ -438,8 +341,8 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::def_1) { - this->exs_type_ = exprstatetype::def_2; + if (this->defxs_type_ == defexprstatetype::def_1) { + this->defxs_type_ = defexprstatetype::def_2; p_stack->push_exprstate(exprstate::expect_type()); } else { @@ -463,7 +366,7 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::def_5) { + if (this->defxs_type_ == defexprstatetype::def_5) { rp expr = this->def_expr_; std::unique_ptr self = p_stack->pop_exprstate(); @@ -491,10 +394,10 @@ namespace xo { xtag("state", *this))); } - if ((this->exs_type_ == exprstatetype::def_1) - || (this->exs_type_ == exprstatetype::def_3)) + if ((this->defxs_type_ == defexprstatetype::def_1) + || (this->defxs_type_ == defexprstatetype::def_3)) { - this->exs_type_ = exprstatetype::def_4; + this->defxs_type_ = defexprstatetype::def_4; p_stack->push_exprstate(exprstate::expect_rhs_expression()); } else { diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index a0e9b0c7..c61ecc60 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -20,18 +20,8 @@ namespace xo { return "?invalid"; case exprstatetype::expect_toplevel_expression_sequence: return "expect_toplevel_expression_sequence"; - case exprstatetype::def_0: - return "def_0"; - case exprstatetype::def_1: - return "def_1"; - case exprstatetype::def_2: - return "def_2"; - case exprstatetype::def_3: - return "def_3"; - case exprstatetype::def_4: - return "def_4"; - case exprstatetype::def_5: - return "def_5"; + case exprstatetype::defexpr: + return "defexpr"; case exprstatetype::lparen_0: return "lparen_0"; case exprstatetype::lparen_1: @@ -57,12 +47,7 @@ namespace xo { case exprstatetype::expect_toplevel_expression_sequence: return true; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + case exprstatetype::defexpr: /* unreachable */ assert(false); return false; @@ -90,12 +75,7 @@ namespace xo { case exprstatetype::expect_toplevel_expression_sequence: return false; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + case exprstatetype::defexpr: /* unreachable */ assert(false); return false; @@ -129,16 +109,12 @@ namespace xo { exprstate::admits_colon() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: + + case exprstatetype::defexpr: + /* unreachable -- redirects to define_xs::admits_colon() */ + assert(false); return false; - case exprstatetype::def_1: - return true; - - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: case exprstatetype::lparen_0: case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: @@ -165,14 +141,7 @@ namespace xo { exprstate::admits_semicolon() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - return false; - case exprstatetype::def_5: - return true; + case exprstatetype::defexpr: case exprstatetype::lparen_0: case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: @@ -208,21 +177,11 @@ namespace xo { * * note that we skip from def_1 -> def_4 if '=' instead of ':' */ - case exprstatetype::def_0: + case exprstatetype::defexpr: + /* unreachable - redirects to define_xs */ + assert(false); return false; - case exprstatetype::def_1: - return true; - - case exprstatetype::def_2: - return false; - - case exprstatetype::def_3: - return true; - - case exprstatetype::def_4: - case exprstatetype::def_5: - case exprstatetype::lparen_0: case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: @@ -249,12 +208,10 @@ namespace xo { exprstate::admits_f64() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: + + case exprstatetype::defexpr: + /* unreachable - redirects to define_xs */ + assert(false); return false; case exprstatetype::lparen_0: @@ -297,13 +254,8 @@ namespace xo { */ return false; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ + case exprstatetype::defexpr: + /* unreachable - redirects to define_xs */ assert(false); return false; @@ -343,13 +295,8 @@ namespace xo { case exprstatetype::expect_toplevel_expression_sequence: return false; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ + case exprstatetype::defexpr: + /* unreachable - redirects to define_xs */ assert(false); return false; @@ -442,13 +389,8 @@ namespace xo { xtag("symbol", tk))); break; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ + case exprstatetype::defexpr: + /* unreachable - redirects to define_xs */ assert(false); return; @@ -558,13 +500,8 @@ namespace xo { switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ + case exprstatetype::defexpr: + /* unreachable - redirects to define_xs */ assert(false); return; @@ -728,7 +665,7 @@ namespace xo { /* right paren confirms stack expression */ rp expr = this->gen_expr_; - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); if (p_stack->empty()) { throw std::runtime_error(tostr(self_name, @@ -744,7 +681,7 @@ namespace xo { } else if (this->exs_type_ == exprstatetype::lparen_1) { rp expr = this->gen_expr_; - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); } @@ -891,13 +828,8 @@ namespace xo { *p_emit_expr = expr.promote(); return; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable. see define_xs::on_expr() */ + case exprstatetype::defexpr: + /* unreachable. redirects to define_xs::on_expr() */ assert(false); return; @@ -962,13 +894,8 @@ namespace xo { /* NOT IMPLEMENTED */ assert(false); return; - case exprstatetype::def_0: - case exprstatetype::def_1: - case exprstatetype::def_2: - case exprstatetype::def_3: - case exprstatetype::def_4: - case exprstatetype::def_5: - /* unreachable */ + case exprstatetype::defexpr: + /* unreachable - redirects to define_xs */ assert(false); return; diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp index 58910bda..8611a40a 100644 --- a/utest/parser.test.cpp +++ b/utest/parser.test.cpp @@ -4,12 +4,15 @@ */ #include "xo/reader/parser.hpp" +#include "xo/reader/define_xs.hpp" #include namespace xo { using parser_type = xo::scm::parser; using token_type = parser_type::token_type; using xo::scm::exprstatetype; + using xo::scm::define_xs; + using xo::scm::defexprstatetype; using std::cerr; using std::endl; @@ -45,8 +48,11 @@ namespace xo { CHECK(parser.stack_size() == 3); if (parser.stack_size() > 0) CHECK(parser.i_exstype(0) == exprstatetype::expect_symbol); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) == exprstatetype::def_0); + if (parser.stack_size() > 1) { + CHECK(parser.i_exstype(1) == exprstatetype::defexpr); + REQUIRE(define_xs::from(parser.i_exstate(1)) != nullptr); + CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_0); + } if (parser.stack_size() > 2) CHECK(parser.i_exstype(2) == exprstatetype::expect_toplevel_expression_sequence); @@ -71,8 +77,11 @@ namespace xo { * def_1 */ CHECK(parser.stack_size() == 2); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::def_1); + if (parser.stack_size() > 0) { + CHECK(parser.i_exstype(0) == exprstatetype::defexpr); + REQUIRE(define_xs::from(parser.i_exstate(0)) != nullptr); + CHECK(define_xs::from(parser.i_exstate(0))->defxs_type() == defexprstatetype::def_1); + } if (parser.stack_size() > 1) CHECK(parser.i_exstype(1) == exprstatetype::expect_toplevel_expression_sequence); @@ -104,8 +113,11 @@ namespace xo { CHECK(parser.stack_size() == 3); if (parser.stack_size() > 0) CHECK(parser.i_exstype(0) == exprstatetype::expect_type); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) == exprstatetype::def_2); + if (parser.stack_size() > 1) { + CHECK(parser.i_exstype(1) == exprstatetype::defexpr); + REQUIRE(define_xs::from(parser.i_exstate(1)) != nullptr); + CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_2); + } if (parser.stack_size() > 2) CHECK(parser.i_exstype(2) == exprstatetype::expect_toplevel_expression_sequence); @@ -132,8 +144,11 @@ namespace xo { * def_3 */ CHECK(parser.stack_size() == 2); - if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::def_3); + if (parser.stack_size() > 0) { + CHECK(parser.i_exstype(0) == exprstatetype::defexpr); + REQUIRE(define_xs::from(parser.i_exstate(0)) != nullptr); + CHECK(define_xs::from(parser.i_exstate(0))->defxs_type() == defexprstatetype::def_3); + } if (parser.stack_size() > 1) CHECK(parser.i_exstype(1) == exprstatetype::expect_toplevel_expression_sequence); @@ -176,8 +191,11 @@ namespace xo { CHECK(parser.stack_size() == 3); if (parser.stack_size() > 0) CHECK(parser.i_exstype(0) == exprstatetype::expect_rhs_expression); - if (parser.stack_size() > 1) - CHECK(parser.i_exstype(1) == exprstatetype::def_4); + if (parser.stack_size() > 1) { + CHECK(parser.i_exstype(1) == exprstatetype::defexpr); + REQUIRE(define_xs::from(parser.i_exstate(1)) != nullptr); + CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_4); + } if (parser.stack_size() > 2) CHECK(parser.i_exstype(2) == exprstatetype::expect_toplevel_expression_sequence); @@ -212,8 +230,11 @@ namespace xo { CHECK(parser.i_exstype(0) == exprstatetype::expr_progress); if (parser.stack_size() > 1) CHECK(parser.i_exstype(1) == exprstatetype::expect_rhs_expression); - if (parser.stack_size() > 2) - CHECK(parser.i_exstype(2) == exprstatetype::def_4); + if (parser.stack_size() > 2) { + CHECK(parser.i_exstype(2) == exprstatetype::defexpr); + REQUIRE(define_xs::from(parser.i_exstate(2)) != nullptr); + CHECK(define_xs::from(parser.i_exstate(2))->defxs_type() == defexprstatetype::def_4); + } if (parser.stack_size() > 3) CHECK(parser.i_exstype(3) == exprstatetype::expect_toplevel_expression_sequence); From cbd411bbf82be627a7e714c18f55df874ac1e33a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 15:15:07 -0400 Subject: [PATCH 069/191] xo-reader: refactor: mv exprstate.cvt_expr -> define_xs --- include/xo/reader/define_xs.hpp | 9 +++++++++ include/xo/reader/exprstate.hpp | 13 ------------- src/reader/define_xs.cpp | 11 +++++++++++ src/reader/exprstate.cpp | 2 -- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 0f872007..6e15c21f 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -27,6 +27,9 @@ namespace xo { * @brief state to provide parsing of a define-expression **/ class define_xs : public exprstate { + public: + using ConvertExprAccess = xo::ast::ConvertExprAccess; + public: define_xs(rp def_expr); virtual ~define_xs() = default; @@ -66,6 +69,8 @@ namespace xo { exprstatestack * p_stack, rp * /*p_emit_expr*/) override; + virtual void print(std::ostream & os) const override; + private: /** * def foo : f64 = 1 ; @@ -88,6 +93,10 @@ namespace xo { * **/ defexprstatetype defxs_type_; + /** scafford a convert-expression here. + * May be nested within a def_expr + **/ + rp cvt_expr_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ea37b934..0d051292 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -21,14 +21,6 @@ namespace xo { expect_toplevel_expression_sequence, defexpr, -#ifdef OBSOLETE - def_0, - def_1, - def_2, - def_3, - def_4, - def_5, -#endif /* lparen_0: look for expression; capture + advance to lparen_1 */ lparen_0, @@ -74,7 +66,6 @@ namespace xo { public: using Expression = xo::ast::Expression; using DefineExprAccess = xo::ast::DefineExprAccess; - using ConvertExprAccess = xo::ast::ConvertExprAccess; using exprtype = xo::ast::exprtype; using token_type = token; using TypeDescr = xo::reflect::TypeDescr; @@ -173,10 +164,6 @@ namespace xo { rp gen_expr_; /** scaffold a define-expression here **/ rp def_expr_; - /** scafford a convert-expression here. - * May be nested within a def_expr - **/ - rp cvt_expr_; }; /*exprstate*/ inline std::ostream & diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 15ff0130..932d011c 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -462,6 +462,17 @@ namespace xo { assert(false); } + + void + define_xs::print(std::ostream & os) const { + os << ""; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index c61ecc60..5b15ef42 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -930,8 +930,6 @@ namespace xo { << xtag("type", exs_type_); if (def_expr_) os << xtag("def_expr", def_expr_); - if (cvt_expr_) - os << xtag("cvt_expr", cvt_expr_); os << ">"; } From 90a921fa4e366cee0ec0f1426627111f8f255ba0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 15:19:51 -0400 Subject: [PATCH 070/191] xo-reader: refactor: mv exprstate.def_expr -> define_xs --- include/xo/reader/define_xs.hpp | 7 ++++++- include/xo/reader/exprstate.hpp | 23 ++++++++--------------- src/reader/define_xs.cpp | 10 +++++----- src/reader/exprstate.cpp | 5 +---- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 6e15c21f..3a740a32 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -5,6 +5,8 @@ #pragma once +#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/ConvertExpr.hpp" #include "exprstate.hpp" //#include @@ -28,6 +30,7 @@ namespace xo { **/ class define_xs : public exprstate { public: + using DefineExprAccess = xo::ast::DefineExprAccess; using ConvertExprAccess = xo::ast::ConvertExprAccess; public: @@ -35,7 +38,7 @@ namespace xo { virtual ~define_xs() = default; static const define_xs * from(const exprstate * x) { return dynamic_cast(x); } - static std::unique_ptr def_0(rp def_expr); + static std::unique_ptr def_0(); defexprstatetype defxs_type() const { return defxs_type_; } @@ -93,6 +96,8 @@ namespace xo { * **/ defexprstatetype defxs_type_; + /** scaffold a define-expression here **/ + rp def_expr_; /** scafford a convert-expression here. * May be nested within a def_expr **/ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 0d051292..ae1a0bf0 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -6,8 +6,6 @@ #pragma once #include "xo/expression/Expression.hpp" -#include "xo/expression/DefineExpr.hpp" -#include "xo/expression/ConvertExpr.hpp" #include "xo/tokenizer/token.hpp" #include //#include @@ -65,7 +63,6 @@ namespace xo { class exprstate { public: using Expression = xo::ast::Expression; - using DefineExprAccess = xo::ast::DefineExprAccess; using exprtype = xo::ast::exprtype; using token_type = token; using TypeDescr = xo::reflect::TypeDescr; @@ -73,30 +70,28 @@ namespace xo { public: exprstate() = default; exprstate(exprstatetype exs_type, - rp candidate_expr, - rp def_expr) + rp candidate_expr) : exs_type_{exs_type}, - gen_expr_{std::move(candidate_expr)}, - def_expr_{std::move(def_expr)} {} + gen_expr_{std::move(candidate_expr)} {} virtual ~exprstate() = default; static std::unique_ptr expect_toplevel_expression_sequence() { - return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr)); } static std::unique_ptr expect_rhs_expression() { - return std::make_unique(exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_rhs_expression, nullptr)); } static std::unique_ptr expect_symbol() { - return std::make_unique(exprstate(exprstatetype::expect_symbol, nullptr, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_symbol, nullptr)); } static std::unique_ptr expect_type() { - return std::make_unique(exprstate(exprstatetype::expect_type, nullptr, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_type, nullptr)); } static std::unique_ptr make_expr_progress(rp expr) { - return std::make_unique(exprstate(exprstatetype::expr_progress, expr, nullptr)); + return std::make_unique(exprstate(exprstatetype::expr_progress, expr)); } static std::unique_ptr lparen_0() { - return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr, nullptr)); + return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr)); } exprstatetype exs_type() const { return exs_type_; } @@ -162,8 +157,6 @@ namespace xo { /** generic expression **/ rp gen_expr_; - /** scaffold a define-expression here **/ - rp def_expr_; }; /*exprstate*/ inline std::ostream & diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 932d011c..d1f93984 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -5,15 +5,15 @@ namespace xo { namespace scm { std::unique_ptr - define_xs::def_0(rp def_expr) { - return std::make_unique(define_xs(def_expr)); + define_xs::def_0() { + return std::make_unique(define_xs(DefineExprAccess::make_empty())); } define_xs::define_xs(rp def_expr) : exprstate(exprstatetype::defexpr, - nullptr /*gen_expr*/, - def_expr), - defxs_type_{defexprstatetype::def_0} + nullptr /*gen_expr*/), + defxs_type_{defexprstatetype::def_0}, + def_expr_{std::move(def_expr)} {} bool diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 5b15ef42..db98d197 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -346,8 +346,7 @@ namespace xo { xtag("state", *this))); } - p_stack->push_exprstate - (define_xs::def_0(DefineExprAccess::make_empty())); + p_stack->push_exprstate(define_xs::def_0()); /* todo: replace: * expect_symbol_or_function_signature() @@ -928,8 +927,6 @@ namespace xo { exprstate::print(std::ostream & os) const { os << ""; } From 5d3e92d1144f319d403dcc5259a72562362af332 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 8 Aug 2024 16:34:35 -0400 Subject: [PATCH 071/191] xo-reader: refactor: mv expr_progress impl -new-> progress_xs.*pp --- include/xo/reader/exprstate.hpp | 4 +- include/xo/reader/progress_xs.hpp | 70 ++++++++++ src/reader/CMakeLists.txt | 3 +- src/reader/exprstate.cpp | 92 ++++--------- src/reader/progress_xs.cpp | 216 ++++++++++++++++++++++++++++++ 5 files changed, 316 insertions(+), 69 deletions(-) create mode 100644 include/xo/reader/progress_xs.hpp create mode 100644 src/reader/progress_xs.cpp diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ae1a0bf0..82ffe0c2 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -87,9 +87,11 @@ namespace xo { static std::unique_ptr expect_type() { return std::make_unique(exprstate(exprstatetype::expect_type, nullptr)); } +#ifdef RELOCATED static std::unique_ptr make_expr_progress(rp expr) { return std::make_unique(exprstate(exprstatetype::expr_progress, expr)); } +#endif static std::unique_ptr lparen_0() { return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr)); } @@ -135,7 +137,7 @@ namespace xo { /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; - protected: + public: virtual void on_def(exprstatestack * p_stack); virtual void on_symbol(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp new file mode 100644 index 00000000..5b2ce28f --- /dev/null +++ b/include/xo/reader/progress_xs.hpp @@ -0,0 +1,70 @@ +/** @file progress_xs.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "exprstate.hpp" +//#include + +namespace xo { + namespace scm { + /** @class progress_xs + * @brief state machine for parsing a schematica runtime-value-expression + **/ + class progress_xs : public exprstate { + public: + progress_xs(rp valex); + virtual ~progress_xs() = default; + + static const progress_xs * from(const exprstate * x) { return dynamic_cast(x); } + + static std::unique_ptr make(rp valex); + + virtual bool admits_definition() const override; + virtual bool admits_symbol() const override; + virtual bool admits_colon() const override; + virtual bool admits_semicolon() const override; + virtual bool admits_singleassign() const override; + virtual bool admits_leftparen() const override; + virtual bool admits_rightparen() const override; + virtual bool admits_f64() const override; + + // virtual void on_f64(..) override + virtual void on_def(exprstatestack * p_stack) override; + + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_typedescr(TypeDescr td, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) override; + virtual void on_colon(exprstatestack * p_stack) override; + virtual void on_semicolon(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_singleassign(exprstatestack * p_stack) override; + virtual void on_leftparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_rightparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + + virtual void print(std::ostream & os) const override; + + private: +#ifdef NOT_YET + /** populate an expression here **/ + rp gen_expr_; +#endif + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end progress_xs.hpp **/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 8896040e..29bb9155 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -5,7 +5,8 @@ set(SELF_SRCS parser.cpp reader.cpp exprstate.cpp - define_xs.cpp) + define_xs.cpp + progress_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index db98d197..b463c00b 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -2,6 +2,7 @@ #include "exprstate.hpp" #include "define_xs.hpp" +#include "progress_xs.hpp" //#include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" //#include "xo/expression/ConvertExpr.hpp" @@ -59,6 +60,8 @@ namespace xo { case exprstatetype::expect_type: return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: @@ -94,6 +97,8 @@ namespace xo { return true; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -126,6 +131,8 @@ namespace xo { return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -149,6 +156,8 @@ namespace xo { case exprstatetype::expect_type: return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return true; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: @@ -193,6 +202,8 @@ namespace xo { return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -228,6 +239,8 @@ namespace xo { return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -276,7 +289,8 @@ namespace xo { return false; case exprstatetype::expr_progress: - /* todo: will parse as function call */ + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -318,9 +332,6 @@ namespace xo { return false; case exprstatetype::expr_progress: - /* satisfies expression form */ - return true; - case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -475,9 +486,7 @@ namespace xo { } case exprstatetype::expr_progress: - /* illegal input, e.g. - * foo bar - */ + /* unreachable */ assert(false); return; @@ -519,6 +528,7 @@ namespace xo { return; case exprstatetype::expr_progress: + /* unreachable */ assert(false); return; @@ -549,8 +559,8 @@ namespace xo { } void - exprstate::on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr) + exprstate::on_semicolon(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -564,33 +574,7 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::expr_progress) { - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); - /* control here on input like: - * (1.234; - * - * a. '(' sets up stack [lparen_0:expect_rhs_expression] - * (see exprstate::on_leftparen()) - * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] - * (see exprstate::on_f64()) - * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] - * deliver expresssion to expect_rhs_expression.on_expr() - * (see exprstate::on_expr()) - * d. expr_rhs_expression forwards expression to [lparen_0] - * e. lparen_0 advances to [lparen_1] - * f. now deliver semicolon; [lparen_1] rejects - */ - - p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); - } else { - assert(false); - } + assert(false); } void @@ -650,33 +634,8 @@ namespace xo { } if (this->exs_type_ == exprstatetype::expr_progress) { - /* stack may be something like: - * - * lparen_0 - * expect_rhs_expression - * expr_progress - * <-- rightparen - * - * 1. rightparen completes expression-in-progress - * 2. rightparen must then match innermost waiting lparen_0 - */ - - /* right paren confirms stack expression */ - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); - - if (p_stack->empty()) { - throw std::runtime_error(tostr(self_name, - ": expected non-empty parsing stack")); - } - - log && log(xtag("stack", p_stack)); - - p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); - - /* now deliver rightparen */ - p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); + /* unreachable -- see progress_xs::on_rightparen() */ + assert(false); } else if (this->exs_type_ == exprstatetype::lparen_1) { rp expr = this->gen_expr_; @@ -709,7 +668,7 @@ namespace xo { * \---tk---/ */ p_stack->push_exprstate - (exprstate::make_expr_progress + (progress_xs::make (Constant::make(tk.f64_value()))); } else { assert(false); @@ -834,7 +793,7 @@ namespace xo { case exprstatetype::lparen_0: { this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ - p_stack->push_exprstate(exprstate::make_expr_progress(expr.promote())); + p_stack->push_exprstate(progress_xs::make(expr.promote())); return; } @@ -865,8 +824,7 @@ namespace xo { assert(false); return; case exprstatetype::expr_progress: - /* consecutive expressions isn't legal - */ + /* unreachable */ assert(false); return; case exprstatetype::invalid: diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp new file mode 100644 index 00000000..a9701901 --- /dev/null +++ b/src/reader/progress_xs.cpp @@ -0,0 +1,216 @@ +/* @file progress_xs.cpp */ + +#include "progress_xs.hpp" + +namespace xo { + namespace scm { + std::unique_ptr + progress_xs::make(rp valex) { + return std::make_unique(progress_xs(std::move(valex))); + } + + progress_xs::progress_xs(rp valex) + : exprstate(exprstatetype::expr_progress, + std::move(valex)) + {} + + bool + progress_xs::admits_definition() const { return false; } + + bool + progress_xs::admits_symbol() const { return false; } + + bool + progress_xs::admits_colon() const { return false; } + + bool + progress_xs::admits_semicolon() const { return true; } + + bool + progress_xs::admits_singleassign() const { return false; } + + /* todo: will parse as function call */ + bool + progress_xs::admits_leftparen() const { return false; } + + bool + progress_xs::admits_rightparen() const { + /* satisfies expression form */ + return true; + } + + bool + progress_xs::admits_f64() const { return false; } + + void + progress_xs::on_def(exprstatestack * /*p_stack*/) { + constexpr const char * self_name = "progress_xs::on_def"; + + /* nothing here - admits_definition unconditionally false */ + throw std::runtime_error(tostr(self_name, + ": unexpected keyword 'def' for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_expr(ref::brw /*expr*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* consecutive expressions isn't legal */ + assert(false); + } + + void + progress_xs::on_symbol(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* illegal input, e.g. + * foo bar + */ + assert(false); + } + + void + progress_xs::on_typedescr(TypeDescr /*td*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* unreachable */ + assert(false); + } + + void + progress_xs::on_colon(exprstatestack * /*p_stack*/) { + constexpr const char * self_name = "progress_xs::on_colon"; + + throw std::runtime_error(tostr(self_name, + ": unexpected colon for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + /* control here on input like: + * (1.234; + * + * a. '(' sets up stack [lparen_0:expect_rhs_expression] + * (see exprstate::on_leftparen()) + * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] + * (see exprstate::on_f64()) + * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] + * deliver expresssion to expect_rhs_expression.on_expr() + * (see exprstate::on_expr()) + * d. expr_rhs_expression forwards expression to [lparen_0] + * e. lparen_0 advances to [lparen_1] + * f. now deliver semicolon; [lparen_1] rejects + */ + + p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); + } + + void + progress_xs::on_singleassign(exprstatestack * /*p_stack*/) { + constexpr const char * self_name = "progress_xs::on_singleassign"; + + throw std::runtime_error(tostr(self_name, + ": unexpected equals for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_leftparen(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_leftparen"; + + throw std::runtime_error(tostr(self_name, + ": unexpected leftparen '(' for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "progress_xs::on_rightparen"; + + /* stack may be something like: + * + * lparen_0 + * expect_rhs_expression + * expr_progress + * <-- rightparen + * + * 1. rightparen completes expression-in-progress + * 2. rightparen must then match innermost waiting lparen_0 + */ + + /* right paren confirms stack expression */ + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); + + if (p_stack->empty()) { + throw std::runtime_error(tostr(self_name, + ": expected non-empty parsing stack")); + } + + log && log(xtag("stack", p_stack)); + + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + + /* now deliver rightparen */ + p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); + + } + + void + progress_xs::on_f64(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "progress_xs::on_f64"; + + throw std::runtime_error(tostr(self_name, + ": unexpected floating-point literal for parsing state", + xtag("state", *this))); + } + + void + progress_xs::print(std::ostream & os) const { + os << ""; + } + + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end progress_xs.cpp */ From ccfd0660d5e30b99760dad93adf03b1150f18bc1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 11:41:40 -0400 Subject: [PATCH 072/191] xo-reader: wip: + paren_xs impl [not used] --- include/xo/reader/paren_xs.hpp | 88 +++++++++++++ src/reader/CMakeLists.txt | 3 +- src/reader/paren_xs.cpp | 222 +++++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 include/xo/reader/paren_xs.hpp create mode 100644 src/reader/paren_xs.cpp diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp new file mode 100644 index 00000000..a8211d96 --- /dev/null +++ b/include/xo/reader/paren_xs.hpp @@ -0,0 +1,88 @@ +/** @file paren_xs.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "exprstate.hpp" +//#include + +namespace xo { + namespace scm { + enum class parenexprstatetype { + invalid = -1, + + lparen_0, + lparen_1, + + n_parenexprstatetype, + }; + + /** @class paren_xs + * @brief state machine for handling parentheses in expressions + **/ + class paren_xs : public exprstate { + public: + //paren_xs(rp valex); + virtual ~paren_xs() = default; + + static const paren_xs * from(const exprstate * x) { return dynamic_cast(x); } + + //static std::unique_ptr make(); + + virtual bool admits_definition() const override; + virtual bool admits_symbol() const override; + virtual bool admits_colon() const override; + virtual bool admits_semicolon() const override; + virtual bool admits_singleassign() const override; + virtual bool admits_leftparen() const override; + virtual bool admits_rightparen() const override; + virtual bool admits_f64() const override; + + // virtual void on_f64(..) override + virtual void on_def(exprstatestack * p_stack) override; + + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_symbol(const std::string & symbol, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_typedescr(TypeDescr td, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) override; + + virtual void on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_colon(exprstatestack * p_stack) override; + virtual void on_semicolon(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_singleassign(exprstatestack * p_stack) override; + virtual void on_leftparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_rightparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + + virtual void print(std::ostream & os) const override; + + private: +#ifdef NOT_YET + /** + * ( foo ... ) + * ^ + * | + * lparen_0 + **/ + parenexprstatetype parenxs_type_; +#endif + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end paren_xs.hpp **/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 29bb9155..4741fa3d 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -6,7 +6,8 @@ set(SELF_SRCS reader.cpp exprstate.cpp define_xs.cpp - progress_xs.cpp) + progress_xs.cpp + paren_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp new file mode 100644 index 00000000..3fe5e40d --- /dev/null +++ b/src/reader/paren_xs.cpp @@ -0,0 +1,222 @@ +/* @file paren_xs.cpp */ + +#include "paren_xs.hpp" +#include "progress_xs.hpp" + +namespace xo { + namespace scm { + bool + paren_xs::admits_definition() const { return false; } + + bool + paren_xs::admits_symbol() const { return true; } + + bool + paren_xs::admits_colon() const { return false; } + + bool + paren_xs::admits_semicolon() const { return false; } + + bool + paren_xs::admits_singleassign() const { return false; } + + bool + paren_xs::admits_leftparen() const { /*unreachable*/ return false; } + + /** TODO: fixme **/ + bool + paren_xs::admits_rightparen() const { return exprstate::admits_rightparen(); } + + /** TODO: fixme **/ + bool + paren_xs::admits_f64() const { return exprstate::admits_f64(); } + + void + paren_xs::on_def(exprstatestack * /*p_stack*/) { + constexpr const char * c_self_name = "paren_xs::on_def"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected keyword 'def' for parsing state", + xtag("state", *this))); + } + + void + paren_xs::on_symbol(const token_type & /*tk*/, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); + + //constexpr const char * self_name = "paren_xs::on_symbol"; + + /* TODO: lparen_0: treat as variable reference */ + + assert(false); + } + + void + paren_xs::on_typedescr(TypeDescr /*td*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + assert(false); + return; + } + + void + paren_xs::on_colon(exprstatestack * /*p_stack*/) + { + constexpr const char * c_self_name = "paren_xs::on_colon"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected colon for parsing state", + xtag("state", *this))); + } + + void + paren_xs::on_semicolon(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr const char * c_self_name = "paren_xs::on_semicolon"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected semicolon for parsing state", + xtag("state", *this))); + } + + void + paren_xs::on_singleassign(exprstatestack * /*p_stack*/) + { + constexpr const char * c_self_name = "paren_xs::on_singleassign"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected equals for parsing state", + xtag("state", *this))); + } + + void + paren_xs::on_leftparen(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr const char * c_self_name = "paren_xs::on_leftparen"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected leftparen '(' for parsing state", + xtag("state", *this))); + } + + void + paren_xs::on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "paren_xs::on_rightparen"; + + if (!this->admits_rightparen()) + { + throw std::runtime_error(tostr(self_name, + ": unexpected rightparen ')' for parsing state", + xtag("state", *this))); + } + + if (this->exs_type_ == exprstatetype::lparen_1) { + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); + + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + } + } + + void + paren_xs::on_f64(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "paren_xs::on_f64"; + + if (!this->admits_f64()) + { + throw std::runtime_error(tostr(c_self_name, + ": unexpected floating-point literal for parsing state", + xtag("state", *this))); + } + + assert(false); + } + + void + paren_xs::on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr)); + + switch (this->exs_type_) { + case exprstatetype::lparen_0: { + this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ + p_stack->push_exprstate(progress_xs::make(expr.promote())); + + return; + } + + case exprstatetype::lparen_1: { + this->gen_expr_ = expr.promote(); + + /* expect immediate incoming call, this time to on_rightparen() */ + return; + } + + default: + /* unreachable */ + assert(false); + return; + } + } /*on_expr*/ + + void + paren_xs::on_symbol(const std::string & /*symbol_name*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + switch(this->exs_type_) { + case exprstatetype::lparen_0: + case exprstatetype::lparen_1: + /* NOT IMPLEMENTED */ + assert(false); + return; + + default: + /* unreachable */ + assert(false); + return; + } + } + + void + paren_xs::print(std::ostream & os) const { + os << ""; + } + + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end paren_xs.cpp */ From 67e76b5d8cab6f629403597a0d337518fd3c2a37 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 11:42:05 -0400 Subject: [PATCH 073/191] xo-reader: nit: fixup progress_xs.print() output --- src/reader/progress_xs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index a9701901..6e1d743a 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -201,7 +201,7 @@ namespace xo { void progress_xs::print(std::ostream & os) const { - os << " Date: Fri, 9 Aug 2024 11:55:22 -0400 Subject: [PATCH 074/191] xo-reader: refactor: splitoff paren handline -> paren_xs --- include/xo/reader/exprstate.hpp | 19 +--- include/xo/reader/paren_xs.hpp | 6 +- src/reader/exprstate.cpp | 174 +++++++++++--------------------- src/reader/paren_xs.cpp | 65 +++++++++--- 4 files changed, 116 insertions(+), 148 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 82ffe0c2..fa0b466f 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -20,10 +20,8 @@ namespace xo { defexpr, - /* lparen_0: look for expression; capture + advance to lparen_1 */ - lparen_0, - /* lparen_1: expect rightparen */ - lparen_1, + /* handle parenthesized expression */ + parenexpr, expect_rhs_expression, expect_symbol, @@ -45,17 +43,6 @@ namespace xo { class exprstatestack; -#ifdef NOT_YET - class exprstateaux { - public: - }; - - class lparen_xsa : public exprstateaux { - public: - private: - }; -#endif - class define_xs; /** state associated with a partially-parsed expression. @@ -92,9 +79,11 @@ namespace xo { return std::make_unique(exprstate(exprstatetype::expr_progress, expr)); } #endif +#ifdef RELOCATED static std::unique_ptr lparen_0() { return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr)); } +#endif exprstatetype exs_type() const { return exs_type_; } diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index a8211d96..a6a8eb3e 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -24,12 +24,12 @@ namespace xo { **/ class paren_xs : public exprstate { public: - //paren_xs(rp valex); + paren_xs(); virtual ~paren_xs() = default; static const paren_xs * from(const exprstate * x) { return dynamic_cast(x); } - //static std::unique_ptr make(); + static std::unique_ptr lparen_0(); virtual bool admits_definition() const override; virtual bool admits_symbol() const override; @@ -71,7 +71,6 @@ namespace xo { virtual void print(std::ostream & os) const override; private: -#ifdef NOT_YET /** * ( foo ... ) * ^ @@ -79,7 +78,6 @@ namespace xo { * lparen_0 **/ parenexprstatetype parenxs_type_; -#endif }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index b463c00b..351fbf5a 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -3,6 +3,7 @@ #include "exprstate.hpp" #include "define_xs.hpp" #include "progress_xs.hpp" +#include "paren_xs.hpp" //#include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" //#include "xo/expression/ConvertExpr.hpp" @@ -23,10 +24,8 @@ namespace xo { return "expect_toplevel_expression_sequence"; case exprstatetype::defexpr: return "defexpr"; - case exprstatetype::lparen_0: - return "lparen_0"; - case exprstatetype::lparen_1: - return "lparen_1"; + case exprstatetype::parenexpr: + return "parenexpr"; case exprstatetype::expect_rhs_expression: return "expect_rhs_expression"; case exprstatetype::expect_symbol: @@ -49,11 +48,10 @@ namespace xo { return true; case exprstatetype::defexpr: + case exprstatetype::parenexpr: /* unreachable */ assert(false); return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: return false; case exprstatetype::expect_symbol: @@ -79,12 +77,11 @@ namespace xo { return false; case exprstatetype::defexpr: + case exprstatetype::parenexpr: /* unreachable */ assert(false); return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: /* treat symbol as variable name */ return true; @@ -116,12 +113,11 @@ namespace xo { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::defexpr: - /* unreachable -- redirects to define_xs::admits_colon() */ + case exprstatetype::parenexpr: + /* unreachable -- redirects to define_xs::admits_colon() etc */ assert(false); return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: /* rhs-expressions (or expressions for that matter) * may not begin with a colon @@ -149,8 +145,7 @@ namespace xo { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::defexpr: - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: + case exprstatetype::parenexpr: case exprstatetype::expect_rhs_expression: case exprstatetype::expect_symbol: case exprstatetype::expect_type: @@ -187,12 +182,11 @@ namespace xo { * note that we skip from def_1 -> def_4 if '=' instead of ':' */ case exprstatetype::defexpr: - /* unreachable - redirects to define_xs */ + case exprstatetype::parenexpr: + /* unreachable - redirects to define_xs etrc */ assert(false); return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: case exprstatetype::expect_rhs_expression: /* rhs-expressions (or expressions for that matter) * may not begin with singleassign '=' @@ -215,43 +209,6 @@ namespace xo { return false; } - bool - exprstate::admits_f64() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - - case exprstatetype::defexpr: - /* unreachable - redirects to define_xs */ - assert(false); - return false; - - case exprstatetype::lparen_0: - return true; - - case exprstatetype::lparen_1: - return false; - - case exprstatetype::expect_rhs_expression: - return true; - - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } - bool exprstate::admits_leftparen() const { switch (exs_type_) { @@ -268,16 +225,11 @@ namespace xo { return false; case exprstatetype::defexpr: + case exprstatetype::parenexpr: /* unreachable - redirects to define_xs */ assert(false); return false; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - /* unreachable */ - assert(false); - return false; - case exprstatetype::expect_rhs_expression: /* can always begin non-toplevel expression with '(' */ return true; @@ -310,18 +262,11 @@ namespace xo { return false; case exprstatetype::defexpr: + case exprstatetype::parenexpr: /* unreachable - redirects to define_xs */ assert(false); return false; - case exprstatetype::lparen_0: - /* unreachable -- will have pushed expect_rhs_expression */ - assert(false); - return false; - - case exprstatetype::lparen_1: - return true; - case exprstatetype::expect_rhs_expression: return false; @@ -342,6 +287,38 @@ namespace xo { return false; } + bool + exprstate::admits_f64() const { + switch (exs_type_) { + case exprstatetype::expect_toplevel_expression_sequence: + + case exprstatetype::defexpr: + case exprstatetype::parenexpr: + /* unreachable - redirects to define_xs */ + assert(false); + return false; + + case exprstatetype::expect_rhs_expression: + return true; + + case exprstatetype::expect_symbol: + case exprstatetype::expect_type: + return false; + + case exprstatetype::expr_progress: + /* unreachable */ + assert(false); + return false; + + case exprstatetype::invalid: + case exprstatetype::n_exprstatetype: + /* unreachable */ + return false; + } + + return false; + } + void exprstate::on_def(exprstatestack * p_stack) { constexpr bool c_debug_flag = true; @@ -400,21 +377,11 @@ namespace xo { break; case exprstatetype::defexpr: + case exprstatetype::parenexpr: /* unreachable - redirects to define_xs */ assert(false); return; - case exprstatetype::lparen_0: - /* todo: variable reference */ - assert(false); - break; - - case exprstatetype::lparen_1: - /* unreachable */ - - assert(false); - break; - case exprstatetype::expect_rhs_expression: { /* various possibilities when looking for rhs expression: @@ -503,21 +470,17 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { - /* returning type description to somethign that wants it */ + /* returning type description to something that wants it */ switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::defexpr: + case exprstatetype::parenexpr: /* unreachable - redirects to define_xs */ assert(false); return; - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - assert(false); - return; - case exprstatetype::expect_rhs_expression: case exprstatetype::expect_type: case exprstatetype::expect_symbol: @@ -612,14 +575,14 @@ namespace xo { if (this->exs_type_ == exprstatetype::expect_rhs_expression) { /* push lparen_0 to remember to look for subsequent rightparen. */ - p_stack->push_exprstate(exprstate::lparen_0()); + p_stack->push_exprstate(paren_xs::lparen_0()); p_stack->push_exprstate(exprstate::expect_rhs_expression()); } } void - exprstate::on_rightparen(exprstatestack * p_stack, - rp * p_emit_expr) + exprstate::on_rightparen(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -633,15 +596,10 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::expr_progress) { - /* unreachable -- see progress_xs::on_rightparen() */ + if (this->exs_type_ == exprstatetype::expr_progress + || this->exs_type_ == exprstatetype::parenexpr) { + /* unreachable -- see progress_xs::on_rightparen() etc */ assert(false); - } else if (this->exs_type_ == exprstatetype::lparen_1) { - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); - - p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); } } @@ -787,24 +745,11 @@ namespace xo { *p_emit_expr = expr.promote(); return; case exprstatetype::defexpr: - /* unreachable. redirects to define_xs::on_expr() */ + case exprstatetype::parenexpr: + /* unreachable. redirects to define_xs::on_expr() etc */ assert(false); return; - case exprstatetype::lparen_0: { - this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ - p_stack->push_exprstate(progress_xs::make(expr.promote())); - - return; - } - - case exprstatetype::lparen_1: { - this->gen_expr_ = expr.promote(); - - /* expect immediate incoming call, this time to on_rightparen() */ - return; - } - case exprstatetype::expect_rhs_expression: { std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ @@ -852,13 +797,8 @@ namespace xo { assert(false); return; case exprstatetype::defexpr: - /* unreachable - redirects to define_xs */ - assert(false); - return; - - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: - /* NOT IMPLEMENTED */ + case exprstatetype::parenexpr: + /* unreachable - redirects to define_xs etc */ assert(false); return; diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 3fe5e40d..e3d41fc9 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -5,6 +5,15 @@ namespace xo { namespace scm { + paren_xs::paren_xs() + : parenxs_type_{parenexprstatetype::lparen_0} + {} + + std::unique_ptr + paren_xs::lparen_0() { + return std::make_unique(paren_xs()); + } + bool paren_xs::admits_definition() const { return false; } @@ -23,13 +32,45 @@ namespace xo { bool paren_xs::admits_leftparen() const { /*unreachable*/ return false; } - /** TODO: fixme **/ bool - paren_xs::admits_rightparen() const { return exprstate::admits_rightparen(); } + paren_xs::admits_rightparen() const { + switch (parenxs_type_) { + case parenexprstatetype::lparen_0: + /* unreachable */ + assert(false); + return false; + + case parenexprstatetype::lparen_1: + return true; + + case parenexprstatetype::invalid: + case parenexprstatetype::n_parenexprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } - /** TODO: fixme **/ bool - paren_xs::admits_f64() const { return exprstate::admits_f64(); } + paren_xs::admits_f64() const { + switch (parenxs_type_) { + case parenexprstatetype::lparen_0: + return true; + + case parenexprstatetype::lparen_1: + return false; + + case parenexprstatetype::invalid: + case parenexprstatetype::n_parenexprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } void paren_xs::on_def(exprstatestack * /*p_stack*/) { @@ -124,7 +165,7 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::lparen_1) { + if (this->parenxs_type_ == parenexprstatetype::lparen_1) { rp expr = this->gen_expr_; std::unique_ptr self = p_stack->pop_exprstate(); @@ -164,15 +205,15 @@ namespace xo { log && log(xtag("exstype", this->exs_type_), xtag("expr", expr)); - switch (this->exs_type_) { - case exprstatetype::lparen_0: { - this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ + switch (this->parenxs_type_) { + case parenexprstatetype::lparen_0: { + this->parenxs_type_ = parenexprstatetype::lparen_1; /* wants on_rightparen */ p_stack->push_exprstate(progress_xs::make(expr.promote())); return; } - case exprstatetype::lparen_1: { + case parenexprstatetype::lparen_1: { this->gen_expr_ = expr.promote(); /* expect immediate incoming call, this time to on_rightparen() */ @@ -191,9 +232,9 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { - switch(this->exs_type_) { - case exprstatetype::lparen_0: - case exprstatetype::lparen_1: + switch(this->parenxs_type_) { + case parenexprstatetype::lparen_0: + case parenexprstatetype::lparen_1: /* NOT IMPLEMENTED */ assert(false); return; From b813e55194d163126faa609ae5f0a3a900be1216 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 12:58:11 -0400 Subject: [PATCH 075/191] xo-reader: refactor: demote exprstate.gen_expr to leaves that care --- include/xo/reader/exprstate.hpp | 29 ++++++++--------------------- include/xo/reader/paren_xs.hpp | 2 ++ include/xo/reader/progress_xs.hpp | 2 -- src/reader/define_xs.cpp | 3 +-- src/reader/progress_xs.cpp | 4 ++-- 5 files changed, 13 insertions(+), 27 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index fa0b466f..ced48160 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -56,34 +56,23 @@ namespace xo { public: exprstate() = default; - exprstate(exprstatetype exs_type, - rp candidate_expr) - : exs_type_{exs_type}, - gen_expr_{std::move(candidate_expr)} {} + exprstate(exprstatetype exs_type) + : exs_type_{exs_type} + {} virtual ~exprstate() = default; static std::unique_ptr expect_toplevel_expression_sequence() { - return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence)); } static std::unique_ptr expect_rhs_expression() { - return std::make_unique(exprstate(exprstatetype::expect_rhs_expression, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_rhs_expression)); } static std::unique_ptr expect_symbol() { - return std::make_unique(exprstate(exprstatetype::expect_symbol, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_symbol)); } static std::unique_ptr expect_type() { - return std::make_unique(exprstate(exprstatetype::expect_type, nullptr)); + return std::make_unique(exprstate(exprstatetype::expect_type)); } -#ifdef RELOCATED - static std::unique_ptr make_expr_progress(rp expr) { - return std::make_unique(exprstate(exprstatetype::expr_progress, expr)); - } -#endif -#ifdef RELOCATED - static std::unique_ptr lparen_0() { - return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr)); - } -#endif exprstatetype exs_type() const { return exs_type_; } @@ -144,10 +133,8 @@ namespace xo { rp * p_emit_expr); protected: + /** explicit subtype: identifies derived class **/ exprstatetype exs_type_; - - /** generic expression **/ - rp gen_expr_; }; /*exprstate*/ inline std::ostream & diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index a6a8eb3e..91d4a633 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -78,6 +78,8 @@ namespace xo { * lparen_0 **/ parenexprstatetype parenxs_type_; + /** populate expression (representing parenthesized value) here **/ + rp gen_expr_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 5b2ce28f..62fba624 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -58,10 +58,8 @@ namespace xo { virtual void print(std::ostream & os) const override; private: -#ifdef NOT_YET /** populate an expression here **/ rp gen_expr_; -#endif }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index d1f93984..5ecb82f5 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -10,8 +10,7 @@ namespace xo { } define_xs::define_xs(rp def_expr) - : exprstate(exprstatetype::defexpr, - nullptr /*gen_expr*/), + : exprstate(exprstatetype::defexpr), defxs_type_{defexprstatetype::def_0}, def_expr_{std::move(def_expr)} {} diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 6e1d743a..2070e909 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -10,8 +10,8 @@ namespace xo { } progress_xs::progress_xs(rp valex) - : exprstate(exprstatetype::expr_progress, - std::move(valex)) + : exprstate(exprstatetype::expr_progress), + gen_expr_{std::move(valex)} {} bool From 49cb0f0bba2c4975289fe759c3807515b459c7cb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:06:34 -0400 Subject: [PATCH 076/191] xo-reader: tidy: rename expstate.on_symbol() -> on_symbol_token() --- include/xo/reader/exprstate.hpp | 21 ++++++++++++++++----- include/xo/reader/paren_xs.hpp | 6 +++--- include/xo/reader/progress_xs.hpp | 6 +++--- src/reader/exprstate.cpp | 8 ++++---- src/reader/paren_xs.cpp | 6 +++--- src/reader/progress_xs.cpp | 6 +++--- 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ced48160..6e2f5481 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -18,15 +18,24 @@ namespace xo { /** toplevel of some translation unit **/ expect_toplevel_expression_sequence, + /** handle define-expression + * see @ref define_xs + **/ defexpr, - /* handle parenthesized expression */ + /** handle parenthesized expression + * see @ref paren_xs + **/ parenexpr, expect_rhs_expression, expect_symbol, expect_type, + /** handle expression-in-progress, + * in case infix operators to follow + * see @ref progress_xs + **/ expr_progress, n_exprstatetype @@ -115,11 +124,13 @@ namespace xo { /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; - public: + // ----- input methods ----- + virtual void on_def(exprstatestack * p_stack); - virtual void on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + /** handle incoming symbol token **/ + virtual void on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); virtual void on_colon(exprstatestack * p_stack); virtual void on_semicolon(exprstatestack * p_stack, rp * p_emit_expr); diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 91d4a633..964b8dc3 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -53,9 +53,9 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; - virtual void on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + virtual void on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; virtual void on_colon(exprstatestack * p_stack) override; virtual void on_semicolon(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 62fba624..7d6a25f1 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -37,9 +37,9 @@ namespace xo { virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; - virtual void on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + virtual void on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; virtual void on_typedescr(TypeDescr td, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 351fbf5a..b83cad6a 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -348,9 +348,9 @@ namespace xo { } void - exprstate::on_symbol(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + exprstate::on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -662,7 +662,7 @@ namespace xo { return; case tokentype::tk_symbol: - this->on_symbol(tk, p_stack, p_emit_expr); + this->on_symbol_token(tk, p_stack, p_emit_expr); return; case tokentype::tk_leftparen: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index e3d41fc9..f9ed033c 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -82,9 +82,9 @@ namespace xo { } void - paren_xs::on_symbol(const token_type & /*tk*/, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + paren_xs::on_symbol_token(const token_type & /*tk*/, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 2070e909..7ac56de5 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -62,9 +62,9 @@ namespace xo { } void - progress_xs::on_symbol(const token_type & /*tk*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + progress_xs::on_symbol_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { /* illegal input, e.g. * foo bar From 1fcac9485b8ad239c27d884f4152b48948e6d74e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:12:01 -0400 Subject: [PATCH 077/191] xo-reader: refactor: rename exprstate.on_colon() -> on_colon_token --- include/xo/reader/define_xs.hpp | 3 ++- include/xo/reader/exprstate.hpp | 4 +++- include/xo/reader/paren_xs.hpp | 3 ++- include/xo/reader/progress_xs.hpp | 3 ++- src/reader/define_xs.cpp | 4 +++- src/reader/exprstate.cpp | 6 ++++-- src/reader/paren_xs.cpp | 3 ++- src/reader/progress_xs.cpp | 4 +++- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 3a740a32..bee7d24f 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -60,7 +60,8 @@ namespace xo { virtual void on_typedescr(TypeDescr td, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; - virtual void on_colon(exprstatestack * p_stack) override; + virtual void on_colon_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_semicolon(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_singleassign(exprstatestack * p_stack) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 6e2f5481..2f0c9e6a 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -131,7 +131,9 @@ namespace xo { virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); - virtual void on_colon(exprstatestack * p_stack); + /** handle incoming ':' token **/ + virtual void on_colon_token(const token_type & tk, + exprstatestack * p_stack); virtual void on_semicolon(exprstatestack * p_stack, rp * p_emit_expr); virtual void on_singleassign(exprstatestack * p_stack); diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 964b8dc3..fa63f212 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -56,7 +56,8 @@ namespace xo { virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; - virtual void on_colon(exprstatestack * p_stack) override; + virtual void on_colon_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_semicolon(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_singleassign(exprstatestack * p_stack) override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 7d6a25f1..e0e2c7db 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -43,7 +43,8 @@ namespace xo { virtual void on_typedescr(TypeDescr td, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; - virtual void on_colon(exprstatestack * p_stack) override; + virtual void on_colon_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_semicolon(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_singleassign(exprstatestack * p_stack) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 5ecb82f5..82081331 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -326,7 +326,9 @@ namespace xo { } void - define_xs::on_colon(exprstatestack * p_stack) { + define_xs::on_colon_token(const token_type & /*tk*/, + exprstatestack * p_stack) + { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index b83cad6a..bb8c1a18 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -504,7 +504,9 @@ namespace xo { } void - exprstate::on_colon(exprstatestack * /*p_stack*/) { + exprstate::on_colon_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) + { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -686,7 +688,7 @@ namespace xo { return; case tokentype::tk_colon: - this->on_colon(p_stack); + this->on_colon_token(tk, p_stack); return; case tokentype::tk_doublecolon: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index f9ed033c..ebc07527 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -108,7 +108,8 @@ namespace xo { } void - paren_xs::on_colon(exprstatestack * /*p_stack*/) + paren_xs::on_colon_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) { constexpr const char * c_self_name = "paren_xs::on_colon"; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 7ac56de5..32964064 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -82,7 +82,9 @@ namespace xo { } void - progress_xs::on_colon(exprstatestack * /*p_stack*/) { + progress_xs::on_colon_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) + { constexpr const char * self_name = "progress_xs::on_colon"; throw std::runtime_error(tostr(self_name, From 544c1def4a00fc6a8a759b0e58e28f97ceb77a25 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:16:52 -0400 Subject: [PATCH 078/191] xo-reader: rename+: exprstate.on_semicolon() -> on_semicolon_token() --- include/xo/reader/define_xs.hpp | 5 +++-- include/xo/reader/exprstate.hpp | 6 ++++-- include/xo/reader/paren_xs.hpp | 5 +++-- include/xo/reader/progress_xs.hpp | 5 +++-- src/reader/define_xs.cpp | 5 +++-- src/reader/exprstate.cpp | 7 ++++--- src/reader/paren_xs.cpp | 5 +++-- src/reader/progress_xs.cpp | 7 ++++--- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index bee7d24f..b90cde31 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -62,8 +62,9 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; - virtual void on_semicolon(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_semicolon_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_singleassign(exprstatestack * p_stack) override; virtual void on_leftparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 2f0c9e6a..c7a419d3 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -134,8 +134,10 @@ namespace xo { /** handle incoming ':' token **/ virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack); - virtual void on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr); + /** handle incoming ';' token **/ + virtual void on_semicolon_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); virtual void on_singleassign(exprstatestack * p_stack); virtual void on_leftparen(exprstatestack * p_stack, rp * p_emit_expr); diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index fa63f212..ed2ad87b 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -58,8 +58,9 @@ namespace xo { rp * p_emit_expr) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; - virtual void on_semicolon(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_semicolon_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_singleassign(exprstatestack * p_stack) override; virtual void on_leftparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index e0e2c7db..a6d3d508 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -45,8 +45,9 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; - virtual void on_semicolon(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_semicolon_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_singleassign(exprstatestack * p_stack) override; virtual void on_leftparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 82081331..512a214b 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -352,8 +352,9 @@ namespace xo { } void - define_xs::on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr) + define_xs::on_semicolon_token(const token_type & /*tk*/, + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index bb8c1a18..9902e75e 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -524,8 +524,9 @@ namespace xo { } void - exprstate::on_semicolon(exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + exprstate::on_semicolon_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -696,7 +697,7 @@ namespace xo { return; case tokentype::tk_semicolon: - this->on_semicolon(p_stack, p_emit_expr); + this->on_semicolon_token(tk, p_stack, p_emit_expr); return; case tokentype::tk_singleassign: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index ebc07527..f8ae4f17 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -119,8 +119,9 @@ namespace xo { } void - paren_xs::on_semicolon(exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + paren_xs::on_semicolon_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr const char * c_self_name = "paren_xs::on_semicolon"; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 32964064..59df672a 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -93,8 +93,9 @@ namespace xo { } void - progress_xs::on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr) + progress_xs::on_semicolon_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -121,7 +122,7 @@ namespace xo { * f. now deliver semicolon; [lparen_1] rejects */ - p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); + p_stack->top_exprstate().on_semicolon_token(tk, p_stack, p_emit_expr); } void From 2cff2b5ca78ad3e99781cf6b75c8a07b1c987f06 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:21:18 -0400 Subject: [PATCH 079/191] xo-reader: rename+: exprstate.on_singleassign() + explicit token --- include/xo/reader/define_xs.hpp | 3 ++- include/xo/reader/exprstate.hpp | 4 +++- include/xo/reader/paren_xs.hpp | 3 ++- include/xo/reader/progress_xs.hpp | 3 ++- src/reader/define_xs.cpp | 3 ++- src/reader/exprstate.cpp | 5 +++-- src/reader/paren_xs.cpp | 3 ++- src/reader/progress_xs.cpp | 4 +++- 8 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index b90cde31..e90abf9f 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -65,7 +65,8 @@ namespace xo { virtual void on_semicolon_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_singleassign(exprstatestack * p_stack) override; + virtual void on_singleassign_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_leftparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_rightparen(exprstatestack * p_stack, diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index c7a419d3..f8921dc9 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -138,7 +138,9 @@ namespace xo { virtual void on_semicolon_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); - virtual void on_singleassign(exprstatestack * p_stack); + /** handle incoming '=' token **/ + virtual void on_singleassign_token(const token_type & tk, + exprstatestack * p_stack); virtual void on_leftparen(exprstatestack * p_stack, rp * p_emit_expr); virtual void on_rightparen(exprstatestack * p_stack, diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index ed2ad87b..821fef13 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -61,7 +61,8 @@ namespace xo { virtual void on_semicolon_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_singleassign(exprstatestack * p_stack) override; + virtual void on_singleassign_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_leftparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_rightparen(exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index a6d3d508..431ad0fd 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -48,7 +48,8 @@ namespace xo { virtual void on_semicolon_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_singleassign(exprstatestack * p_stack) override; + virtual void on_singleassign_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_leftparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_rightparen(exprstatestack * p_stack, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 512a214b..be531be3 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -382,7 +382,8 @@ namespace xo { } void - define_xs::on_singleassign(exprstatestack * p_stack) + define_xs::on_singleassign_token(const token_type & /*tk*/, + exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 9902e75e..236bc895 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -544,7 +544,8 @@ namespace xo { } void - exprstate::on_singleassign(exprstatestack * /*p_stack*/) { + exprstate::on_singleassign_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -701,7 +702,7 @@ namespace xo { return; case tokentype::tk_singleassign: - this->on_singleassign(p_stack); + this->on_singleassign_token(tk, p_stack); return; case tokentype::tk_assign: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index f8ae4f17..8b7ee84d 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -131,7 +131,8 @@ namespace xo { } void - paren_xs::on_singleassign(exprstatestack * /*p_stack*/) + paren_xs::on_singleassign_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) { constexpr const char * c_self_name = "paren_xs::on_singleassign"; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 59df672a..d8ab19d8 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -126,7 +126,9 @@ namespace xo { } void - progress_xs::on_singleassign(exprstatestack * /*p_stack*/) { + progress_xs::on_singleassign_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) + { constexpr const char * self_name = "progress_xs::on_singleassign"; throw std::runtime_error(tostr(self_name, From 8d1ae35075891fea9f2d372bc97b1f5c68e08cfd Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:25:59 -0400 Subject: [PATCH 080/191] xo-reader: rename+: exprstate.on_leftparen() -> on_leftparen_token() --- include/xo/reader/define_xs.hpp | 5 +++-- include/xo/reader/exprstate.hpp | 4 +++- include/xo/reader/paren_xs.hpp | 5 +++-- include/xo/reader/progress_xs.hpp | 5 +++-- src/reader/define_xs.cpp | 5 +++-- src/reader/exprstate.cpp | 7 ++++--- src/reader/paren_xs.cpp | 5 +++-- src/reader/progress_xs.cpp | 5 +++-- 8 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index e90abf9f..bf12e566 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -67,8 +67,9 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack) override; - virtual void on_leftparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_leftparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_rightparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_f64(const token_type & tk, diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index f8921dc9..0a41e5a0 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -141,7 +141,9 @@ namespace xo { /** handle incoming '=' token **/ virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack); - virtual void on_leftparen(exprstatestack * p_stack, + /** handle incoming '(' token **/ + virtual void on_leftparen_token(const token_type & tk, + exprstatestack * p_stack, rp * p_emit_expr); virtual void on_rightparen(exprstatestack * p_stack, rp * p_emit_expr); diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 821fef13..9a9dba83 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -63,8 +63,9 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack) override; - virtual void on_leftparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_leftparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_rightparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_f64(const token_type & tk, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 431ad0fd..a2e8da6c 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -50,8 +50,9 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack) override; - virtual void on_leftparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_leftparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_rightparen(exprstatestack * p_stack, rp * /*p_emit_expr*/) override; virtual void on_f64(const token_type & tk, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index be531be3..3373c0a7 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -409,8 +409,9 @@ namespace xo { } void - define_xs::on_leftparen(exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + define_xs::on_leftparen_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 236bc895..3c53bf74 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -562,8 +562,9 @@ namespace xo { } void - exprstate::on_leftparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) + exprstate::on_leftparen_token(const token_type & /*tk*/, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -670,7 +671,7 @@ namespace xo { return; case tokentype::tk_leftparen: - this->on_leftparen(p_stack, p_emit_expr); + this->on_leftparen_token(tk, p_stack, p_emit_expr); return; case tokentype::tk_rightparen: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 8b7ee84d..afa96b47 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -142,8 +142,9 @@ namespace xo { } void - paren_xs::on_leftparen(exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + paren_xs::on_leftparen_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr const char * c_self_name = "paren_xs::on_leftparen"; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index d8ab19d8..0118132c 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -137,8 +137,9 @@ namespace xo { } void - progress_xs::on_leftparen(exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + progress_xs::on_leftparen_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); From a51f1d65dbc003fa804906c19986065c23c33d59 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:30:41 -0400 Subject: [PATCH 081/191] xo-reader: rename+: exprstate.on_rightparen() + token arg --- include/xo/reader/define_xs.hpp | 5 +++-- include/xo/reader/exprstate.hpp | 6 ++++-- include/xo/reader/paren_xs.hpp | 5 +++-- include/xo/reader/progress_xs.hpp | 5 +++-- src/reader/define_xs.cpp | 5 +++-- src/reader/exprstate.cpp | 7 ++++--- src/reader/paren_xs.cpp | 5 +++-- src/reader/progress_xs.cpp | 7 ++++--- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index bf12e566..87871ac9 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -70,8 +70,9 @@ namespace xo { virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_rightparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_f64(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 0a41e5a0..820ec9d3 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -145,8 +145,10 @@ namespace xo { virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); - virtual void on_rightparen(exprstatestack * p_stack, - rp * p_emit_expr); + /** handle incoming ')' token **/ + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); virtual void on_f64(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 9a9dba83..ce646bfb 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -66,8 +66,9 @@ namespace xo { virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_rightparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_f64(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index a2e8da6c..0d36a0b3 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -53,8 +53,9 @@ namespace xo { virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_rightparen(exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void on_f64(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 3373c0a7..dba2118a 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -429,8 +429,9 @@ namespace xo { } void - define_xs::on_rightparen(exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + define_xs::on_rightparen_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 3c53bf74..d625a758 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -586,8 +586,9 @@ namespace xo { } void - exprstate::on_rightparen(exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + exprstate::on_rightparen_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -675,7 +676,7 @@ namespace xo { return; case tokentype::tk_rightparen: - this->on_rightparen(p_stack, p_emit_expr); + this->on_rightparen_token(tk, p_stack, p_emit_expr); return; case tokentype::tk_leftbracket: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index afa96b47..2b92419e 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -154,8 +154,9 @@ namespace xo { } void - paren_xs::on_rightparen(exprstatestack * p_stack, - rp * p_emit_expr) + paren_xs::on_rightparen_token(const token_type & /*tk*/, + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 0118132c..f2ccf0ea 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -152,8 +152,9 @@ namespace xo { } void - progress_xs::on_rightparen(exprstatestack * p_stack, - rp * p_emit_expr) + progress_xs::on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -186,7 +187,7 @@ namespace xo { p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); /* now deliver rightparen */ - p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); + p_stack->top_exprstate().on_rightparen_token(tk, p_stack, p_emit_expr); } From 892b332a20ca090f36d77f80f6d1a89982e211de Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:36:33 -0400 Subject: [PATCH 082/191] xo-reader: rename: exprstate.on_f64() -> on_f64_token() --- include/xo/reader/define_xs.hpp | 6 +++--- include/xo/reader/exprstate.hpp | 7 ++++--- include/xo/reader/paren_xs.hpp | 6 +++--- include/xo/reader/progress_xs.hpp | 6 +++--- src/reader/define_xs.cpp | 6 +++--- src/reader/exprstate.cpp | 8 ++++---- src/reader/paren_xs.cpp | 6 +++--- src/reader/progress_xs.cpp | 6 +++--- 8 files changed, 26 insertions(+), 25 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 87871ac9..10d53459 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -73,9 +73,9 @@ namespace xo { virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_f64_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void print(std::ostream & os) const override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 820ec9d3..943b70bc 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -149,9 +149,10 @@ namespace xo { virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); - virtual void on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + /** handle incoming floating-point-literal token **/ + virtual void on_f64_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); protected: /** explicit subtype: identifies derived class **/ diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index ce646bfb..8bf137b5 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -69,9 +69,9 @@ namespace xo { virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_f64_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void print(std::ostream & os) const override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 0d36a0b3..3203a274 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -56,9 +56,9 @@ namespace xo { virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; - virtual void on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + virtual void on_f64_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; virtual void print(std::ostream & os) const override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index dba2118a..d7bccf82 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -449,9 +449,9 @@ namespace xo { } void - define_xs::on_f64(const token_type & /*tk*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + define_xs::on_f64_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index d625a758..1a33a503 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -610,9 +610,9 @@ namespace xo { } void - exprstate::on_f64(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + exprstate::on_f64_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -660,7 +660,7 @@ namespace xo { return; case tokentype::tk_f64: - this->on_f64(tk, p_stack, p_emit_expr); + this->on_f64_token(tk, p_stack, p_emit_expr); return; case tokentype::tk_string: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 2b92419e..5446cccb 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -180,9 +180,9 @@ namespace xo { } void - paren_xs::on_f64(const token_type & /*tk*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + paren_xs::on_f64_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index f2ccf0ea..bb51cf02 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -192,9 +192,9 @@ namespace xo { } void - progress_xs::on_f64(const token_type & /*tk*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + progress_xs::on_f64_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); From 60a7ec1cd04908600eab4da7217a6dd5e258eeae Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:42:50 -0400 Subject: [PATCH 083/191] xo-reader: rename+: exprstate.on_def() -> on_def_token() + token arg --- include/xo/reader/exprstate.hpp | 4 +++- include/xo/reader/paren_xs.hpp | 5 ++--- include/xo/reader/progress_xs.hpp | 6 +++--- src/reader/exprstate.cpp | 5 +++-- src/reader/paren_xs.cpp | 4 +++- src/reader/progress_xs.cpp | 4 +++- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 943b70bc..467d2eab 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -126,7 +126,9 @@ namespace xo { // ----- input methods ----- - virtual void on_def(exprstatestack * p_stack); + /** handle incoming 'def' token **/ + virtual void on_def_token(const token_type & tk, + exprstatestack * p_stack); /** handle incoming symbol token **/ virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 8bf137b5..5992837a 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -40,9 +40,6 @@ namespace xo { virtual bool admits_rightparen() const override; virtual bool admits_f64() const override; - // virtual void on_f64(..) override - virtual void on_def(exprstatestack * p_stack) override; - virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; @@ -53,6 +50,8 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; + virtual void on_def_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 3203a274..0a0516cf 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -31,9 +31,6 @@ namespace xo { virtual bool admits_rightparen() const override; virtual bool admits_f64() const override; - // virtual void on_f64(..) override - virtual void on_def(exprstatestack * p_stack) override; - virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; @@ -43,6 +40,9 @@ namespace xo { virtual void on_typedescr(TypeDescr td, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; + + virtual void on_def_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_semicolon_token(const token_type & tk, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 1a33a503..5227135c 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -320,7 +320,8 @@ namespace xo { } void - exprstate::on_def(exprstatestack * p_stack) { + exprstate::on_def_token(const token_type & /*tk*/, + exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -652,7 +653,7 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_def: - this->on_def(p_stack); + this->on_def_token(tk, p_stack); return; case tokentype::tk_i64: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 5446cccb..20d7573d 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -73,7 +73,9 @@ namespace xo { } void - paren_xs::on_def(exprstatestack * /*p_stack*/) { + paren_xs::on_def_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) + { constexpr const char * c_self_name = "paren_xs::on_def"; throw std::runtime_error(tostr(c_self_name, diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index bb51cf02..19df5489 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -43,7 +43,9 @@ namespace xo { progress_xs::admits_f64() const { return false; } void - progress_xs::on_def(exprstatestack * /*p_stack*/) { + progress_xs::on_def_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/) + { constexpr const char * self_name = "progress_xs::on_def"; /* nothing here - admits_definition unconditionally false */ From 74099cacab8979b8deddf3614787a1913f3647e9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 13:57:42 -0400 Subject: [PATCH 084/191] xo-reader: uncopy: with + exprstate.illegal_input_error() --- include/xo/reader/exprstate.hpp | 7 ++++++ src/reader/define_xs.cpp | 27 +++++++------------- src/reader/exprstate.cpp | 34 ++++++++++++++----------- src/reader/paren_xs.cpp | 44 +++++++++++---------------------- src/reader/progress_xs.cpp | 30 ++++++++-------------- 5 files changed, 61 insertions(+), 81 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 467d2eab..c775a5b9 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -156,6 +156,13 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr); + protected: + /** throw exception when next token is inconsistent with + * parsing state + **/ + void illegal_input_error(const char * self_name, + const token_type & tk) const; + protected: /** explicit subtype: identifies derived class **/ exprstatetype exs_type_; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index d7bccf82..95fde120 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -382,7 +382,7 @@ namespace xo { } void - define_xs::on_singleassign_token(const token_type & /*tk*/, + define_xs::on_singleassign_token(const token_type & tk, exprstatestack * p_stack) { constexpr bool c_debug_flag = true; @@ -390,11 +390,8 @@ namespace xo { constexpr const char * self_name = "exprstate::on_singleassign"; - if (!this->admits_singleassign()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected equals for parsing state", - xtag("state", *this))); + if (!this->admits_singleassign()) { + this->illegal_input_error(self_name, tk); } if ((this->defxs_type_ == defexprstatetype::def_1) @@ -409,7 +406,7 @@ namespace xo { } void - define_xs::on_leftparen_token(const token_type & /*tk*/, + define_xs::on_leftparen_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -420,16 +417,14 @@ namespace xo { if (!this->admits_leftparen()) { - throw std::runtime_error(tostr(self_name, - ": unexpected leftparen '(' for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } assert(false); /* inserting this during refactor...? */ } void - define_xs::on_rightparen_token(const token_type & /*tk*/, + define_xs::on_rightparen_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -440,16 +435,14 @@ namespace xo { if (!this->admits_rightparen()) { - throw std::runtime_error(tostr(self_name, - ": unexpected rightparen ')' for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } assert(false); /* inserting this during refactor..? */ } void - define_xs::on_f64_token(const token_type & /*tk*/, + define_xs::on_f64_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -460,9 +453,7 @@ namespace xo { if (!this->admits_f64()) { - throw std::runtime_error(tostr(self_name, - ": unexpected floating-point literal for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } assert(false); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 5227135c..d6242730 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -320,19 +320,18 @@ namespace xo { } void - exprstate::on_def_token(const token_type & /*tk*/, - exprstatestack * p_stack) { + exprstate::on_def_token(const token_type & tk, + exprstatestack * p_stack) + { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_def"; + constexpr const char * c_self_name = "exprstate::on_def_token"; /* lots of illegal states */ if (!this->admits_definition()) { - throw std::runtime_error(tostr(self_name, - ": unexpected keyword 'def' for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } p_stack->push_exprstate(define_xs::def_0()); @@ -358,20 +357,16 @@ namespace xo { log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); - constexpr const char * self_name = "exprstate::on_symbol"; + constexpr const char * c_self_name = "exprstate::on_symbol_token"; if (!this->admits_symbol()) { - throw std::runtime_error - (tostr(self_name, - ": unexpected symbol-token for parsing state", - xtag("symbol", tk), - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: throw std::runtime_error - (tostr(self_name, + (tostr(c_self_name, ": unexpected symbol-token at top-level", " (expecting decl|def)", xtag("symbol", tk))); @@ -442,7 +437,7 @@ namespace xo { if (!td) { throw std::runtime_error - (tostr(self_name, + (tostr(c_self_name, ": unknown type name", " (expecting f64|f32|i16|i32|i64)", xtag("typename", tk.text()))); @@ -835,6 +830,17 @@ namespace xo { os << ">"; } + void + exprstate::illegal_input_error(const char * self_name, + const token_type & tk) const + { + throw std::runtime_error + (tostr(self_name, + ": unexpected input token for parsing state", + xtag("token", tk), + xtag("state", *this))); + } + // ----- exprstatestack ----- exprstate & diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 20d7573d..6d464178 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -73,14 +73,12 @@ namespace xo { } void - paren_xs::on_def_token(const token_type & /*tk*/, + paren_xs::on_def_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr const char * c_self_name = "paren_xs::on_def"; - throw std::runtime_error(tostr(c_self_name, - ": unexpected keyword 'def' for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } void @@ -110,66 +108,56 @@ namespace xo { } void - paren_xs::on_colon_token(const token_type & /*tk*/, + paren_xs::on_colon_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr const char * c_self_name = "paren_xs::on_colon"; - throw std::runtime_error(tostr(c_self_name, - ": unexpected colon for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } void - paren_xs::on_semicolon_token(const token_type & /*tk*/, + paren_xs::on_semicolon_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { constexpr const char * c_self_name = "paren_xs::on_semicolon"; - throw std::runtime_error(tostr(c_self_name, - ": unexpected semicolon for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } void - paren_xs::on_singleassign_token(const token_type & /*tk*/, + paren_xs::on_singleassign_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr const char * c_self_name = "paren_xs::on_singleassign"; - throw std::runtime_error(tostr(c_self_name, - ": unexpected equals for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } void - paren_xs::on_leftparen_token(const token_type & /*tk*/, + paren_xs::on_leftparen_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { constexpr const char * c_self_name = "paren_xs::on_leftparen"; - throw std::runtime_error(tostr(c_self_name, - ": unexpected leftparen '(' for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } void - paren_xs::on_rightparen_token(const token_type & /*tk*/, + paren_xs::on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "paren_xs::on_rightparen"; + constexpr const char * c_self_name = "paren_xs::on_rightparen"; if (!this->admits_rightparen()) { - throw std::runtime_error(tostr(self_name, - ": unexpected rightparen ')' for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } if (this->parenxs_type_ == parenexprstatetype::lparen_1) { @@ -182,7 +170,7 @@ namespace xo { } void - paren_xs::on_f64_token(const token_type & /*tk*/, + paren_xs::on_f64_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -193,9 +181,7 @@ namespace xo { if (!this->admits_f64()) { - throw std::runtime_error(tostr(c_self_name, - ": unexpected floating-point literal for parsing state", - xtag("state", *this))); + this->illegal_input_error(c_self_name, tk); } assert(false); diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 19df5489..a355229e 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -43,15 +43,13 @@ namespace xo { progress_xs::admits_f64() const { return false; } void - progress_xs::on_def_token(const token_type & /*tk*/, + progress_xs::on_def_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr const char * self_name = "progress_xs::on_def"; /* nothing here - admits_definition unconditionally false */ - throw std::runtime_error(tostr(self_name, - ": unexpected keyword 'def' for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk) ; } void @@ -84,14 +82,12 @@ namespace xo { } void - progress_xs::on_colon_token(const token_type & /*tk*/, + progress_xs::on_colon_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr const char * self_name = "progress_xs::on_colon"; - throw std::runtime_error(tostr(self_name, - ": unexpected colon for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } void @@ -128,18 +124,16 @@ namespace xo { } void - progress_xs::on_singleassign_token(const token_type & /*tk*/, + progress_xs::on_singleassign_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr const char * self_name = "progress_xs::on_singleassign"; - throw std::runtime_error(tostr(self_name, - ": unexpected equals for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } void - progress_xs::on_leftparen_token(const token_type & /*tk*/, + progress_xs::on_leftparen_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -148,9 +142,7 @@ namespace xo { constexpr const char * self_name = "exprstate::on_leftparen"; - throw std::runtime_error(tostr(self_name, - ": unexpected leftparen '(' for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } void @@ -194,7 +186,7 @@ namespace xo { } void - progress_xs::on_f64_token(const token_type & /*tk*/, + progress_xs::on_f64_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -203,9 +195,7 @@ namespace xo { constexpr const char * self_name = "progress_xs::on_f64"; - throw std::runtime_error(tostr(self_name, - ": unexpected floating-point literal for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } void From 04f79eaf013ba9f64bb2107d54bc61a51a97bfad Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 14:10:16 -0400 Subject: [PATCH 085/191] xo-reader: wip: + exprseq_xs class --- include/xo/reader/exprseq_xs.hpp | 28 +++++++++++++++++++++++++++ src/reader/CMakeLists.txt | 3 ++- src/reader/exprseq_xs.cpp | 33 ++++++++++++++++++++++++++++++++ src/reader/exprstate.cpp | 2 ++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 include/xo/reader/exprseq_xs.hpp create mode 100644 src/reader/exprseq_xs.cpp diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp new file mode 100644 index 00000000..28a17088 --- /dev/null +++ b/include/xo/reader/exprseq_xs.hpp @@ -0,0 +1,28 @@ +/** @file exprseq_xs.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "exprstate.hpp" +//#include + +namespace xo { + namespace scm { + /** @class exprseq_xs + * @brief parsing state-machine for top-level expression sequence + * + **/ + class exprseq_xs : public exprstate { + public: + // ----- token input methods ----- + + virtual void on_def_token(const token_type & tk, + exprstatestack * p_stack) override; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end exprseq_xs.hpp **/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 4741fa3d..e75e248a 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -7,7 +7,8 @@ set(SELF_SRCS exprstate.cpp define_xs.cpp progress_xs.cpp - paren_xs.cpp) + paren_xs.cpp + exprseq_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp new file mode 100644 index 00000000..012e9b2e --- /dev/null +++ b/src/reader/exprseq_xs.cpp @@ -0,0 +1,33 @@ +/* @file exprseq_xs.cpp */ + +#include "exprseq_xs.hpp" +#include "define_xs.hpp" + +namespace xo { + namespace scm { + void + exprseq_xs::on_def_token(const token_type & /*tk*/, + exprstatestack * p_stack) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + //constexpr const char * c_self_name = "exprseq_xs::on_def_token"; + + p_stack->push_exprstate(define_xs::def_0()); + + /* todo: replace: + * expect_symbol_or_function_signature() + */ + p_stack->push_exprstate(exprstate::expect_symbol()); + + /* keyword 'def' introduces a definition: + * def pi : f64 = 3.14159265 + * def sq(x : f64) -> f64 { (x * x) } + */ + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end exprseq_xs.cpp */ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index d6242730..6116b349 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -41,6 +41,7 @@ namespace xo { return "???"; } +#ifdef OBSOLETE bool exprstate::admits_definition() const { switch (exs_type_) { @@ -69,6 +70,7 @@ namespace xo { return false; } +#endif bool exprstate::admits_symbol() const { From 424a4cd0f1789923ac7e7a9cd132029ef09c0ea8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 19:43:00 -0400 Subject: [PATCH 086/191] xo-reader: simplify: adopt exprseq_xs + drop .admits_definition() --- include/xo/reader/define_xs.hpp | 2 ++ include/xo/reader/exprseq_xs.hpp | 5 +++++ include/xo/reader/exprstate.hpp | 4 ++++ include/xo/reader/paren_xs.hpp | 2 ++ include/xo/reader/progress_xs.hpp | 2 ++ src/reader/define_xs.cpp | 2 ++ src/reader/exprseq_xs.cpp | 12 +++++++++++- src/reader/exprstate.cpp | 6 +++++- src/reader/paren_xs.cpp | 2 ++ src/reader/parser.cpp | 3 ++- src/reader/progress_xs.cpp | 2 ++ 11 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 10d53459..dafafed4 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -42,7 +42,9 @@ namespace xo { defexprstatetype defxs_type() const { return defxs_type_; } +#ifdef OBSOLETE virtual bool admits_definition() const override; +#endif virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 28a17088..261cbd5a 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -15,6 +15,11 @@ namespace xo { * **/ class exprseq_xs : public exprstate { + public: + exprseq_xs(); + + static std::unique_ptr expect_toplevel_expression_sequence(); + public: // ----- token input methods ----- diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index c775a5b9..7b590f48 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -70,9 +70,11 @@ namespace xo { {} virtual ~exprstate() = default; +#ifdef RELOCATED static std::unique_ptr expect_toplevel_expression_sequence() { return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence)); } +#endif static std::unique_ptr expect_rhs_expression() { return std::make_unique(exprstate(exprstatetype::expect_rhs_expression)); } @@ -85,10 +87,12 @@ namespace xo { exprstatetype exs_type() const { return exs_type_; } +#ifdef OBSOLETE /** true iff this parsing state admits a 'def' keyword * as next token **/ virtual bool admits_definition() const; +#endif /** true iff this parsing state admits a symbol as next token **/ virtual bool admits_symbol() const; /** true iff this parsing state admits a colon as next token **/ diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 5992837a..670a62c3 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -31,7 +31,9 @@ namespace xo { static std::unique_ptr lparen_0(); +#ifdef OBSOLETE virtual bool admits_definition() const override; +#endif virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 0a0516cf..9df42717 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -22,7 +22,9 @@ namespace xo { static std::unique_ptr make(rp valex); +#ifdef OBSOLETE virtual bool admits_definition() const override; +#endif virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 95fde120..3d85c860 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -15,6 +15,7 @@ namespace xo { def_expr_{std::move(def_expr)} {} +#ifdef OBSOLETE bool define_xs::admits_definition() const { @@ -41,6 +42,7 @@ namespace xo { return false; } +#endif bool define_xs::admits_symbol() const { diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 012e9b2e..e0a5af6f 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -5,6 +5,17 @@ namespace xo { namespace scm { + std::unique_ptr + exprseq_xs::expect_toplevel_expression_sequence() + { + return std::make_unique(exprseq_xs()); + } + + exprseq_xs::exprseq_xs() + : exprstate(exprstatetype::expect_toplevel_expression_sequence) + { + } + void exprseq_xs::on_def_token(const token_type & /*tk*/, exprstatestack * p_stack) @@ -29,5 +40,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ - /* end exprseq_xs.cpp */ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 6116b349..b04aa227 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -323,8 +323,11 @@ namespace xo { void exprstate::on_def_token(const token_type & tk, - exprstatestack * p_stack) + exprstatestack * /*p_stack*/) { + this->illegal_input_error("exprstate::on_def_token", tk); + +#ifdef OBSOLETE constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -347,6 +350,7 @@ namespace xo { * def pi : f64 = 3.14159265 * def sq(x : f64) -> f64 { (x * x) } */ +#endif } void diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 6d464178..0911928d 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -14,8 +14,10 @@ namespace xo { return std::make_unique(paren_xs()); } +#ifdef OBSOLETE bool paren_xs::admits_definition() const { return false; } +#endif bool paren_xs::admits_symbol() const { return true; } diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index f056eeac..5ac71dd0 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -5,6 +5,7 @@ #include "parser.hpp" #include "define_xs.hpp" +#include "exprseq_xs.hpp" #include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" #include "xo/expression/ConvertExpr.hpp" @@ -30,7 +31,7 @@ namespace xo { void parser::begin_translation_unit() { xs_stack_.push_exprstate - (exprstate::expect_toplevel_expression_sequence()); + (exprseq_xs::expect_toplevel_expression_sequence()); } rp diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index a355229e..baf4df55 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -14,8 +14,10 @@ namespace xo { gen_expr_{std::move(valex)} {} +#ifdef OBSOLETE bool progress_xs::admits_definition() const { return false; } +#endif bool progress_xs::admits_symbol() const { return false; } From 6473ab6e26f0efd71e360910d9f57765f9dcbfc5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 19:45:19 -0400 Subject: [PATCH 087/191] xo-reader: tidy: kill RELOCATED + OBSOLETE code --- include/xo/reader/exprstate.hpp | 11 ------- src/reader/exprstate.cpp | 56 --------------------------------- 2 files changed, 67 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 7b590f48..41d4da81 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -70,11 +70,6 @@ namespace xo { {} virtual ~exprstate() = default; -#ifdef RELOCATED - static std::unique_ptr expect_toplevel_expression_sequence() { - return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence)); - } -#endif static std::unique_ptr expect_rhs_expression() { return std::make_unique(exprstate(exprstatetype::expect_rhs_expression)); } @@ -87,12 +82,6 @@ namespace xo { exprstatetype exs_type() const { return exs_type_; } -#ifdef OBSOLETE - /** true iff this parsing state admits a 'def' keyword - * as next token - **/ - virtual bool admits_definition() const; -#endif /** true iff this parsing state admits a symbol as next token **/ virtual bool admits_symbol() const; /** true iff this parsing state admits a colon as next token **/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index b04aa227..beab670a 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -41,37 +41,6 @@ namespace xo { return "???"; } -#ifdef OBSOLETE - bool - exprstate::admits_definition() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - return true; - - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - /* unreachable */ - assert(false); - return false; - case exprstatetype::expect_rhs_expression: - return false; - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return false; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } -#endif - bool exprstate::admits_symbol() const { switch (exs_type_) { @@ -326,31 +295,6 @@ namespace xo { exprstatestack * /*p_stack*/) { this->illegal_input_error("exprstate::on_def_token", tk); - -#ifdef OBSOLETE - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * c_self_name = "exprstate::on_def_token"; - - /* lots of illegal states */ - if (!this->admits_definition()) - { - this->illegal_input_error(c_self_name, tk); - } - - p_stack->push_exprstate(define_xs::def_0()); - - /* todo: replace: - * expect_symbol_or_function_signature() - */ - p_stack->push_exprstate(exprstate::expect_symbol()); - - /* keyword 'def' introduces a definition: - * def pi : f64 = 3.14159265 - * def sq(x : f64) -> f64 { (x * x) } - */ -#endif } void From 30cfe0c918256c5cb12b4d47e5b32eb7061537ae Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 19:52:30 -0400 Subject: [PATCH 088/191] xo-reader: simplify exprseq_xs::on_symbol_token() --- include/xo/reader/exprseq_xs.hpp | 6 ++++++ src/reader/exprseq_xs.cpp | 10 ++++++++++ src/reader/exprstate.cpp | 9 +-------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 261cbd5a..861a6321 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -25,6 +25,12 @@ namespace xo { virtual void on_def_token(const token_type & tk, exprstatestack * p_stack) override; + virtual void on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + + // ----- victory methods ----- + }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index e0a5af6f..a127cdc8 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -37,6 +37,16 @@ namespace xo { * def sq(x : f64) -> f64 { (x * x) } */ } + + void + exprseq_xs::on_symbol_token(const token_type & tk, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr const char * c_self_name = "exprseq_xs::on_symbol_token"; + + this->illegal_input_error(c_self_name, tk); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index beab670a..3e3ae9ec 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -315,13 +315,6 @@ namespace xo { switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - throw std::runtime_error - (tostr(c_self_name, - ": unexpected symbol-token at top-level", - " (expecting decl|def)", - xtag("symbol", tk))); - break; - case exprstatetype::defexpr: case exprstatetype::parenexpr: /* unreachable - redirects to define_xs */ @@ -409,7 +402,7 @@ namespace xo { assert(false); return; } - } /*on_symbol*/ + } void exprstate::on_typedescr(TypeDescr /*td*/, From cf3448bc8249bbc1ad9516c0621723791439f040 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 19:56:47 -0400 Subject: [PATCH 089/191] xo-reader: + exprseq_xs.on_typedef() + simplie tl exprseq case --- include/xo/reader/exprseq_xs.hpp | 4 ++++ src/reader/exprseq_xs.cpp | 10 ++++++++++ src/reader/exprstate.cpp | 1 - 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 861a6321..6ea8ff21 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -31,6 +31,10 @@ namespace xo { // ----- victory methods ----- + virtual void on_typedescr(TypeDescr /*td*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) override; + }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index a127cdc8..48c69fbd 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -47,6 +47,16 @@ namespace xo { this->illegal_input_error(c_self_name, tk); } + + void + exprseq_xs::on_typedescr(TypeDescr /*td*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* unreachable - typedescr should never get delivered to exprseq */ + assert(false); + return; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 3e3ae9ec..7fa30923 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -413,7 +413,6 @@ namespace xo { switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: case exprstatetype::parenexpr: /* unreachable - redirects to define_xs */ From 372a86485f5fa9048160b48af69f4e8ea4e39983 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:01:22 -0400 Subject: [PATCH 090/191] xo-reader: + exprseq_xs.on_expr() --- include/xo/reader/exprseq_xs.hpp | 9 ++++++--- src/reader/exprseq_xs.cpp | 15 +++++++++++++++ src/reader/exprstate.cpp | 8 -------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 6ea8ff21..d6afffe8 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -31,9 +31,12 @@ namespace xo { // ----- victory methods ----- - virtual void on_typedescr(TypeDescr /*td*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) override; + virtual void on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) override; }; } /*namespace scm*/ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 48c69fbd..502f129f 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -57,6 +57,21 @@ namespace xo { assert(false); return; } + + void + exprseq_xs::on_expr(ref::brw expr, + exprstatestack * /*p_stack*/, + rp * p_emit_expr) + { + /* toplevel expression sequence accepts an + * arbitrary number of expressions. + * + * parser::include_token() returns + */ + + *p_emit_expr = expr.promote(); + } /*on_expr*/ + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 7fa30923..052488bf 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -680,14 +680,6 @@ namespace xo { switch (this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - /* toplevel expression sequence accepts an - * arbitrary number of expressions. - * - * parser::include_token() returns - */ - - *p_emit_expr = expr.promote(); - return; case exprstatetype::defexpr: case exprstatetype::parenexpr: /* unreachable. redirects to define_xs::on_expr() etc */ From e2f9fbb9a47c27802aeba68814851c175953418f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:04:16 -0400 Subject: [PATCH 091/191] xo-reader: streamline tl expr seq --- src/reader/exprstate.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 052488bf..d9ea94b6 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -82,7 +82,6 @@ namespace xo { exprstate::admits_colon() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: case exprstatetype::parenexpr: /* unreachable -- redirects to define_xs::admits_colon() etc */ @@ -137,7 +136,6 @@ namespace xo { exprstate::admits_singleassign() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - /* * def foo = 1 ; * def foo : f64 = 1 ; @@ -262,7 +260,6 @@ namespace xo { exprstate::admits_f64() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: case exprstatetype::parenexpr: /* unreachable - redirects to define_xs */ @@ -723,15 +720,6 @@ namespace xo { { switch(this->exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: - /* toplevel expression sequence accepts an - * arbitrary number of expressions. - * - * parser::include_token() returns - */ - - /* NOT IMPLEMENTED */ - assert(false); - return; case exprstatetype::defexpr: case exprstatetype::parenexpr: /* unreachable - redirects to define_xs etc */ From f0f4c57362538fb3567f8b4d922f084193720318 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:09:12 -0400 Subject: [PATCH 092/191] xo-reader: streamline: drop degenerate switch stmts --- src/reader/exprstate.cpp | 60 +++++----------------------------------- 1 file changed, 7 insertions(+), 53 deletions(-) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index d9ea94b6..6e876bac 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -408,34 +408,9 @@ namespace xo { { /* returning type description to something that wants it */ - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - /* unreachable - redirects to define_xs */ - assert(false); - return; - - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - /* unreachable - * (this exprstate issues pop instruction from exprstate::on_input() - */ - assert(false); - return; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } + /* unreachable - implement in derived class */ + assert(false); + return; } void @@ -718,31 +693,10 @@ namespace xo { exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { - switch(this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - /* unreachable - redirects to define_xs etc */ - assert(false); - return; - - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - /* unreachable - * (this exprstate issues pop instruction from exprstate::on_input() - */ - assert(false); - return; - case exprstatetype::expr_progress: - assert(false); - return; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } + /* unreachable - derived class that can receive + * will override this method + */ + assert(false); } void From 5a4923e5cf6bba7f213be5c596aa76b60ae483a9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:20:57 -0400 Subject: [PATCH 093/191] xo-reader: refactor: + expect_expr_xs cls [wip] --- include/xo/reader/expect_expr_xs.hpp | 29 +++++++++++++++++++++++++ include/xo/reader/exprstate.hpp | 2 ++ src/reader/CMakeLists.txt | 3 ++- src/reader/define_xs.cpp | 32 ++-------------------------- src/reader/expect_expr_xs.cpp | 24 +++++++++++++++++++++ src/reader/exprstate.cpp | 5 +++-- 6 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 include/xo/reader/expect_expr_xs.hpp create mode 100644 src/reader/expect_expr_xs.cpp diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp new file mode 100644 index 00000000..6e039c79 --- /dev/null +++ b/include/xo/reader/expect_expr_xs.hpp @@ -0,0 +1,29 @@ +/* file expect_expr_xs.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" + +namespace xo { + namespace scm { + + /** @class expect_expr_xs + * @brief state machine to expect + capture an expression + **/ + class expect_expr_xs : public exprstate { + public: + expect_expr_xs(); + + static std::unique_ptr expect_rhs_expression(); + + private: + }; + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_expr_xs.hpp */ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 41d4da81..1a0219e6 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -70,9 +70,11 @@ namespace xo { {} virtual ~exprstate() = default; +#ifdef RELOCATED static std::unique_ptr expect_rhs_expression() { return std::make_unique(exprstate(exprstatetype::expect_rhs_expression)); } +#endif static std::unique_ptr expect_symbol() { return std::make_unique(exprstate(exprstatetype::expect_symbol)); } diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index e75e248a..77a06a63 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -8,7 +8,8 @@ set(SELF_SRCS define_xs.cpp progress_xs.cpp paren_xs.cpp - exprseq_xs.cpp) + exprseq_xs.cpp + expect_expr_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 3d85c860..5dc5c760 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -1,6 +1,7 @@ /* @file define_xs.cpp */ #include "define_xs.hpp" +#include "expect_expr_xs.hpp" namespace xo { namespace scm { @@ -15,35 +16,6 @@ namespace xo { def_expr_{std::move(def_expr)} {} -#ifdef OBSOLETE - bool - define_xs::admits_definition() const - { - switch (defxs_type_) { - - case defexprstatetype::def_0: - case defexprstatetype::def_1: - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - case defexprstatetype::def_5: - /* note for def_4: - * rhs could certainly be a function body that contains - * nested defines; but then immediately-enclosing-exprstate - * would be a block - */ - return false; - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } -#endif - bool define_xs::admits_symbol() const { switch (defxs_type_) { @@ -401,7 +373,7 @@ namespace xo { { this->defxs_type_ = defexprstatetype::def_4; - p_stack->push_exprstate(exprstate::expect_rhs_expression()); + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); } else { assert(false); } diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp new file mode 100644 index 00000000..ddc75aa6 --- /dev/null +++ b/src/reader/expect_expr_xs.cpp @@ -0,0 +1,24 @@ +/* file expect_expr_xs.cpp + * + * author: Roland Conybeare + */ + +#include "expect_expr_xs.hpp" + +namespace xo { + namespace scm { + + std::unique_ptr + expect_expr_xs::expect_rhs_expression() { + return std::make_unique(expect_expr_xs()); + + } + + expect_expr_xs::expect_expr_xs() + : exprstate(exprstatetype::expect_rhs_expression) + {} + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end expect_expr_xs.cpp */ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 6e876bac..88154353 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -4,6 +4,7 @@ #include "define_xs.hpp" #include "progress_xs.hpp" #include "paren_xs.hpp" +#include "expect_expr_xs.hpp" //#include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" //#include "xo/expression/ConvertExpr.hpp" @@ -491,7 +492,7 @@ namespace xo { if (this->exs_type_ == exprstatetype::expect_rhs_expression) { /* push lparen_0 to remember to look for subsequent rightparen. */ p_stack->push_exprstate(paren_xs::lparen_0()); - p_stack->push_exprstate(exprstate::expect_rhs_expression()); + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); } } @@ -660,7 +661,7 @@ namespace xo { case exprstatetype::expect_rhs_expression: { - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_stack, From b8b9efd6339266b3c64fcca7a9f9f3b2277cbb56 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:28:58 -0400 Subject: [PATCH 094/191] xo-reader: simplify f64 token handling --- include/xo/reader/expect_expr_xs.hpp | 4 ++++ include/xo/reader/exprstate.hpp | 2 ++ include/xo/reader/paren_xs.hpp | 6 ++---- include/xo/reader/progress_xs.hpp | 6 ++---- src/reader/define_xs.cpp | 7 +------ src/reader/expect_expr_xs.cpp | 24 ++++++++++++++++++++++++ src/reader/exprstate.cpp | 27 +++++---------------------- 7 files changed, 40 insertions(+), 36 deletions(-) diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 6e039c79..d826b5ae 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -19,6 +19,10 @@ namespace xo { static std::unique_ptr expect_rhs_expression(); + virtual void on_f64_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + private: }; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 1a0219e6..2ac8cf67 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -96,8 +96,10 @@ namespace xo { virtual bool admits_leftparen() const; /** truee iff this parsing state admits a rightparen ')' as next token **/ virtual bool admits_rightparen() const; +#ifdef OBSOLETE /** true iff this parsing state admits a 64-bit floating point literal token **/ virtual bool admits_f64() const; +#endif /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 670a62c3..31e3e45c 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -31,16 +31,14 @@ namespace xo { static std::unique_ptr lparen_0(); -#ifdef OBSOLETE - virtual bool admits_definition() const override; -#endif + bool admits_f64() const; + virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; virtual bool admits_leftparen() const override; virtual bool admits_rightparen() const override; - virtual bool admits_f64() const override; virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 9df42717..9131b048 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -22,16 +22,14 @@ namespace xo { static std::unique_ptr make(rp valex); -#ifdef OBSOLETE - virtual bool admits_definition() const override; -#endif + bool admits_f64() const; + virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; virtual bool admits_leftparen() const override; virtual bool admits_rightparen() const override; - virtual bool admits_f64() const override; virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 5dc5c760..ad6c994f 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -425,12 +425,7 @@ namespace xo { constexpr const char * self_name = "exprstate::on_f64"; - if (!this->admits_f64()) - { - this->illegal_input_error(self_name, tk); - } - - assert(false); + this->illegal_input_error(self_name, tk); } void diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index ddc75aa6..78a69be2 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -4,8 +4,12 @@ */ #include "expect_expr_xs.hpp" +#include "progress_xs.hpp" +#include "xo/expression/Constant.hpp" namespace xo { + using xo::ast::Constant; + namespace scm { std::unique_ptr @@ -18,6 +22,26 @@ namespace xo { : exprstate(exprstatetype::expect_rhs_expression) {} + void + expect_expr_xs::on_f64_token(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + //constexpr const char * self_name = "exprstate::on_f64_token"; + + /* e.g. + * def pi = 3.14159265; + * \---tk---/ + */ + p_stack->push_exprstate + (progress_xs::make + (Constant::make(tk.f64_value()))); + } + + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 88154353..8161f62e 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -257,19 +257,18 @@ namespace xo { return false; } +#ifdef OBSOLETE bool exprstate::admits_f64() const { switch (exs_type_) { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::defexpr: case exprstatetype::parenexpr: + case exprstatetype::expect_rhs_expression: /* unreachable - redirects to define_xs */ assert(false); return false; - case exprstatetype::expect_rhs_expression: - return true; - case exprstatetype::expect_symbol: case exprstatetype::expect_type: return false; @@ -287,6 +286,7 @@ namespace xo { return false; } +#endif void exprstate::on_def_token(const token_type & tk, @@ -522,7 +522,7 @@ namespace xo { void exprstate::on_f64_token(const token_type & tk, - exprstatestack * p_stack, + exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; @@ -530,24 +530,7 @@ namespace xo { constexpr const char * self_name = "exprstate::on_f64"; - if (!this->admits_f64()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected floating-point literal for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::expect_rhs_expression) { - /* e.g. - * def pi = 3.14159265; - * \---tk---/ - */ - p_stack->push_exprstate - (progress_xs::make - (Constant::make(tk.f64_value()))); - } else { - assert(false); - } + this->illegal_input_error(self_name, tk); } void From 6b9503ef7668f2eb34cf77d7d33728bb9201df02 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:33:28 -0400 Subject: [PATCH 095/191] xo-reader: simplify paren handling for expressions --- include/xo/reader/expect_expr_xs.hpp | 3 +++ include/xo/reader/exprstate.hpp | 9 ------- src/reader/expect_expr_xs.cpp | 16 ++++++++++++ src/reader/exprstate.cpp | 38 ++-------------------------- 4 files changed, 21 insertions(+), 45 deletions(-) diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index d826b5ae..a7cc997f 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -19,6 +19,9 @@ namespace xo { static std::unique_ptr expect_rhs_expression(); + virtual void on_leftparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; virtual void on_f64_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 2ac8cf67..0997792e 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -70,11 +70,6 @@ namespace xo { {} virtual ~exprstate() = default; -#ifdef RELOCATED - static std::unique_ptr expect_rhs_expression() { - return std::make_unique(exprstate(exprstatetype::expect_rhs_expression)); - } -#endif static std::unique_ptr expect_symbol() { return std::make_unique(exprstate(exprstatetype::expect_symbol)); } @@ -96,10 +91,6 @@ namespace xo { virtual bool admits_leftparen() const; /** truee iff this parsing state admits a rightparen ')' as next token **/ virtual bool admits_rightparen() const; -#ifdef OBSOLETE - /** true iff this parsing state admits a 64-bit floating point literal token **/ - virtual bool admits_f64() const; -#endif /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 78a69be2..be19b8bc 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -4,6 +4,7 @@ */ #include "expect_expr_xs.hpp" +#include "paren_xs.hpp" #include "progress_xs.hpp" #include "xo/expression/Constant.hpp" @@ -22,6 +23,21 @@ namespace xo { : exprstate(exprstatetype::expect_rhs_expression) {} + void + expect_expr_xs::on_leftparen_token(const token_type & /*tk*/, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + //constexpr const char * self_name = "exprstate::on_leftparen"; + + /* push lparen_0 to remember to look for subsequent rightparen. */ + p_stack->push_exprstate(paren_xs::lparen_0()); + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + } + void expect_expr_xs::on_f64_token(const token_type & tk, exprstatestack * p_stack, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 8161f62e..b013feb1 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -196,14 +196,11 @@ namespace xo { case exprstatetype::defexpr: case exprstatetype::parenexpr: - /* unreachable - redirects to define_xs */ + case exprstatetype::expect_rhs_expression: + /* unreachable - redirects to define_xs etc */ assert(false); return false; - case exprstatetype::expect_rhs_expression: - /* can always begin non-toplevel expression with '(' */ - return true; - case exprstatetype::expect_type: return false; @@ -257,37 +254,6 @@ namespace xo { return false; } -#ifdef OBSOLETE - bool - exprstate::admits_f64() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - case exprstatetype::expect_rhs_expression: - /* unreachable - redirects to define_xs */ - assert(false); - return false; - - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } -#endif - void exprstate::on_def_token(const token_type & tk, exprstatestack * /*p_stack*/) From 538c9d90e5f69435882c836d86e3d1cfa7d89210 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:40:37 -0400 Subject: [PATCH 096/191] xo-reader: simplify paren handling logic --- include/xo/reader/define_xs.hpp | 6 ++++-- include/xo/reader/exprstate.hpp | 2 ++ include/xo/reader/paren_xs.hpp | 2 ++ include/xo/reader/progress_xs.hpp | 2 ++ src/reader/define_xs.cpp | 9 +++++---- src/reader/exprstate.cpp | 19 +++++-------------- src/reader/paren_xs.cpp | 7 ++----- src/reader/progress_xs.cpp | 9 --------- 8 files changed, 22 insertions(+), 34 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index dafafed4..34670230 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -43,13 +43,13 @@ namespace xo { defexprstatetype defxs_type() const { return defxs_type_; } #ifdef OBSOLETE - virtual bool admits_definition() const override; + bool admits_leftparen() const; #endif + virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; - virtual bool admits_leftparen() const override; virtual bool admits_rightparen() const override; // virtual void on_f64(..) override @@ -69,9 +69,11 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack) override; +#ifdef OBSOLETE virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; +#endif virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 0997792e..28ba4694 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -87,8 +87,10 @@ namespace xo { virtual bool admits_semicolon() const; /** true iff this parsing state admits a singleassign '=' as next token **/ virtual bool admits_singleassign() const; +#ifdef OBSOLETE /** true iff this parsing state admits a leftparen '(' as next token **/ virtual bool admits_leftparen() const; +#endif /** truee iff this parsing state admits a rightparen ')' as next token **/ virtual bool admits_rightparen() const; diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 31e3e45c..22b72f8b 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -37,7 +37,9 @@ namespace xo { virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; +#ifdef OBSOLETE virtual bool admits_leftparen() const override; +#endif virtual bool admits_rightparen() const override; virtual void on_expr(ref::brw expr, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 9131b048..83a2ce65 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -28,7 +28,9 @@ namespace xo { virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; +#ifdef OBSOLETE virtual bool admits_leftparen() const override; +#endif virtual bool admits_rightparen() const override; virtual void on_expr(ref::brw expr, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index ad6c994f..ffa8a094 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -131,6 +131,7 @@ namespace xo { return false; } +#ifdef OBSOLETE bool define_xs::admits_leftparen() const { switch (defxs_type_) { @@ -163,6 +164,7 @@ namespace xo { return false; } +#endif bool define_xs::admits_rightparen() const { @@ -379,6 +381,7 @@ namespace xo { } } +#ifdef OBSOLETE void define_xs::on_leftparen_token(const token_type & tk, exprstatestack * /*p_stack*/, @@ -389,13 +392,11 @@ namespace xo { constexpr const char * self_name = "exprstate::on_leftparen"; - if (!this->admits_leftparen()) - { - this->illegal_input_error(self_name, tk); - } + this->illegal_input_error(self_name, tk); assert(false); /* inserting this during refactor...? */ } +#endif void define_xs::on_rightparen_token(const token_type & tk, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index b013feb1..1fd4d08a 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -179,6 +179,7 @@ namespace xo { return false; } +#ifdef OBSOLETE bool exprstate::admits_leftparen() const { switch (exs_type_) { @@ -221,6 +222,7 @@ namespace xo { return false; } +#endif bool exprstate::admits_rightparen() const { @@ -439,8 +441,8 @@ namespace xo { } void - exprstate::on_leftparen_token(const token_type & /*tk*/, - exprstatestack * p_stack, + exprstate::on_leftparen_token(const token_type & tk, + exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; @@ -448,18 +450,7 @@ namespace xo { constexpr const char * self_name = "exprstate::on_leftparen"; - if (!this->admits_leftparen()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected leftparen '(' for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::expect_rhs_expression) { - /* push lparen_0 to remember to look for subsequent rightparen. */ - p_stack->push_exprstate(paren_xs::lparen_0()); - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); - } + this->illegal_input_error(self_name, tk); } void diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 0911928d..2fcf427b 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -14,11 +14,6 @@ namespace xo { return std::make_unique(paren_xs()); } -#ifdef OBSOLETE - bool - paren_xs::admits_definition() const { return false; } -#endif - bool paren_xs::admits_symbol() const { return true; } @@ -31,8 +26,10 @@ namespace xo { bool paren_xs::admits_singleassign() const { return false; } +#ifdef OBSOLETE bool paren_xs::admits_leftparen() const { /*unreachable*/ return false; } +#endif bool paren_xs::admits_rightparen() const { diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index baf4df55..f5ba36ee 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -14,11 +14,6 @@ namespace xo { gen_expr_{std::move(valex)} {} -#ifdef OBSOLETE - bool - progress_xs::admits_definition() const { return false; } -#endif - bool progress_xs::admits_symbol() const { return false; } @@ -31,10 +26,6 @@ namespace xo { bool progress_xs::admits_singleassign() const { return false; } - /* todo: will parse as function call */ - bool - progress_xs::admits_leftparen() const { return false; } - bool progress_xs::admits_rightparen() const { /* satisfies expression form */ From fb30451684070bca2a54c4524fbe7ebf981984fb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Aug 2024 20:45:06 -0400 Subject: [PATCH 097/191] xo-reader: simplify rightparen logic --- include/xo/reader/define_xs.hpp | 10 +---- include/xo/reader/exprstate.hpp | 2 +- include/xo/reader/paren_xs.hpp | 2 +- include/xo/reader/progress_xs.hpp | 2 +- src/reader/exprstate.cpp | 64 +++---------------------------- src/reader/progress_xs.cpp | 2 + 6 files changed, 11 insertions(+), 71 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 34670230..8c9ef9c1 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -42,15 +42,12 @@ namespace xo { defexprstatetype defxs_type() const { return defxs_type_; } -#ifdef OBSOLETE - bool admits_leftparen() const; -#endif + bool admits_rightparen() const; virtual bool admits_symbol() const override; virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; - virtual bool admits_rightparen() const override; // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, @@ -69,11 +66,6 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack) override; -#ifdef OBSOLETE - virtual void on_leftparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; -#endif virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 28ba4694..61ba3319 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -90,9 +90,9 @@ namespace xo { #ifdef OBSOLETE /** true iff this parsing state admits a leftparen '(' as next token **/ virtual bool admits_leftparen() const; -#endif /** truee iff this parsing state admits a rightparen ')' as next token **/ virtual bool admits_rightparen() const; +#endif /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 22b72f8b..d00dc384 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -32,6 +32,7 @@ namespace xo { static std::unique_ptr lparen_0(); bool admits_f64() const; + bool admits_rightparen() const; virtual bool admits_symbol() const override; virtual bool admits_colon() const override; @@ -40,7 +41,6 @@ namespace xo { #ifdef OBSOLETE virtual bool admits_leftparen() const override; #endif - virtual bool admits_rightparen() const override; virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 83a2ce65..d4a0c190 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -30,8 +30,8 @@ namespace xo { virtual bool admits_singleassign() const override; #ifdef OBSOLETE virtual bool admits_leftparen() const override; -#endif virtual bool admits_rightparen() const override; +#endif virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 1fd4d08a..31553c1c 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -180,50 +180,6 @@ namespace xo { } #ifdef OBSOLETE - bool - exprstate::admits_leftparen() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* input like - * (function(blah...)) - * not allowed at toplevel; - * creates ambiguity e.g. consider - * x := foo - * (bar) - * - * is rhs 'foo' or 'foo(bar)' - */ - return false; - - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - case exprstatetype::expect_rhs_expression: - /* unreachable - redirects to define_xs etc */ - assert(false); - return false; - - case exprstatetype::expect_type: - return false; - - case exprstatetype::expect_symbol: - return false; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } -#endif - bool exprstate::admits_rightparen() const { switch (exs_type_) { @@ -255,6 +211,7 @@ namespace xo { return false; } +#endif void exprstate::on_def_token(const token_type & tk, @@ -428,7 +385,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_singleassign"; + constexpr const char * self_name = "exprstate::on_singleassign_token"; if (!this->admits_singleassign()) { @@ -448,13 +405,13 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_leftparen"; + constexpr const char * self_name = "exprstate::on_leftparen_token"; this->illegal_input_error(self_name, tk); } void - exprstate::on_rightparen_token(const token_type & /*tk*/, + exprstate::on_rightparen_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -463,18 +420,7 @@ namespace xo { constexpr const char * self_name = "exprstate::on_rightparen"; - if (!this->admits_rightparen()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected rightparen ')' for parsing state", - xtag("state", *this))); - } - - if (this->exs_type_ == exprstatetype::expr_progress - || this->exs_type_ == exprstatetype::parenexpr) { - /* unreachable -- see progress_xs::on_rightparen() etc */ - assert(false); - } + this->illegal_input_error(self_name, tk); } void diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index f5ba36ee..f518374a 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -26,11 +26,13 @@ namespace xo { bool progress_xs::admits_singleassign() const { return false; } +#ifdef OBSOLETE bool progress_xs::admits_rightparen() const { /* satisfies expression form */ return true; } +#endif bool progress_xs::admits_f64() const { return false; } From d1d72f9fc9d81c75dede4fe4402684584de27c00 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 15:56:48 -0500 Subject: [PATCH 098/191] xo-reader: streamline: simplify expect_expr_xs --- include/xo/reader/expect_expr_xs.hpp | 10 +++ include/xo/reader/exprstate.hpp | 6 -- src/reader/expect_expr_xs.cpp | 53 +++++++++++++ src/reader/exprstate.cpp | 112 ++------------------------- 4 files changed, 69 insertions(+), 112 deletions(-) diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index a7cc997f..fa6c4630 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -22,10 +22,20 @@ namespace xo { virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; + + virtual void on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_f64_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; + /** update exprstate in response to a successfully-parsed subexpression **/ + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) override; + private: }; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 61ba3319..9f20dfd8 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -87,12 +87,6 @@ namespace xo { virtual bool admits_semicolon() const; /** true iff this parsing state admits a singleassign '=' as next token **/ virtual bool admits_singleassign() const; -#ifdef OBSOLETE - /** true iff this parsing state admits a leftparen '(' as next token **/ - virtual bool admits_leftparen() const; - /** truee iff this parsing state admits a rightparen ')' as next token **/ - virtual bool admits_rightparen() const; -#endif /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index be19b8bc..131bfc42 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -38,6 +38,41 @@ namespace xo { p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); } + void + expect_expr_xs::on_symbol_token(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* todo: treat symbol as variable name */ + + /* various possibilities when looking for rhs expression: + * + * x := y // (1) + * x := f(a) // (2) + * x := f(a,b) // (3) + * + * need lookahead token following symbol to distinguish + * between (1) (symbol completes rhs expression) + * and {(2), (3)} (symbol is function call) + */ + + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ +#ifdef NOT_YET + p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, + Variable::make(name, type))); +#endif + +#ifdef LATER + p_stack->pop_exprstate(); + p_stack->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); +#endif + return; + } + + void expect_expr_xs::on_f64_token(const token_type & tk, exprstatestack * p_stack, @@ -57,6 +92,24 @@ namespace xo { (Constant::make(tk.f64_value()))); } + void + expect_expr_xs::on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr)); + + + std::unique_ptr self = p_stack->pop_exprstate(); + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + } /*on_expr*/ } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 31553c1c..540bcaaa 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -50,14 +50,11 @@ namespace xo { case exprstatetype::defexpr: case exprstatetype::parenexpr: + case exprstatetype::expect_rhs_expression: /* unreachable */ assert(false); return false; - case exprstatetype::expect_rhs_expression: - /* treat symbol as variable name */ - return true; - case exprstatetype::expect_symbol: return true; @@ -179,40 +176,6 @@ namespace xo { return false; } -#ifdef OBSOLETE - bool - exprstate::admits_rightparen() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - return false; - - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - /* unreachable - redirects to define_xs */ - assert(false); - return false; - - case exprstatetype::expect_rhs_expression: - return false; - - case exprstatetype::expect_type: - return false; - - case exprstatetype::expect_symbol: - return false; - - case exprstatetype::expr_progress: - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } -#endif - void exprstate::on_def_token(const token_type & tk, exprstatestack * /*p_stack*/) @@ -240,39 +203,11 @@ namespace xo { case exprstatetype::expect_toplevel_expression_sequence: case exprstatetype::defexpr: case exprstatetype::parenexpr: - /* unreachable - redirects to define_xs */ + case exprstatetype::expect_rhs_expression: + /* unreachable - redirected to define_xs etc */ assert(false); return; - case exprstatetype::expect_rhs_expression: - { - /* various possibilities when looking for rhs expression: - * - * x := y // (1) - * x := f(a) // (2) - * x := f(a,b) // (3) - * - * need lookahead token following symbol to distinguish - * between (1) (symbol completes rhs expression) - * and {(2), (3)} (symbol is function call) - */ - - /* have to do pop first, before sending symbol to - * the o.g. symbol-requester - */ -#ifdef NOT_YET - p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, - Variable::make(name, type))); -#endif - -#ifdef LATER - p_stack->pop_exprstate(); - p_stack->top_exprstate().on_symbol(tk.text(), - p_stack, p_emit_expr); -#endif - return; - } - case exprstatetype::expect_symbol: { /* have to do pop first, before sending symbol to @@ -528,8 +463,8 @@ namespace xo { void exprstate::on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -537,42 +472,7 @@ namespace xo { log && log(xtag("exstype", this->exs_type_), xtag("expr", expr)); - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - /* unreachable. redirects to define_xs::on_expr() etc */ - assert(false); - return; - - case exprstatetype::expect_rhs_expression: { - - std::unique_ptr self = p_stack->pop_exprstate(); - - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); - - return; - } - - case exprstatetype::expect_type: - case exprstatetype::expect_symbol: - /* unreachable - * (this exprstate issues pop instruction from exprstate::on_input() - */ - assert(false); - return; - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } + assert(false); } /*on_expr*/ void From be412cb5aef734f5ee2e4ae99f9b5fbaddd5e92b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 16:20:51 -0500 Subject: [PATCH 099/191] xo-reader: refactor: + expect_symbol_xs [wip] --- include/xo/reader/expect_symbol_xs.hpp | 27 ++++++++++++++++++++++++++ include/xo/reader/exprstate.hpp | 2 ++ src/reader/CMakeLists.txt | 3 ++- src/reader/expect_symbol_xs.cpp | 23 ++++++++++++++++++++++ src/reader/exprseq_xs.cpp | 3 ++- src/reader/exprstate.cpp | 6 ------ 6 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 include/xo/reader/expect_symbol_xs.hpp create mode 100644 src/reader/expect_symbol_xs.cpp diff --git a/include/xo/reader/expect_symbol_xs.hpp b/include/xo/reader/expect_symbol_xs.hpp new file mode 100644 index 00000000..103b89aa --- /dev/null +++ b/include/xo/reader/expect_symbol_xs.hpp @@ -0,0 +1,27 @@ +/* file expect_symbol_xs.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" + +namespace xo { + namespace scm { + /** @class expect_symbol_xs + * @brief state machine to expect + capture a symbol + * + * For example, lhs in a define-expression + **/ + class expect_symbol_xs : public exprstate { + public: + expect_symbol_xs(); + + static std::unique_ptr expect_symbol_expression(); + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_symbol_xs.hpp */ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 9f20dfd8..7f643921 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -70,9 +70,11 @@ namespace xo { {} virtual ~exprstate() = default; +#ifdef RELOCATED static std::unique_ptr expect_symbol() { return std::make_unique(exprstate(exprstatetype::expect_symbol)); } +#endif static std::unique_ptr expect_type() { return std::make_unique(exprstate(exprstatetype::expect_type)); } diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 77a06a63..473c9a93 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -9,7 +9,8 @@ set(SELF_SRCS progress_xs.cpp paren_xs.cpp exprseq_xs.cpp - expect_expr_xs.cpp) + expect_expr_xs.cpp + expect_symbol_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp new file mode 100644 index 00000000..afc8bf6e --- /dev/null +++ b/src/reader/expect_symbol_xs.cpp @@ -0,0 +1,23 @@ +/* file expect_symbol_xs.cpp + * + * author: Roland Conybeare + */ + +#include "expect_symbol_xs.hpp" + +namespace xo { + namespace scm { + std::unique_ptr + expect_symbol_xs::expect_symbol_expression() { + return std::make_unique(expect_symbol_xs()); + } + + expect_symbol_xs::expect_symbol_xs() + : exprstate(exprstatetype::expect_symbol) + {} + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_symbol_xs.cpp */ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 502f129f..042c5eb3 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -2,6 +2,7 @@ #include "exprseq_xs.hpp" #include "define_xs.hpp" +#include "expect_symbol_xs.hpp" namespace xo { namespace scm { @@ -30,7 +31,7 @@ namespace xo { /* todo: replace: * expect_symbol_or_function_signature() */ - p_stack->push_exprstate(exprstate::expect_symbol()); + p_stack->push_exprstate(expect_symbol_xs::expect_symbol_expression()); /* keyword 'def' introduces a definition: * def pi : f64 = 3.14159265 diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 540bcaaa..9c083656 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -87,9 +87,6 @@ namespace xo { return false; case exprstatetype::expect_rhs_expression: - /* rhs-expressions (or expressions for that matter) - * may not begin with a colon - */ case exprstatetype::expect_symbol: case exprstatetype::expect_type: return false; @@ -155,9 +152,6 @@ namespace xo { return false; case exprstatetype::expect_rhs_expression: - /* rhs-expressions (or expressions for that matter) - * may not begin with singleassign '=' - */ case exprstatetype::expect_symbol: case exprstatetype::expect_type: return false; From 08497a371c3c6aba070eca40fc0314456b52fa71 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 16:56:35 -0500 Subject: [PATCH 100/191] xo-reader: mv symbol handling to expect_symbol_xs --- include/xo/reader/expect_symbol_xs.hpp | 4 ++++ src/reader/expect_symbol_xs.cpp | 14 ++++++++++++++ src/reader/exprstate.cpp | 13 +------------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/xo/reader/expect_symbol_xs.hpp b/include/xo/reader/expect_symbol_xs.hpp index 103b89aa..144bc3d0 100644 --- a/include/xo/reader/expect_symbol_xs.hpp +++ b/include/xo/reader/expect_symbol_xs.hpp @@ -19,6 +19,10 @@ namespace xo { expect_symbol_xs(); static std::unique_ptr expect_symbol_expression(); + + virtual void on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index afc8bf6e..84faeaa3 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -16,6 +16,20 @@ namespace xo { : exprstate(exprstatetype::expect_symbol) {} + void + expect_symbol_xs::on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ + std::unique_ptr self = p_stack->pop_exprstate(); + + p_stack->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); + return; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 9c083656..aa916b0d 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -198,22 +198,11 @@ namespace xo { case exprstatetype::defexpr: case exprstatetype::parenexpr: case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_symbol: /* unreachable - redirected to define_xs etc */ assert(false); return; - case exprstatetype::expect_symbol: - { - /* have to do pop first, before sending symbol to - * the o.g. symbol-requester - */ - std::unique_ptr self = p_stack->pop_exprstate(); - - p_stack->top_exprstate().on_symbol(tk.text(), - p_stack, p_emit_expr); - return; - } - case exprstatetype::expect_type: { TypeDescr td = nullptr; From 1087e57a624d984855e6e242531f6a78a764956e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 17:02:50 -0500 Subject: [PATCH 101/191] xo-reader: refactor: + expect_type_xs [wip] --- include/xo/reader/expect_type_xs.hpp | 25 +++++++++++++++++++++++++ include/xo/reader/exprstate.hpp | 2 ++ src/reader/CMakeLists.txt | 3 ++- src/reader/define_xs.cpp | 3 ++- src/reader/expect_type_xs.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 include/xo/reader/expect_type_xs.hpp create mode 100644 src/reader/expect_type_xs.cpp diff --git a/include/xo/reader/expect_type_xs.hpp b/include/xo/reader/expect_type_xs.hpp new file mode 100644 index 00000000..261074f9 --- /dev/null +++ b/include/xo/reader/expect_type_xs.hpp @@ -0,0 +1,25 @@ +/* file expect_type_xs.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" + +namespace xo { + namespace scm { + /** @class expect_type_xs + * @brief state-machine for accepting a typename-expression + **/ + class expect_type_xs : public exprstate { + public: + expect_type_xs(); + + static std::unique_ptr make(); + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_type_xs.hpp */ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 7f643921..b3cdf24e 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -75,9 +75,11 @@ namespace xo { return std::make_unique(exprstate(exprstatetype::expect_symbol)); } #endif +#ifdef RELOCATED static std::unique_ptr expect_type() { return std::make_unique(exprstate(exprstatetype::expect_type)); } +#endif exprstatetype exs_type() const { return exs_type_; } diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 473c9a93..6907dff2 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -10,7 +10,8 @@ set(SELF_SRCS paren_xs.cpp exprseq_xs.cpp expect_expr_xs.cpp - expect_symbol_xs.cpp) + expect_symbol_xs.cpp + expect_type_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index ffa8a094..ea8a72a1 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -2,6 +2,7 @@ #include "define_xs.hpp" #include "expect_expr_xs.hpp" +#include "expect_type_xs.hpp" namespace xo { namespace scm { @@ -321,7 +322,7 @@ namespace xo { if (this->defxs_type_ == defexprstatetype::def_1) { this->defxs_type_ = defexprstatetype::def_2; - p_stack->push_exprstate(exprstate::expect_type()); + p_stack->push_exprstate(expect_type_xs::make()); } else { assert(false); } diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp new file mode 100644 index 00000000..65f0f7a9 --- /dev/null +++ b/src/reader/expect_type_xs.cpp @@ -0,0 +1,24 @@ +/* file expect_type_xs.cpp + * + * author: Roland Conybeare + */ + +#include "expect_type_xs.hpp" +#include "exprstate.hpp" + +namespace xo { + namespace scm { + std::unique_ptr + expect_type_xs::make() { + return std::make_unique(expect_type_xs()); + } + + expect_type_xs::expect_type_xs() + : exprstate(exprstatetype::expect_type) + {} + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_type_xs.cpp */ From 29f21730701695bec32b8c5c7b7f2c0948ceba12 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 17:08:40 -0500 Subject: [PATCH 102/191] xo-reader: refactor: mv type-expr handling to expect_type_xs --- include/xo/reader/expect_type_xs.hpp | 4 ++++ src/reader/expect_type_xs.cpp | 36 ++++++++++++++++++++++++++++ src/reader/exprstate.cpp | 32 ++----------------------- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/include/xo/reader/expect_type_xs.hpp b/include/xo/reader/expect_type_xs.hpp index 261074f9..c75c91cb 100644 --- a/include/xo/reader/expect_type_xs.hpp +++ b/include/xo/reader/expect_type_xs.hpp @@ -17,6 +17,10 @@ namespace xo { expect_type_xs(); static std::unique_ptr make(); + + virtual void on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index 65f0f7a9..6c4c5afb 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -5,8 +5,11 @@ #include "expect_type_xs.hpp" #include "exprstate.hpp" +#include "xo/reflect/Reflect.hpp" namespace xo { + using xo::reflect::Reflect; + namespace scm { std::unique_ptr expect_type_xs::make() { @@ -17,6 +20,39 @@ namespace xo { : exprstate(exprstatetype::expect_type) {} + void + expect_type_xs::on_symbol_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + const char * c_self_name = "expect_type_xs::on_symbol_token"; + + TypeDescr td = nullptr; + + /* TODO: replace with typetable lookup */ + + if (tk.text() == "f64") + td = Reflect::require(); + else if(tk.text() == "f32") + td = Reflect::require(); + else if(tk.text() == "i16") + td = Reflect::require(); + else if(tk.text() == "i32") + td = Reflect::require(); + else if(tk.text() == "i64") + td = Reflect::require(); + + if (!td) { + throw std::runtime_error + (tostr(c_self_name, + ": unknown type name", + " (expecting f64|f32|i16|i32|i64)", + xtag("typename", tk.text()))); + } + + std::unique_ptr self = p_stack->pop_exprstate(); + p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index aa916b0d..1b7bd878 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -180,7 +180,7 @@ namespace xo { void exprstate::on_symbol_token(const token_type & tk, exprstatestack * p_stack, - rp * p_emit_expr) + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -199,39 +199,11 @@ namespace xo { case exprstatetype::parenexpr: case exprstatetype::expect_rhs_expression: case exprstatetype::expect_symbol: + case exprstatetype::expect_type: /* unreachable - redirected to define_xs etc */ assert(false); return; - case exprstatetype::expect_type: { - TypeDescr td = nullptr; - - /* TODO: replace with typetable lookup */ - - if (tk.text() == "f64") - td = Reflect::require(); - else if(tk.text() == "f32") - td = Reflect::require(); - else if(tk.text() == "i16") - td = Reflect::require(); - else if(tk.text() == "i32") - td = Reflect::require(); - else if(tk.text() == "i64") - td = Reflect::require(); - - if (!td) { - throw std::runtime_error - (tostr(c_self_name, - ": unknown type name", - " (expecting f64|f32|i16|i32|i64)", - xtag("typename", tk.text()))); - } - - std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); - return; - } - case exprstatetype::expr_progress: /* unreachable */ assert(false); From 99d9f400912f991ffcdbe8d65ca0d3a090d595c5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 17:09:51 -0500 Subject: [PATCH 103/191] xo-reader: streamline: collapse exprstate::on_symbol_token() --- src/reader/exprstate.cpp | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 1b7bd878..051a023d 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -189,32 +189,7 @@ namespace xo { constexpr const char * c_self_name = "exprstate::on_symbol_token"; - if (!this->admits_symbol()) { - this->illegal_input_error(c_self_name, tk); - } - - switch (this->exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - /* unreachable - redirected to define_xs etc */ - assert(false); - return; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - assert(false); - return; - } + this->illegal_input_error(c_self_name, tk); } void From 2b436850cf3e12f4cab6d7dd04f62dae568c1dcf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 17:12:52 -0500 Subject: [PATCH 104/191] xo-reader: simplify: drop exprstate.admits_colon() --- include/xo/reader/define_xs.hpp | 2 +- include/xo/reader/exprstate.hpp | 2 -- include/xo/reader/paren_xs.hpp | 4 ---- include/xo/reader/progress_xs.hpp | 1 - src/reader/exprstate.cpp | 38 +++---------------------------- src/reader/paren_xs.cpp | 3 --- src/reader/progress_xs.cpp | 3 --- 7 files changed, 4 insertions(+), 49 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 8c9ef9c1..dc5a5944 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -43,9 +43,9 @@ namespace xo { defexprstatetype defxs_type() const { return defxs_type_; } bool admits_rightparen() const; + bool admits_colon() const; virtual bool admits_symbol() const override; - virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index b3cdf24e..4da51d5d 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -85,8 +85,6 @@ namespace xo { /** true iff this parsing state admits a symbol as next token **/ virtual bool admits_symbol() const; - /** true iff this parsing state admits a colon as next token **/ - virtual bool admits_colon() const; /** true iff this parsing state admits a semicolon as next token **/ virtual bool admits_semicolon() const; /** true iff this parsing state admits a singleassign '=' as next token **/ diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index d00dc384..61a057ae 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -35,12 +35,8 @@ namespace xo { bool admits_rightparen() const; virtual bool admits_symbol() const override; - virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; -#ifdef OBSOLETE - virtual bool admits_leftparen() const override; -#endif virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index d4a0c190..47912d20 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -25,7 +25,6 @@ namespace xo { bool admits_f64() const; virtual bool admits_symbol() const override; - virtual bool admits_colon() const override; virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; #ifdef OBSOLETE diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 051a023d..2eaac5bb 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -76,35 +76,6 @@ namespace xo { return false; } - bool - exprstate::admits_colon() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - /* unreachable -- redirects to define_xs::admits_colon() etc */ - assert(false); - return false; - - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } - bool exprstate::admits_semicolon() const { switch (exs_type_) { @@ -214,12 +185,9 @@ namespace xo { constexpr const char * self_name = "exprstate::on_colon"; /* lots of illegal states */ - if (!this->admits_colon()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected colon for parsing state", - xtag("state", *this))); - } + throw std::runtime_error(tostr(self_name, + ": unexpected colon for parsing state", + xtag("state", *this))); assert(false); } diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 2fcf427b..1f882b9f 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -17,9 +17,6 @@ namespace xo { bool paren_xs::admits_symbol() const { return true; } - bool - paren_xs::admits_colon() const { return false; } - bool paren_xs::admits_semicolon() const { return false; } diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index f518374a..16f31ce2 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -17,9 +17,6 @@ namespace xo { bool progress_xs::admits_symbol() const { return false; } - bool - progress_xs::admits_colon() const { return false; } - bool progress_xs::admits_semicolon() const { return true; } From 57b9a7f561c1034c7d4f3a1c5b1a6346d14a5ba3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 17:14:19 -0500 Subject: [PATCH 105/191] xo-reader: tidy: cleanup debris --- include/xo/reader/exprstate.hpp | 11 ----------- src/reader/paren_xs.cpp | 5 ----- 2 files changed, 16 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 4da51d5d..b6807776 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -70,17 +70,6 @@ namespace xo { {} virtual ~exprstate() = default; -#ifdef RELOCATED - static std::unique_ptr expect_symbol() { - return std::make_unique(exprstate(exprstatetype::expect_symbol)); - } -#endif -#ifdef RELOCATED - static std::unique_ptr expect_type() { - return std::make_unique(exprstate(exprstatetype::expect_type)); - } -#endif - exprstatetype exs_type() const { return exs_type_; } /** true iff this parsing state admits a symbol as next token **/ diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 1f882b9f..232bdb72 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -23,11 +23,6 @@ namespace xo { bool paren_xs::admits_singleassign() const { return false; } -#ifdef OBSOLETE - bool - paren_xs::admits_leftparen() const { /*unreachable*/ return false; } -#endif - bool paren_xs::admits_rightparen() const { switch (parenxs_type_) { From 18a4b51d3cd7a64550b71166c71be429b1a9b973 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 17:30:45 -0500 Subject: [PATCH 106/191] xo-reader: simplify: drop redundant virtual admits_xxx() --- include/xo/reader/define_xs.hpp | 2 +- include/xo/reader/exprstate.hpp | 2 ++ include/xo/reader/paren_xs.hpp | 1 - include/xo/reader/progress_xs.hpp | 5 ----- src/reader/exprstate.cpp | 13 +++++-------- src/reader/paren_xs.cpp | 3 --- src/reader/progress_xs.cpp | 10 ++-------- 7 files changed, 10 insertions(+), 26 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index dc5a5944..5e70012c 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -44,9 +44,9 @@ namespace xo { bool admits_rightparen() const; bool admits_colon() const; + bool admits_semicolon() const; virtual bool admits_symbol() const override; - virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; // virtual void on_f64(..) override diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index b6807776..c75870ce 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -74,8 +74,10 @@ namespace xo { /** true iff this parsing state admits a symbol as next token **/ virtual bool admits_symbol() const; +#ifdef OBSOLETE /** true iff this parsing state admits a semicolon as next token **/ virtual bool admits_semicolon() const; +#endif /** true iff this parsing state admits a singleassign '=' as next token **/ virtual bool admits_singleassign() const; diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 61a057ae..058cdf37 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -35,7 +35,6 @@ namespace xo { bool admits_rightparen() const; virtual bool admits_symbol() const override; - virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; virtual void on_expr(ref::brw expr, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 47912d20..9ec61099 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -25,12 +25,7 @@ namespace xo { bool admits_f64() const; virtual bool admits_symbol() const override; - virtual bool admits_semicolon() const override; virtual bool admits_singleassign() const override; -#ifdef OBSOLETE - virtual bool admits_leftparen() const override; - virtual bool admits_rightparen() const override; -#endif virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 2eaac5bb..3416f7d1 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -76,6 +76,7 @@ namespace xo { return false; } +#ifdef OBSOLETE bool exprstate::admits_semicolon() const { switch (exs_type_) { @@ -97,6 +98,7 @@ namespace xo { return false; } +#endif bool exprstate::admits_singleassign() const { @@ -202,14 +204,9 @@ namespace xo { constexpr const char * self_name = "exprstate::on_semicolon"; - if (!this->admits_semicolon()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected semicolon for parsing state", - xtag("state", *this))); - } - - assert(false); + throw std::runtime_error(tostr(self_name, + ": unexpected semicolon for parsing state", + xtag("state", *this))); } void diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 232bdb72..448e0faa 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -17,9 +17,6 @@ namespace xo { bool paren_xs::admits_symbol() const { return true; } - bool - paren_xs::admits_semicolon() const { return false; } - bool paren_xs::admits_singleassign() const { return false; } diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 16f31ce2..3a978505 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -17,20 +17,14 @@ namespace xo { bool progress_xs::admits_symbol() const { return false; } +#ifdef OSBOLETE bool progress_xs::admits_semicolon() const { return true; } +#endif bool progress_xs::admits_singleassign() const { return false; } -#ifdef OBSOLETE - bool - progress_xs::admits_rightparen() const { - /* satisfies expression form */ - return true; - } -#endif - bool progress_xs::admits_f64() const { return false; } From f1f5b44a8182d6b24d955fa36dc264f718a8c009 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 17:31:44 -0500 Subject: [PATCH 107/191] xo-reader: tidy: buty debris --- src/reader/exprstate.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 3416f7d1..cb85ae6a 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -76,30 +76,6 @@ namespace xo { return false; } -#ifdef OBSOLETE - bool - exprstate::admits_semicolon() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return true; - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - return false; - } - - return false; - } -#endif - bool exprstate::admits_singleassign() const { switch (exs_type_) { From e9e0d5255fbd88fc066e9689a7bdd7805dd7cd02 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 23:57:01 -0500 Subject: [PATCH 108/191] xo-reader: streamline: drop redundant admits_xxx() methods --- include/xo/reader/define_xs.hpp | 4 +++- include/xo/reader/exprstate.hpp | 4 +--- include/xo/reader/paren_xs.hpp | 1 - include/xo/reader/progress_xs.hpp | 4 +++- src/reader/define_xs.cpp | 36 +++++++++++++++---------------- src/reader/exprstate.cpp | 13 +++++------ src/reader/paren_xs.cpp | 3 --- src/reader/progress_xs.cpp | 8 ------- 8 files changed, 29 insertions(+), 44 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 5e70012c..d00b2d79 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -47,7 +47,9 @@ namespace xo { bool admits_semicolon() const; virtual bool admits_symbol() const override; - virtual bool admits_singleassign() const override; +#ifdef OBSOLETE + bool admits_singleassign() const; +#endif // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index c75870ce..2577c920 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -75,11 +75,9 @@ namespace xo { /** true iff this parsing state admits a symbol as next token **/ virtual bool admits_symbol() const; #ifdef OBSOLETE - /** true iff this parsing state admits a semicolon as next token **/ - virtual bool admits_semicolon() const; -#endif /** true iff this parsing state admits a singleassign '=' as next token **/ virtual bool admits_singleassign() const; +#endif /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 058cdf37..3f4922de 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -35,7 +35,6 @@ namespace xo { bool admits_rightparen() const; virtual bool admits_symbol() const override; - virtual bool admits_singleassign() const override; virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 9ec61099..93e442e3 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -25,7 +25,9 @@ namespace xo { bool admits_f64() const; virtual bool admits_symbol() const override; - virtual bool admits_singleassign() const override; +#ifdef OBSOLETE + bool admits_singleassign() const; +#endif virtual void on_expr(ref::brw expr, exprstatestack * p_stack, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index ea8a72a1..d901f3fb 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -88,24 +88,11 @@ namespace xo { return false; } +#ifdef OBSOLETE bool define_xs::admits_singleassign() const { switch (defxs_type_) { - /* - * def foo = 1 ; - * def foo : f64 = 1 ; - * ^ ^ ^ ^ ^ ^ ^ - * | | | | | | (done) - * | | | | | def_4:expect_rhs_expression - * | | | | def_3 - * | | | def_2:expect_type - * | | def_1 - * | def_0:expect_symbol - * expect_toplevel_expression_sequence - * - * note that we skip from def_1 -> def_4 if '=' instead of ':' - */ case defexprstatetype::def_0: return false; @@ -131,6 +118,7 @@ namespace xo { return false; } +#endif #ifdef OBSOLETE bool @@ -367,10 +355,20 @@ namespace xo { constexpr const char * self_name = "exprstate::on_singleassign"; - if (!this->admits_singleassign()) { - this->illegal_input_error(self_name, tk); - } - + /* + * def foo = 1 ; + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ + * | | | | | | (done) + * | | | | | def_4:expect_rhs_expression + * | | | | def_3 + * | | | def_2:expect_type + * | | def_1 + * | def_0:expect_symbol + * expect_toplevel_expression_sequence + * + * note that we skip from def_1 -> def_4 if '=' instead of ':' + */ if ((this->defxs_type_ == defexprstatetype::def_1) || (this->defxs_type_ == defexprstatetype::def_3)) { @@ -378,7 +376,7 @@ namespace xo { p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); } else { - assert(false); + this->illegal_input_error(self_name, tk); } } diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index cb85ae6a..869056b1 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -76,6 +76,7 @@ namespace xo { return false; } +#ifdef OBSOLETE bool exprstate::admits_singleassign() const { switch (exs_type_) { @@ -118,6 +119,7 @@ namespace xo { return false; } +#endif void exprstate::on_def_token(const token_type & tk, @@ -193,14 +195,9 @@ namespace xo { constexpr const char * self_name = "exprstate::on_singleassign_token"; - if (!this->admits_singleassign()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected equals for parsing state", - xtag("state", *this))); - } - - assert(false); + throw std::runtime_error(tostr(self_name, + ": unexpected equals for parsing state", + xtag("state", *this))); } void diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 448e0faa..304babb6 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -17,9 +17,6 @@ namespace xo { bool paren_xs::admits_symbol() const { return true; } - bool - paren_xs::admits_singleassign() const { return false; } - bool paren_xs::admits_rightparen() const { switch (parenxs_type_) { diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 3a978505..077450eb 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -17,14 +17,6 @@ namespace xo { bool progress_xs::admits_symbol() const { return false; } -#ifdef OSBOLETE - bool - progress_xs::admits_semicolon() const { return true; } -#endif - - bool - progress_xs::admits_singleassign() const { return false; } - bool progress_xs::admits_f64() const { return false; } From 652a454887082164343aa1de2de0b1fb002e120e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 10 Aug 2024 23:58:08 -0500 Subject: [PATCH 109/191] xo-reader: bury debris --- include/xo/reader/exprstate.hpp | 4 --- src/reader/exprstate.cpp | 45 --------------------------------- 2 files changed, 49 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 2577c920..9f6e46d2 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -74,10 +74,6 @@ namespace xo { /** true iff this parsing state admits a symbol as next token **/ virtual bool admits_symbol() const; -#ifdef OBSOLETE - /** true iff this parsing state admits a singleassign '=' as next token **/ - virtual bool admits_singleassign() const; -#endif /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 869056b1..ce33737d 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -76,51 +76,6 @@ namespace xo { return false; } -#ifdef OBSOLETE - bool - exprstate::admits_singleassign() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - /* - * def foo = 1 ; - * def foo : f64 = 1 ; - * ^ ^ ^ ^ ^ ^ ^ - * | | | | | | (done) - * | | | | | def_4:expect_rhs_expression - * | | | | def_3 - * | | | def_2:expect_type - * | | def_1 - * | def_0:expect_symbol - * expect_toplevel_expression_sequence - * - * note that we skip from def_1 -> def_4 if '=' instead of ':' - */ - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - /* unreachable - redirects to define_xs etrc */ - assert(false); - return false; - - case exprstatetype::expect_rhs_expression: - case exprstatetype::expect_symbol: - case exprstatetype::expect_type: - return false; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } -#endif - void exprstate::on_def_token(const token_type & tk, exprstatestack * /*p_stack*/) From ae746b31736209674d265b8fb565f02ff3591ed2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 11 Aug 2024 00:01:11 -0500 Subject: [PATCH 110/191] xo-reader: retire unused admits_symbol() --- include/xo/reader/define_xs.hpp | 5 +---- include/xo/reader/exprstate.hpp | 6 +++++- include/xo/reader/paren_xs.hpp | 2 -- include/xo/reader/progress_xs.hpp | 5 ----- src/reader/define_xs.cpp | 22 ---------------------- src/reader/exprstate.cpp | 2 ++ src/reader/paren_xs.cpp | 3 --- src/reader/progress_xs.cpp | 3 --- 8 files changed, 8 insertions(+), 40 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index d00b2d79..f3a5f15a 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -46,10 +46,7 @@ namespace xo { bool admits_colon() const; bool admits_semicolon() const; - virtual bool admits_symbol() const override; -#ifdef OBSOLETE - bool admits_singleassign() const; -#endif + //bool admits_symbol() const; // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 9f6e46d2..8cb278e7 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -72,13 +72,17 @@ namespace xo { exprstatetype exs_type() const { return exs_type_; } +#ifdef OBSOLETE /** true iff this parsing state admits a symbol as next token **/ virtual bool admits_symbol() const; +#endif /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser **/ - void on_input(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); + void on_input(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(ref::brw expr, diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 3f4922de..65811607 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -34,8 +34,6 @@ namespace xo { bool admits_f64() const; bool admits_rightparen() const; - virtual bool admits_symbol() const override; - virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 93e442e3..361e6d3d 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -24,11 +24,6 @@ namespace xo { bool admits_f64() const; - virtual bool admits_symbol() const override; -#ifdef OBSOLETE - bool admits_singleassign() const; -#endif - virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index d901f3fb..d3c2d5c2 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -17,28 +17,6 @@ namespace xo { def_expr_{std::move(def_expr)} {} - bool - define_xs::admits_symbol() const { - switch (defxs_type_) { - - case defexprstatetype::def_0: - case defexprstatetype::def_1: - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - case defexprstatetype::def_5: - return false; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } - bool define_xs::admits_colon() const { switch (defxs_type_) { diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index ce33737d..c3b85833 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -42,6 +42,7 @@ namespace xo { return "???"; } +#ifdef OBSOLETE bool exprstate::admits_symbol() const { switch (exs_type_) { @@ -75,6 +76,7 @@ namespace xo { return false; } +#endif void exprstate::on_def_token(const token_type & tk, diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 304babb6..cfd20f95 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -14,9 +14,6 @@ namespace xo { return std::make_unique(paren_xs()); } - bool - paren_xs::admits_symbol() const { return true; } - bool paren_xs::admits_rightparen() const { switch (parenxs_type_) { diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 077450eb..4d78fb8a 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -14,9 +14,6 @@ namespace xo { gen_expr_{std::move(valex)} {} - bool - progress_xs::admits_symbol() const { return false; } - bool progress_xs::admits_f64() const { return false; } From 4f44bada3dd971927396a3a4568827a812c9c42a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 11 Aug 2024 00:02:29 -0500 Subject: [PATCH 111/191] xo-reader: tidy - bury debris --- include/xo/reader/exprstate.hpp | 5 ----- src/reader/exprstate.cpp | 38 --------------------------------- 2 files changed, 43 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 8cb278e7..dc62e86f 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -72,11 +72,6 @@ namespace xo { exprstatetype exs_type() const { return exs_type_; } -#ifdef OBSOLETE - /** true iff this parsing state admits a symbol as next token **/ - virtual bool admits_symbol() const; -#endif - /** update exprstate in response to incoming token @p tk, * forward instructions to parent parser **/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index c3b85833..f38f3540 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -5,9 +5,7 @@ #include "progress_xs.hpp" #include "paren_xs.hpp" #include "expect_expr_xs.hpp" -//#include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" -//#include "xo/expression/ConvertExpr.hpp" #include "xo/reflect/Reflect.hpp" namespace xo { @@ -42,42 +40,6 @@ namespace xo { return "???"; } -#ifdef OBSOLETE - bool - exprstate::admits_symbol() const { - switch (exs_type_) { - case exprstatetype::expect_toplevel_expression_sequence: - return false; - - case exprstatetype::defexpr: - case exprstatetype::parenexpr: - case exprstatetype::expect_rhs_expression: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::expect_symbol: - return true; - - case exprstatetype::expect_type: - /* treat symbol as typename */ - return true; - - case exprstatetype::expr_progress: - /* unreachable */ - assert(false); - return false; - - case exprstatetype::invalid: - case exprstatetype::n_exprstatetype: - /* unreachable */ - return false; - } - - return false; - } -#endif - void exprstate::on_def_token(const token_type & tk, exprstatestack * /*p_stack*/) From 1918148999755b71b8472a48febe2bffe71887ba Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 11 Aug 2024 00:05:44 -0500 Subject: [PATCH 112/191] xo-reader: refactor: consolidate w/ illegal_input_error() --- src/reader/exprstate.cpp | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index f38f3540..e7933d7c 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -1,16 +1,16 @@ /* @file exprstate.cpp */ #include "exprstate.hpp" -#include "define_xs.hpp" -#include "progress_xs.hpp" -#include "paren_xs.hpp" -#include "expect_expr_xs.hpp" -#include "xo/expression/Constant.hpp" -#include "xo/reflect/Reflect.hpp" +//#include "define_xs.hpp" +//#include "progress_xs.hpp" +//#include "paren_xs.hpp" +//#include "expect_expr_xs.hpp" +//#include "xo/expression/Constant.hpp" +//#include "xo/reflect/Reflect.hpp" namespace xo { - using xo::ast::Constant; - using xo::reflect::Reflect; + //using xo::ast::Constant; + //using xo::reflect::Reflect; using xo::reflect::TypeDescr; namespace scm { @@ -75,7 +75,7 @@ namespace xo { } void - exprstate::on_colon_token(const token_type & /*tk*/, + exprstate::on_colon_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr bool c_debug_flag = true; @@ -83,16 +83,11 @@ namespace xo { constexpr const char * self_name = "exprstate::on_colon"; - /* lots of illegal states */ - throw std::runtime_error(tostr(self_name, - ": unexpected colon for parsing state", - xtag("state", *this))); - - assert(false); + this->illegal_input_error(self_name, tk); } void - exprstate::on_semicolon_token(const token_type & /*tk*/, + exprstate::on_semicolon_token(const token_type & tk, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { @@ -101,22 +96,18 @@ namespace xo { constexpr const char * self_name = "exprstate::on_semicolon"; - throw std::runtime_error(tostr(self_name, - ": unexpected semicolon for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } void - exprstate::on_singleassign_token(const token_type & /*tk*/, + exprstate::on_singleassign_token(const token_type & tk, exprstatestack * /*p_stack*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); constexpr const char * self_name = "exprstate::on_singleassign_token"; - throw std::runtime_error(tostr(self_name, - ": unexpected equals for parsing state", - xtag("state", *this))); + this->illegal_input_error(self_name, tk); } void From f677995f77a7a84f0aaeceb697f810195dc73292 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 14 Aug 2024 15:44:52 -0400 Subject: [PATCH 113/191] xo-reader: minor: comment --- include/xo/reader/exprstate.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index dc62e86f..ef65e8f5 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -144,6 +144,8 @@ namespace xo { return os; } + // ----- exprstatestack ----- + /** @class exprstatestack * @brief A stack of exprstate objects **/ From 29596a7c1dc3f91bd8719fbbb9d16c6e7e8ac11e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 14 Aug 2024 23:44:17 -0400 Subject: [PATCH 114/191] xo-reader: feat: parse infix exprs for +,-,*,/ operators --- include/xo/reader/exprstate.hpp | 4 ++ include/xo/reader/progress_xs.hpp | 21 +++++++ src/reader/exprstate.cpp | 20 ++++++ src/reader/progress_xs.cpp | 101 +++++++++++++++++++++++++++--- utest/reader.test.cpp | 3 +- 5 files changed, 141 insertions(+), 8 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ef65e8f5..d109f280 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -121,6 +121,10 @@ namespace xo { virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); + /** handle incoming operator token **/ + virtual void on_operator_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); /** handle incoming floating-point-literal token **/ virtual void on_f64_token(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 361e6d3d..9a7381c7 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -10,6 +10,18 @@ namespace xo { namespace scm { + /* represent an infix operator */ + enum class optype { + invalid = -1, + + op_add, + op_subtract, + op_multiply, + op_divide, + + n_optype + }; + /** @class progress_xs * @brief state machine for parsing a schematica runtime-value-expression **/ @@ -49,6 +61,12 @@ namespace xo { virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; + + /* entry point for an infix operator token */ + virtual void on_operator_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_f64_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; @@ -58,6 +76,9 @@ namespace xo { private: /** populate an expression here **/ rp gen_expr_; + + /** infix operator, if supplied **/ + optype op_type_ = optype::invalid; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index e7933d7c..1985aa7d 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -136,6 +136,19 @@ namespace xo { this->illegal_input_error(self_name, tk); } + void + exprstate::on_operator_token(const token_type & tk, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_operator_token"; + + this->illegal_input_error(self_name, tk); + } + void exprstate::on_f64_token(const token_type & tk, exprstatestack * /*p_stack*/, @@ -220,6 +233,13 @@ namespace xo { case tokentype::tk_assign: case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + this->on_operator_token(tk, p_stack, p_emit_expr); + return; + case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_if: diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 4d78fb8a..241c5da4 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -1,8 +1,12 @@ /* @file progress_xs.cpp */ #include "progress_xs.hpp" +#include "expect_expr_xs.hpp" +#include "xo/expression/Apply.hpp" namespace xo { + using xo::ast::Apply; + namespace scm { std::unique_ptr progress_xs::make(rp valex) { @@ -28,12 +32,54 @@ namespace xo { } void - progress_xs::on_expr(ref::brw /*expr*/, - exprstatestack * /*p_stack*/, + progress_xs::on_expr(ref::brw expr, + exprstatestack * p_stack, rp * /*p_emit_expr*/) { + constexpr const char * c_self_name = "progress_xs::on_expr"; + + rp result; + /* consecutive expressions isn't legal */ - assert(false); + switch (op_type_) { + case optype::invalid: + throw std::runtime_error(tostr(c_self_name, + ": consecutive unseparated exprs not legal")); + + break; + + case optype::op_add: + result = Apply::make_add2_f64(this->gen_expr_ /*lhs*/, + expr.promote() /*rhs*/); + break; + + case optype::op_subtract: + result = Apply::make_sub2_f64(this->gen_expr_ /*lhs*/, + expr.promote() /*rhs*/); + break; + + case optype::op_multiply: + result = Apply::make_mul2_f64(this->gen_expr_ /*lhs*/, + expr.promote() /*rhs*/); + break; + + case optype::op_divide: + result = Apply::make_div2_f64(this->gen_expr_ /*lhs*/, + expr.promote() /*rhs*/); + break; + + case optype::n_optype: + /* unreachable */ + assert(false); + } + + assert(result.get()); + + /* this expression complete.. */ + std::unique_ptr self = p_stack->pop_exprstate(); + + /* ..but more operators could follow, so don't commit yet */ + p_stack->push_exprstate(progress_xs::make(result)); } void @@ -75,7 +121,7 @@ namespace xo { rp expr = this->gen_expr_; - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_stack, @@ -160,17 +206,58 @@ namespace xo { } + void + progress_xs::on_operator_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr const char * c_self_name = "progress_xs::on_operator_token"; + + if (op_type_ == optype::invalid) { + switch(tk.tk_type()) { + case tokentype::tk_plus: + this->op_type_ = optype::op_add; + break; + case tokentype::tk_minus: + this->op_type_ = optype::op_subtract; + break; + case tokentype::tk_star: + this->op_type_ = optype::op_multiply; + break; + case tokentype::tk_slash: + this->op_type_ = optype::op_divide; + break; + default: + /* unreachable */ + assert(false); + exprstate::on_operator_token(tk, p_stack, p_emit_expr); + } + + /* infix operator must be followed by non-empty expression */ + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + } else { + throw std::runtime_error(tostr(c_self_name, + ": expected expression following operator", + xtag("tk", tk))); + } + } + void progress_xs::on_f64_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + exprstatestack * p_stack, + rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); constexpr const char * self_name = "progress_xs::on_f64"; - this->illegal_input_error(self_name, tk); + if (this->op_type_ == optype::invalid) { + this->illegal_input_error(self_name, tk); + } else { + assert(false); + exprstate::on_f64_token(tk, p_stack, p_emit_expr); + } } void diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp index 8aff0011..fb4a170d 100644 --- a/utest/reader.test.cpp +++ b/utest/reader.test.cpp @@ -14,7 +14,8 @@ namespace xo { std::vector s_testcase_v = { {"def foo : f64 = 3.14159265;"}, - {"def foo : f64 = (3.14159265);"} + {"def foo : f64 = (3.14159265);"}, + {"def foo : f64 = 2.0 * 3.14159265;"} }; } From bba6898ee15e7dcc3a8db683046ec99b7f48e5d3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 15 Aug 2024 00:14:55 -0400 Subject: [PATCH 115/191] xo-reader: fix+prep: setup for associative behaviore --- include/xo/reader/progress_xs.hpp | 28 +++++++- src/reader/progress_xs.cpp | 110 ++++++++++++++++++++++-------- 2 files changed, 106 insertions(+), 32 deletions(-) diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 9a7381c7..fb56c141 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -6,6 +6,7 @@ #pragma once #include "exprstate.hpp" +#include //#include namespace xo { @@ -22,6 +23,15 @@ namespace xo { n_optype }; + extern const char * + optype_descr(optype x); + + inline std::ostream & + operator<< (std::ostream & os, optype x) { + os << optype_descr(x); + return os; + } + /** @class progress_xs * @brief state machine for parsing a schematica runtime-value-expression **/ @@ -74,11 +84,25 @@ namespace xo { virtual void print(std::ostream & os) const override; private: - /** populate an expression here **/ - rp gen_expr_; + /** assemble expression representing + * value of + * @code + * f(lhs_, rhs_) + * @endcode + * + * where f determined by @ref op_type_ + **/ + rp assemble_expr(); + + private: + /** populate an expression here, may be followed by an operator **/ + rp lhs_; /** infix operator, if supplied **/ optype op_type_ = optype::invalid; + + /** populate an expression here, following infix operator */ + rp rhs_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 241c5da4..b7a1775b 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -5,9 +5,29 @@ #include "xo/expression/Apply.hpp" namespace xo { + using xo::ast::Expression; using xo::ast::Apply; namespace scm { + const char * + optype_descr(optype x) { + switch (x) { + case optype::invalid: + return "?optype"; + case optype::op_add: + return "op+"; + case optype::op_subtract: + return "op-"; + case optype::op_multiply: + return "op*"; + case optype::op_divide: + return "op/"; + case optype::n_optype: + break; + } + return "???"; + } + std::unique_ptr progress_xs::make(rp valex) { return std::make_unique(progress_xs(std::move(valex))); @@ -15,7 +35,7 @@ namespace xo { progress_xs::progress_xs(rp valex) : exprstate(exprstatetype::expr_progress), - gen_expr_{std::move(valex)} + lhs_{std::move(valex)} {} bool @@ -31,48 +51,66 @@ namespace xo { this->illegal_input_error(self_name, tk) ; } - void - progress_xs::on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) - { - constexpr const char * c_self_name = "progress_xs::on_expr"; + rp + progress_xs::assemble_expr() { + /* need to defer building Apply incase expr followed by higher-precedence operator: + * consider input like + * 3.14 + 2.0 * ... + */ - rp result; - - /* consecutive expressions isn't legal */ + /* consecutive expressions not legal, e.g: + * 3.14 6.28 + * but expressions surrounding an infix operators is: + * 3.14 / 6.28 + */ switch (op_type_) { case optype::invalid: - throw std::runtime_error(tostr(c_self_name, - ": consecutive unseparated exprs not legal")); - - break; + return this->lhs_; case optype::op_add: - result = Apply::make_add2_f64(this->gen_expr_ /*lhs*/, - expr.promote() /*rhs*/); - break; + return Apply::make_add2_f64(this->lhs_, + this->rhs_); case optype::op_subtract: - result = Apply::make_sub2_f64(this->gen_expr_ /*lhs*/, - expr.promote() /*rhs*/); - break; + return Apply::make_sub2_f64(this->lhs_, + this->rhs_); case optype::op_multiply: - result = Apply::make_mul2_f64(this->gen_expr_ /*lhs*/, - expr.promote() /*rhs*/); - break; + return Apply::make_mul2_f64(this->lhs_, + this->rhs_); case optype::op_divide: - result = Apply::make_div2_f64(this->gen_expr_ /*lhs*/, - expr.promote() /*rhs*/); - break; + return Apply::make_div2_f64(this->lhs_, + this->rhs_); case optype::n_optype: /* unreachable */ assert(false); + return nullptr; } + return nullptr; + } + + void + progress_xs::on_expr(ref::brw expr, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* note: previous token probably an operator, + * handled from progress_xs::on_operator_token(), + * which pushes expect_expr_xs::expect_rhs_expression() + */ + + constexpr const char * c_self_name = "progress_xs::on_expr"; + + + if (op_type_ == optype::invalid) { + throw std::runtime_error(tostr(c_self_name, + ": consecutive unseparated exprs not legal")); + } + +#ifdef NOT_QUITE assert(result.get()); /* this expression complete.. */ @@ -80,6 +118,9 @@ namespace xo { /* ..but more operators could follow, so don't commit yet */ p_stack->push_exprstate(progress_xs::make(result)); +#endif + + this->rhs_ = expr.promote(); } void @@ -116,10 +157,12 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) { + /* note: implementation parllels .on_rightparen_token() */ + constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - rp expr = this->gen_expr_; + rp expr = this->assemble_expr(); std::unique_ptr self = p_stack->pop_exprstate(); @@ -171,6 +214,9 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) { + /* note: implementation parallels .on_semicolon_token() */ + + constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -188,7 +234,7 @@ namespace xo { */ /* right paren confirms stack expression */ - rp expr = this->gen_expr_; + rp expr = this->assemble_expr(); std::unique_ptr self = p_stack->pop_exprstate(); @@ -264,8 +310,12 @@ namespace xo { progress_xs::print(std::ostream & os) const { os << ""; } From c36e8cae40edc0a011df1cd4594d7aa7c6962ec3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 15 Aug 2024 00:36:02 -0400 Subject: [PATCH 116/191] xo-reader: feat: support operator precedence for *,/ over +,- --- include/xo/reader/progress_xs.hpp | 8 +- src/reader/progress_xs.cpp | 132 ++++++++++++++++++++++++------ 2 files changed, 114 insertions(+), 26 deletions(-) diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index fb56c141..aca1977e 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -26,6 +26,9 @@ namespace xo { extern const char * optype_descr(optype x); + extern int + precedence(optype x); + inline std::ostream & operator<< (std::ostream & os, optype x) { os << optype_descr(x); @@ -37,12 +40,13 @@ namespace xo { **/ class progress_xs : public exprstate { public: - progress_xs(rp valex); + progress_xs(rp valex, optype op); virtual ~progress_xs() = default; static const progress_xs * from(const exprstate * x) { return dynamic_cast(x); } - static std::unique_ptr make(rp valex); + static std::unique_ptr make(rp valex, + optype optype = optype::invalid); bool admits_f64() const; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index b7a1775b..421524a2 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -28,14 +28,34 @@ namespace xo { return "???"; } - std::unique_ptr - progress_xs::make(rp valex) { - return std::make_unique(progress_xs(std::move(valex))); + int + precedence(optype x) { + switch (x) { + case optype::invalid: + case optype::n_optype: + return 0; + + case optype::op_add: + case optype::op_subtract: + return 1; + + case optype::op_multiply: + case optype::op_divide: + return 2; + } + + return 0; } - progress_xs::progress_xs(rp valex) + std::unique_ptr + progress_xs::make(rp valex, optype op) { + return std::make_unique(progress_xs(std::move(valex), op)); + } + + progress_xs::progress_xs(rp valex, optype op) : exprstate(exprstatetype::expr_progress), - lhs_{std::move(valex)} + lhs_{std::move(valex)}, + op_type_{op} {} bool @@ -58,6 +78,15 @@ namespace xo { * 3.14 + 2.0 * ... */ + constexpr const char * c_self_name = "progress_xs::assemble_expr"; + + if ((op_type_ != optype::invalid) && (rhs_.get() == nullptr)) { + throw std::runtime_error(tostr(c_self_name, + ": expected expr on rhs of operator", + xtag("lhs", lhs_), + xtag("op", op_type_))); + } + /* consecutive expressions not legal, e.g: * 3.14 6.28 * but expressions surrounding an infix operators is: @@ -252,35 +281,90 @@ namespace xo { } + namespace { + optype + tk2op(const tokentype & tktype) { + switch (tktype) { + case tokentype::tk_plus: + return optype::op_add; + case tokentype::tk_minus: + return optype::op_subtract; + case tokentype::tk_star: + return optype::op_multiply; + case tokentype::tk_slash: + return optype::op_divide; + default: + assert(false); + return optype::invalid; + } + return optype::invalid; + } + } + void progress_xs::on_operator_token(const token_type & tk, exprstatestack * p_stack, - rp * p_emit_expr) + rp * /*p_emit_expr*/) { constexpr const char * c_self_name = "progress_xs::on_operator_token"; if (op_type_ == optype::invalid) { - switch(tk.tk_type()) { - case tokentype::tk_plus: - this->op_type_ = optype::op_add; - break; - case tokentype::tk_minus: - this->op_type_ = optype::op_subtract; - break; - case tokentype::tk_star: - this->op_type_ = optype::op_multiply; - break; - case tokentype::tk_slash: - this->op_type_ = optype::op_divide; - break; - default: - /* unreachable */ - assert(false); - exprstate::on_operator_token(tk, p_stack, p_emit_expr); - } + this->op_type_ = tk2op(tk.tk_type()); /* infix operator must be followed by non-empty expression */ p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + } else if (rhs_) { + /* already have complete expression stashed. + * behavior depends on operator precedence for tk with stored operator + * this->op_type_ + */ + optype op2 = tk2op(tk.tk_type()); + + if (precedence(op2) <= precedence(this->op_type_)) { + /* e.g. + * 6.2 * 4.9 + ... + * + * in stack: + * 1. progress_xs lhs=6.2, op=*, rhs=4.9 + * + * out stack + * 1. progress_xs lhs=apply(*,6.2,4.9), op=+ + */ + + /* 1. instantiate expression for *this */ + auto expr = this->assemble_expr(); + + /* 2. remove from stack */ + std::unique_ptr self = p_stack->pop_exprstate(); + + /* 3. replace with new progress_xs: */ + p_stack->push_exprstate(progress_xs::make(expr, op2)); + + /* infix operator must be followed by non-empty expression */ + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + } else { + /* e.g. + * 6.2 + 4.9 * ... + * + * in stack: + * 1. progress_xs lhs=6.2, op=+, rhs=4.9 + * + * out stack: + * 1. progress_xs lhs=6.2, op=+ + * 2. expect_rhs_expression + * 3. progress_xs lhs=4.9, op=* + * 4. expect_rhs_expression + */ + + std::unique_ptr self = p_stack->pop_exprstate(); + + /* 1. replace with nested incomplete infix exprs */ + p_stack->push_exprstate(progress_xs::make(lhs_, op_type_)); + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + p_stack->push_exprstate(progress_xs::make(rhs_, op2)); + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + } + } else { throw std::runtime_error(tostr(c_self_name, ": expected expression following operator", From 5b53dbeac7ba5d1d2a743c7539d14f5605395c02 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 15 Aug 2024 14:00:35 -0400 Subject: [PATCH 117/191] xo-reader: wip: stub for lambda expression --- include/xo/reader/lambda_xs.hpp | 26 ++++++++++++++++++++++++++ src/reader/CMakeLists.txt | 3 ++- src/reader/lambda_xs.cpp | 13 +++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 include/xo/reader/lambda_xs.hpp create mode 100644 src/reader/lambda_xs.cpp diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp new file mode 100644 index 00000000..4c72efe9 --- /dev/null +++ b/include/xo/reader/lambda_xs.hpp @@ -0,0 +1,26 @@ +/** @file lambda_xs.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "exprstate.hpp" +//#include + +namespace xo { + namespace scm { + /** @class lambda_xs + * @brief parsing state-machine for a lambda-expression + **/ + class lambda_xs : public exprstate { + public: + lambda_xs(); + + private: + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end lambda_xs.hpp **/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 6907dff2..faf190f3 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -11,7 +11,8 @@ set(SELF_SRCS exprseq_xs.cpp expect_expr_xs.cpp expect_symbol_xs.cpp - expect_type_xs.cpp) + expect_type_xs.cpp + lambda_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp new file mode 100644 index 00000000..603f3585 --- /dev/null +++ b/src/reader/lambda_xs.cpp @@ -0,0 +1,13 @@ +/* @file lambda_xs.cpp */ + +#include "lambda_xs.hpp" + +namespace xo { + namespace scm { + lambda_xs::lambda_xs() {} + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end lambda_xs.cpp */ From 6d5387eef7f332d1cf8261346e5a152836f05cce Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 16 Aug 2024 21:55:23 -0400 Subject: [PATCH 118/191] xo-reader: + expect_formal_xs [wip - not used] --- include/xo/reader/define_xs.hpp | 8 +-- include/xo/reader/expect_formal_xs.hpp | 80 +++++++++++++++++++++++ include/xo/reader/exprstate.hpp | 6 +- include/xo/reader/formal_arg.hpp | 58 +++++++++++++++++ include/xo/reader/progress_xs.hpp | 4 +- src/reader/CMakeLists.txt | 1 + src/reader/expect_formal_xs.cpp | 87 ++++++++++++++++++++++++++ src/reader/exprstate.cpp | 50 +++++++++++++-- 8 files changed, 282 insertions(+), 12 deletions(-) create mode 100644 include/xo/reader/expect_formal_xs.hpp create mode 100644 include/xo/reader/formal_arg.hpp create mode 100644 src/reader/expect_formal_xs.cpp diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index f3a5f15a..59b55d83 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -56,18 +56,18 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_typedescr(TypeDescr td, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) override; + exprstatestack * p_stack, + rp * p_emit_expr) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_semicolon_token(const token_type & tk, exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + rp * p_emit_expr) override; virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + rp * p_emit_expr) override; virtual void on_f64_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp new file mode 100644 index 00000000..557ffa61 --- /dev/null +++ b/include/xo/reader/expect_formal_xs.hpp @@ -0,0 +1,80 @@ +/* file expect_formal_xs.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" +#include "formal_arg.hpp" + +namespace xo { + namespace scm { + /** + * name : type + * ^ ^ ^ + * | | formal_2 + * | formal_1 + * formal_0 + * + **/ + enum class formalstatetype { + invalid = -1, + + formal_0, + formal_1, + formal_2, + + n_formalstatetype, + }; + + extern const char * + formalstatetype_descr(formalstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, formalstatetype x) { + os << formalstatetype_descr(x); + return os; + } + + /** @class expect_formal_xs + * @brief parser state-machine for a typed formal parameter + **/ + class expect_formal_xs : public exprstate { + public: + expect_formal_xs() = default; + + virtual void on_symbol(const std::string & symbol_name, + exprstatestack * p_stack, + rp * p_emit_expr) override; + + virtual void on_colon_token(const token_type & tk, + exprstatestack * p_stack + /*rp * p_emit_expr*/) override; + + // virtual void on_comma_token(...) override; + +#ifdef PROBABLY_NOT + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; +#endif + + virtual void on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr) override; + + virtual void print(std::ostream & os) const override; + + private: + /** parsing state-machine state **/ + formalstatetype formalxs_type_; + /** populate with {parameter-name, parameter-type} + * as they're encountered + **/ + formal_arg result_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end expect_formal_xs.hpp */ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ef65e8f5..fbdc8b50 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -52,7 +52,7 @@ namespace xo { class exprstatestack; - class define_xs; + class formal_arg; /** state associated with a partially-parsed expression. **/ @@ -91,6 +91,10 @@ namespace xo { virtual void on_typedescr(TypeDescr td, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate when expecting a formal parameter **/ + virtual void on_formal(const formal_arg & formal, + exprstatestack * p_stack, + rp * p_emit_expr); /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; diff --git a/include/xo/reader/formal_arg.hpp b/include/xo/reader/formal_arg.hpp new file mode 100644 index 00000000..4f0afaef --- /dev/null +++ b/include/xo/reader/formal_arg.hpp @@ -0,0 +1,58 @@ +/* file formal_arg.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "TypeDescr.hpp" +#include "xo/indentlog/print/tag.hpp" + +namespace xo { + namespace scm { + /** @class formal_arg + * @brief description of formal parameter in an argument list + * + * Terminated by an argument separator ',' or rightparen ')' + **/ + class formal_arg { + public: + using TypeDescr = xo::reflect::TypeDescr; + + public: + formal_arg() = default; + formal_arg(const std::string & n, TypeDescr td) : name_{n}, td_{td} {} + + const std::string & name() const { return name_; } + TypeDescr td() const { return td_; } + + void assign_name(const std::string & x) { name_ = x; } + void assign_td(TypeDescr x) { td_ = x; } + + void print(std::ostream & os) const { + os << ""; + } + + private: + /** formal parameter name **/ + std::string name_; + /** type description for variable @p name **/ + TypeDescr td_; + }; + + inline std::ostream & + operator<< (std::ostream & os, + const formal_arg & x) { + x.print(os); + return os; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end formal_arg.hpp */ diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 361e6d3d..bc1ada8d 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -18,7 +18,9 @@ namespace xo { progress_xs(rp valex); virtual ~progress_xs() = default; - static const progress_xs * from(const exprstate * x) { return dynamic_cast(x); } + static const progress_xs * from(const exprstate * x) { + return dynamic_cast(x); + } static std::unique_ptr make(rp valex); diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 6907dff2..ae233e22 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -11,6 +11,7 @@ set(SELF_SRCS exprseq_xs.cpp expect_expr_xs.cpp expect_symbol_xs.cpp + expect_formal_xs.cpp expect_type_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp new file mode 100644 index 00000000..5ec91987 --- /dev/null +++ b/src/reader/expect_formal_xs.cpp @@ -0,0 +1,87 @@ +/* file expect_formal_xs.cpp + * + * author: Roland Conybeare + */ + +#include "expect_formal_xs.hpp" + +namespace xo { + using xo::reflect::TypeDescr; + + namespace scm{ + const char * + formalstatetype_descr(formalstatetype x) { + switch (x) { + case formalstatetype::invalid: + case formalstatetype::n_formalstatetype: + return "?formalstatetype"; + case formalstatetype::formal_0: + return "formal_0"; + case formalstatetype::formal_1: + return "formal_1"; + case formalstatetype::formal_2: + return "formal_2"; + } + + return "???formalstatetype"; + } + + void + expect_formal_xs::on_symbol(const std::string & symbol_name, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (this->formalxs_type_ == formalstatetype::formal_0) { + this->formalxs_type_ = formalstatetype::formal_1; + this->result_.assign_name(symbol_name); + } else { + exprstate::on_symbol(symbol_name, + p_stack, + p_emit_expr); + } + } + + void + expect_formal_xs::on_colon_token(const token_type & tk, + exprstatestack * p_stack + /* rp * p_emit_expr */) + { + if (this->formalxs_type_ == formalstatetype::formal_1) { + this->formalxs_type_ = formalstatetype::formal_2; + } else { + exprstate::on_colon_token(tk, + p_stack); + } + } + + void + expect_formal_xs::on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (this->formalxs_type_ == formalstatetype::formal_2) { + this->result_.assign_td(td); + + std::unique_ptr self = p_stack->pop_exprstate(); + + //p_stack->top_exprstate().on_formal(result_, p_stack, p_emit_expr); + } else { + exprstate::on_typedescr(td, p_stack, p_emit_expr); + } + } + + void + expect_formal_xs::print(std::ostream & os) const { + os << ""; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_formal_xs.cpp */ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index e7933d7c..d36fba94 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -1,6 +1,8 @@ /* @file exprstate.cpp */ #include "exprstate.hpp" +#include "formal_arg.hpp" +#include //#include "define_xs.hpp" //#include "progress_xs.hpp" //#include "paren_xs.hpp" @@ -63,15 +65,45 @@ namespace xo { } void - exprstate::on_typedescr(TypeDescr /*td*/, - exprstatestack * /*p_stack*/, + exprstate::on_typedescr(TypeDescr td, + exprstatestack * p_stack, rp * /*p_emit_expr*/) { /* returning type description to something that wants it */ - /* unreachable - implement in derived class */ - assert(false); - return; + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", + p_stack->top_exprstate().exs_type())); + + constexpr const char * c_self_name = "exprstate::on_typedescr"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected typedescr for parsing state", + xtag("td", td), + xtag("state", *this))); + } + + void + exprstate::on_formal(const formal_arg & formal, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + /* returning type description to something that wants it */ + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", + p_stack->top_exprstate().exs_type())); + + constexpr const char * c_self_name = "exprstate::on_formal"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected formal-arg for parsing state", + xtag("formal", formal), + xtag("state", *this))); } void @@ -254,13 +286,19 @@ namespace xo { } /*on_expr*/ void - exprstate::on_symbol(const std::string & /*symbol_name*/, + exprstate::on_symbol(const std::string & symbol_name, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { /* unreachable - derived class that can receive * will override this method */ + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("symbol_name", symbol_name)); + assert(false); } From 52d1bd87900f28bf88bdbda708617f028b3b8255 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 16 Aug 2024 22:15:58 -0400 Subject: [PATCH 119/191] xo-reader: + exprstate.on_comma_token() [wip, not used] --- include/xo/reader/exprstate.hpp | 4 ++++ src/reader/exprstate.cpp | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 87eaf29d..74d8f0dc 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -107,6 +107,10 @@ namespace xo { virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr); + /** handle incoming ',' token **/ + virtual void on_comma_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); /** handle incoming ':' token **/ virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 43504622..17c68eff 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -118,6 +118,19 @@ namespace xo { this->illegal_input_error(self_name, tk); } + void + exprstate::on_comma_token(const token_type & tk, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_comma"; + + this->illegal_input_error(self_name, tk); + } + void exprstate::on_semicolon_token(const token_type & tk, exprstatestack * /*p_stack*/, From 8ed090c2e20401e2dede2055e2def0de97446548 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 16 Aug 2024 22:17:39 -0400 Subject: [PATCH 120/191] xo-reader: dispatch comm token -> exprstate.on_comma_token() --- src/reader/exprstate.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 17c68eff..7e207da8 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -255,10 +255,13 @@ namespace xo { case tokentype::tk_leftangle: case tokentype::tk_rightangle: case tokentype::tk_dot: - case tokentype::tk_comma: assert(false); return; + case tokentype::tk_comma: + this->on_comma_token(tk, p_stack, p_emit_expr); + return; + case tokentype::tk_colon: this->on_colon_token(tk, p_stack); return; From 0841fd7dbd5c90e65e7e8d218e3b9dcfcc09b68d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 17 Aug 2024 01:09:17 -0400 Subject: [PATCH 121/191] xo-reader: wip: parsing lambda expressions [wip, non-functional] --- include/xo/reader/expect_expr_xs.hpp | 3 + .../xo/reader/expect_formal_arglist_xs.hpp | 55 +++++++++++++ include/xo/reader/exprstate.hpp | 11 ++- include/xo/reader/lambda_xs.hpp | 46 +++++++++++ src/reader/CMakeLists.txt | 2 + src/reader/expect_expr_xs.cpp | 18 +++++ src/reader/expect_formal_arglist_xs.cpp | 37 +++++++++ src/reader/expect_type_xs.cpp | 1 + src/reader/exprstate.cpp | 42 +++++++++- src/reader/lambda_xs.cpp | 79 +++++++++++++++++++ 10 files changed, 289 insertions(+), 5 deletions(-) create mode 100644 include/xo/reader/expect_formal_arglist_xs.hpp create mode 100644 src/reader/expect_formal_arglist_xs.cpp diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index fa6c4630..740eecc8 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -19,6 +19,9 @@ namespace xo { static std::unique_ptr expect_rhs_expression(); + virtual void on_lambda_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/expect_formal_arglist_xs.hpp b/include/xo/reader/expect_formal_arglist_xs.hpp new file mode 100644 index 00000000..88b0adc1 --- /dev/null +++ b/include/xo/reader/expect_formal_arglist_xs.hpp @@ -0,0 +1,55 @@ +/* file expect_formal_arglist_xs.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" +#include "formal_arg.hpp" +#include + +namespace xo { + namespace scm { + enum class formalarglstatetype { + invalid = -1, + + argl_0, + argl_1, + + n_formalarglstatetype, + }; + + /** @class expect_formal_arglist + * @brief parser state-machine for a formal parameter list + * + * ( name(1) : type(1), ..., ) + * ^ + * | + * argl_0 + **/ + class expect_formal_arglist_xs : public exprstate { + public: + expect_formal_arglist_xs(); + + static std::unique_ptr make(); + + const std::vector & argl() const { return argl_; } + + virtual void on_leftparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + + private: + /** parsing state-machine state **/ + formalarglstatetype farglxs_type_; + /** populate with (parmaeter-name, parameter-type) list + * as they're encountered + **/ + std::vector argl_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_formal_arglist_xs.hpp */ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 74d8f0dc..65dd944e 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -59,6 +59,7 @@ namespace xo { class exprstate { public: using Expression = xo::ast::Expression; + using Variable = xo::ast::Variable; using exprtype = xo::ast::exprtype; using token_type = token; using TypeDescr = xo::reflect::TypeDescr; @@ -92,9 +93,13 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr); /** update exprstate when expecting a formal parameter **/ - virtual void on_formal(const formal_arg & formal, + virtual void on_formal(const rp & formal, exprstatestack * p_stack, rp * p_emit_expr); + /** update expression when epecting a formal parameter list **/ + virtual void on_formal_arglist(const std::vector> & argl, + exprstatestack * p_stack, + rp * p_emit_expr); /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; @@ -103,6 +108,10 @@ namespace xo { /** handle incoming 'def' token **/ virtual void on_def_token(const token_type & tk, exprstatestack * p_stack); + /** handle incoming 'lambda' token **/ + virtual void on_lambda_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr); /** handle incoming symbol token **/ virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 4c72efe9..4b4fb74c 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -10,14 +10,60 @@ namespace xo { namespace scm { + /** + * lambda ( name(1) : type(1), ..., ) body-expr ; + * ^ ^ ^ ^ + * | | | | + * lm_0 lm_1 lm_2 lm_3 + * + * lm_0 --on_lambda_token()--> lm_1 + * lm_1 --on_formal_arglist()--> lm_2 + * lm_2 --on_expr()--> lm_3 + * lm_3 --on_semicolon_token()--> (done) + **/ + enum class lambdastatetype { + invalid = -1, + + lm_0, + lm_1, + lm_2, + lm_3, + + n_lambdastatetype + }; + /** @class lambda_xs * @brief parsing state-machine for a lambda-expression + * **/ class lambda_xs : public exprstate { public: lambda_xs(); + static std::unique_ptr make(); + + virtual void on_lambda_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_formal_arglist(const std::vector> & argl, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_semicolon_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + private: + /** parsing state-machine state **/ + lambdastatetype lmxs_type_; + + /** formal parameter list **/ + std::vector> argl_; + + /** body expression **/ + rp body_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 5be9eb8a..32a4cd5a 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -11,7 +11,9 @@ set(SELF_SRCS exprseq_xs.cpp expect_expr_xs.cpp expect_symbol_xs.cpp + expect_formal_xs.cpp + expect_formal_arglist_xs.cpp expect_type_xs.cpp lambda_xs.cpp) diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 131bfc42..fe4a1830 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -4,8 +4,10 @@ */ #include "expect_expr_xs.hpp" +#include "lambda_xs.hpp" #include "paren_xs.hpp" #include "progress_xs.hpp" +#include "xo/expression/Lambda.hpp" #include "xo/expression/Constant.hpp" namespace xo { @@ -23,6 +25,22 @@ namespace xo { : exprstate(exprstatetype::expect_rhs_expression) {} + void + expect_expr_xs::on_lambda_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + //constexpr const char * self_name = "exprstate::on_leftparen"; + + /* push lparen_0 to remember to look for subsequent rightparen. */ + p_stack->push_exprstate(lambda_xs::make()); + p_stack->top_exprstate().on_lambda_token(tk, p_stack, p_emit_expr); + //p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + } + void expect_expr_xs::on_leftparen_token(const token_type & /*tk*/, exprstatestack * p_stack, diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp new file mode 100644 index 00000000..c540dbd3 --- /dev/null +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -0,0 +1,37 @@ +/* file expect_formal_arglist_xs.cpp + * + * author: Roland Conybeare + */ + +#include "expect_formal_arglist_xs.hpp" + +namespace xo { + namespace scm { + std::unique_ptr + expect_formal_arglist_xs::make() { + return std::make_unique + (expect_formal_arglist_xs()); + } + + expect_formal_arglist_xs::expect_formal_arglist_xs() + : farglxs_type_{formalarglstatetype::argl_0} + {} + + void + expect_formal_arglist_xs::on_leftparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (farglxs_type_ == formalarglstatetype::argl_0) { + this->farglxs_type_ = formalarglstatetype::argl_1; + return; + } + + exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_formal_arglist_xs.cpp */ diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index 6c4c5afb..fa4a517a 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -11,6 +11,7 @@ namespace xo { using xo::reflect::Reflect; namespace scm { + std::unique_ptr expect_type_xs::make() { return std::make_unique(expect_type_xs()); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 7e207da8..859d0be8 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -1,7 +1,9 @@ /* @file exprstate.cpp */ #include "exprstate.hpp" -#include "formal_arg.hpp" +//#include "formal_arg.hpp" +#include "xo/expression/Variable.hpp" +#include "xo/indentlog/print/vector.hpp" #include //#include "define_xs.hpp" //#include "progress_xs.hpp" @@ -49,6 +51,14 @@ namespace xo { this->illegal_input_error("exprstate::on_def_token", tk); } + void + exprstate::on_lambda_token(const token_type & tk, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + this->illegal_input_error("exprstate::on_lambda_token", tk); + } + void exprstate::on_symbol_token(const token_type & tk, exprstatestack * p_stack, @@ -86,7 +96,7 @@ namespace xo { } void - exprstate::on_formal(const formal_arg & formal, + exprstate::on_formal(const rp & formal, exprstatestack * p_stack, rp * /*p_emit_expr*/) { @@ -102,7 +112,28 @@ namespace xo { throw std::runtime_error(tostr(c_self_name, ": unexpected formal-arg for parsing state", - xtag("formal", formal), + xtag("formal", formal.get()), + xtag("state", *this))); + } + + void + exprstate::on_formal_arglist(const std::vector> & argl, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + /* returning type description to something that wants it */ + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", + p_stack->top_exprstate().exs_type())); + + constexpr const char * c_self_name = "exprstate::on_formal_arglist"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected formal-arg for parsing state", + xtag("argl", argl), xtag("state", *this))); } @@ -223,6 +254,10 @@ namespace xo { this->on_def_token(tk, p_stack); return; + case tokentype::tk_lambda: + this->on_lambda_token(tk, p_stack, p_emit_expr); + return; + case tokentype::tk_i64: assert(false); return; @@ -289,7 +324,6 @@ namespace xo { return; case tokentype::tk_type: - case tokentype::tk_lambda: case tokentype::tk_if: case tokentype::tk_let: diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 603f3585..e38d5718 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -1,11 +1,90 @@ /* @file lambda_xs.cpp */ #include "lambda_xs.hpp" +#include "expect_formal_arglist_xs.hpp" +#include "expect_expr_xs.hpp" +#include "xo/expression/Lambda.hpp" namespace xo { + using xo::ast::Lambda; + namespace scm { + std::unique_ptr + lambda_xs::make() { + return std::make_unique(lambda_xs()); + } + lambda_xs::lambda_xs() {} + void + lambda_xs::on_lambda_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (lmxs_type_ == lambdastatetype::lm_0) { + this->lmxs_type_ = lambdastatetype::lm_1; + p_stack->push_exprstate(expect_formal_arglist_xs::make()); + return; + } + + exprstate::on_lambda_token(tk, + p_stack, + p_emit_expr); + } + + void + lambda_xs::on_formal_arglist(const std::vector> & argl, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (lmxs_type_ == lambdastatetype::lm_1) { + this->lmxs_type_ = lambdastatetype::lm_2; + this->argl_ = argl; + p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + return; + } + + exprstate::on_formal_arglist(argl, + p_stack, + p_emit_expr); + } + + void + lambda_xs::on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (lmxs_type_ == lambdastatetype::lm_2) { + this->lmxs_type_ = lambdastatetype::lm_3; + this->body_ = expr.promote(); + return; + } + + exprstate::on_expr(expr, p_stack, p_emit_expr); + } + + void + lambda_xs::on_semicolon_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (lmxs_type_ == lambdastatetype::lm_3) { + /* done! */ + + std::unique_ptr self = p_stack->pop_exprstate(); + + std::string name = "fixmename"; + + rp lm = Lambda::make(name, argl_, body_); + + p_stack->top_exprstate().on_expr(lm, p_stack, p_emit_expr); + p_stack->top_exprstate().on_semicolon_token(tk, p_stack, p_emit_expr); + + return; + } + + exprstate::on_semicolon_token(tk, p_stack, p_emit_expr); + } } /*namespace scm*/ } /*namespace xo*/ From 1628d8f44cea04497e351fff4e36fe5391ba6475 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 17 Aug 2024 13:26:57 -0400 Subject: [PATCH 122/191] xo-reader: feat: mvp lambda parsing [untested] --- .../xo/reader/expect_formal_arglist_xs.hpp | 47 ++++++++--- include/xo/reader/expect_formal_xs.hpp | 7 +- src/reader/expect_formal_arglist_xs.cpp | 78 ++++++++++++++++++- src/reader/expect_formal_xs.cpp | 12 ++- src/reader/lambda_xs.cpp | 19 ++--- 5 files changed, 135 insertions(+), 28 deletions(-) diff --git a/include/xo/reader/expect_formal_arglist_xs.hpp b/include/xo/reader/expect_formal_arglist_xs.hpp index 88b0adc1..501d945f 100644 --- a/include/xo/reader/expect_formal_arglist_xs.hpp +++ b/include/xo/reader/expect_formal_arglist_xs.hpp @@ -11,34 +11,63 @@ namespace xo { namespace scm { + /** + * ( name(1) : type(1) , ..., ) + * ^ ^ ^ ^ ^ + * | | | | | + * | | | | argl_1b + * | argl_1a | argla + * argl_0 argl_1b + * + * argl_0 --on_leftparen_token()--> argl_1a + * argl_1a --on_formal()--> argl_1b + * argl_1b -+-on_comma_token()--> argl_1a + * \-on_rightparen_token()--> (done) + **/ enum class formalarglstatetype { invalid = -1, argl_0, - argl_1, + argl_1a, + argl_1b, n_formalarglstatetype, }; + extern const char * + formalarglstatetype_descr(formalarglstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, formalarglstatetype x) { + os << formalarglstatetype_descr(x); + return os; + } + /** @class expect_formal_arglist * @brief parser state-machine for a formal parameter list - * - * ( name(1) : type(1), ..., ) - * ^ - * | - * argl_0 **/ class expect_formal_arglist_xs : public exprstate { + public: + using Variable = xo::ast::Variable; + public: expect_formal_arglist_xs(); static std::unique_ptr make(); - const std::vector & argl() const { return argl_; } - virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; + virtual void on_formal(const rp & formal, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_comma_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void print(std::ostream & os) const override; private: /** parsing state-machine state **/ @@ -46,7 +75,7 @@ namespace xo { /** populate with (parmaeter-name, parameter-type) list * as they're encountered **/ - std::vector argl_; + std::vector> argl_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp index 557ffa61..b4c046b9 100644 --- a/include/xo/reader/expect_formal_xs.hpp +++ b/include/xo/reader/expect_formal_xs.hpp @@ -17,6 +17,9 @@ namespace xo { * | formal_1 * formal_0 * + * formal_0 --on_symbol()--> formal_1 + * formal_1 --on_colon_token()--> formal_2 + * formal_2 --on_typedescr()--> (done) **/ enum class formalstatetype { invalid = -1, @@ -44,6 +47,8 @@ namespace xo { public: expect_formal_xs() = default; + static std::unique_ptr make(); + virtual void on_symbol(const std::string & symbol_name, exprstatestack * p_stack, rp * p_emit_expr) override; @@ -68,7 +73,7 @@ namespace xo { private: /** parsing state-machine state **/ - formalstatetype formalxs_type_; + formalstatetype formalxs_type_ = formalstatetype::formal_0; /** populate with {parameter-name, parameter-type} * as they're encountered **/ diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index c540dbd3..473cfb0c 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -4,9 +4,30 @@ */ #include "expect_formal_arglist_xs.hpp" +#include "expect_formal_xs.hpp" +#include "xo/expression/Variable.hpp" +#include "xo/indentlog/print/vector.hpp" namespace xo { namespace scm { + const char * + formalarglstatetype_descr(formalarglstatetype x) { + switch (x) { + case formalarglstatetype::invalid: + return "invalid"; + case formalarglstatetype::argl_0: + return "argl_0"; + case formalarglstatetype::argl_1a: + return "argl_1a"; + case formalarglstatetype::argl_1b: + return "argl_1b"; + case formalarglstatetype::n_formalarglstatetype: + break; + } + + return "?formalarglstatetype"; + } + std::unique_ptr expect_formal_arglist_xs::make() { return std::make_unique @@ -23,13 +44,62 @@ namespace xo { rp * p_emit_expr) { if (farglxs_type_ == formalarglstatetype::argl_0) { - this->farglxs_type_ = formalarglstatetype::argl_1; - return; + this->farglxs_type_ = formalarglstatetype::argl_1a; + p_stack->push_exprstate(expect_formal_xs::make()); + } else { + exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); } - - exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); } + void + expect_formal_arglist_xs::on_formal(const rp & formal, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (farglxs_type_ == formalarglstatetype::argl_1a) { + this->farglxs_type_ = formalarglstatetype::argl_1b; + this->argl_.push_back(formal); + } else { + exprstate::on_formal(formal, p_stack, p_emit_expr); + } + } + + void + expect_formal_arglist_xs::on_comma_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (farglxs_type_ == formalarglstatetype::argl_1b) { + this->farglxs_type_ = formalarglstatetype::argl_1a; + p_stack->push_exprstate(expect_formal_xs::make()); + } else { + exprstate::on_comma_token(tk, p_stack, p_emit_expr); + } + } + + void + expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (farglxs_type_ == formalarglstatetype::argl_1b) { + std::unique_ptr self = p_stack->pop_exprstate(); + + p_stack->top_exprstate().on_formal_arglist(this->argl_, + p_stack, p_emit_expr); + } else { + exprstate::on_rightparen_token(tk, p_stack, p_emit_expr); + } + } + + void + expect_formal_arglist_xs::print(std::ostream & os) const { + os << ""; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 5ec91987..9d69b137 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -4,8 +4,10 @@ */ #include "expect_formal_xs.hpp" +#include "xo/expression/Variable.hpp" namespace xo { + using xo::ast::Variable; using xo::reflect::TypeDescr; namespace scm{ @@ -26,6 +28,11 @@ namespace xo { return "???formalstatetype"; } + std::unique_ptr + expect_formal_xs::make() { + return std::make_unique(expect_formal_xs()); + } + void expect_formal_xs::on_symbol(const std::string & symbol_name, exprstatestack * p_stack, @@ -64,7 +71,10 @@ namespace xo { std::unique_ptr self = p_stack->pop_exprstate(); - //p_stack->top_exprstate().on_formal(result_, p_stack, p_emit_expr); + rp var = Variable::make(result_.name(), + result_.td()); + + p_stack->top_exprstate().on_formal(var, p_stack, p_emit_expr); } else { exprstate::on_typedescr(td, p_stack, p_emit_expr); } diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index e38d5718..a4a19845 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -24,12 +24,9 @@ namespace xo { if (lmxs_type_ == lambdastatetype::lm_0) { this->lmxs_type_ = lambdastatetype::lm_1; p_stack->push_exprstate(expect_formal_arglist_xs::make()); - return; + } else { + exprstate::on_lambda_token(tk, p_stack, p_emit_expr); } - - exprstate::on_lambda_token(tk, - p_stack, - p_emit_expr); } void @@ -41,12 +38,9 @@ namespace xo { this->lmxs_type_ = lambdastatetype::lm_2; this->argl_ = argl; p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); - return; + } else { + exprstate::on_formal_arglist(argl, p_stack, p_emit_expr); } - - exprstate::on_formal_arglist(argl, - p_stack, - p_emit_expr); } void @@ -57,10 +51,9 @@ namespace xo { if (lmxs_type_ == lambdastatetype::lm_2) { this->lmxs_type_ = lambdastatetype::lm_3; this->body_ = expr.promote(); - return; + } else { + exprstate::on_expr(expr, p_stack, p_emit_expr); } - - exprstate::on_expr(expr, p_stack, p_emit_expr); } void From de9f813d82dbd83ca1b8e3e526197011a40247a8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 10:19:56 -0400 Subject: [PATCH 123/191] xo-reader: utest: + lambda [failing] --- utest/reader.test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp index fb4a170d..926b6436 100644 --- a/utest/reader.test.cpp +++ b/utest/reader.test.cpp @@ -15,7 +15,8 @@ namespace xo { std::vector s_testcase_v = { {"def foo : f64 = 3.14159265;"}, {"def foo : f64 = (3.14159265);"}, - {"def foo : f64 = 2.0 * 3.14159265;"} + //{"def foo : f64 = 2.0 * 3.14159265;"}, + {"def foo = lambda (x : f64) 3.1415965;"} }; } From 8edbfcf21fdfc349c3a2d2a20c28f73f5df9c775 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:02:21 -0400 Subject: [PATCH 124/191] xo-reader: bugfix: init expect_formal_arglist_xs.farglxs_type --- include/xo/reader/expect_formal_arglist_xs.hpp | 2 +- include/xo/reader/expect_formal_xs.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/xo/reader/expect_formal_arglist_xs.hpp b/include/xo/reader/expect_formal_arglist_xs.hpp index 501d945f..82116133 100644 --- a/include/xo/reader/expect_formal_arglist_xs.hpp +++ b/include/xo/reader/expect_formal_arglist_xs.hpp @@ -71,7 +71,7 @@ namespace xo { private: /** parsing state-machine state **/ - formalarglstatetype farglxs_type_; + formalarglstatetype farglxs_type_ = formalarglstatetype::argl_0; /** populate with (parmaeter-name, parameter-type) list * as they're encountered **/ diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp index b4c046b9..79b8bf05 100644 --- a/include/xo/reader/expect_formal_xs.hpp +++ b/include/xo/reader/expect_formal_xs.hpp @@ -45,7 +45,7 @@ namespace xo { **/ class expect_formal_xs : public exprstate { public: - expect_formal_xs() = default; + expect_formal_xs(); static std::unique_ptr make(); From 2f2a1d2e1373e01c52156ff44023ee9877f4be43 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:03:58 -0400 Subject: [PATCH 125/191] xo-reader: bugfix: + missing exprstatetype.lambdaexpr --- include/xo/reader/exprstate.hpp | 5 +++++ src/reader/exprstate.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 65dd944e..37687a56 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -23,6 +23,11 @@ namespace xo { **/ defexpr, + /** handle lambda-expression + * see @ref lambda_xs + **/ + lambdaexpr, + /** handle parenthesized expression * see @ref paren_xs **/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 859d0be8..a734f3b9 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -27,6 +27,8 @@ namespace xo { return "expect_toplevel_expression_sequence"; case exprstatetype::defexpr: return "defexpr"; + case exprstatetype::lambdaexpr: + return "lambdaexpr"; case exprstatetype::parenexpr: return "parenexpr"; case exprstatetype::expect_rhs_expression: From 67125d5c651fc91cc61162342b73343da2184b30 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:04:34 -0400 Subject: [PATCH 126/191] xo-reader: bugfix: + missing exprstatetype.expect_formal --- include/xo/reader/exprstate.hpp | 4 ++++ src/reader/exprstate.cpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 37687a56..d5696020 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -36,6 +36,10 @@ namespace xo { expect_rhs_expression, expect_symbol, expect_type, + /** handle formal argument + * see @ref expec_formal_xs + **/ + expect_formal, /** handle expression-in-progress, * in case infix operators to follow diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index a734f3b9..6d3376bc 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -37,6 +37,8 @@ namespace xo { return "expect_symbol"; case exprstatetype::expect_type: return "expect_type"; + case exprstatetype::expect_formal: + return "expect_formal"; case exprstatetype::expr_progress: return "expr_progress"; case exprstatetype::n_exprstatetype: From 8a633a4f94e90590205a13844959b57675fcd2cb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:04:59 -0400 Subject: [PATCH 127/191] xo-reader: bugfix: + missing exprstatetype.expect_formal_arglist --- include/xo/reader/exprstate.hpp | 4 ++++ src/reader/exprstate.cpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index d5696020..5d3ee107 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -36,6 +36,10 @@ namespace xo { expect_rhs_expression, expect_symbol, expect_type, + /** handle formal argument list + * see @ref expect_formal_arglist_xs + **/ + expect_formal_arglist, /** handle formal argument * see @ref expec_formal_xs **/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 6d3376bc..8352914a 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -37,6 +37,8 @@ namespace xo { return "expect_symbol"; case exprstatetype::expect_type: return "expect_type"; + case exprstatetype::expect_formal_arglist: + return "expect_formal_arglist"; case exprstatetype::expect_formal: return "expect_formal"; case exprstatetype::expr_progress: From e9289e855ec1eec35fb1b347152a488773b1e475 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:05:47 -0400 Subject: [PATCH 128/191] xo-reader: bugfix: lambda_xs: supply exprstate.exs_type --- include/xo/reader/lambda_xs.hpp | 2 +- src/reader/lambda_xs.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 4b4fb74c..1152406a 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -57,7 +57,7 @@ namespace xo { private: /** parsing state-machine state **/ - lambdastatetype lmxs_type_; + lambdastatetype lmxs_type_ = lambdastatetype::lm_0; /** formal parameter list **/ std::vector> argl_; diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index a4a19845..d6b1eec1 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -14,7 +14,7 @@ namespace xo { return std::make_unique(lambda_xs()); } - lambda_xs::lambda_xs() {} + lambda_xs::lambda_xs() : exprstate(exprstatetype::lambdaexpr) {} void lambda_xs::on_lambda_token(const token_type & tk, From ebeefdc447f8c187d58268671795ac35a0d4f10b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:10:11 -0400 Subject: [PATCH 129/191] xo-reader: bugfix: expect_formal_arglist_xs sets exprstate.exs_type --- src/reader/expect_formal_arglist_xs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 473cfb0c..0c312302 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -35,7 +35,8 @@ namespace xo { } expect_formal_arglist_xs::expect_formal_arglist_xs() - : farglxs_type_{formalarglstatetype::argl_0} + : exprstate(exprstatetype::expect_formal_arglist), + farglxs_type_{formalarglstatetype::argl_0} {} void From 29638438b5a700bd3a06aa0168677723cd457542 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:12:12 -0400 Subject: [PATCH 130/191] xo-reader: bugfix: expect_formal_xs supply exprstate.exs_type --- src/reader/expect_formal_xs.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 9d69b137..bd940ec6 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -33,6 +33,10 @@ namespace xo { return std::make_unique(expect_formal_xs()); } + expect_formal_xs::expect_formal_xs() + : exprstate(exprstatetype::expect_formal) + {} + void expect_formal_xs::on_symbol(const std::string & symbol_name, exprstatestack * p_stack, From e43d3536c04163189c858849c06217d9dc0e37ea Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:12:48 -0400 Subject: [PATCH 131/191] xo-reader: bugfix: w/ expect_formal_xs need push expect_symbol_xs --- src/reader/expect_formal_arglist_xs.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 0c312302..839a2f51 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -5,6 +5,7 @@ #include "expect_formal_arglist_xs.hpp" #include "expect_formal_xs.hpp" +#include "expect_symbol_xs.hpp" #include "xo/expression/Variable.hpp" #include "xo/indentlog/print/vector.hpp" @@ -46,7 +47,9 @@ namespace xo { { if (farglxs_type_ == formalarglstatetype::argl_0) { this->farglxs_type_ = formalarglstatetype::argl_1a; + /* TODO: refactor to have setup method on each exprstate */ p_stack->push_exprstate(expect_formal_xs::make()); + p_stack->push_exprstate(expect_symbol_xs::expect_symbol_expression()); } else { exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); } From 12efbebe2164c9d27d420a0e3b0283264934e447 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 11:13:54 -0400 Subject: [PATCH 132/191] xo-reader: bugfix: expect_formal_xs push expect_type_xs for rhs type --- src/reader/expect_formal_xs.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index bd940ec6..b181583d 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -4,6 +4,7 @@ */ #include "expect_formal_xs.hpp" +#include "expect_type_xs.hpp" #include "xo/expression/Variable.hpp" namespace xo { @@ -59,6 +60,7 @@ namespace xo { { if (this->formalxs_type_ == formalstatetype::formal_1) { this->formalxs_type_ = formalstatetype::formal_2; + p_stack->push_exprstate(expect_type_xs::make()); } else { exprstate::on_colon_token(tk, p_stack); From 818127a44652ea83bdd127c4dea96882e1a77eef Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:29:36 -0400 Subject: [PATCH 133/191] xo-reader: refactor: simplify define_xs behavior --- include/xo/reader/define_xs.hpp | 61 ++++++---- src/reader/define_xs.cpp | 207 ++++++++++---------------------- src/reader/exprseq_xs.cpp | 7 +- utest/parser.test.cpp | 20 +-- 4 files changed, 112 insertions(+), 183 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 59b55d83..58846f33 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -12,6 +12,36 @@ namespace xo { namespace scm { + /** + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | (done) + * | | | | | | def_6:expect_rhs_expression:expr_progress + * | | | | | def_5:expect_rhs_expression + * | | | | def_4 + * | | | def_3:expect_type + * | | def_2 + * | def_1:expect_symbol + * def_0 + * expect_toplevel_expression_sequence + * + * def_0 --on_def_token()--> def_1 + * def_1 --on_symbol()--> def_2 + * def_2 --on_colon_token()--> def_3 + * --on_singleassign_token()--> def_5 + * def_3 --on_typedescr()--> def_4 + * def_4 --on_singleassign_token()--> def_5 + * def_5 --on_expr()--> def_6 + * def_6 --on_semicolon_token()--> (done) + * + * def_1:expect_symbol: got 'def' keyword, symbol to follow + * def_1: got symbol name + * def_3:expect_symbol got (optional) colon, type name to follow + * def_4: got symbol type + * def_6:expect_rhs_expression got (optional) equal sign, value to follow + * (done): definition complete, pop exprstate from stack + * + **/ enum class defexprstatetype { invalid = -1, @@ -21,6 +51,7 @@ namespace xo { def_3, def_4, def_5, + def_6, n_defexprstatetype, }; @@ -38,12 +69,13 @@ namespace xo { virtual ~define_xs() = default; static const define_xs * from(const exprstate * x) { return dynamic_cast(x); } - static std::unique_ptr def_0(); + + static void start(exprstatestack * p_stack); defexprstatetype defxs_type() const { return defxs_type_; } bool admits_rightparen() const; - bool admits_colon() const; + //bool admits_colon() const; bool admits_semicolon() const; //bool admits_symbol() const; @@ -58,6 +90,8 @@ namespace xo { virtual void on_typedescr(TypeDescr td, exprstatestack * p_stack, rp * p_emit_expr) override; + virtual void on_def_token(const token_type & tk, + exprstatestack * p_stack) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_semicolon_token(const token_type & tk, @@ -75,26 +109,9 @@ namespace xo { virtual void print(std::ostream & os) const override; private: - /** - * def foo : f64 = 1 ; - * ^ ^ ^ ^ ^ ^ ^ ^ - * | | | | | | | (done) - * | | | | | | def_4:expect_rhs_expression:expr_progress - * | | | | | def_4:expect_rhs_expression - * | | | | def_3 - * | | | def_2:expect_type - * | | def_1 - * | def_0:expect_symbol - * expect_toplevel_expression_sequence - * - * def_0:expect_symbol: got 'def' keyword, symbol to follow - * def_1: got symbol name - * def_2:expect_symbol got (optional) colon, type name to follow - * def_3: got symbol type - * def_4:expect_rhs_expression got (optional) equal sign, value to follow - * (done): definition complete, pop exprstate from stack - * - **/ + static std::unique_ptr make(); + + private: defexprstatetype defxs_type_; /** scaffold a define-expression here **/ rp def_expr_; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index d3c2d5c2..c3b977a2 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -1,48 +1,30 @@ /* @file define_xs.cpp */ #include "define_xs.hpp" +#include "expect_symbol_xs.hpp" #include "expect_expr_xs.hpp" #include "expect_type_xs.hpp" namespace xo { namespace scm { std::unique_ptr - define_xs::def_0() { + define_xs::make() { return std::make_unique(define_xs(DefineExprAccess::make_empty())); } + void + define_xs::start(exprstatestack * p_stack) + { + p_stack->push_exprstate(define_xs::make()); + p_stack->top_exprstate().on_def_token(token_type::def(), p_stack); + } + define_xs::define_xs(rp def_expr) : exprstate(exprstatetype::defexpr), defxs_type_{defexprstatetype::def_0}, def_expr_{std::move(def_expr)} {} - bool - define_xs::admits_colon() const { - switch (defxs_type_) { - - case defexprstatetype::def_0: - return false; - - case defexprstatetype::def_1: - return true; - - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - case defexprstatetype::def_5: - return false; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } - bool define_xs::admits_semicolon() const { switch (defxs_type_) { @@ -52,8 +34,9 @@ namespace xo { case defexprstatetype::def_2: case defexprstatetype::def_3: case defexprstatetype::def_4: - return false; case defexprstatetype::def_5: + return false; + case defexprstatetype::def_6: return true; case defexprstatetype::invalid: @@ -66,73 +49,6 @@ namespace xo { return false; } -#ifdef OBSOLETE - bool - define_xs::admits_singleassign() const { - switch (defxs_type_) { - - case defexprstatetype::def_0: - return false; - - case defexprstatetype::def_1: - return true; - - case defexprstatetype::def_2: - return false; - - case defexprstatetype::def_3: - return true; - - case defexprstatetype::def_4: - case defexprstatetype::def_5: - return false; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } -#endif - -#ifdef OBSOLETE - bool - define_xs::admits_leftparen() const { - switch (defxs_type_) { - - case defexprstatetype::def_0: - case defexprstatetype::def_1: - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - case defexprstatetype::def_5: - /* input like - * def foo : f64 = ( - * ^ ^ ^ ^ ^ - * | | | | def_4 - * | | | def_3 - * | | def_2 - * | def_1 - * def_0 - * - * not allowed or relies on pushing another state - */ - return false; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } -#endif - bool define_xs::admits_rightparen() const { switch (defxs_type_) { @@ -143,6 +59,7 @@ namespace xo { case defexprstatetype::def_3: case defexprstatetype::def_4: case defexprstatetype::def_5: + case defexprstatetype::def_6: return false; case defexprstatetype::invalid: @@ -166,10 +83,11 @@ namespace xo { case defexprstatetype::def_1: case defexprstatetype::def_2: case defexprstatetype::def_3: + case defexprstatetype::def_4: /* NOT IMPLEMENTED */ assert(false); return; - case defexprstatetype::def_4: { + case defexprstatetype::def_5: { /* have all the ingredients to create an expression * representing a definition * @@ -186,11 +104,11 @@ namespace xo { rp def_expr = this->def_expr_; - this->defxs_type_ = defexprstatetype::def_5; + this->defxs_type_ = defexprstatetype::def_6; return; } - case defexprstatetype::def_5: + case defexprstatetype::def_6: assert(false); return; @@ -209,16 +127,20 @@ namespace xo { { switch (this->defxs_type_) { case defexprstatetype::def_0: - this->defxs_type_ = defexprstatetype::def_1; + assert(false); + return; + + case defexprstatetype::def_1: + this->defxs_type_ = defexprstatetype::def_2; this->def_expr_->assign_lhs_name(symbol_name); //this->def_lhs_symbol_ = symbol_name; return; - case defexprstatetype::def_1: case defexprstatetype::def_2: case defexprstatetype::def_3: case defexprstatetype::def_4: case defexprstatetype::def_5: + case defexprstatetype::def_6: /* NOT IMPLEMENTED */ assert(false); return; @@ -240,12 +162,13 @@ namespace xo { case defexprstatetype::def_0: case defexprstatetype::def_1: + case defexprstatetype::def_2: /* NOT IMPLEMENTED (ill-formed program) */ assert(false); return; - case defexprstatetype::def_2: - this->defxs_type_ = defexprstatetype::def_3; + case defexprstatetype::def_3: + this->defxs_type_ = defexprstatetype::def_4; this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, nullptr /*source_expr*/); this->def_expr_->assign_rhs(this->cvt_expr_); @@ -253,9 +176,9 @@ namespace xo { return; - case defexprstatetype::def_3: case defexprstatetype::def_4: case defexprstatetype::def_5: + case defexprstatetype::def_6: /* NOT IMPLEMENTED */ assert(false); return; @@ -269,28 +192,38 @@ namespace xo { } void - define_xs::on_colon_token(const token_type & /*tk*/, + define_xs::on_def_token(const token_type & tk, + exprstatestack * p_stack) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + //constexpr const char * self_name = "define_xs::on_def_token"; + + if (this->defxs_type_ == defexprstatetype::def_0) { + this->defxs_type_ = defexprstatetype::def_1; + + p_stack->push_exprstate(expect_symbol_xs::expect_symbol_expression()); + } else { + exprstate::on_def_token(tk, p_stack); + } + } + + void + define_xs::on_colon_token(const token_type & tk, exprstatestack * p_stack) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_colon"; + //constexpr const char * self_name = "define_xs::on_colon_token"; - /* lots of illegal states */ - if (!this->admits_colon()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected colon for parsing state", - xtag("state", *this))); - } - - if (this->defxs_type_ == defexprstatetype::def_1) { - this->defxs_type_ = defexprstatetype::def_2; + if (this->defxs_type_ == defexprstatetype::def_2) { + this->defxs_type_ = defexprstatetype::def_3; p_stack->push_exprstate(expect_type_xs::make()); } else { - assert(false); + exprstate::on_colon_token(tk, p_stack); } } @@ -311,7 +244,7 @@ namespace xo { xtag("state", *this))); } - if (this->defxs_type_ == defexprstatetype::def_5) { + if (this->defxs_type_ == defexprstatetype::def_6) { rp expr = this->def_expr_; std::unique_ptr self = p_stack->pop_exprstate(); @@ -336,21 +269,22 @@ namespace xo { /* * def foo = 1 ; * def foo : f64 = 1 ; - * ^ ^ ^ ^ ^ ^ ^ - * | | | | | | (done) - * | | | | | def_4:expect_rhs_expression - * | | | | def_3 - * | | | def_2:expect_type - * | | def_1 - * | def_0:expect_symbol + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | (done) + * | | | | | | def_6 + * | | | | | def_5:expect_rhs_expression + * | | | | def_4 + * | | | def_3:expect_type + * | | def_2 + * | def_1:expect_symbol * expect_toplevel_expression_sequence * - * note that we skip from def_1 -> def_4 if '=' instead of ':' + * note that we skip from def_2 -> def_5 if '=' instead of ':' */ - if ((this->defxs_type_ == defexprstatetype::def_1) - || (this->defxs_type_ == defexprstatetype::def_3)) + if ((this->defxs_type_ == defexprstatetype::def_2) + || (this->defxs_type_ == defexprstatetype::def_4)) { - this->defxs_type_ = defexprstatetype::def_4; + this->defxs_type_ = defexprstatetype::def_5; p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); } else { @@ -358,23 +292,6 @@ namespace xo { } } -#ifdef OBSOLETE - void - define_xs::on_leftparen_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) - { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); - - constexpr const char * self_name = "exprstate::on_leftparen"; - - this->illegal_input_error(self_name, tk); - - assert(false); /* inserting this during refactor...? */ - } -#endif - void define_xs::on_rightparen_token(const token_type & tk, exprstatestack * /*p_stack*/, diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 042c5eb3..ed613dd2 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -26,12 +26,7 @@ namespace xo { //constexpr const char * c_self_name = "exprseq_xs::on_def_token"; - p_stack->push_exprstate(define_xs::def_0()); - - /* todo: replace: - * expect_symbol_or_function_signature() - */ - p_stack->push_exprstate(expect_symbol_xs::expect_symbol_expression()); + define_xs::start(p_stack); /* keyword 'def' introduces a definition: * def pi : f64 = 3.14159265 diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp index 8611a40a..e2190f91 100644 --- a/utest/parser.test.cpp +++ b/utest/parser.test.cpp @@ -42,7 +42,7 @@ namespace xo { /* stack should be: * * expect_toplevel_expression_sequence - * def_0 + * def_1 * expect_symbol */ CHECK(parser.stack_size() == 3); @@ -51,7 +51,7 @@ namespace xo { if (parser.stack_size() > 1) { CHECK(parser.i_exstype(1) == exprstatetype::defexpr); REQUIRE(define_xs::from(parser.i_exstate(1)) != nullptr); - CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_0); + CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_1); } if (parser.stack_size() > 2) CHECK(parser.i_exstype(2) @@ -80,7 +80,7 @@ namespace xo { if (parser.stack_size() > 0) { CHECK(parser.i_exstype(0) == exprstatetype::defexpr); REQUIRE(define_xs::from(parser.i_exstate(0)) != nullptr); - CHECK(define_xs::from(parser.i_exstate(0))->defxs_type() == defexprstatetype::def_1); + CHECK(define_xs::from(parser.i_exstate(0))->defxs_type() == defexprstatetype::def_2); } if (parser.stack_size() > 1) CHECK(parser.i_exstype(1) @@ -107,7 +107,7 @@ namespace xo { /* stack should be: * * expect_toplevel_expression_sequence - * def_2 + * def_3 * expect_symbol */ CHECK(parser.stack_size() == 3); @@ -116,7 +116,7 @@ namespace xo { if (parser.stack_size() > 1) { CHECK(parser.i_exstype(1) == exprstatetype::defexpr); REQUIRE(define_xs::from(parser.i_exstate(1)) != nullptr); - CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_2); + CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_3); } if (parser.stack_size() > 2) CHECK(parser.i_exstype(2) @@ -141,13 +141,13 @@ namespace xo { /* stack should be: * * expect_toplevel_expression_sequence - * def_3 + * def_4 */ CHECK(parser.stack_size() == 2); if (parser.stack_size() > 0) { CHECK(parser.i_exstype(0) == exprstatetype::defexpr); REQUIRE(define_xs::from(parser.i_exstate(0)) != nullptr); - CHECK(define_xs::from(parser.i_exstate(0))->defxs_type() == defexprstatetype::def_3); + CHECK(define_xs::from(parser.i_exstate(0))->defxs_type() == defexprstatetype::def_4); } if (parser.stack_size() > 1) CHECK(parser.i_exstype(1) @@ -185,7 +185,7 @@ namespace xo { /* stack should be * * expect_toplevel_expression_sequence - * def_4 + * def_5 * expect_expression */ CHECK(parser.stack_size() == 3); @@ -194,7 +194,7 @@ namespace xo { if (parser.stack_size() > 1) { CHECK(parser.i_exstype(1) == exprstatetype::defexpr); REQUIRE(define_xs::from(parser.i_exstate(1)) != nullptr); - CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_4); + CHECK(define_xs::from(parser.i_exstate(1))->defxs_type() == defexprstatetype::def_5); } if (parser.stack_size() > 2) CHECK(parser.i_exstype(2) @@ -233,7 +233,7 @@ namespace xo { if (parser.stack_size() > 2) { CHECK(parser.i_exstype(2) == exprstatetype::defexpr); REQUIRE(define_xs::from(parser.i_exstate(2)) != nullptr); - CHECK(define_xs::from(parser.i_exstate(2))->defxs_type() == defexprstatetype::def_4); + CHECK(define_xs::from(parser.i_exstate(2))->defxs_type() == defexprstatetype::def_5); } if (parser.stack_size() > 3) CHECK(parser.i_exstype(3) From 5b221b1fae94fa6c44203cf6950cdbb78587e3cd Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:31:45 -0400 Subject: [PATCH 134/191] xo-reader: refactor: streamline define_xs --- include/xo/reader/define_xs.hpp | 4 +--- src/reader/define_xs.cpp | 37 +++------------------------------ 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 58846f33..5d7a0639 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -75,9 +75,7 @@ namespace xo { defexprstatetype defxs_type() const { return defxs_type_; } bool admits_rightparen() const; - //bool admits_colon() const; - bool admits_semicolon() const; - + //bool admits_semicolon() const; //bool admits_symbol() const; // virtual void on_f64(..) override diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index c3b977a2..9a6fe858 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -25,30 +25,6 @@ namespace xo { def_expr_{std::move(def_expr)} {} - bool - define_xs::admits_semicolon() const { - switch (defxs_type_) { - - case defexprstatetype::def_0: - case defexprstatetype::def_1: - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - case defexprstatetype::def_5: - return false; - case defexprstatetype::def_6: - return true; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } - bool define_xs::admits_rightparen() const { switch (defxs_type_) { @@ -228,21 +204,14 @@ namespace xo { } void - define_xs::on_semicolon_token(const token_type & /*tk*/, + define_xs::on_semicolon_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_semicolon"; - - if (!this->admits_semicolon()) - { - throw std::runtime_error(tostr(self_name, - ": unexpected semicolon for parsing state", - xtag("state", *this))); - } + //constexpr const char * self_name = "exprstate::on_semicolon"; if (this->defxs_type_ == defexprstatetype::def_6) { rp expr = this->def_expr_; @@ -253,7 +222,7 @@ namespace xo { p_stack, p_emit_expr); } else { - assert(false); + exprstate::on_semicolon_token(tk, p_stack, p_emit_expr); } } From b607c8b6dcca98ef78ee8cadda89151544e1b48e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:33:32 -0400 Subject: [PATCH 135/191] xo-reader: refactor: streamline define_xs --- include/xo/reader/define_xs.hpp | 5 ----- src/reader/define_xs.cpp | 30 +----------------------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 5d7a0639..67c53878 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -74,11 +74,6 @@ namespace xo { defexprstatetype defxs_type() const { return defxs_type_; } - bool admits_rightparen() const; - //bool admits_semicolon() const; - //bool admits_symbol() const; - - // virtual void on_f64(..) override virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 9a6fe858..6204ef3d 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -25,29 +25,6 @@ namespace xo { def_expr_{std::move(def_expr)} {} - bool - define_xs::admits_rightparen() const { - switch (defxs_type_) { - - case defexprstatetype::def_0: - case defexprstatetype::def_1: - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - case defexprstatetype::def_5: - case defexprstatetype::def_6: - return false; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return false; - } - - return false; - } - void define_xs::on_expr(ref::brw expr, exprstatestack * /* p_stack */, @@ -271,12 +248,7 @@ namespace xo { constexpr const char * self_name = "exprstate::on_rightparen"; - if (!this->admits_rightparen()) - { - this->illegal_input_error(self_name, tk); - } - - assert(false); /* inserting this during refactor..? */ + this->illegal_input_error(self_name, tk); } void From e8e03f7b4cf5cb14d796b5e9c6579060c8efb60c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:36:56 -0400 Subject: [PATCH 136/191] xo-reader: refactor: streamline define_xs impl --- src/reader/define_xs.cpp | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 6204ef3d..4795fe5f 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -27,20 +27,10 @@ namespace xo { void define_xs::on_expr(ref::brw expr, - exprstatestack * /* p_stack */, - rp * /* p_emit_expr */) + exprstatestack * p_stack, + rp * p_emit_expr) { - switch (this->defxs_type_) { - - case defexprstatetype::def_0: - case defexprstatetype::def_1: - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - /* NOT IMPLEMENTED */ - assert(false); - return; - case defexprstatetype::def_5: { + if (this->defxs_type_ == defexprstatetype::def_5) { /* have all the ingredients to create an expression * representing a definition * @@ -61,16 +51,7 @@ namespace xo { return; } - case defexprstatetype::def_6: - assert(false); - return; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return; - } + exprstate::on_expr(expr, p_stack, p_emit_expr); } void From f432e950abcb0ecb498cae2d6bb7a6e1dcf17f7d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:38:53 -0400 Subject: [PATCH 137/191] xo-reader: refactor: streamline define_xs impl --- src/reader/define_xs.cpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 4795fe5f..d983bdf2 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -56,34 +56,15 @@ namespace xo { void define_xs::on_symbol(const std::string & symbol_name, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + exprstatestack * p_stack, + rp * p_emit_expr) { - switch (this->defxs_type_) { - case defexprstatetype::def_0: - assert(false); - return; - - case defexprstatetype::def_1: + if (this->defxs_type_ == defexprstatetype::def_1) { this->defxs_type_ = defexprstatetype::def_2; this->def_expr_->assign_lhs_name(symbol_name); - //this->def_lhs_symbol_ = symbol_name; - - return; - case defexprstatetype::def_2: - case defexprstatetype::def_3: - case defexprstatetype::def_4: - case defexprstatetype::def_5: - case defexprstatetype::def_6: - /* NOT IMPLEMENTED */ - assert(false); - return; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); return; + } else { + exprstate::on_symbol(symbol_name, p_stack, p_emit_expr); } } From 8bff8adc57d9d388353fddb81cd676b4044d049d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:40:43 -0400 Subject: [PATCH 138/191] xo-reader: refactor: streamline define_xs impl --- src/reader/define_xs.cpp | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index d983bdf2..b813dc4d 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -70,19 +70,10 @@ namespace xo { void define_xs::on_typedescr(TypeDescr td, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + exprstatestack * p_stack, + rp * p_emit_expr) { - switch (this->defxs_type_) { - - case defexprstatetype::def_0: - case defexprstatetype::def_1: - case defexprstatetype::def_2: - /* NOT IMPLEMENTED (ill-formed program) */ - assert(false); - return; - - case defexprstatetype::def_3: + if (this->defxs_type_ == defexprstatetype::def_3) { this->defxs_type_ = defexprstatetype::def_4; this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, nullptr /*source_expr*/); @@ -90,19 +81,8 @@ namespace xo { //this->def_lhs_td_ = td; return; - - case defexprstatetype::def_4: - case defexprstatetype::def_5: - case defexprstatetype::def_6: - /* NOT IMPLEMENTED */ - assert(false); - return; - - case defexprstatetype::invalid: - case defexprstatetype::n_defexprstatetype: - /* unreachable */ - assert(false); - return; + } else { + exprstate::on_typedescr(td, p_stack, p_emit_expr); } } From f8754913bb31827083a3696a267a7c59f3fa35a5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:43:59 -0400 Subject: [PATCH 139/191] xo-reader: refactor: simplify expect_symbol_xs api --- include/xo/reader/expect_symbol_xs.hpp | 4 +++- src/reader/define_xs.cpp | 2 +- src/reader/expect_formal_arglist_xs.cpp | 2 +- src/reader/expect_symbol_xs.cpp | 8 +++++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/xo/reader/expect_symbol_xs.hpp b/include/xo/reader/expect_symbol_xs.hpp index 144bc3d0..40cb25b6 100644 --- a/include/xo/reader/expect_symbol_xs.hpp +++ b/include/xo/reader/expect_symbol_xs.hpp @@ -18,7 +18,9 @@ namespace xo { public: expect_symbol_xs(); - static std::unique_ptr expect_symbol_expression(); + static std::unique_ptr make(); + + static void start(exprstatestack * p_stack); virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index b813dc4d..6eab1bb7 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -98,7 +98,7 @@ namespace xo { if (this->defxs_type_ == defexprstatetype::def_0) { this->defxs_type_ = defexprstatetype::def_1; - p_stack->push_exprstate(expect_symbol_xs::expect_symbol_expression()); + expect_symbol_xs::start(p_stack); } else { exprstate::on_def_token(tk, p_stack); } diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 839a2f51..2c67c474 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -49,7 +49,7 @@ namespace xo { this->farglxs_type_ = formalarglstatetype::argl_1a; /* TODO: refactor to have setup method on each exprstate */ p_stack->push_exprstate(expect_formal_xs::make()); - p_stack->push_exprstate(expect_symbol_xs::expect_symbol_expression()); + expect_symbol_xs::start(p_stack); } else { exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); } diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index 84faeaa3..e6fd2bb7 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -8,10 +8,16 @@ namespace xo { namespace scm { std::unique_ptr - expect_symbol_xs::expect_symbol_expression() { + expect_symbol_xs::make() { return std::make_unique(expect_symbol_xs()); } + void + expect_symbol_xs::start(exprstatestack * p_stack) + { + p_stack->push_exprstate(expect_symbol_xs::make()); + } + expect_symbol_xs::expect_symbol_xs() : exprstate(exprstatetype::expect_symbol) {} From 2b6b15480ea2dcc398b5e2c2be8a2e98391cc459 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:47:47 -0400 Subject: [PATCH 140/191] expect_type_xs: refactor: simplify api --- include/xo/reader/expect_type_xs.hpp | 5 ++++- src/reader/define_xs.cpp | 2 +- src/reader/expect_formal_xs.cpp | 3 ++- src/reader/expect_type_xs.cpp | 5 +++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/xo/reader/expect_type_xs.hpp b/include/xo/reader/expect_type_xs.hpp index c75c91cb..0e534a2a 100644 --- a/include/xo/reader/expect_type_xs.hpp +++ b/include/xo/reader/expect_type_xs.hpp @@ -16,11 +16,14 @@ namespace xo { public: expect_type_xs(); - static std::unique_ptr make(); + static void start(exprstatestack * p_stack); virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; + + private: + static std::unique_ptr make(); }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 6eab1bb7..96514b97 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -116,7 +116,7 @@ namespace xo { if (this->defxs_type_ == defexprstatetype::def_2) { this->defxs_type_ = defexprstatetype::def_3; - p_stack->push_exprstate(expect_type_xs::make()); + expect_type_xs::start(p_stack); } else { exprstate::on_colon_token(tk, p_stack); } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index b181583d..b796a209 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -60,7 +60,8 @@ namespace xo { { if (this->formalxs_type_ == formalstatetype::formal_1) { this->formalxs_type_ = formalstatetype::formal_2; - p_stack->push_exprstate(expect_type_xs::make()); + expect_type_xs::start(p_stack); + /* control reenters via expect_formal_xs::on_typedescr() */ } else { exprstate::on_colon_token(tk, p_stack); diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index fa4a517a..add0dc77 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -17,6 +17,11 @@ namespace xo { return std::make_unique(expect_type_xs()); } + void + expect_type_xs::start(exprstatestack * p_stack) { + p_stack->push_exprstate(expect_type_xs::make()); + } + expect_type_xs::expect_type_xs() : exprstate(exprstatetype::expect_type) {} From 9a42f02f0c119d6c98e70f0c5c4cbeaaa52e5a54 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:53:06 -0400 Subject: [PATCH 141/191] xo-reader: refactor: simplify expect_expr_xs api --- include/xo/reader/expect_expr_xs.hpp | 3 ++- src/reader/define_xs.cpp | 2 +- src/reader/expect_expr_xs.cpp | 9 +++++++-- src/reader/lambda_xs.cpp | 2 +- src/reader/progress_xs.cpp | 8 ++++---- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 740eecc8..85686d96 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -17,7 +17,7 @@ namespace xo { public: expect_expr_xs(); - static std::unique_ptr expect_rhs_expression(); + static void start(exprstatestack * p_stack); virtual void on_lambda_token(const token_type & tk, exprstatestack * p_stack, @@ -40,6 +40,7 @@ namespace xo { rp * p_emit_expr) override; private: + static std::unique_ptr make(); }; } /*namespace scm*/ diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 96514b97..20ffbd40 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -174,7 +174,7 @@ namespace xo { { this->defxs_type_ = defexprstatetype::def_5; - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + expect_expr_xs::start(p_stack); } else { this->illegal_input_error(self_name, tk); } diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index fe4a1830..edc67357 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -16,11 +16,16 @@ namespace xo { namespace scm { std::unique_ptr - expect_expr_xs::expect_rhs_expression() { + expect_expr_xs::make() { return std::make_unique(expect_expr_xs()); } + void + expect_expr_xs::start(exprstatestack * p_stack) { + p_stack->push_exprstate(expect_expr_xs::make()); + } + expect_expr_xs::expect_expr_xs() : exprstate(exprstatetype::expect_rhs_expression) {} @@ -53,7 +58,7 @@ namespace xo { /* push lparen_0 to remember to look for subsequent rightparen. */ p_stack->push_exprstate(paren_xs::lparen_0()); - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + expect_expr_xs::start(p_stack); } void diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index d6b1eec1..82b91ae2 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -37,7 +37,7 @@ namespace xo { if (lmxs_type_ == lambdastatetype::lm_1) { this->lmxs_type_ = lambdastatetype::lm_2; this->argl_ = argl; - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + expect_expr_xs::start(p_stack); } else { exprstate::on_formal_arglist(argl, p_stack, p_emit_expr); } diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 421524a2..93862147 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -312,7 +312,7 @@ namespace xo { this->op_type_ = tk2op(tk.tk_type()); /* infix operator must be followed by non-empty expression */ - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + expect_expr_xs::start(p_stack); } else if (rhs_) { /* already have complete expression stashed. * behavior depends on operator precedence for tk with stored operator @@ -341,7 +341,7 @@ namespace xo { p_stack->push_exprstate(progress_xs::make(expr, op2)); /* infix operator must be followed by non-empty expression */ - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + expect_expr_xs::start(p_stack); } else { /* e.g. * 6.2 + 4.9 * ... @@ -360,9 +360,9 @@ namespace xo { /* 1. replace with nested incomplete infix exprs */ p_stack->push_exprstate(progress_xs::make(lhs_, op_type_)); - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + expect_expr_xs::start(p_stack); p_stack->push_exprstate(progress_xs::make(rhs_, op2)); - p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + expect_expr_xs::start(p_stack); } } else { From bd8f093a00f292675730c2118e8dcb1e4ba73a16 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:56:50 -0400 Subject: [PATCH 142/191] xo-reader: refactor: simplify exprseq_xs api --- include/xo/reader/exprseq_xs.hpp | 4 +++- src/reader/exprseq_xs.cpp | 8 +++++++- src/reader/parser.cpp | 3 +-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index d6afffe8..1797855a 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -18,7 +18,7 @@ namespace xo { public: exprseq_xs(); - static std::unique_ptr expect_toplevel_expression_sequence(); + static void start(exprstatestack * p_stack); public: // ----- token input methods ----- @@ -38,6 +38,8 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; + private: + static std::unique_ptr make(); }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index ed613dd2..840cd958 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -7,11 +7,17 @@ namespace xo { namespace scm { std::unique_ptr - exprseq_xs::expect_toplevel_expression_sequence() + exprseq_xs::make() { return std::make_unique(exprseq_xs()); } + void + exprseq_xs::start(exprstatestack * p_stack) + { + p_stack->push_exprstate(exprseq_xs::make()); + } + exprseq_xs::exprseq_xs() : exprstate(exprstatetype::expect_toplevel_expression_sequence) { diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 5ac71dd0..5c2a99bb 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -30,8 +30,7 @@ namespace xo { void parser::begin_translation_unit() { - xs_stack_.push_exprstate - (exprseq_xs::expect_toplevel_expression_sequence()); + exprseq_xs::start(&xs_stack_); } rp From 5916ac874ff14ceae950cb863dc2c0fdaf0410f2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Aug 2024 23:59:01 -0400 Subject: [PATCH 143/191] xo-reader: refactor: simplify expect_formal_arglist_xs api --- include/xo/reader/expect_formal_arglist_xs.hpp | 5 ++++- src/reader/expect_formal_arglist_xs.cpp | 6 ++++++ src/reader/lambda_xs.cpp | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/xo/reader/expect_formal_arglist_xs.hpp b/include/xo/reader/expect_formal_arglist_xs.hpp index 82116133..442dde62 100644 --- a/include/xo/reader/expect_formal_arglist_xs.hpp +++ b/include/xo/reader/expect_formal_arglist_xs.hpp @@ -53,7 +53,7 @@ namespace xo { public: expect_formal_arglist_xs(); - static std::unique_ptr make(); + static void start(exprstatestack * p_stack); virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, @@ -69,6 +69,9 @@ namespace xo { rp * p_emit_expr) override; virtual void print(std::ostream & os) const override; + private: + static std::unique_ptr make(); + private: /** parsing state-machine state **/ formalarglstatetype farglxs_type_ = formalarglstatetype::argl_0; diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 2c67c474..6f2a4e13 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -35,6 +35,12 @@ namespace xo { (expect_formal_arglist_xs()); } + void + expect_formal_arglist_xs::start(exprstatestack * p_stack) + { + p_stack->push_exprstate(expect_formal_arglist_xs::make()); + } + expect_formal_arglist_xs::expect_formal_arglist_xs() : exprstate(exprstatetype::expect_formal_arglist), farglxs_type_{formalarglstatetype::argl_0} diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 82b91ae2..c9c131ac 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -23,7 +23,7 @@ namespace xo { { if (lmxs_type_ == lambdastatetype::lm_0) { this->lmxs_type_ = lambdastatetype::lm_1; - p_stack->push_exprstate(expect_formal_arglist_xs::make()); + expect_formal_arglist_xs::start(p_stack); } else { exprstate::on_lambda_token(tk, p_stack, p_emit_expr); } From 6d73caf308f1b6670af86bee70b45703027c55cc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:06:34 -0400 Subject: [PATCH 144/191] xo-reader: refactor: simplify progress_xs api --- include/xo/reader/progress_xs.hpp | 11 +++++++++-- src/reader/expect_expr_xs.cpp | 6 +++--- src/reader/paren_xs.cpp | 2 +- src/reader/progress_xs.cpp | 10 ++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index eeaee588..466b4b02 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -47,8 +47,11 @@ namespace xo { return dynamic_cast(x); } - static std::unique_ptr make(rp valex, - optype optype = optype::invalid); + static void start(rp valex, + optype optype, + exprstatestack * p_stack); + static void start(rp valex, + exprstatestack * p_stack); bool admits_f64() const; @@ -89,6 +92,10 @@ namespace xo { virtual void print(std::ostream & os) const override; + private: + static std::unique_ptr make(rp valex, + optype optype = optype::invalid); + private: /** assemble expression representing * value of diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index edc67357..c91205d0 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -110,9 +110,9 @@ namespace xo { * def pi = 3.14159265; * \---tk---/ */ - p_stack->push_exprstate - (progress_xs::make - (Constant::make(tk.f64_value()))); + progress_xs::start + (Constant::make(tk.f64_value()), + p_stack); } void diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index cfd20f95..06329bde 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -183,7 +183,7 @@ namespace xo { switch (this->parenxs_type_) { case parenexprstatetype::lparen_0: { this->parenxs_type_ = parenexprstatetype::lparen_1; /* wants on_rightparen */ - p_stack->push_exprstate(progress_xs::make(expr.promote())); + progress_xs::start(expr.promote(), p_stack); return; } diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 93862147..61d1cd77 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -52,6 +52,16 @@ namespace xo { return std::make_unique(progress_xs(std::move(valex), op)); } + void + progress_xs::start(rp valex, optype op, exprstatestack * p_stack) { + p_stack->push_exprstate(progress_xs::make(valex, op)); + } + + void + progress_xs::start(rp valex, exprstatestack * p_stack) { + p_stack->push_exprstate(progress_xs::make(valex)); + } + progress_xs::progress_xs(rp valex, optype op) : exprstate(exprstatetype::expr_progress), lhs_{std::move(valex)}, From 8c0ddab587495a23c05c28e001ee060461736fbf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:08:14 -0400 Subject: [PATCH 145/191] xo-reader: minor: missed progress_xs refactor to use .start() --- src/reader/progress_xs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 61d1cd77..8d83ad9c 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -348,7 +348,7 @@ namespace xo { std::unique_ptr self = p_stack->pop_exprstate(); /* 3. replace with new progress_xs: */ - p_stack->push_exprstate(progress_xs::make(expr, op2)); + progress_xs::start(expr, op2, p_stack); /* infix operator must be followed by non-empty expression */ expect_expr_xs::start(p_stack); From 79c4b59a193a6b35a89538faff6189b49a60cbc5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:10:13 -0400 Subject: [PATCH 146/191] xo-reader: refactor: minor streamlining in progress_xs --- src/reader/progress_xs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 8d83ad9c..407b8b9f 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -369,9 +369,9 @@ namespace xo { std::unique_ptr self = p_stack->pop_exprstate(); /* 1. replace with nested incomplete infix exprs */ - p_stack->push_exprstate(progress_xs::make(lhs_, op_type_)); + progress_xs::start(lhs_, op_type_, p_stack); expect_expr_xs::start(p_stack); - p_stack->push_exprstate(progress_xs::make(rhs_, op2)); + progress_xs::start(rhs_, op2, p_stack); expect_expr_xs::start(p_stack); } From a5e2f622a4fcade434d1b6c5c68a151c7e006385 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:13:59 -0400 Subject: [PATCH 147/191] xo-reader: refactor: simplify expect_formal_xs api --- include/xo/reader/expect_formal_xs.hpp | 5 ++++- src/reader/expect_formal_arglist_xs.cpp | 4 ++-- src/reader/expect_formal_xs.cpp | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp index 79b8bf05..892e447f 100644 --- a/include/xo/reader/expect_formal_xs.hpp +++ b/include/xo/reader/expect_formal_xs.hpp @@ -47,7 +47,7 @@ namespace xo { public: expect_formal_xs(); - static std::unique_ptr make(); + static void start(exprstatestack * p_stack); virtual void on_symbol(const std::string & symbol_name, exprstatestack * p_stack, @@ -71,6 +71,9 @@ namespace xo { virtual void print(std::ostream & os) const override; + private: + static std::unique_ptr make(); + private: /** parsing state-machine state **/ formalstatetype formalxs_type_ = formalstatetype::formal_0; diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 6f2a4e13..19087cce 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -54,7 +54,7 @@ namespace xo { if (farglxs_type_ == formalarglstatetype::argl_0) { this->farglxs_type_ = formalarglstatetype::argl_1a; /* TODO: refactor to have setup method on each exprstate */ - p_stack->push_exprstate(expect_formal_xs::make()); + expect_formal_xs::start(p_stack); expect_symbol_xs::start(p_stack); } else { exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); @@ -81,7 +81,7 @@ namespace xo { { if (farglxs_type_ == formalarglstatetype::argl_1b) { this->farglxs_type_ = formalarglstatetype::argl_1a; - p_stack->push_exprstate(expect_formal_xs::make()); + expect_formal_xs::start(p_stack); } else { exprstate::on_comma_token(tk, p_stack, p_emit_expr); } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index b796a209..31c0ccf9 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -34,6 +34,11 @@ namespace xo { return std::make_unique(expect_formal_xs()); } + void + expect_formal_xs::start(exprstatestack * p_stack) { + p_stack->push_exprstate(expect_formal_xs::make()); + } + expect_formal_xs::expect_formal_xs() : exprstate(exprstatetype::expect_formal) {} From 2df98cc0295e6aaeb2283d4af8701572c3503115 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:15:58 -0400 Subject: [PATCH 148/191] xo-reader: bugfix: missed expect_symbol_xs.start() + utest to reveal --- src/reader/expect_formal_arglist_xs.cpp | 1 + utest/reader.test.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 19087cce..469566bc 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -82,6 +82,7 @@ namespace xo { if (farglxs_type_ == formalarglstatetype::argl_1b) { this->farglxs_type_ = formalarglstatetype::argl_1a; expect_formal_xs::start(p_stack); + expect_symbol_xs::start(p_stack); } else { exprstate::on_comma_token(tk, p_stack, p_emit_expr); } diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp index 926b6436..aa85fcc7 100644 --- a/utest/reader.test.cpp +++ b/utest/reader.test.cpp @@ -16,7 +16,8 @@ namespace xo { {"def foo : f64 = 3.14159265;"}, {"def foo : f64 = (3.14159265);"}, //{"def foo : f64 = 2.0 * 3.14159265;"}, - {"def foo = lambda (x : f64) 3.1415965;"} + {"def foo = lambda (x : f64) 3.1415965;"}, + {"def foo = lambda (x : f64, y : f64) 3.1415965;"} }; } From 0dd66a4bcc4d5b6c8784d1f73944081da5ad9133 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:17:32 -0400 Subject: [PATCH 149/191] xo-reader: refactor: simplify expect_formal_xs api --- src/reader/expect_formal_arglist_xs.cpp | 2 -- src/reader/expect_formal_xs.cpp | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 469566bc..5b58e3cf 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -55,7 +55,6 @@ namespace xo { this->farglxs_type_ = formalarglstatetype::argl_1a; /* TODO: refactor to have setup method on each exprstate */ expect_formal_xs::start(p_stack); - expect_symbol_xs::start(p_stack); } else { exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); } @@ -82,7 +81,6 @@ namespace xo { if (farglxs_type_ == formalarglstatetype::argl_1b) { this->farglxs_type_ = formalarglstatetype::argl_1a; expect_formal_xs::start(p_stack); - expect_symbol_xs::start(p_stack); } else { exprstate::on_comma_token(tk, p_stack, p_emit_expr); } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 31c0ccf9..3be6bcf8 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -4,6 +4,7 @@ */ #include "expect_formal_xs.hpp" +#include "expect_symbol_xs.hpp" #include "expect_type_xs.hpp" #include "xo/expression/Variable.hpp" @@ -37,6 +38,8 @@ namespace xo { void expect_formal_xs::start(exprstatestack * p_stack) { p_stack->push_exprstate(expect_formal_xs::make()); + + expect_symbol_xs::start(p_stack); } expect_formal_xs::expect_formal_xs() From 7767833afbb172cce963563134c99f66777c445d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:24:11 -0400 Subject: [PATCH 150/191] xo-reader: refactor: simplify lambda_xs api --- include/xo/reader/lambda_xs.hpp | 5 ++++- src/reader/expect_expr_xs.cpp | 6 +++--- src/reader/lambda_xs.cpp | 9 +++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 1152406a..e1880039 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -40,7 +40,7 @@ namespace xo { public: lambda_xs(); - static std::unique_ptr make(); + static void start(exprstatestack * p_stack, rp * p_emit_expr); virtual void on_lambda_token(const token_type & tk, exprstatestack * p_stack, @@ -55,6 +55,9 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; + private: + static std::unique_ptr make(); + private: /** parsing state-machine state **/ lambdastatetype lmxs_type_ = lambdastatetype::lm_0; diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index c91205d0..9f27d2a0 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -31,7 +31,7 @@ namespace xo { {} void - expect_expr_xs::on_lambda_token(const token_type & tk, + expect_expr_xs::on_lambda_token(const token_type & /*tk*/, exprstatestack * p_stack, rp * p_emit_expr) { @@ -41,8 +41,8 @@ namespace xo { //constexpr const char * self_name = "exprstate::on_leftparen"; /* push lparen_0 to remember to look for subsequent rightparen. */ - p_stack->push_exprstate(lambda_xs::make()); - p_stack->top_exprstate().on_lambda_token(tk, p_stack, p_emit_expr); + lambda_xs::start(p_stack, p_emit_expr); + //p_stack->top_exprstate().on_lambda_token(tk, p_stack, p_emit_expr); //p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); } diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index c9c131ac..1b28cf11 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -14,6 +14,15 @@ namespace xo { return std::make_unique(lambda_xs()); } + void + lambda_xs::start(exprstatestack * p_stack, + rp * p_emit_expr) + { + p_stack->push_exprstate(lambda_xs::make()); + p_stack->top_exprstate() + .on_lambda_token(token_type::lambda(), p_stack, p_emit_expr); + } + lambda_xs::lambda_xs() : exprstate(exprstatetype::lambdaexpr) {} void From 6a71f718bda97fb8ffb1fc7eb75217541316ecfc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:27:35 -0400 Subject: [PATCH 151/191] xo-reader: refactor: simplify paren_xs api --- include/xo/reader/paren_xs.hpp | 5 ++++- src/reader/expect_expr_xs.cpp | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 65811607..dada4627 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -29,7 +29,7 @@ namespace xo { static const paren_xs * from(const exprstate * x) { return dynamic_cast(x); } - static std::unique_ptr lparen_0(); + static void start(exprstatestack * p_stack); bool admits_f64() const; bool admits_rightparen() const; @@ -68,6 +68,9 @@ namespace xo { virtual void print(std::ostream & os) const override; + private: + static std::unique_ptr make(); + private: /** * ( foo ... ) diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 9f27d2a0..8ecc2e5b 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -57,8 +57,7 @@ namespace xo { //constexpr const char * self_name = "exprstate::on_leftparen"; /* push lparen_0 to remember to look for subsequent rightparen. */ - p_stack->push_exprstate(paren_xs::lparen_0()); - expect_expr_xs::start(p_stack); + paren_xs::start(p_stack); } void From 034dac7dfdd946efe021dcceeaff38245156098c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:44:34 -0400 Subject: [PATCH 152/191] xo-reader: refactor: + parserstatemachine; use for def_expr --- include/xo/reader/define_xs.hpp | 4 +-- include/xo/reader/exprseq_xs.hpp | 2 +- include/xo/reader/exprstate.hpp | 3 +- include/xo/reader/paren_xs.hpp | 2 +- include/xo/reader/parserstatemachine.hpp | 36 ++++++++++++++++++++++++ include/xo/reader/progress_xs.hpp | 2 +- src/reader/define_xs.cpp | 13 +++++---- src/reader/exprseq_xs.cpp | 4 +-- src/reader/exprstate.cpp | 7 +++-- src/reader/paren_xs.cpp | 12 ++++++-- src/reader/progress_xs.cpp | 2 +- 11 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 include/xo/reader/parserstatemachine.hpp diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 67c53878..dad682c3 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -70,7 +70,7 @@ namespace xo { static const define_xs * from(const exprstate * x) { return dynamic_cast(x); } - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_psm); defexprstatetype defxs_type() const { return defxs_type_; } @@ -84,7 +84,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_def_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_semicolon_token(const token_type & tk, diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 1797855a..6955e8a6 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -24,7 +24,7 @@ namespace xo { // ----- token input methods ----- virtual void on_def_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 5d3ee107..fb541cd9 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -63,6 +63,7 @@ namespace xo { return os; } + class parserstatemachine; class exprstatestack; class formal_arg; @@ -120,7 +121,7 @@ namespace xo { /** handle incoming 'def' token **/ virtual void on_def_token(const token_type & tk, - exprstatestack * p_stack); + parserstatemachine * p_psm); /** handle incoming 'lambda' token **/ virtual void on_lambda_token(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index dada4627..48cc6ea8 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -45,7 +45,7 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_def_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp new file mode 100644 index 00000000..55b285ee --- /dev/null +++ b/include/xo/reader/parserstatemachine.hpp @@ -0,0 +1,36 @@ +/* file parserstatemachine.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" + +namespace xo { + namespace scm { + /** @class parserstatemachine + * @brief public parser state. + * + * Schematica parser state; sent to subsidiary single-feature state machines. + * For example entry points for the lambda feature (@ref lambda_xs) + * will accept a non-const parserstatemachine pointer argument + **/ + class parserstatemachine { + public: + using Expression = xo::ast::Expression; + + public: + parserstatemachine(exprstatestack * p_stack, + rp * p_emit_expr) + : p_stack_{p_stack}, p_emit_expr_{p_emit_expr} {} + + public: + exprstatestack * p_stack_; + rp * p_emit_expr_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end parserstatemachine.hpp */ diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 466b4b02..6efe21eb 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -66,7 +66,7 @@ namespace xo { rp * /*p_emit_expr*/) override; virtual void on_def_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_semicolon_token(const token_type & tk, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 20ffbd40..a141bfb8 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -1,6 +1,7 @@ /* @file define_xs.cpp */ #include "define_xs.hpp" +#include "parserstatemachine.hpp" #include "expect_symbol_xs.hpp" #include "expect_expr_xs.hpp" #include "expect_type_xs.hpp" @@ -13,10 +14,12 @@ namespace xo { } void - define_xs::start(exprstatestack * p_stack) + define_xs::start(parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + p_stack->push_exprstate(define_xs::make()); - p_stack->top_exprstate().on_def_token(token_type::def(), p_stack); + p_stack->top_exprstate().on_def_token(token_type::def(), p_psm); } define_xs::define_xs(rp def_expr) @@ -88,7 +91,7 @@ namespace xo { void define_xs::on_def_token(const token_type & tk, - exprstatestack * p_stack) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -98,9 +101,9 @@ namespace xo { if (this->defxs_type_ == defexprstatetype::def_0) { this->defxs_type_ = defexprstatetype::def_1; - expect_symbol_xs::start(p_stack); + expect_symbol_xs::start(p_psm->p_stack_); } else { - exprstate::on_def_token(tk, p_stack); + exprstate::on_def_token(tk, p_psm); } } diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 840cd958..25873606 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -25,14 +25,14 @@ namespace xo { void exprseq_xs::on_def_token(const token_type & /*tk*/, - exprstatestack * p_stack) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); //constexpr const char * c_self_name = "exprseq_xs::on_def_token"; - define_xs::start(p_stack); + define_xs::start(p_psm); /* keyword 'def' introduces a definition: * def pi : f64 = 3.14159265 diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 8352914a..71f0eb50 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -1,6 +1,7 @@ /* @file exprstate.cpp */ #include "exprstate.hpp" +#include "parserstatemachine.hpp" //#include "formal_arg.hpp" #include "xo/expression/Variable.hpp" #include "xo/indentlog/print/vector.hpp" @@ -52,7 +53,7 @@ namespace xo { void exprstate::on_def_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_psm*/) { this->illegal_input_error("exprstate::on_def_token", tk); } @@ -254,10 +255,12 @@ namespace xo { log && log(xtag("tk", tk)); log && log(xtag("state", *this)); + parserstatemachine psm(p_stack, p_emit_expr); + switch (tk.tk_type()) { case tokentype::tk_def: - this->on_def_token(tk, p_stack); + this->on_def_token(tk, &psm); return; case tokentype::tk_lambda: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 06329bde..906a9b18 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -2,6 +2,7 @@ #include "paren_xs.hpp" #include "progress_xs.hpp" +#include "expect_expr_xs.hpp" namespace xo { namespace scm { @@ -10,10 +11,17 @@ namespace xo { {} std::unique_ptr - paren_xs::lparen_0() { + paren_xs::make() { return std::make_unique(paren_xs()); } + void + paren_xs::start(exprstatestack * p_stack) + { + p_stack->push_exprstate(paren_xs::make()); + expect_expr_xs::start(p_stack); + } + bool paren_xs::admits_rightparen() const { switch (parenxs_type_) { @@ -56,7 +64,7 @@ namespace xo { void paren_xs::on_def_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_stack*/) { constexpr const char * c_self_name = "paren_xs::on_def"; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 407b8b9f..481cb895 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -73,7 +73,7 @@ namespace xo { void progress_xs::on_def_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_stack*/) { constexpr const char * self_name = "progress_xs::on_def"; From e5dc8d14d42e5a4066d5427a7ac9a819b765c5cb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:48:53 -0400 Subject: [PATCH 153/191] xo-reader: refactor: use parserstatemachine for parser.on_input() --- include/xo/reader/exprstate.hpp | 5 ++--- src/reader/exprstate.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index fb541cd9..e36972fa 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -63,7 +63,7 @@ namespace xo { return os; } - class parserstatemachine; + class parserstatemachine; /* see parserstatemachine.hpp */ class exprstatestack; class formal_arg; @@ -91,8 +91,7 @@ namespace xo { * forward instructions to parent parser **/ void on_input(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(ref::brw expr, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 71f0eb50..d5f72881 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -247,20 +247,20 @@ namespace xo { void exprstate::on_input(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); log && log(xtag("tk", tk)); log && log(xtag("state", *this)); - parserstatemachine psm(p_stack, p_emit_expr); + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; switch (tk.tk_type()) { case tokentype::tk_def: - this->on_def_token(tk, &psm); + this->on_def_token(tk, p_psm); return; case tokentype::tk_lambda: From 8cae38817bd7cecbf541809a52e57cfd59ec4527 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 00:54:45 -0400 Subject: [PATCH 154/191] xo-reader: refactor: parserstatemachine w/ exprstate.on_lambda_token --- include/xo/reader/expect_expr_xs.hpp | 3 +-- include/xo/reader/exprstate.hpp | 3 +-- include/xo/reader/lambda_xs.hpp | 3 +-- src/reader/expect_expr_xs.cpp | 7 +++++-- src/reader/exprstate.cpp | 5 ++--- src/reader/lambda_xs.cpp | 12 ++++++++---- src/reader/parser.cpp | 5 ++++- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 85686d96..f7bcb097 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -20,8 +20,7 @@ namespace xo { static void start(exprstatestack * p_stack); virtual void on_lambda_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_leftparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index e36972fa..f0bbf2f3 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -123,8 +123,7 @@ namespace xo { parserstatemachine * p_psm); /** handle incoming 'lambda' token **/ virtual void on_lambda_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** handle incoming symbol token **/ virtual void on_symbol_token(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index e1880039..7597e937 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -43,8 +43,7 @@ namespace xo { static void start(exprstatestack * p_stack, rp * p_emit_expr); virtual void on_lambda_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_formal_arglist(const std::vector> & argl, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 8ecc2e5b..bb90047f 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -4,6 +4,7 @@ */ #include "expect_expr_xs.hpp" +#include "parserstatemachine.hpp" #include "lambda_xs.hpp" #include "paren_xs.hpp" #include "progress_xs.hpp" @@ -32,14 +33,16 @@ namespace xo { void expect_expr_xs::on_lambda_token(const token_type & /*tk*/, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); //constexpr const char * self_name = "exprstate::on_leftparen"; + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + /* push lparen_0 to remember to look for subsequent rightparen. */ lambda_xs::start(p_stack, p_emit_expr); //p_stack->top_exprstate().on_lambda_token(tk, p_stack, p_emit_expr); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index d5f72881..cd1342ff 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -60,8 +60,7 @@ namespace xo { void exprstate::on_lambda_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { this->illegal_input_error("exprstate::on_lambda_token", tk); } @@ -264,7 +263,7 @@ namespace xo { return; case tokentype::tk_lambda: - this->on_lambda_token(tk, p_stack, p_emit_expr); + this->on_lambda_token(tk, p_psm); return; case tokentype::tk_i64: diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 1b28cf11..f861d1aa 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -1,6 +1,7 @@ /* @file lambda_xs.cpp */ #include "lambda_xs.hpp" +#include "parserstatemachine.hpp" #include "expect_formal_arglist_xs.hpp" #include "expect_expr_xs.hpp" #include "xo/expression/Lambda.hpp" @@ -18,23 +19,26 @@ namespace xo { lambda_xs::start(exprstatestack * p_stack, rp * p_emit_expr) { + parserstatemachine psm(p_stack, p_emit_expr); + p_stack->push_exprstate(lambda_xs::make()); p_stack->top_exprstate() - .on_lambda_token(token_type::lambda(), p_stack, p_emit_expr); + .on_lambda_token(token_type::lambda(), &psm); } lambda_xs::lambda_xs() : exprstate(exprstatetype::lambdaexpr) {} void lambda_xs::on_lambda_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + if (lmxs_type_ == lambdastatetype::lm_0) { this->lmxs_type_ = lambdastatetype::lm_1; expect_formal_arglist_xs::start(p_stack); } else { - exprstate::on_lambda_token(tk, p_stack, p_emit_expr); + exprstate::on_lambda_token(tk, p_psm); } } diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 5c2a99bb..9c9d373e 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -4,6 +4,7 @@ */ #include "parser.hpp" +#include "parserstatemachine.hpp" #include "define_xs.hpp" #include "exprseq_xs.hpp" #include "xo/expression/DefineExpr.hpp" @@ -50,7 +51,9 @@ namespace xo { rp retval; - xs_stack_.top_exprstate().on_input(tk, &xs_stack_, &retval); + parserstatemachine psm(&xs_stack_, &retval); + + xs_stack_.top_exprstate().on_input(tk, &psm); log && log(xtag("retval", retval)); From bda115037bada94905b038e34e90fd9472000257 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 01:03:18 -0400 Subject: [PATCH 155/191] xo-reader: refactor: use parsestatemachine w/ on_symbol_token() --- include/xo/reader/expect_expr_xs.hpp | 3 +-- include/xo/reader/expect_symbol_xs.hpp | 3 +-- include/xo/reader/expect_type_xs.hpp | 3 +-- include/xo/reader/exprseq_xs.hpp | 3 +-- include/xo/reader/exprstate.hpp | 3 +-- include/xo/reader/paren_xs.hpp | 3 +-- include/xo/reader/progress_xs.hpp | 3 +-- src/reader/expect_expr_xs.cpp | 3 +-- src/reader/expect_symbol_xs.cpp | 8 ++++++-- src/reader/expect_type_xs.cpp | 8 +++++--- src/reader/exprseq_xs.cpp | 3 +-- src/reader/exprstate.cpp | 7 ++++--- src/reader/paren_xs.cpp | 8 +++++--- src/reader/progress_xs.cpp | 3 +-- 14 files changed, 30 insertions(+), 31 deletions(-) diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index f7bcb097..0259e6a6 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -26,8 +26,7 @@ namespace xo { rp * p_emit_expr) override; virtual void on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_f64_token(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/expect_symbol_xs.hpp b/include/xo/reader/expect_symbol_xs.hpp index 40cb25b6..63740aeb 100644 --- a/include/xo/reader/expect_symbol_xs.hpp +++ b/include/xo/reader/expect_symbol_xs.hpp @@ -23,8 +23,7 @@ namespace xo { static void start(exprstatestack * p_stack); virtual void on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader/expect_type_xs.hpp b/include/xo/reader/expect_type_xs.hpp index 0e534a2a..86e5adf7 100644 --- a/include/xo/reader/expect_type_xs.hpp +++ b/include/xo/reader/expect_type_xs.hpp @@ -19,8 +19,7 @@ namespace xo { static void start(exprstatestack * p_stack); virtual void on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; private: static std::unique_ptr make(); diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 6955e8a6..a5576001 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -26,8 +26,7 @@ namespace xo { virtual void on_def_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; // ----- victory methods ----- diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index f0bbf2f3..ab091fdc 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -126,8 +126,7 @@ namespace xo { parserstatemachine * p_psm); /** handle incoming symbol token **/ virtual void on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** handle incoming ',' token **/ virtual void on_comma_token(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 48cc6ea8..9e8c8dff 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -47,8 +47,7 @@ namespace xo { virtual void on_def_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_semicolon_token(const token_type & tk, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 6efe21eb..06107bad 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -59,8 +59,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) override; diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index bb90047f..9e28eb6e 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -65,8 +65,7 @@ namespace xo { void expect_expr_xs::on_symbol_token(const token_type & /*tk*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { /* todo: treat symbol as variable name */ diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index e6fd2bb7..12334e73 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -4,6 +4,7 @@ */ #include "expect_symbol_xs.hpp" +#include "parserstatemachine.hpp" namespace xo { namespace scm { @@ -24,14 +25,17 @@ namespace xo { void expect_symbol_xs::on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + /* have to do pop first, before sending symbol to * the o.g. symbol-requester */ std::unique_ptr self = p_stack->pop_exprstate(); + p_stack->top_exprstate().on_symbol(tk.text(), p_stack, p_emit_expr); return; diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index add0dc77..11ab04ed 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -4,7 +4,7 @@ */ #include "expect_type_xs.hpp" -#include "exprstate.hpp" +#include "parserstatemachine.hpp" #include "xo/reflect/Reflect.hpp" namespace xo { @@ -28,11 +28,13 @@ namespace xo { void expect_type_xs::on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { const char * c_self_name = "expect_type_xs::on_symbol_token"; + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + TypeDescr td = nullptr; /* TODO: replace with typetable lookup */ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 25873606..76722e5b 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -42,8 +42,7 @@ namespace xo { void exprseq_xs::on_symbol_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr const char * c_self_name = "exprseq_xs::on_symbol_token"; diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index cd1342ff..97be6fec 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -67,12 +67,13 @@ namespace xo { void exprstate::on_symbol_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + auto p_stack = p_psm->p_stack_; + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); constexpr const char * c_self_name = "exprstate::on_symbol_token"; @@ -279,7 +280,7 @@ namespace xo { return; case tokentype::tk_symbol: - this->on_symbol_token(tk, p_stack, p_emit_expr); + this->on_symbol_token(tk, p_psm); return; case tokentype::tk_leftparen: diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 906a9b18..9ec0a0b8 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -1,6 +1,7 @@ /* @file paren_xs.cpp */ #include "paren_xs.hpp" +#include "parserstatemachine.hpp" #include "progress_xs.hpp" #include "expect_expr_xs.hpp" @@ -64,7 +65,7 @@ namespace xo { void paren_xs::on_def_token(const token_type & tk, - parserstatemachine * /*p_stack*/) + parserstatemachine * /*p_psm*/) { constexpr const char * c_self_name = "paren_xs::on_def"; @@ -73,12 +74,13 @@ namespace xo { void paren_xs::on_symbol_token(const token_type & /*tk*/, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + auto p_stack = p_psm->p_stack_; + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); //constexpr const char * self_name = "paren_xs::on_symbol"; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 481cb895..431b0cb8 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -164,8 +164,7 @@ namespace xo { void progress_xs::on_symbol_token(const token_type & /*tk*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { /* illegal input, e.g. * foo bar From b02d1e17e4041545e518953ed5415b33481f1231 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 11:39:27 -0400 Subject: [PATCH 156/191] xo-reader: refactor: parserstatemachine to consolidate on_input() --- include/xo/reader/define_xs.hpp | 13 +++--- include/xo/reader/expect_expr_xs.hpp | 7 ++-- .../xo/reader/expect_formal_arglist_xs.hpp | 9 ++-- include/xo/reader/expect_formal_xs.hpp | 3 +- include/xo/reader/exprstate.hpp | 24 +++++------ include/xo/reader/lambda_xs.hpp | 3 +- include/xo/reader/paren_xs.hpp | 16 +++----- include/xo/reader/progress_xs.hpp | 19 ++++----- src/reader/define_xs.cpp | 24 ++++++----- src/reader/expect_expr_xs.cpp | 10 ++--- src/reader/expect_formal_arglist_xs.cpp | 23 +++++++---- src/reader/expect_formal_xs.cpp | 8 ++-- src/reader/exprstate.cpp | 41 ++++++++----------- src/reader/lambda_xs.cpp | 10 +++-- src/reader/paren_xs.cpp | 26 +++++------- src/reader/progress_xs.cpp | 36 ++++++++-------- 16 files changed, 124 insertions(+), 148 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index dad682c3..9e616b31 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -86,18 +86,15 @@ namespace xo { virtual void on_def_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_singleassign_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_f64_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 0259e6a6..3808e7bc 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -21,16 +21,15 @@ namespace xo { virtual void on_lambda_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void on_leftparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_symbol_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_f64_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(ref::brw expr, diff --git a/include/xo/reader/expect_formal_arglist_xs.hpp b/include/xo/reader/expect_formal_arglist_xs.hpp index 442dde62..7eef773d 100644 --- a/include/xo/reader/expect_formal_arglist_xs.hpp +++ b/include/xo/reader/expect_formal_arglist_xs.hpp @@ -56,17 +56,14 @@ namespace xo { static void start(exprstatestack * p_stack); virtual void on_leftparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_formal(const rp & formal, exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_comma_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; private: diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp index 892e447f..b757f6f5 100644 --- a/include/xo/reader/expect_formal_xs.hpp +++ b/include/xo/reader/expect_formal_xs.hpp @@ -54,8 +54,7 @@ namespace xo { rp * p_emit_expr) override; virtual void on_colon_token(const token_type & tk, - exprstatestack * p_stack - /*rp * p_emit_expr*/) override; + parserstatemachine * p_psm) override; // virtual void on_comma_token(...) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ab091fdc..bf93a3f5 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -129,34 +129,30 @@ namespace xo { parserstatemachine * p_psm); /** handle incoming ',' token **/ virtual void on_comma_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** handle incoming ':' token **/ virtual void on_colon_token(const token_type & tk, - exprstatestack * p_stack); + parserstatemachine * p_psm); /** handle incoming ';' token **/ virtual void on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** handle incoming '=' token **/ virtual void on_singleassign_token(const token_type & tk, - exprstatestack * p_stack); + parserstatemachine * p_psm); /** handle incoming '(' token **/ virtual void on_leftparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** handle incoming ')' token **/ virtual void on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); + /** handle incoming operator token **/ virtual void on_operator_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); + /** handle incoming floating-point-literal token **/ virtual void on_f64_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); protected: /** throw exception when next token is inconsistent with diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 7597e937..59f9f78a 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -51,8 +51,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; private: static std::unique_ptr make(); diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 9e8c8dff..b4225f4e 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -49,21 +49,17 @@ namespace xo { virtual void on_symbol_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void on_singleassign_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_leftparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void on_f64_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 06107bad..965da117 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -67,27 +67,22 @@ namespace xo { virtual void on_def_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void on_singleassign_token(const token_type & tk, - exprstatestack * p_stack) override; + parserstatemachine * p_psm) override; virtual void on_leftparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; /* entry point for an infix operator token */ virtual void on_operator_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_f64_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index a141bfb8..0f5561dc 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -109,30 +109,34 @@ namespace xo { void define_xs::on_colon_token(const token_type & tk, - exprstatestack * p_stack) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); //constexpr const char * self_name = "define_xs::on_colon_token"; + auto p_stack = p_psm->p_stack_; + if (this->defxs_type_ == defexprstatetype::def_2) { this->defxs_type_ = defexprstatetype::def_3; expect_type_xs::start(p_stack); } else { - exprstate::on_colon_token(tk, p_stack); + exprstate::on_colon_token(tk, p_psm); } } void define_xs::on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + //constexpr const char * self_name = "exprstate::on_semicolon"; if (this->defxs_type_ == defexprstatetype::def_6) { @@ -144,13 +148,13 @@ namespace xo { p_stack, p_emit_expr); } else { - exprstate::on_semicolon_token(tk, p_stack, p_emit_expr); + exprstate::on_semicolon_token(tk, p_psm); } } void define_xs::on_singleassign_token(const token_type & tk, - exprstatestack * p_stack) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -177,7 +181,7 @@ namespace xo { { this->defxs_type_ = defexprstatetype::def_5; - expect_expr_xs::start(p_stack); + expect_expr_xs::start(p_psm->p_stack_); } else { this->illegal_input_error(self_name, tk); } @@ -185,8 +189,7 @@ namespace xo { void define_xs::on_rightparen_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -198,8 +201,7 @@ namespace xo { void define_xs::on_f64_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 9e28eb6e..123f52da 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -51,14 +51,15 @@ namespace xo { void expect_expr_xs::on_leftparen_token(const token_type & /*tk*/, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); //constexpr const char * self_name = "exprstate::on_leftparen"; + auto p_stack = p_psm->p_stack_; + /* push lparen_0 to remember to look for subsequent rightparen. */ paren_xs::start(p_stack); } @@ -99,8 +100,7 @@ namespace xo { void expect_expr_xs::on_f64_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -113,7 +113,7 @@ namespace xo { */ progress_xs::start (Constant::make(tk.f64_value()), - p_stack); + p_psm->p_stack_); } void diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 5b58e3cf..6bb9b099 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -6,6 +6,7 @@ #include "expect_formal_arglist_xs.hpp" #include "expect_formal_xs.hpp" #include "expect_symbol_xs.hpp" +#include "parserstatemachine.hpp" #include "xo/expression/Variable.hpp" #include "xo/indentlog/print/vector.hpp" @@ -48,15 +49,16 @@ namespace xo { void expect_formal_arglist_xs::on_leftparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + if (farglxs_type_ == formalarglstatetype::argl_0) { this->farglxs_type_ = formalarglstatetype::argl_1a; /* TODO: refactor to have setup method on each exprstate */ expect_formal_xs::start(p_stack); } else { - exprstate::on_leftparen_token(tk, p_stack, p_emit_expr); + exprstate::on_leftparen_token(tk, p_psm); } } @@ -75,29 +77,32 @@ namespace xo { void expect_formal_arglist_xs::on_comma_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + if (farglxs_type_ == formalarglstatetype::argl_1b) { this->farglxs_type_ = formalarglstatetype::argl_1a; expect_formal_xs::start(p_stack); } else { - exprstate::on_comma_token(tk, p_stack, p_emit_expr); + exprstate::on_comma_token(tk, p_psm); } } void expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + if (farglxs_type_ == formalarglstatetype::argl_1b) { std::unique_ptr self = p_stack->pop_exprstate(); p_stack->top_exprstate().on_formal_arglist(this->argl_, p_stack, p_emit_expr); } else { - exprstate::on_rightparen_token(tk, p_stack, p_emit_expr); + exprstate::on_rightparen_token(tk, p_psm); } } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 3be6bcf8..3455de23 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -6,6 +6,7 @@ #include "expect_formal_xs.hpp" #include "expect_symbol_xs.hpp" #include "expect_type_xs.hpp" +#include "parserstatemachine.hpp" #include "xo/expression/Variable.hpp" namespace xo { @@ -63,16 +64,17 @@ namespace xo { void expect_formal_xs::on_colon_token(const token_type & tk, - exprstatestack * p_stack - /* rp * p_emit_expr */) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + if (this->formalxs_type_ == formalstatetype::formal_1) { this->formalxs_type_ = formalstatetype::formal_2; expect_type_xs::start(p_stack); /* control reenters via expect_formal_xs::on_typedescr() */ } else { exprstate::on_colon_token(tk, - p_stack); + p_psm); } } diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 97be6fec..ba58eb79 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -146,7 +146,7 @@ namespace xo { void exprstate::on_colon_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -158,8 +158,7 @@ namespace xo { void exprstate::on_comma_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -171,8 +170,7 @@ namespace xo { void exprstate::on_semicolon_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -184,7 +182,7 @@ namespace xo { void exprstate::on_singleassign_token(const token_type & tk, - exprstatestack * /*p_stack*/) { + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -195,8 +193,7 @@ namespace xo { void exprstate::on_leftparen_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -208,8 +205,7 @@ namespace xo { void exprstate::on_rightparen_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -221,8 +217,7 @@ namespace xo { void exprstate::on_operator_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -234,8 +229,7 @@ namespace xo { void exprstate::on_f64_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -254,9 +248,6 @@ namespace xo { log && log(xtag("tk", tk)); log && log(xtag("state", *this)); - auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; - switch (tk.tk_type()) { case tokentype::tk_def: @@ -272,7 +263,7 @@ namespace xo { return; case tokentype::tk_f64: - this->on_f64_token(tk, p_stack, p_emit_expr); + this->on_f64_token(tk, p_psm); return; case tokentype::tk_string: @@ -284,11 +275,11 @@ namespace xo { return; case tokentype::tk_leftparen: - this->on_leftparen_token(tk, p_stack, p_emit_expr); + this->on_leftparen_token(tk, p_psm); return; case tokentype::tk_rightparen: - this->on_rightparen_token(tk, p_stack, p_emit_expr); + this->on_rightparen_token(tk, p_psm); return; case tokentype::tk_leftbracket: @@ -303,11 +294,11 @@ namespace xo { return; case tokentype::tk_comma: - this->on_comma_token(tk, p_stack, p_emit_expr); + this->on_comma_token(tk, p_psm); return; case tokentype::tk_colon: - this->on_colon_token(tk, p_stack); + this->on_colon_token(tk, p_psm); return; case tokentype::tk_doublecolon: @@ -315,11 +306,11 @@ namespace xo { return; case tokentype::tk_semicolon: - this->on_semicolon_token(tk, p_stack, p_emit_expr); + this->on_semicolon_token(tk, p_psm); return; case tokentype::tk_singleassign: - this->on_singleassign_token(tk, p_stack); + this->on_singleassign_token(tk, p_psm); return; case tokentype::tk_assign: @@ -329,7 +320,7 @@ namespace xo { case tokentype::tk_minus: case tokentype::tk_star: case tokentype::tk_slash: - this->on_operator_token(tk, p_stack, p_emit_expr); + this->on_operator_token(tk, p_psm); return; case tokentype::tk_type: diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index f861d1aa..8824ab26 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -71,9 +71,11 @@ namespace xo { void lambda_xs::on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + if (lmxs_type_ == lambdastatetype::lm_3) { /* done! */ @@ -84,12 +86,12 @@ namespace xo { rp lm = Lambda::make(name, argl_, body_); p_stack->top_exprstate().on_expr(lm, p_stack, p_emit_expr); - p_stack->top_exprstate().on_semicolon_token(tk, p_stack, p_emit_expr); + p_stack->top_exprstate().on_semicolon_token(tk, p_psm); return; } - exprstate::on_semicolon_token(tk, p_stack, p_emit_expr); + exprstate::on_semicolon_token(tk, p_psm); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 9ec0a0b8..8f6dff50 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -101,7 +101,7 @@ namespace xo { void paren_xs::on_colon_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_psm*/) { constexpr const char * c_self_name = "paren_xs::on_colon"; @@ -110,8 +110,7 @@ namespace xo { void paren_xs::on_semicolon_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr const char * c_self_name = "paren_xs::on_semicolon"; @@ -120,7 +119,7 @@ namespace xo { void paren_xs::on_singleassign_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_psm*/) { constexpr const char * c_self_name = "paren_xs::on_singleassign"; @@ -129,8 +128,7 @@ namespace xo { void paren_xs::on_leftparen_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr const char * c_self_name = "paren_xs::on_leftparen"; @@ -139,8 +137,7 @@ namespace xo { void paren_xs::on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -155,6 +152,9 @@ namespace xo { if (this->parenxs_type_ == parenexprstatetype::lparen_1) { rp expr = this->gen_expr_; + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + std::unique_ptr self = p_stack->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); @@ -163,20 +163,14 @@ namespace xo { void paren_xs::on_f64_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); constexpr const char * c_self_name = "paren_xs::on_f64"; - if (!this->admits_f64()) - { - this->illegal_input_error(c_self_name, tk); - } - - assert(false); + this->illegal_input_error(c_self_name, tk); } void diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 431b0cb8..12f62740 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -2,6 +2,7 @@ #include "progress_xs.hpp" #include "expect_expr_xs.hpp" +#include "parserstatemachine.hpp" #include "xo/expression/Apply.hpp" namespace xo { @@ -183,7 +184,7 @@ namespace xo { void progress_xs::on_colon_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_psm*/) { constexpr const char * self_name = "progress_xs::on_colon"; @@ -192,14 +193,16 @@ namespace xo { void progress_xs::on_semicolon_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { /* note: implementation parllels .on_rightparen_token() */ constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + rp expr = this->assemble_expr(); std::unique_ptr self = p_stack->pop_exprstate(); @@ -222,12 +225,12 @@ namespace xo { * f. now deliver semicolon; [lparen_1] rejects */ - p_stack->top_exprstate().on_semicolon_token(tk, p_stack, p_emit_expr); + p_stack->top_exprstate().on_semicolon_token(tk, p_psm); } void progress_xs::on_singleassign_token(const token_type & tk, - exprstatestack * /*p_stack*/) + parserstatemachine * /*p_psm*/) { constexpr const char * self_name = "progress_xs::on_singleassign"; @@ -236,8 +239,7 @@ namespace xo { void progress_xs::on_leftparen_token(const token_type & tk, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -249,8 +251,7 @@ namespace xo { void progress_xs::on_rightparen_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { /* note: implementation parallels .on_semicolon_token() */ @@ -260,6 +261,9 @@ namespace xo { constexpr const char * self_name = "progress_xs::on_rightparen"; + auto p_stack = p_psm->p_stack_; + auto p_emit_expr = p_psm->p_emit_expr_; + /* stack may be something like: * * lparen_0 @@ -286,8 +290,7 @@ namespace xo { p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); /* now deliver rightparen */ - p_stack->top_exprstate().on_rightparen_token(tk, p_stack, p_emit_expr); - + p_stack->top_exprstate().on_rightparen_token(tk, p_psm); } namespace { @@ -312,11 +315,12 @@ namespace xo { void progress_xs::on_operator_token(const token_type & tk, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { constexpr const char * c_self_name = "progress_xs::on_operator_token"; + auto p_stack = p_psm->p_stack_; + if (op_type_ == optype::invalid) { this->op_type_ = tk2op(tk.tk_type()); @@ -383,8 +387,7 @@ namespace xo { void progress_xs::on_f64_token(const token_type & tk, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -394,8 +397,7 @@ namespace xo { if (this->op_type_ == optype::invalid) { this->illegal_input_error(self_name, tk); } else { - assert(false); - exprstate::on_f64_token(tk, p_stack, p_emit_expr); + exprstate::on_f64_token(tk, p_psm); } } From 29932f9a3df6001896def291e2d4de14cbb9ba3f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 11:43:20 -0400 Subject: [PATCH 157/191] xo-reader: parserstatemachine -> consolidate on_formal_arglist() --- include/xo/reader/exprstate.hpp | 8 ++++++-- include/xo/reader/lambda_xs.hpp | 3 +-- src/reader/expect_formal_arglist_xs.cpp | 4 +--- src/reader/exprstate.cpp | 5 +++-- src/reader/lambda_xs.cpp | 7 ++++--- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index bf93a3f5..3c5e2e6a 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -97,22 +97,26 @@ namespace xo { virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate when expecting a symbol **/ virtual void on_symbol(const std::string & symbol, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate when expeccting a typedescr **/ virtual void on_typedescr(TypeDescr td, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate when expecting a formal parameter **/ virtual void on_formal(const rp & formal, exprstatestack * p_stack, rp * p_emit_expr); + /** update expression when epecting a formal parameter list **/ virtual void on_formal_arglist(const std::vector> & argl, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); + /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 59f9f78a..b60f14a6 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -45,8 +45,7 @@ namespace xo { virtual void on_lambda_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_formal_arglist(const std::vector> & argl, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 6bb9b099..dc400aeb 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -94,13 +94,11 @@ namespace xo { parserstatemachine * p_psm) { auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; if (farglxs_type_ == formalarglstatetype::argl_1b) { std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_formal_arglist(this->argl_, - p_stack, p_emit_expr); + p_stack->top_exprstate().on_formal_arglist(this->argl_, p_psm); } else { exprstate::on_rightparen_token(tk, p_psm); } diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index ba58eb79..c9d14c82 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -125,14 +125,15 @@ namespace xo { void exprstate::on_formal_arglist(const std::vector> & argl, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { /* returning type description to something that wants it */ constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + auto p_stack = p_psm->p_stack_; + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 8824ab26..7aaf657d 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -44,15 +44,16 @@ namespace xo { void lambda_xs::on_formal_arglist(const std::vector> & argl, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + if (lmxs_type_ == lambdastatetype::lm_1) { this->lmxs_type_ = lambdastatetype::lm_2; this->argl_ = argl; expect_expr_xs::start(p_stack); } else { - exprstate::on_formal_arglist(argl, p_stack, p_emit_expr); + exprstate::on_formal_arglist(argl, p_psm); } } From dbd2f69533b69e6cda48474c8246f383f0b1861a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 11:46:46 -0400 Subject: [PATCH 158/191] xo-reader: parserstatemachine -> consolidate on_formal() args --- include/xo/reader/expect_formal_arglist_xs.hpp | 3 +-- include/xo/reader/exprstate.hpp | 3 +-- src/reader/expect_formal_arglist_xs.cpp | 5 ++--- src/reader/expect_formal_xs.cpp | 4 +++- src/reader/exprstate.cpp | 5 +++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/xo/reader/expect_formal_arglist_xs.hpp b/include/xo/reader/expect_formal_arglist_xs.hpp index 7eef773d..5bf75a8f 100644 --- a/include/xo/reader/expect_formal_arglist_xs.hpp +++ b/include/xo/reader/expect_formal_arglist_xs.hpp @@ -58,8 +58,7 @@ namespace xo { virtual void on_leftparen_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_formal(const rp & formal, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_comma_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 3c5e2e6a..8a7cf0d4 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -110,8 +110,7 @@ namespace xo { /** update exprstate when expecting a formal parameter **/ virtual void on_formal(const rp & formal, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** update expression when epecting a formal parameter list **/ virtual void on_formal_arglist(const std::vector> & argl, diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index dc400aeb..3dcd2c2e 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -64,14 +64,13 @@ namespace xo { void expect_formal_arglist_xs::on_formal(const rp & formal, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { if (farglxs_type_ == formalarglstatetype::argl_1a) { this->farglxs_type_ = formalarglstatetype::argl_1b; this->argl_.push_back(formal); } else { - exprstate::on_formal(formal, p_stack, p_emit_expr); + exprstate::on_formal(formal, p_psm); } } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 3455de23..24484b5b 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -91,7 +91,9 @@ namespace xo { rp var = Variable::make(result_.name(), result_.td()); - p_stack->top_exprstate().on_formal(var, p_stack, p_emit_expr); + parserstatemachine psm(p_stack, p_emit_expr); + + p_stack->top_exprstate().on_formal(var, &psm); } else { exprstate::on_typedescr(td, p_stack, p_emit_expr); } diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index c9d14c82..013f88a5 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -104,14 +104,15 @@ namespace xo { void exprstate::on_formal(const rp & formal, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { /* returning type description to something that wants it */ constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + auto p_stack = p_psm->p_stack_; + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); From 370722b086411c96e9c46939edc37dbb87b6f4d5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 11:51:45 -0400 Subject: [PATCH 159/191] xo-parser: parserstatemachine -> consolidate on_typedescr() args --- include/xo/reader/define_xs.hpp | 3 +-- include/xo/reader/expect_formal_xs.hpp | 3 +-- include/xo/reader/exprseq_xs.hpp | 3 +-- include/xo/reader/exprstate.hpp | 3 +-- include/xo/reader/paren_xs.hpp | 3 +-- include/xo/reader/progress_xs.hpp | 3 +-- src/reader/define_xs.cpp | 5 ++--- src/reader/expect_formal_xs.cpp | 11 +++++------ src/reader/expect_type_xs.cpp | 3 +-- src/reader/exprseq_xs.cpp | 3 +-- src/reader/exprstate.cpp | 5 +++-- src/reader/paren_xs.cpp | 3 +-- src/reader/progress_xs.cpp | 3 +-- 13 files changed, 20 insertions(+), 31 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 9e616b31..6e3da294 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -81,8 +81,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_def_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp index b757f6f5..c1b2e0d4 100644 --- a/include/xo/reader/expect_formal_xs.hpp +++ b/include/xo/reader/expect_formal_xs.hpp @@ -65,8 +65,7 @@ namespace xo { #endif virtual void on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index a5576001..2d2cec7b 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -31,8 +31,7 @@ namespace xo { // ----- victory methods ----- virtual void on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_expr(ref::brw expr, exprstatestack * p_stack, rp * p_emit_expr) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 8a7cf0d4..f52cd65e 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -105,8 +105,7 @@ namespace xo { /** update exprstate when expeccting a typedescr **/ virtual void on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** update exprstate when expecting a formal parameter **/ virtual void on_formal(const rp & formal, diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index b4225f4e..c250f020 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -41,8 +41,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_typedescr(TypeDescr td, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void on_def_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 965da117..92f3df04 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -61,8 +61,7 @@ namespace xo { virtual void on_symbol_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) override; + parserstatemachine * p_psm) override; virtual void on_def_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 0f5561dc..6bc17c13 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -73,8 +73,7 @@ namespace xo { void define_xs::on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { if (this->defxs_type_ == defexprstatetype::def_3) { this->defxs_type_ = defexprstatetype::def_4; @@ -85,7 +84,7 @@ namespace xo { return; } else { - exprstate::on_typedescr(td, p_stack, p_emit_expr); + exprstate::on_typedescr(td, p_psm); } } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 24484b5b..99275c02 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -80,9 +80,10 @@ namespace xo { void expect_formal_xs::on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { + auto p_stack = p_psm->p_stack_; + if (this->formalxs_type_ == formalstatetype::formal_2) { this->result_.assign_td(td); @@ -91,11 +92,9 @@ namespace xo { rp var = Variable::make(result_.name(), result_.td()); - parserstatemachine psm(p_stack, p_emit_expr); - - p_stack->top_exprstate().on_formal(var, &psm); + p_stack->top_exprstate().on_formal(var, p_psm); } else { - exprstate::on_typedescr(td, p_stack, p_emit_expr); + exprstate::on_typedescr(td, p_psm); } } diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index 11ab04ed..90f2932a 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -33,7 +33,6 @@ namespace xo { const char * c_self_name = "expect_type_xs::on_symbol_token"; auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; TypeDescr td = nullptr; @@ -59,7 +58,7 @@ namespace xo { } std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); + p_stack->top_exprstate().on_typedescr(td, p_psm); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 76722e5b..2d9d7053 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -51,8 +51,7 @@ namespace xo { void exprseq_xs::on_typedescr(TypeDescr /*td*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { /* unreachable - typedescr should never get delivered to exprseq */ assert(false); diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 013f88a5..de77cb52 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -83,14 +83,15 @@ namespace xo { void exprstate::on_typedescr(TypeDescr td, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { /* returning type description to something that wants it */ constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + auto p_stack = p_psm->p_stack_; + log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 8f6dff50..a536612c 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -92,8 +92,7 @@ namespace xo { void paren_xs::on_typedescr(TypeDescr /*td*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { assert(false); return; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 12f62740..d319bcf1 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -175,8 +175,7 @@ namespace xo { void progress_xs::on_typedescr(TypeDescr /*td*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { /* unreachable */ assert(false); From 355f73b2a1e7dcd5c9084ca4c649e0732f00013b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 11:55:11 -0400 Subject: [PATCH 160/191] xo-reader: parserstatemachine -> consolidate on_symbol() args --- include/xo/reader/define_xs.hpp | 3 +-- include/xo/reader/expect_formal_xs.hpp | 3 +-- include/xo/reader/exprstate.hpp | 3 +-- include/xo/reader/paren_xs.hpp | 3 +-- src/reader/define_xs.cpp | 5 ++--- src/reader/expect_formal_xs.cpp | 7 ++----- src/reader/expect_symbol_xs.cpp | 4 +--- src/reader/exprstate.cpp | 3 +-- src/reader/paren_xs.cpp | 3 +-- 9 files changed, 11 insertions(+), 23 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 6e3da294..50c76da5 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -78,8 +78,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_symbol(const std::string & symbol_name, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, parserstatemachine * p_psm) override; virtual void on_def_token(const token_type & tk, diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp index c1b2e0d4..64663239 100644 --- a/include/xo/reader/expect_formal_xs.hpp +++ b/include/xo/reader/expect_formal_xs.hpp @@ -50,8 +50,7 @@ namespace xo { static void start(exprstatestack * p_stack); virtual void on_symbol(const std::string & symbol_name, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index f52cd65e..0f9362ab 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -100,8 +100,7 @@ namespace xo { /** update exprstate when expecting a symbol **/ virtual void on_symbol(const std::string & symbol, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** update exprstate when expeccting a typedescr **/ virtual void on_typedescr(TypeDescr td, diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index c250f020..a45a516a 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -38,8 +38,7 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_symbol(const std::string & symbol, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, parserstatemachine * p_psm) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 6bc17c13..30938ce7 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -59,15 +59,14 @@ namespace xo { void define_xs::on_symbol(const std::string & symbol_name, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { if (this->defxs_type_ == defexprstatetype::def_1) { this->defxs_type_ = defexprstatetype::def_2; this->def_expr_->assign_lhs_name(symbol_name); return; } else { - exprstate::on_symbol(symbol_name, p_stack, p_emit_expr); + exprstate::on_symbol(symbol_name, p_psm); } } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 99275c02..94120e79 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -49,16 +49,13 @@ namespace xo { void expect_formal_xs::on_symbol(const std::string & symbol_name, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { if (this->formalxs_type_ == formalstatetype::formal_0) { this->formalxs_type_ = formalstatetype::formal_1; this->result_.assign_name(symbol_name); } else { - exprstate::on_symbol(symbol_name, - p_stack, - p_emit_expr); + exprstate::on_symbol(symbol_name, p_psm); } } diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index 12334e73..bae85927 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -28,7 +28,6 @@ namespace xo { parserstatemachine * p_psm) { auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; /* have to do pop first, before sending symbol to * the o.g. symbol-requester @@ -36,8 +35,7 @@ namespace xo { std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_symbol(tk.text(), - p_stack, p_emit_expr); + p_stack->top_exprstate().on_symbol(tk.text(), p_psm); return; } } /*namespace scm*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index de77cb52..db501154 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -360,8 +360,7 @@ namespace xo { void exprstate::on_symbol(const std::string & symbol_name, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { /* unreachable - derived class that can receive * will override this method diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index a536612c..6f94b37f 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -207,8 +207,7 @@ namespace xo { void paren_xs::on_symbol(const std::string & /*symbol_name*/, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { switch(this->parenxs_type_) { case parenexprstatetype::lparen_0: From bdf75d5620fab76d6a4df17359829939be573074 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 12:17:26 -0400 Subject: [PATCH 161/191] xo-reader: parserstatemachine -> consolidate on_expr() args --- include/xo/reader/define_xs.hpp | 3 +-- include/xo/reader/expect_expr_xs.hpp | 3 +-- include/xo/reader/exprseq_xs.hpp | 3 +-- include/xo/reader/exprstate.hpp | 3 +-- include/xo/reader/lambda_xs.hpp | 3 +-- include/xo/reader/paren_xs.hpp | 3 +-- include/xo/reader/progress_xs.hpp | 3 +-- src/reader/define_xs.cpp | 10 +++------- src/reader/expect_expr_xs.cpp | 8 +++----- src/reader/exprseq_xs.cpp | 6 ++++-- src/reader/exprstate.cpp | 3 +-- src/reader/lambda_xs.cpp | 8 +++----- src/reader/paren_xs.cpp | 8 ++++---- src/reader/progress_xs.cpp | 12 ++++-------- 14 files changed, 29 insertions(+), 47 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 50c76da5..ebb7b161 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -75,8 +75,7 @@ namespace xo { defexprstatetype defxs_type() const { return defxs_type_; } virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_symbol(const std::string & symbol_name, parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 3808e7bc..90477c72 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -33,8 +33,7 @@ namespace xo { /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; private: static std::unique_ptr make(); diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 2d2cec7b..e1808a15 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -33,8 +33,7 @@ namespace xo { virtual void on_typedescr(TypeDescr td, parserstatemachine * p_psm) override; virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; private: static std::unique_ptr make(); diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 0f9362ab..d2c58d67 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -95,8 +95,7 @@ namespace xo { /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr); + parserstatemachine * p_psm); /** update exprstate when expecting a symbol **/ virtual void on_symbol(const std::string & symbol, diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index b60f14a6..5ad0adfb 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -47,8 +47,7 @@ namespace xo { virtual void on_formal_arglist(const std::vector> & argl, parserstatemachine * p_psm) override; virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_semicolon_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index a45a516a..0fd6bf86 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -35,8 +35,7 @@ namespace xo { bool admits_rightparen() const; virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_symbol(const std::string & symbol, parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 92f3df04..6436b117 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -56,8 +56,7 @@ namespace xo { bool admits_f64() const; virtual void on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) override; + parserstatemachine * p_psm) override; virtual void on_symbol_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 30938ce7..58006125 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -30,8 +30,7 @@ namespace xo { void define_xs::on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { if (this->defxs_type_ == defexprstatetype::def_5) { /* have all the ingredients to create an expression @@ -54,7 +53,7 @@ namespace xo { return; } - exprstate::on_expr(expr, p_stack, p_emit_expr); + exprstate::on_expr(expr, p_psm); } void @@ -133,7 +132,6 @@ namespace xo { scope log(XO_DEBUG(c_debug_flag)); auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; //constexpr const char * self_name = "exprstate::on_semicolon"; @@ -142,9 +140,7 @@ namespace xo { std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); + p_stack->top_exprstate().on_expr(expr, p_psm); } else { exprstate::on_semicolon_token(tk, p_psm); } diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 123f52da..74afec19 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -118,8 +118,7 @@ namespace xo { void expect_expr_xs::on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -127,12 +126,11 @@ namespace xo { log && log(xtag("exstype", this->exs_type_), xtag("expr", expr)); + auto p_stack = p_psm->p_stack_; std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); + p_stack->top_exprstate().on_expr(expr, p_psm); } /*on_expr*/ } /*namespace scm*/ diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 2d9d7053..44f28624 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -3,6 +3,7 @@ #include "exprseq_xs.hpp" #include "define_xs.hpp" #include "expect_symbol_xs.hpp" +#include "parserstatemachine.hpp" namespace xo { namespace scm { @@ -60,8 +61,7 @@ namespace xo { void exprseq_xs::on_expr(ref::brw expr, - exprstatestack * /*p_stack*/, - rp * p_emit_expr) + parserstatemachine * p_psm) { /* toplevel expression sequence accepts an * arbitrary number of expressions. @@ -69,6 +69,8 @@ namespace xo { * parser::include_token() returns */ + auto p_emit_expr = p_psm->p_emit_expr_; + *p_emit_expr = expr.promote(); } /*on_expr*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index db501154..1b9644b6 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -346,8 +346,7 @@ namespace xo { void exprstate::on_expr(ref::brw expr, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 7aaf657d..fbde492a 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -59,14 +59,13 @@ namespace xo { void lambda_xs::on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * p_emit_expr) + parserstatemachine * p_psm) { if (lmxs_type_ == lambdastatetype::lm_2) { this->lmxs_type_ = lambdastatetype::lm_3; this->body_ = expr.promote(); } else { - exprstate::on_expr(expr, p_stack, p_emit_expr); + exprstate::on_expr(expr, p_psm); } } @@ -75,7 +74,6 @@ namespace xo { parserstatemachine * p_psm) { auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; if (lmxs_type_ == lambdastatetype::lm_3) { /* done! */ @@ -86,7 +84,7 @@ namespace xo { rp lm = Lambda::make(name, argl_, body_); - p_stack->top_exprstate().on_expr(lm, p_stack, p_emit_expr); + p_stack->top_exprstate().on_expr(lm, p_psm); p_stack->top_exprstate().on_semicolon_token(tk, p_psm); return; diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 6f94b37f..b9dde8f4 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -152,11 +152,10 @@ namespace xo { rp expr = this->gen_expr_; auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + p_stack->top_exprstate().on_expr(expr, p_psm); } } @@ -174,8 +173,7 @@ namespace xo { void paren_xs::on_expr(ref::brw expr, - exprstatestack * p_stack, - rp * /*p_emit_expr*/) + parserstatemachine * p_psm) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -186,6 +184,8 @@ namespace xo { switch (this->parenxs_type_) { case parenexprstatetype::lparen_0: { this->parenxs_type_ = parenexprstatetype::lparen_1; /* wants on_rightparen */ + auto p_stack = p_psm->p_stack_; + progress_xs::start(expr.promote(), p_stack); return; diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index d319bcf1..6b474db3 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -134,8 +134,7 @@ namespace xo { void progress_xs::on_expr(ref::brw expr, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) + parserstatemachine * /*p_psm*/) { /* note: previous token probably an operator, * handled from progress_xs::on_operator_token(), @@ -200,15 +199,13 @@ namespace xo { scope log(XO_DEBUG(c_debug_flag)); auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; rp expr = this->assemble_expr(); std::unique_ptr self = p_stack->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); + p_stack->top_exprstate().on_expr(expr, p_psm); + /* control here on input like: * (1.234; * @@ -261,7 +258,6 @@ namespace xo { constexpr const char * self_name = "progress_xs::on_rightparen"; auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; /* stack may be something like: * @@ -286,7 +282,7 @@ namespace xo { log && log(xtag("stack", p_stack)); - p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + p_stack->top_exprstate().on_expr(expr, p_psm); /* now deliver rightparen */ p_stack->top_exprstate().on_rightparen_token(tk, p_psm); From bcb2af4a56d394ee7f04fe8d4df6c515aa9c3273 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 13:48:47 -0400 Subject: [PATCH 162/191] xo-reader: split: exprstatestack to own .*pp files --- include/xo/reader/exprstate.hpp | 53 ------------------ include/xo/reader/exprstatestack.hpp | 66 +++++++++++++++++++++++ include/xo/reader/parser.hpp | 2 +- src/reader/CMakeLists.txt | 1 + src/reader/define_xs.cpp | 1 + src/reader/expect_expr_xs.cpp | 1 + src/reader/expect_formal_arglist_xs.cpp | 3 +- src/reader/expect_formal_xs.cpp | 1 + src/reader/expect_symbol_xs.cpp | 1 + src/reader/expect_type_xs.cpp | 1 + src/reader/exprseq_xs.cpp | 3 +- src/reader/exprstate.cpp | 62 +-------------------- src/reader/exprstatestack.cpp | 71 +++++++++++++++++++++++++ src/reader/lambda_xs.cpp | 1 + src/reader/paren_xs.cpp | 1 + src/reader/progress_xs.cpp | 1 + 16 files changed, 152 insertions(+), 117 deletions(-) create mode 100644 include/xo/reader/exprstatestack.hpp create mode 100644 src/reader/exprstatestack.cpp diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index d2c58d67..3e79dee4 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -171,59 +171,6 @@ namespace xo { x.print(os); return os; } - - // ----- exprstatestack ----- - - /** @class exprstatestack - * @brief A stack of exprstate objects - **/ - class exprstatestack { - public: - exprstatestack() {} - - bool empty() const { return stack_.empty(); } - std::size_t size() const { return stack_.size(); } - - exprstate & top_exprstate(); - void push_exprstate(std::unique_ptr exs); - std::unique_ptr pop_exprstate(); - - /** relative to top-of-stack. - * 0 -> top (last in), z-1 -> bottom (first in) - **/ - std::unique_ptr & operator[](std::size_t i) { - std::size_t z = stack_.size(); - - assert(i < z); - - return stack_[z - i - 1]; - } - - const std::unique_ptr & operator[](std::size_t i) const { - std::size_t z = stack_.size(); - - assert(i < z); - - return stack_[z - i - 1]; - } - - void print (std::ostream & os) const; - - private: - std::vector> stack_; - }; - - inline std::ostream & - operator<< (std::ostream & os, const exprstatestack & x) { - x.print(os); - return os; - } - - inline std::ostream & - operator<< (std::ostream & os, const exprstatestack * x) { - x->print(os); - return os; - } } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader/exprstatestack.hpp b/include/xo/reader/exprstatestack.hpp new file mode 100644 index 00000000..c5ee0894 --- /dev/null +++ b/include/xo/reader/exprstatestack.hpp @@ -0,0 +1,66 @@ +/* file exprstatestack.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" + +namespace xo { + namespace scm { + /** @class exprstatestack + * @brief A stack of exprstate objects + **/ + class exprstatestack { + public: + exprstatestack() {} + + bool empty() const { return stack_.empty(); } + std::size_t size() const { return stack_.size(); } + + exprstate & top_exprstate(); + void push_exprstate(std::unique_ptr exs); + std::unique_ptr pop_exprstate(); + + /** relative to top-of-stack. + * 0 -> top (last in), z-1 -> bottom (first in) + **/ + std::unique_ptr & operator[](std::size_t i) { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + const std::unique_ptr & operator[](std::size_t i) const { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + void print (std::ostream & os) const; + + private: + std::vector> stack_; + }; + + inline std::ostream & + operator<< (std::ostream & os, const exprstatestack & x) { + x.print(os); + return os; + } + + inline std::ostream & + operator<< (std::ostream & os, const exprstatestack * x) { + x->print(os); + return os; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end exprstatestack.hpp */ diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index 3211fd0c..dae3091f 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -5,7 +5,7 @@ #pragma once -#include "exprstate.hpp" +#include "exprstatestack.hpp" #include namespace xo { diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 32a4cd5a..0a2f7704 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -5,6 +5,7 @@ set(SELF_SRCS parser.cpp reader.cpp exprstate.cpp + exprstatestack.cpp define_xs.cpp progress_xs.cpp paren_xs.cpp diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 58006125..f0e7924f 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -1,6 +1,7 @@ /* @file define_xs.cpp */ #include "define_xs.hpp" +#include "exprstatestack.hpp" #include "parserstatemachine.hpp" #include "expect_symbol_xs.hpp" #include "expect_expr_xs.hpp" diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 74afec19..3c5001ae 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -5,6 +5,7 @@ #include "expect_expr_xs.hpp" #include "parserstatemachine.hpp" +#include "exprstatestack.hpp" #include "lambda_xs.hpp" #include "paren_xs.hpp" #include "progress_xs.hpp" diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 3dcd2c2e..1eef0563 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -4,9 +4,10 @@ */ #include "expect_formal_arglist_xs.hpp" +#include "parserstatemachine.hpp" +#include "exprstatestack.hpp" #include "expect_formal_xs.hpp" #include "expect_symbol_xs.hpp" -#include "parserstatemachine.hpp" #include "xo/expression/Variable.hpp" #include "xo/indentlog/print/vector.hpp" diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 94120e79..8bdcf6b1 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -7,6 +7,7 @@ #include "expect_symbol_xs.hpp" #include "expect_type_xs.hpp" #include "parserstatemachine.hpp" +#include "exprstatestack.hpp" #include "xo/expression/Variable.hpp" namespace xo { diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index bae85927..591f4ca8 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -5,6 +5,7 @@ #include "expect_symbol_xs.hpp" #include "parserstatemachine.hpp" +#include "exprstatestack.hpp" namespace xo { namespace scm { diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index 90f2932a..97365062 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -5,6 +5,7 @@ #include "expect_type_xs.hpp" #include "parserstatemachine.hpp" +#include "exprstatestack.hpp" #include "xo/reflect/Reflect.hpp" namespace xo { diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 44f28624..0db1a394 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -1,9 +1,10 @@ /* @file exprseq_xs.cpp */ #include "exprseq_xs.hpp" +#include "parserstatemachine.hpp" +#include "exprstatestack.hpp" #include "define_xs.hpp" #include "expect_symbol_xs.hpp" -#include "parserstatemachine.hpp" namespace xo { namespace scm { diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 1b9644b6..9a2917e0 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -1,6 +1,7 @@ /* @file exprstate.cpp */ #include "exprstate.hpp" +#include "exprstatestack.hpp" #include "parserstatemachine.hpp" //#include "formal_arg.hpp" #include "xo/expression/Variable.hpp" @@ -390,67 +391,6 @@ namespace xo { xtag("token", tk), xtag("state", *this))); } - - // ----- exprstatestack ----- - - exprstate & - exprstatestack::top_exprstate() { - std::size_t z = stack_.size(); - - if (z == 0) { - throw std::runtime_error - ("parser::top_exprstate: unexpected empty stack"); - } - - return *(stack_[z-1]); - } - - void - exprstatestack::push_exprstate(std::unique_ptr exs) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag), - xtag("exs", *exs)); - - std::size_t z = stack_.size(); - - stack_.resize(z+1); - - stack_[z] = std::move(exs); - } - - std::unique_ptr - exprstatestack::pop_exprstate() { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag), - xtag("top.exstype", top_exprstate().exs_type())); - - std::size_t z = stack_.size(); - - if (z > 0) { - std::unique_ptr top = std::move(stack_[z-1]); - - stack_.resize(z-1); - - return top; - } else { - return nullptr; - } - } - - void - exprstatestack::print(std::ostream & os) const { - os << "" << std::endl; - } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstatestack.cpp b/src/reader/exprstatestack.cpp new file mode 100644 index 00000000..07ca85bb --- /dev/null +++ b/src/reader/exprstatestack.cpp @@ -0,0 +1,71 @@ +/* file exprstatestack.cpp + * + * author: Roland Conybeare + */ + +#include "exprstatestack.hpp" + +namespace xo { + namespace scm { + exprstate & + exprstatestack::top_exprstate() { + std::size_t z = stack_.size(); + + if (z == 0) { + throw std::runtime_error + ("parser::top_exprstate: unexpected empty stack"); + } + + return *(stack_[z-1]); + } + + void + exprstatestack::push_exprstate(std::unique_ptr exs) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("exs", *exs)); + + std::size_t z = stack_.size(); + + stack_.resize(z+1); + + stack_[z] = std::move(exs); + } + + std::unique_ptr + exprstatestack::pop_exprstate() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("top.exstype", top_exprstate().exs_type())); + + std::size_t z = stack_.size(); + + if (z > 0) { + std::unique_ptr top = std::move(stack_[z-1]); + + stack_.resize(z-1); + + return top; + } else { + return nullptr; + } + } + + void + exprstatestack::print(std::ostream & os) const { + os << "" << std::endl; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end exprstatestack.cpp */ diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index fbde492a..90270b07 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -2,6 +2,7 @@ #include "lambda_xs.hpp" #include "parserstatemachine.hpp" +#include "exprstatestack.hpp" #include "expect_formal_arglist_xs.hpp" #include "expect_expr_xs.hpp" #include "xo/expression/Lambda.hpp" diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index b9dde8f4..96318e4c 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -2,6 +2,7 @@ #include "paren_xs.hpp" #include "parserstatemachine.hpp" +#include "exprstatestack.hpp" #include "progress_xs.hpp" #include "expect_expr_xs.hpp" diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 6b474db3..d1bae5c3 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -1,6 +1,7 @@ /* @file progress_xs.cpp */ #include "progress_xs.hpp" +#include "exprstatestack.hpp" #include "expect_expr_xs.hpp" #include "parserstatemachine.hpp" #include "xo/expression/Apply.hpp" From 4232da4ef2c9fadf86d0cd5ab25d3c280320bef0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 13:54:58 -0400 Subject: [PATCH 163/191] xo-reader: streamline: + parserstatemachine::pop_exprstate() + use --- include/xo/reader/parserstatemachine.hpp | 2 ++ src/reader/CMakeLists.txt | 1 + src/reader/define_xs.cpp | 2 +- src/reader/expect_expr_xs.cpp | 4 ++-- src/reader/expect_formal_arglist_xs.cpp | 2 +- src/reader/expect_formal_xs.cpp | 2 +- src/reader/expect_symbol_xs.cpp | 2 +- src/reader/expect_type_xs.cpp | 2 +- src/reader/lambda_xs.cpp | 2 +- src/reader/paren_xs.cpp | 2 +- src/reader/parserstatemachine.cpp | 19 +++++++++++++++++++ src/reader/progress_xs.cpp | 10 +++++----- 12 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 src/reader/parserstatemachine.cpp diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index 55b285ee..060ec841 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -25,6 +25,8 @@ namespace xo { rp * p_emit_expr) : p_stack_{p_stack}, p_emit_expr_{p_emit_expr} {} + std::unique_ptr pop_exprstate(); + public: exprstatestack * p_stack_; rp * p_emit_expr_; diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 0a2f7704..5edbb2e4 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -3,6 +3,7 @@ set(SELF_LIB xo_reader) set(SELF_SRCS parser.cpp + parserstatemachine.cpp reader.cpp exprstate.cpp exprstatestack.cpp diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index f0e7924f..a4d9f1b6 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -139,7 +139,7 @@ namespace xo { if (this->defxs_type_ == defexprstatetype::def_6) { rp expr = this->def_expr_; - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_psm); } else { diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 3c5001ae..538bd45c 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -91,7 +91,7 @@ namespace xo { #endif #ifdef LATER - p_stack->pop_exprstate(); + p_psm->pop_exprstate(); p_stack->top_exprstate().on_symbol(tk.text(), p_stack, p_emit_expr); #endif @@ -129,7 +129,7 @@ namespace xo { auto p_stack = p_psm->p_stack_; - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_psm); } /*on_expr*/ diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 1eef0563..1dc27429 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -96,7 +96,7 @@ namespace xo { auto p_stack = p_psm->p_stack_; if (farglxs_type_ == formalarglstatetype::argl_1b) { - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); p_stack->top_exprstate().on_formal_arglist(this->argl_, p_psm); } else { diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 8bdcf6b1..2cb2e9be 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -85,7 +85,7 @@ namespace xo { if (this->formalxs_type_ == formalstatetype::formal_2) { this->result_.assign_td(td); - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); rp var = Variable::make(result_.name(), result_.td()); diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index 591f4ca8..77219efb 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -33,7 +33,7 @@ namespace xo { /* have to do pop first, before sending symbol to * the o.g. symbol-requester */ - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); p_stack->top_exprstate().on_symbol(tk.text(), p_psm); diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index 97365062..9bbf4e18 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -58,7 +58,7 @@ namespace xo { xtag("typename", tk.text()))); } - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); p_stack->top_exprstate().on_typedescr(td, p_psm); } } /*namespace scm*/ diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 90270b07..80aac681 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -79,7 +79,7 @@ namespace xo { if (lmxs_type_ == lambdastatetype::lm_3) { /* done! */ - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); std::string name = "fixmename"; diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 96318e4c..c39a89cb 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -154,7 +154,7 @@ namespace xo { auto p_stack = p_psm->p_stack_; - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_psm); } diff --git a/src/reader/parserstatemachine.cpp b/src/reader/parserstatemachine.cpp new file mode 100644 index 00000000..6d47b909 --- /dev/null +++ b/src/reader/parserstatemachine.cpp @@ -0,0 +1,19 @@ +/* file parserstatemachine.cpp + * + * author: Roland Conybeare + */ + +#include "parserstatemachine.hpp" +#include "exprstatestack.hpp" + +namespace xo { + namespace scm { + std::unique_ptr + parserstatemachine::pop_exprstate() { + return p_stack_->pop_exprstate(); + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end parserstatemachine.cpp */ diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index d1bae5c3..3431e689 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -154,7 +154,7 @@ namespace xo { assert(result.get()); /* this expression complete.. */ - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); /* ..but more operators could follow, so don't commit yet */ p_stack->push_exprstate(progress_xs::make(result)); @@ -203,7 +203,7 @@ namespace xo { rp expr = this->assemble_expr(); - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); p_stack->top_exprstate().on_expr(expr, p_psm); @@ -274,7 +274,7 @@ namespace xo { /* right paren confirms stack expression */ rp expr = this->assemble_expr(); - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); if (p_stack->empty()) { throw std::runtime_error(tostr(self_name, @@ -344,7 +344,7 @@ namespace xo { auto expr = this->assemble_expr(); /* 2. remove from stack */ - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); /* 3. replace with new progress_xs: */ progress_xs::start(expr, op2, p_stack); @@ -365,7 +365,7 @@ namespace xo { * 4. expect_rhs_expression */ - std::unique_ptr self = p_stack->pop_exprstate(); + std::unique_ptr self = p_psm->pop_exprstate(); /* 1. replace with nested incomplete infix exprs */ progress_xs::start(lhs_, op_type_, p_stack); From b988bc67903fbb7e30dc572531b1a7431f851a30 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 15:55:36 -0400 Subject: [PATCH 164/191] xo-reader: parsestatemachine.top_exprstate() + use to simplify --- include/xo/reader/parserstatemachine.hpp | 1 + src/reader/define_xs.cpp | 6 ++---- src/reader/expect_expr_xs.cpp | 8 +++----- src/reader/expect_formal_arglist_xs.cpp | 4 +--- src/reader/expect_formal_xs.cpp | 4 +--- src/reader/expect_symbol_xs.cpp | 4 +--- src/reader/expect_type_xs.cpp | 4 +--- src/reader/exprstate.cpp | 16 ++++------------ src/reader/lambda_xs.cpp | 6 ++---- src/reader/paren_xs.cpp | 8 ++------ src/reader/progress_xs.cpp | 10 ++++------ 11 files changed, 22 insertions(+), 49 deletions(-) diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index 060ec841..c5222194 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -26,6 +26,7 @@ namespace xo { : p_stack_{p_stack}, p_emit_expr_{p_emit_expr} {} std::unique_ptr pop_exprstate(); + exprstate & top_exprstate(); public: exprstatestack * p_stack_; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index a4d9f1b6..4672bc96 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -20,7 +20,7 @@ namespace xo { auto p_stack = p_psm->p_stack_; p_stack->push_exprstate(define_xs::make()); - p_stack->top_exprstate().on_def_token(token_type::def(), p_psm); + p_psm->top_exprstate().on_def_token(token_type::def(), p_psm); } define_xs::define_xs(rp def_expr) @@ -132,8 +132,6 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - auto p_stack = p_psm->p_stack_; - //constexpr const char * self_name = "exprstate::on_semicolon"; if (this->defxs_type_ == defexprstatetype::def_6) { @@ -141,7 +139,7 @@ namespace xo { std::unique_ptr self = p_psm->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, p_psm); + p_psm->top_exprstate().on_expr(expr, p_psm); } else { exprstate::on_semicolon_token(tk, p_psm); } diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 538bd45c..bdd66b1a 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -46,7 +46,7 @@ namespace xo { /* push lparen_0 to remember to look for subsequent rightparen. */ lambda_xs::start(p_stack, p_emit_expr); - //p_stack->top_exprstate().on_lambda_token(tk, p_stack, p_emit_expr); + //p_psm->top_exprstate().on_lambda_token(tk, p_stack, p_emit_expr); //p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); } @@ -92,7 +92,7 @@ namespace xo { #ifdef LATER p_psm->pop_exprstate(); - p_stack->top_exprstate().on_symbol(tk.text(), + p_psm->top_exprstate().on_symbol(tk.text(), p_stack, p_emit_expr); #endif return; @@ -127,11 +127,9 @@ namespace xo { log && log(xtag("exstype", this->exs_type_), xtag("expr", expr)); - auto p_stack = p_psm->p_stack_; - std::unique_ptr self = p_psm->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, p_psm); + p_psm->top_exprstate().on_expr(expr, p_psm); } /*on_expr*/ } /*namespace scm*/ diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 1dc27429..2f9f0fce 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -93,12 +93,10 @@ namespace xo { expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (farglxs_type_ == formalarglstatetype::argl_1b) { std::unique_ptr self = p_psm->pop_exprstate(); - p_stack->top_exprstate().on_formal_arglist(this->argl_, p_psm); + p_psm->top_exprstate().on_formal_arglist(this->argl_, p_psm); } else { exprstate::on_rightparen_token(tk, p_psm); } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 2cb2e9be..7bd8773d 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -80,8 +80,6 @@ namespace xo { expect_formal_xs::on_typedescr(TypeDescr td, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (this->formalxs_type_ == formalstatetype::formal_2) { this->result_.assign_td(td); @@ -90,7 +88,7 @@ namespace xo { rp var = Variable::make(result_.name(), result_.td()); - p_stack->top_exprstate().on_formal(var, p_psm); + p_psm->top_exprstate().on_formal(var, p_psm); } else { exprstate::on_typedescr(td, p_psm); } diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index 77219efb..3c8bfd2d 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -28,15 +28,13 @@ namespace xo { expect_symbol_xs::on_symbol_token(const token_type & tk, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - /* have to do pop first, before sending symbol to * the o.g. symbol-requester */ std::unique_ptr self = p_psm->pop_exprstate(); - p_stack->top_exprstate().on_symbol(tk.text(), p_psm); + p_psm->top_exprstate().on_symbol(tk.text(), p_psm); return; } } /*namespace scm*/ diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index 9bbf4e18..f8efd265 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -33,8 +33,6 @@ namespace xo { { const char * c_self_name = "expect_type_xs::on_symbol_token"; - auto p_stack = p_psm->p_stack_; - TypeDescr td = nullptr; /* TODO: replace with typetable lookup */ @@ -59,7 +57,7 @@ namespace xo { } std::unique_ptr self = p_psm->pop_exprstate(); - p_stack->top_exprstate().on_typedescr(td, p_psm); + p_psm->top_exprstate().on_typedescr(td, p_psm); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 9a2917e0..9721ede2 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -73,9 +73,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - auto p_stack = p_psm->p_stack_; - - log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); + log && log(xtag("exstype", p_psm->top_exprstate().exs_type())); constexpr const char * c_self_name = "exprstate::on_symbol_token"; @@ -91,10 +89,8 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - auto p_stack = p_psm->p_stack_; - log && log(xtag("exstype", - p_stack->top_exprstate().exs_type())); + p_psm->top_exprstate().exs_type())); constexpr const char * c_self_name = "exprstate::on_typedescr"; @@ -113,10 +109,8 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - auto p_stack = p_psm->p_stack_; - log && log(xtag("exstype", - p_stack->top_exprstate().exs_type())); + p_psm->top_exprstate().exs_type())); constexpr const char * c_self_name = "exprstate::on_formal"; @@ -135,10 +129,8 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - auto p_stack = p_psm->p_stack_; - log && log(xtag("exstype", - p_stack->top_exprstate().exs_type())); + p_psm->top_exprstate().exs_type())); constexpr const char * c_self_name = "exprstate::on_formal_arglist"; diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 80aac681..1ad6f401 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -74,8 +74,6 @@ namespace xo { lambda_xs::on_semicolon_token(const token_type & tk, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (lmxs_type_ == lambdastatetype::lm_3) { /* done! */ @@ -85,8 +83,8 @@ namespace xo { rp lm = Lambda::make(name, argl_, body_); - p_stack->top_exprstate().on_expr(lm, p_psm); - p_stack->top_exprstate().on_semicolon_token(tk, p_psm); + p_psm->top_exprstate().on_expr(lm, p_psm); + p_psm->top_exprstate().on_semicolon_token(tk, p_psm); return; } diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index c39a89cb..d1d9535c 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -80,9 +80,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - auto p_stack = p_psm->p_stack_; - - log && log(xtag("exstype", p_stack->top_exprstate().exs_type())); + log && log(xtag("exstype", p_psm->top_exprstate().exs_type())); //constexpr const char * self_name = "paren_xs::on_symbol"; @@ -152,11 +150,9 @@ namespace xo { if (this->parenxs_type_ == parenexprstatetype::lparen_1) { rp expr = this->gen_expr_; - auto p_stack = p_psm->p_stack_; - std::unique_ptr self = p_psm->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, p_psm); + p_psm->top_exprstate().on_expr(expr, p_psm); } } diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 3431e689..6f62f853 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -199,13 +199,11 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - auto p_stack = p_psm->p_stack_; - rp expr = this->assemble_expr(); std::unique_ptr self = p_psm->pop_exprstate(); - p_stack->top_exprstate().on_expr(expr, p_psm); + p_psm->top_exprstate().on_expr(expr, p_psm); /* control here on input like: * (1.234; @@ -222,7 +220,7 @@ namespace xo { * f. now deliver semicolon; [lparen_1] rejects */ - p_stack->top_exprstate().on_semicolon_token(tk, p_psm); + p_psm->top_exprstate().on_semicolon_token(tk, p_psm); } void @@ -283,10 +281,10 @@ namespace xo { log && log(xtag("stack", p_stack)); - p_stack->top_exprstate().on_expr(expr, p_psm); + p_psm->top_exprstate().on_expr(expr, p_psm); /* now deliver rightparen */ - p_stack->top_exprstate().on_rightparen_token(tk, p_psm); + p_psm->top_exprstate().on_rightparen_token(tk, p_psm); } namespace { From fa9f4967f2389619baa82b436b7031f1f5298594 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 15:58:35 -0400 Subject: [PATCH 165/191] xo-reader: + parserstatemachine.push_exprstate(); simplify lambda_xs --- include/xo/reader/lambda_xs.hpp | 2 +- include/xo/reader/parserstatemachine.hpp | 1 + src/reader/expect_expr_xs.cpp | 7 +------ src/reader/lambda_xs.cpp | 11 ++++------- src/reader/parserstatemachine.cpp | 10 ++++++++++ 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 5ad0adfb..79c084ab 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -40,7 +40,7 @@ namespace xo { public: lambda_xs(); - static void start(exprstatestack * p_stack, rp * p_emit_expr); + static void start(parserstatemachine * p_psm); virtual void on_lambda_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index c5222194..c7ca130c 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -27,6 +27,7 @@ namespace xo { std::unique_ptr pop_exprstate(); exprstate & top_exprstate(); + void push_exprstate(std::unique_ptr x); public: exprstatestack * p_stack_; diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index bdd66b1a..2ec95272 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -41,13 +41,8 @@ namespace xo { //constexpr const char * self_name = "exprstate::on_leftparen"; - auto p_stack = p_psm->p_stack_; - auto p_emit_expr = p_psm->p_emit_expr_; - /* push lparen_0 to remember to look for subsequent rightparen. */ - lambda_xs::start(p_stack, p_emit_expr); - //p_psm->top_exprstate().on_lambda_token(tk, p_stack, p_emit_expr); - //p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); + lambda_xs::start(p_psm); } void diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 1ad6f401..491ab908 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -17,14 +17,11 @@ namespace xo { } void - lambda_xs::start(exprstatestack * p_stack, - rp * p_emit_expr) + lambda_xs::start(parserstatemachine * p_psm) { - parserstatemachine psm(p_stack, p_emit_expr); - - p_stack->push_exprstate(lambda_xs::make()); - p_stack->top_exprstate() - .on_lambda_token(token_type::lambda(), &psm); + p_psm->push_exprstate(lambda_xs::make()); + p_psm->top_exprstate() + .on_lambda_token(token_type::lambda(), p_psm); } lambda_xs::lambda_xs() : exprstate(exprstatetype::lambdaexpr) {} diff --git a/src/reader/parserstatemachine.cpp b/src/reader/parserstatemachine.cpp index 6d47b909..103ac15b 100644 --- a/src/reader/parserstatemachine.cpp +++ b/src/reader/parserstatemachine.cpp @@ -12,6 +12,16 @@ namespace xo { parserstatemachine::pop_exprstate() { return p_stack_->pop_exprstate(); } + + exprstate & + parserstatemachine::top_exprstate() { + return p_stack_->top_exprstate(); + } + + void + parserstatemachine::push_exprstate(std::unique_ptr x) { + p_stack_->push_exprstate(std::move(x)); + } } /*namespace scm*/ } /*namespace xo*/ From f5a309d6116be6b0d1b1bfbe20a23fa3247a5622 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 15:59:42 -0400 Subject: [PATCH 166/191] xo-reader: simplify: define_xs::start() --- src/reader/define_xs.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 4672bc96..43d700b1 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -17,9 +17,7 @@ namespace xo { void define_xs::start(parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - - p_stack->push_exprstate(define_xs::make()); + p_psm->push_exprstate(define_xs::make()); p_psm->top_exprstate().on_def_token(token_type::def(), p_psm); } From c8f166acc84b6052752630cea142d64f1c6d11b6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 16:19:23 -0400 Subject: [PATCH 167/191] xo-reader: streamline exprseq_xs.start() using psm --- include/xo/reader/exprseq_xs.hpp | 2 +- src/reader/exprseq_xs.cpp | 4 ++-- src/reader/parser.cpp | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index e1808a15..05d0a6e3 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -18,7 +18,7 @@ namespace xo { public: exprseq_xs(); - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_psm); public: // ----- token input methods ----- diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 0db1a394..b934c2ef 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -15,9 +15,9 @@ namespace xo { } void - exprseq_xs::start(exprstatestack * p_stack) + exprseq_xs::start(parserstatemachine * p_psm) { - p_stack->push_exprstate(exprseq_xs::make()); + p_psm->push_exprstate(exprseq_xs::make()); } exprseq_xs::exprseq_xs() diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 9c9d373e..9301f1df 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -31,7 +31,11 @@ namespace xo { void parser::begin_translation_unit() { - exprseq_xs::start(&xs_stack_); + /* note: not using emit expr here */ + parserstatemachine psm(&xs_stack_, + nullptr /*p_emit_expr*/); + + exprseq_xs::start(&psm); } rp From 96c0bea2f54e4723f61878b5799ea272d3a715d8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 16:42:52 -0400 Subject: [PATCH 168/191] xo-reader: simplify expect_formal_xs, expect_symbol_xs --- include/xo/reader/expect_formal_xs.hpp | 2 +- include/xo/reader/expect_symbol_xs.hpp | 2 +- src/reader/define_xs.cpp | 2 +- src/reader/expect_formal_arglist_xs.cpp | 8 ++------ src/reader/expect_formal_xs.cpp | 6 +++--- src/reader/expect_symbol_xs.cpp | 4 ++-- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp index 64663239..97d781ee 100644 --- a/include/xo/reader/expect_formal_xs.hpp +++ b/include/xo/reader/expect_formal_xs.hpp @@ -47,7 +47,7 @@ namespace xo { public: expect_formal_xs(); - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_psm); virtual void on_symbol(const std::string & symbol_name, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/expect_symbol_xs.hpp b/include/xo/reader/expect_symbol_xs.hpp index 63740aeb..be4df5e4 100644 --- a/include/xo/reader/expect_symbol_xs.hpp +++ b/include/xo/reader/expect_symbol_xs.hpp @@ -20,7 +20,7 @@ namespace xo { static std::unique_ptr make(); - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_psm); virtual void on_symbol_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 43d700b1..460d98d2 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -97,7 +97,7 @@ namespace xo { if (this->defxs_type_ == defexprstatetype::def_0) { this->defxs_type_ = defexprstatetype::def_1; - expect_symbol_xs::start(p_psm->p_stack_); + expect_symbol_xs::start(p_psm); } else { exprstate::on_def_token(tk, p_psm); } diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 2f9f0fce..8e455413 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -52,12 +52,10 @@ namespace xo { expect_formal_arglist_xs::on_leftparen_token(const token_type & tk, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (farglxs_type_ == formalarglstatetype::argl_0) { this->farglxs_type_ = formalarglstatetype::argl_1a; /* TODO: refactor to have setup method on each exprstate */ - expect_formal_xs::start(p_stack); + expect_formal_xs::start(p_psm); } else { exprstate::on_leftparen_token(tk, p_psm); } @@ -79,11 +77,9 @@ namespace xo { expect_formal_arglist_xs::on_comma_token(const token_type & tk, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (farglxs_type_ == formalarglstatetype::argl_1b) { this->farglxs_type_ = formalarglstatetype::argl_1a; - expect_formal_xs::start(p_stack); + expect_formal_xs::start(p_psm); } else { exprstate::on_comma_token(tk, p_psm); } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index 7bd8773d..e60b77b0 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -38,10 +38,10 @@ namespace xo { } void - expect_formal_xs::start(exprstatestack * p_stack) { - p_stack->push_exprstate(expect_formal_xs::make()); + expect_formal_xs::start(parserstatemachine * p_psm) { + p_psm->push_exprstate(expect_formal_xs::make()); - expect_symbol_xs::start(p_stack); + expect_symbol_xs::start(p_psm); } expect_formal_xs::expect_formal_xs() diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index 3c8bfd2d..930d12b0 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -15,9 +15,9 @@ namespace xo { } void - expect_symbol_xs::start(exprstatestack * p_stack) + expect_symbol_xs::start(parserstatemachine * p_psm) { - p_stack->push_exprstate(expect_symbol_xs::make()); + p_psm->push_exprstate(expect_symbol_xs::make()); } expect_symbol_xs::expect_symbol_xs() From 6dcc0d420e0e16b31cf5967208bdcab7fd1212c6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 16:45:31 -0400 Subject: [PATCH 169/191] xo-reader: simplify expect_formal_arglist_xs.start() using psm --- include/xo/reader/expect_formal_arglist_xs.hpp | 2 +- src/reader/expect_formal_arglist_xs.cpp | 4 ++-- src/reader/lambda_xs.cpp | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/xo/reader/expect_formal_arglist_xs.hpp b/include/xo/reader/expect_formal_arglist_xs.hpp index 5bf75a8f..f3a6bf22 100644 --- a/include/xo/reader/expect_formal_arglist_xs.hpp +++ b/include/xo/reader/expect_formal_arglist_xs.hpp @@ -53,7 +53,7 @@ namespace xo { public: expect_formal_arglist_xs(); - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_psm); virtual void on_leftparen_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/src/reader/expect_formal_arglist_xs.cpp b/src/reader/expect_formal_arglist_xs.cpp index 8e455413..916841da 100644 --- a/src/reader/expect_formal_arglist_xs.cpp +++ b/src/reader/expect_formal_arglist_xs.cpp @@ -38,9 +38,9 @@ namespace xo { } void - expect_formal_arglist_xs::start(exprstatestack * p_stack) + expect_formal_arglist_xs::start(parserstatemachine * p_psm) { - p_stack->push_exprstate(expect_formal_arglist_xs::make()); + p_psm->push_exprstate(expect_formal_arglist_xs::make()); } expect_formal_arglist_xs::expect_formal_arglist_xs() diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 491ab908..8fd2f46f 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -30,11 +30,9 @@ namespace xo { lambda_xs::on_lambda_token(const token_type & tk, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (lmxs_type_ == lambdastatetype::lm_0) { this->lmxs_type_ = lambdastatetype::lm_1; - expect_formal_arglist_xs::start(p_stack); + expect_formal_arglist_xs::start(p_psm); } else { exprstate::on_lambda_token(tk, p_psm); } From 0b0c424b8422892210ec0b9d87fb2557beb586b0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 16:48:58 -0400 Subject: [PATCH 170/191] xo-reader: simplify expect_expr_xs,expect_lparen_xs using qsm --- include/xo/reader/expect_expr_xs.hpp | 2 +- include/xo/reader/paren_xs.hpp | 2 +- src/reader/define_xs.cpp | 2 +- src/reader/expect_expr_xs.cpp | 8 +++----- src/reader/lambda_xs.cpp | 4 +--- src/reader/paren_xs.cpp | 6 +++--- src/reader/progress_xs.cpp | 8 ++++---- 7 files changed, 14 insertions(+), 18 deletions(-) diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 90477c72..650a3195 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -17,7 +17,7 @@ namespace xo { public: expect_expr_xs(); - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_psm); virtual void on_lambda_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 0fd6bf86..429a2a6e 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -29,7 +29,7 @@ namespace xo { static const paren_xs * from(const exprstate * x) { return dynamic_cast(x); } - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_psm); bool admits_f64() const; bool admits_rightparen() const; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 460d98d2..4a21a0d7 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -172,7 +172,7 @@ namespace xo { { this->defxs_type_ = defexprstatetype::def_5; - expect_expr_xs::start(p_psm->p_stack_); + expect_expr_xs::start(p_psm); } else { this->illegal_input_error(self_name, tk); } diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 2ec95272..cd4f4cf5 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -24,8 +24,8 @@ namespace xo { } void - expect_expr_xs::start(exprstatestack * p_stack) { - p_stack->push_exprstate(expect_expr_xs::make()); + expect_expr_xs::start(parserstatemachine * p_psm) { + p_psm->push_exprstate(expect_expr_xs::make()); } expect_expr_xs::expect_expr_xs() @@ -54,10 +54,8 @@ namespace xo { //constexpr const char * self_name = "exprstate::on_leftparen"; - auto p_stack = p_psm->p_stack_; - /* push lparen_0 to remember to look for subsequent rightparen. */ - paren_xs::start(p_stack); + paren_xs::start(p_psm); } void diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 8fd2f46f..a134a23d 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -42,12 +42,10 @@ namespace xo { lambda_xs::on_formal_arglist(const std::vector> & argl, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (lmxs_type_ == lambdastatetype::lm_1) { this->lmxs_type_ = lambdastatetype::lm_2; this->argl_ = argl; - expect_expr_xs::start(p_stack); + expect_expr_xs::start(p_psm); } else { exprstate::on_formal_arglist(argl, p_psm); } diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index d1d9535c..f48d9d49 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -18,10 +18,10 @@ namespace xo { } void - paren_xs::start(exprstatestack * p_stack) + paren_xs::start(parserstatemachine * p_psm) { - p_stack->push_exprstate(paren_xs::make()); - expect_expr_xs::start(p_stack); + p_psm->push_exprstate(paren_xs::make()); + expect_expr_xs::start(p_psm); } bool diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 6f62f853..3ad4144f 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -319,7 +319,7 @@ namespace xo { this->op_type_ = tk2op(tk.tk_type()); /* infix operator must be followed by non-empty expression */ - expect_expr_xs::start(p_stack); + expect_expr_xs::start(p_psm); } else if (rhs_) { /* already have complete expression stashed. * behavior depends on operator precedence for tk with stored operator @@ -348,7 +348,7 @@ namespace xo { progress_xs::start(expr, op2, p_stack); /* infix operator must be followed by non-empty expression */ - expect_expr_xs::start(p_stack); + expect_expr_xs::start(p_psm); } else { /* e.g. * 6.2 + 4.9 * ... @@ -367,9 +367,9 @@ namespace xo { /* 1. replace with nested incomplete infix exprs */ progress_xs::start(lhs_, op_type_, p_stack); - expect_expr_xs::start(p_stack); + expect_expr_xs::start(p_psm); progress_xs::start(rhs_, op2, p_stack); - expect_expr_xs::start(p_stack); + expect_expr_xs::start(p_psm); } } else { From e74e55832e92516f081da571fb67ec265900d3e3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 16:50:58 -0400 Subject: [PATCH 171/191] xo-reader: simplify expect_type_xs.start() using psm --- include/xo/reader/expect_type_xs.hpp | 2 +- src/reader/define_xs.cpp | 4 +--- src/reader/expect_formal_xs.cpp | 4 +--- src/reader/expect_type_xs.cpp | 4 ++-- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/include/xo/reader/expect_type_xs.hpp b/include/xo/reader/expect_type_xs.hpp index 86e5adf7..1a388f54 100644 --- a/include/xo/reader/expect_type_xs.hpp +++ b/include/xo/reader/expect_type_xs.hpp @@ -16,7 +16,7 @@ namespace xo { public: expect_type_xs(); - static void start(exprstatestack * p_stack); + static void start(parserstatemachine * p_stack); virtual void on_symbol_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 4a21a0d7..04c37c5b 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -112,12 +112,10 @@ namespace xo { //constexpr const char * self_name = "define_xs::on_colon_token"; - auto p_stack = p_psm->p_stack_; - if (this->defxs_type_ == defexprstatetype::def_2) { this->defxs_type_ = defexprstatetype::def_3; - expect_type_xs::start(p_stack); + expect_type_xs::start(p_psm); } else { exprstate::on_colon_token(tk, p_psm); } diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp index e60b77b0..28e19ce4 100644 --- a/src/reader/expect_formal_xs.cpp +++ b/src/reader/expect_formal_xs.cpp @@ -64,11 +64,9 @@ namespace xo { expect_formal_xs::on_colon_token(const token_type & tk, parserstatemachine * p_psm) { - auto p_stack = p_psm->p_stack_; - if (this->formalxs_type_ == formalstatetype::formal_1) { this->formalxs_type_ = formalstatetype::formal_2; - expect_type_xs::start(p_stack); + expect_type_xs::start(p_psm); /* control reenters via expect_formal_xs::on_typedescr() */ } else { exprstate::on_colon_token(tk, diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index f8efd265..d994257e 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -19,8 +19,8 @@ namespace xo { } void - expect_type_xs::start(exprstatestack * p_stack) { - p_stack->push_exprstate(expect_type_xs::make()); + expect_type_xs::start(parserstatemachine * p_psm) { + p_psm->push_exprstate(expect_type_xs::make()); } expect_type_xs::expect_type_xs() From 8db0bf11d0f8a88512a556f0134cbb29b629ca01 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 16:53:43 -0400 Subject: [PATCH 172/191] xo-reader: simplify progress_xs.start() using psm --- include/xo/reader/progress_xs.hpp | 4 ++-- src/reader/expect_expr_xs.cpp | 2 +- src/reader/paren_xs.cpp | 4 +--- src/reader/progress_xs.cpp | 16 +++++++--------- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 6436b117..b370a1f9 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -49,9 +49,9 @@ namespace xo { static void start(rp valex, optype optype, - exprstatestack * p_stack); + parserstatemachine * p_psm); static void start(rp valex, - exprstatestack * p_stack); + parserstatemachine * p_psm); bool admits_f64() const; diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index cd4f4cf5..eed3b006 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -107,7 +107,7 @@ namespace xo { */ progress_xs::start (Constant::make(tk.f64_value()), - p_psm->p_stack_); + p_psm); } void diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index f48d9d49..5b1974cc 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -181,9 +181,7 @@ namespace xo { switch (this->parenxs_type_) { case parenexprstatetype::lparen_0: { this->parenxs_type_ = parenexprstatetype::lparen_1; /* wants on_rightparen */ - auto p_stack = p_psm->p_stack_; - - progress_xs::start(expr.promote(), p_stack); + progress_xs::start(expr.promote(), p_psm); return; } diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 3ad4144f..ed873e35 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -55,13 +55,13 @@ namespace xo { } void - progress_xs::start(rp valex, optype op, exprstatestack * p_stack) { - p_stack->push_exprstate(progress_xs::make(valex, op)); + progress_xs::start(rp valex, optype op, parserstatemachine * p_psm) { + p_psm->push_exprstate(progress_xs::make(valex, op)); } void - progress_xs::start(rp valex, exprstatestack * p_stack) { - p_stack->push_exprstate(progress_xs::make(valex)); + progress_xs::start(rp valex, parserstatemachine * p_psm) { + p_psm->push_exprstate(progress_xs::make(valex)); } progress_xs::progress_xs(rp valex, optype op) @@ -313,8 +313,6 @@ namespace xo { { constexpr const char * c_self_name = "progress_xs::on_operator_token"; - auto p_stack = p_psm->p_stack_; - if (op_type_ == optype::invalid) { this->op_type_ = tk2op(tk.tk_type()); @@ -345,7 +343,7 @@ namespace xo { std::unique_ptr self = p_psm->pop_exprstate(); /* 3. replace with new progress_xs: */ - progress_xs::start(expr, op2, p_stack); + progress_xs::start(expr, op2, p_psm); /* infix operator must be followed by non-empty expression */ expect_expr_xs::start(p_psm); @@ -366,9 +364,9 @@ namespace xo { std::unique_ptr self = p_psm->pop_exprstate(); /* 1. replace with nested incomplete infix exprs */ - progress_xs::start(lhs_, op_type_, p_stack); + progress_xs::start(lhs_, op_type_, p_psm); expect_expr_xs::start(p_psm); - progress_xs::start(rhs_, op2, p_stack); + progress_xs::start(rhs_, op2, p_psm); expect_expr_xs::start(p_psm); } From 8d495a642724d3fab6c6176687d98ff250000ab4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 17:28:35 -0400 Subject: [PATCH 173/191] xo-reader: wip: + envframe, envframestack [not used] --- include/xo/reader/envframe.hpp | 48 ++++++++++++++++++++ include/xo/reader/envframestack.hpp | 66 +++++++++++++++++++++++++++ src/reader/CMakeLists.txt | 5 ++- src/reader/envframe.cpp | 34 ++++++++++++++ src/reader/envframestack.cpp | 70 +++++++++++++++++++++++++++++ 5 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 include/xo/reader/envframe.hpp create mode 100644 include/xo/reader/envframestack.hpp create mode 100644 src/reader/envframe.cpp create mode 100644 src/reader/envframestack.cpp diff --git a/include/xo/reader/envframe.hpp b/include/xo/reader/envframe.hpp new file mode 100644 index 00000000..a0fcfb7d --- /dev/null +++ b/include/xo/reader/envframe.hpp @@ -0,0 +1,48 @@ +/* file envframe.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "xo/expression/Variable.hpp" +#include + +namespace xo { + namespace scm { + /** @class envframe + * @brief names/types of formal paremeters introduced by a function + * + * + **/ + class envframe { + public: + using Variable = xo::ast::Variable; + + public: + envframe() = default; + envframe(const std::vector> & argl) : argl_(argl) {} + + const std::vector> & argl() const { return argl_; } + + /** lookup variable by name. If found, return it. + * Otherwise return nullptr + **/ + rp lookup(const std::string & name) const; + + void print (std::ostream & os) const; + + private: + std::vector> argl_; + }; + + inline std::ostream & + operator<< (std::ostream & os, const envframe & x) { + x.print(os); + return os; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end envframe.hpp */ diff --git a/include/xo/reader/envframestack.hpp b/include/xo/reader/envframestack.hpp new file mode 100644 index 00000000..d27713ac --- /dev/null +++ b/include/xo/reader/envframestack.hpp @@ -0,0 +1,66 @@ +/* file envframestack.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "envframe.hpp" + +namespace xo { + namespace scm { + /** @class envframestack + * @brief A stack of envframe objects + **/ + class envframestack { + public: + envframestack() {} + + bool empty() const { return stack_.empty(); } + std::size_t size() const { return stack_.size(); } + + envframe & top_envframe(); + void push_envframe(envframe x); + void pop_envframe(); + + /** relative to top-of-stack. + * 0 -> top (last in), z-1 -> bottom (first in) + **/ + envframe & operator[](std::size_t i) { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + const envframe & operator[](std::size_t i) const { + std::size_t z = stack_.size(); + + assert(i < z); + + return stack_[z - i - 1]; + } + + void print (std::ostream & os) const; + + private: + std::vector stack_; + }; + + inline std::ostream & + operator<< (std::ostream & os, const envframestack & x) { + x.print(os); + return os; + } + + inline std::ostream & + operator<< (std::ostream & os, const envframestack * x) { + x->print(os); + return os; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end envframestack.hpp */ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 5edbb2e4..83dc675d 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -13,11 +13,12 @@ set(SELF_SRCS exprseq_xs.cpp expect_expr_xs.cpp expect_symbol_xs.cpp - expect_formal_xs.cpp expect_formal_arglist_xs.cpp expect_type_xs.cpp - lambda_xs.cpp) + lambda_xs.cpp + envframestack.cpp + envframe.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/envframe.cpp b/src/reader/envframe.cpp new file mode 100644 index 00000000..38ff1fcb --- /dev/null +++ b/src/reader/envframe.cpp @@ -0,0 +1,34 @@ +/* file envframe.cpp + * + * author: Roland Conybeare + */ + +#include "envframe.hpp" +#include "xo/indentlog/print/vector.hpp" + +namespace xo { + using xo::ast::Variable; + + namespace scm { + rp + envframe::lookup(const std::string & x) const { + for (const auto & var : argl_) { + if (x == var->name()) + return var; + } + + return nullptr; + } + + void + envframe::print(std::ostream & os) const { + os << ""; + } + + } /*namespace scm */ +} /*namespace xo*/ + + +/* end envframe.cpp */ diff --git a/src/reader/envframestack.cpp b/src/reader/envframestack.cpp new file mode 100644 index 00000000..52543dc4 --- /dev/null +++ b/src/reader/envframestack.cpp @@ -0,0 +1,70 @@ +/* file envframestack.cpp + * + * author: Roland Conybeare + */ + +#include "envframestack.hpp" + +namespace xo { + namespace scm { + envframe & + envframestack::top_envframe() { + std::size_t z = stack_.size(); + + if (z == 0) { + throw std::runtime_error + ("parser::top_exprstate: unexpected empty stack"); + } + + return stack_[z-1]; + } + + void + envframestack::push_envframe(envframe frame) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), + xtag("frame", frame)); + + std::size_t z = stack_.size(); + + stack_.resize(z+1); + + stack_[z] = std::move(frame); + } + + void + envframestack::pop_envframe() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + std::size_t z = stack_.size(); + + if (z > 0) { + //std::unique_ptr top = std::move(stack_[z-1]); + + stack_.resize(z-1); + + //return top; + } else { + //return nullptr; + } + } + + void + envframestack::print(std::ostream & os) const { + os << "" << std::endl; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end envframestack.cpp */ From 94109c93b7f51e9720cd2b7f84b5ee0451390cfa Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 17:30:15 -0400 Subject: [PATCH 174/191] xo-reader: wip: + parser.env_stack [not used] --- include/xo/reader/parser.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index dae3091f..30dd94ea 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -6,6 +6,7 @@ #pragma once #include "exprstatestack.hpp" +#include "envframestack.hpp" #include namespace xo { @@ -212,6 +213,12 @@ namespace xo { **/ exprstatestack xs_stack_; + /** environment frames for lexical context. + * push a frame on each nested lambda; + * pop when lambda body goes out of scope + **/ + envframestack env_stack_; + }; /*parser*/ inline std::ostream & From 3b57a1f142b461bb58bbcbb20ef1a7458999334e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 17:34:20 -0400 Subject: [PATCH 175/191] xo-reader: wip: add environment-frame stack to psm [not used] --- include/xo/reader/parserstatemachine.hpp | 12 +++++++++++- src/reader/parser.cpp | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index c7ca130c..e39021f3 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -6,6 +6,7 @@ #pragma once #include "exprstate.hpp" +#include "envframestack.hpp" namespace xo { namespace scm { @@ -22,15 +23,24 @@ namespace xo { public: parserstatemachine(exprstatestack * p_stack, + envframestack * p_env_stack, rp * p_emit_expr) - : p_stack_{p_stack}, p_emit_expr_{p_emit_expr} {} + : p_stack_{p_stack}, + p_env_stack_{p_env_stack}, + p_emit_expr_{p_emit_expr} {} std::unique_ptr pop_exprstate(); exprstate & top_exprstate(); void push_exprstate(std::unique_ptr x); public: + /** stack of incomplete parser work. + * generally speaking, push when to start new work for nested content; + * pop when work complete + **/ exprstatestack * p_stack_; + /** stack of environment frames, one for each enclosing lambda **/ + envframestack * p_env_stack_; rp * p_emit_expr_; }; } /*namespace scm*/ diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index 9301f1df..e71deb40 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -33,6 +33,7 @@ namespace xo { parser::begin_translation_unit() { /* note: not using emit expr here */ parserstatemachine psm(&xs_stack_, + &env_stack_, nullptr /*p_emit_expr*/); exprseq_xs::start(&psm); @@ -55,7 +56,7 @@ namespace xo { rp retval; - parserstatemachine psm(&xs_stack_, &retval); + parserstatemachine psm(&xs_stack_, &env_stack_, &retval); xs_stack_.top_exprstate().on_input(tk, &psm); From eed5cdf6910d37b5318c43f0d3dce0591ff304fd Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 18:11:28 -0400 Subject: [PATCH 176/191] xo-reader: feat: + var lookup in envframestack, psm --- include/xo/reader/envframestack.hpp | 9 +++++++++ include/xo/reader/parserstatemachine.hpp | 9 +++++++++ src/reader/envframestack.cpp | 16 ++++++++++++++++ src/reader/parserstatemachine.cpp | 17 +++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/include/xo/reader/envframestack.hpp b/include/xo/reader/envframestack.hpp index d27713ac..ac933dae 100644 --- a/include/xo/reader/envframestack.hpp +++ b/include/xo/reader/envframestack.hpp @@ -13,12 +13,21 @@ namespace xo { * @brief A stack of envframe objects **/ class envframestack { + public: + using Variable = xo::ast::Variable; + public: envframestack() {} bool empty() const { return stack_.empty(); } std::size_t size() const { return stack_.size(); } + /** lookup variable in environment stack. + * Visit frames in fifo order, report first match; + * nullptr if no matches. + **/ + rp lookup(const std::string & x) const; + envframe & top_envframe(); void push_envframe(envframe x); void pop_envframe(); diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index e39021f3..3ad71b13 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -20,6 +20,7 @@ namespace xo { class parserstatemachine { public: using Expression = xo::ast::Expression; + using Variable = xo::ast::Variable; public: parserstatemachine(exprstatestack * p_stack, @@ -33,6 +34,14 @@ namespace xo { exprstate & top_exprstate(); void push_exprstate(std::unique_ptr x); + /** lookup variable name in lexical context represented by + * this psm. nullptr if not found + **/ + rp lookup_var(const std::string & x) const; + + void push_envframe(envframe x); + void pop_envframe(); + public: /** stack of incomplete parser work. * generally speaking, push when to start new work for nested content; diff --git a/src/reader/envframestack.cpp b/src/reader/envframestack.cpp index 52543dc4..047e1789 100644 --- a/src/reader/envframestack.cpp +++ b/src/reader/envframestack.cpp @@ -6,6 +6,8 @@ #include "envframestack.hpp" namespace xo { + using xo::ast::Variable; + namespace scm { envframe & envframestack::top_envframe() { @@ -50,6 +52,20 @@ namespace xo { } } + rp + envframestack::lookup(const std::string & x) const { + for (std::size_t i = 0, z = this->size(); i < z; ++i) { + const auto & frame = (*this)[i]; + + auto retval = frame.lookup(x); + + if (retval) + return retval; + } + + return nullptr; + } + void envframestack::print(std::ostream & os) const { os << " + parserstatemachine::lookup_var(const std::string & x) const { + return p_env_stack_->lookup(x); + } + std::unique_ptr parserstatemachine::pop_exprstate() { return p_stack_->pop_exprstate(); @@ -22,6 +29,16 @@ namespace xo { parserstatemachine::push_exprstate(std::unique_ptr x) { p_stack_->push_exprstate(std::move(x)); } + + void + parserstatemachine::push_envframe(envframe x) { + p_env_stack_->push_envframe(std::move(x)); + } + + void + parserstatemachine::pop_envframe() { + p_env_stack_->pop_envframe(); + } } /*namespace scm*/ } /*namespace xo*/ From fbc21222715f1203ef559a39537c7fc44f68740a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 18:33:25 -0400 Subject: [PATCH 177/191] xo-reader: wip: push/pop env frames for lambdas --- src/reader/lambda_xs.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index a134a23d..00fb5c0e 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -45,6 +45,9 @@ namespace xo { if (lmxs_type_ == lambdastatetype::lm_1) { this->lmxs_type_ = lambdastatetype::lm_2; this->argl_ = argl; + + p_psm->push_envframe(envframe(argl)); + expect_expr_xs::start(p_psm); } else { exprstate::on_formal_arglist(argl, p_psm); @@ -76,6 +79,8 @@ namespace xo { rp lm = Lambda::make(name, argl_, body_); + p_psm->pop_envframe(); + p_psm->top_exprstate().on_expr(lm, p_psm); p_psm->top_exprstate().on_semicolon_token(tk, p_psm); From 50dd94e354cfc6e9d55b87a5b124bb1ef33feeee Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 18:33:54 -0400 Subject: [PATCH 178/191] xo-reader: wip: expect_expr looks up symbols --- src/reader/expect_expr_xs.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index eed3b006..9896421e 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -59,8 +59,8 @@ namespace xo { } void - expect_expr_xs::on_symbol_token(const token_type & /*tk*/, - parserstatemachine * /*p_psm*/) + expect_expr_xs::on_symbol_token(const token_type & tk, + parserstatemachine * p_psm) { /* todo: treat symbol as variable name */ @@ -75,9 +75,26 @@ namespace xo { * and {(2), (3)} (symbol is function call) */ - /* have to do pop first, before sending symbol to - * the o.g. symbol-requester + rp var = p_psm->lookup_var(tk.text()); + + if (!var) { + throw std::runtime_error + (tostr("expect_expr_xs::on_symbol_token", + ": unknown symbol", + xtag("name", tk.text()))); + } + + /* e.g. + * def pi = 3.14159265; + * def mypi = pi; + * ^ + * def pi2 = pi * 2; + * ^ + * def y = foo(pi2); + * ^ */ + progress_xs::start(var, p_psm); + #ifdef NOT_YET p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, Variable::make(name, type))); From e712169daac6445debe2049fcb771589133b7a9c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Aug 2024 18:35:27 -0400 Subject: [PATCH 179/191] xo-reader: utest: + test variable lookup [working] --- utest/reader.test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp index aa85fcc7..2c9a490d 100644 --- a/utest/reader.test.cpp +++ b/utest/reader.test.cpp @@ -17,7 +17,8 @@ namespace xo { {"def foo : f64 = (3.14159265);"}, //{"def foo : f64 = 2.0 * 3.14159265;"}, {"def foo = lambda (x : f64) 3.1415965;"}, - {"def foo = lambda (x : f64, y : f64) 3.1415965;"} + {"def foo = lambda (x : f64, y : f64) 3.1415965;"}, + {"def foo = lambda (x : f64) x;"} }; } From dad6b2562c5d485851094287289c4b844ced7359 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Aug 2024 13:32:08 -0400 Subject: [PATCH 180/191] xo-reader: + sequence expression (aka beginexpr or block) --- include/xo/reader/expect_expr_xs.hpp | 29 ++++++++++- include/xo/reader/exprstate.hpp | 13 +++++ include/xo/reader/sequence_xs.hpp | 34 ++++++++++++ src/reader/CMakeLists.txt | 1 + src/reader/expect_expr_xs.cpp | 69 +++++++++++++++++++++--- src/reader/exprstate.cpp | 26 ++++++++++ src/reader/sequence_xs.cpp | 78 ++++++++++++++++++++++++++++ 7 files changed, 241 insertions(+), 9 deletions(-) create mode 100644 include/xo/reader/sequence_xs.hpp create mode 100644 src/reader/sequence_xs.cpp diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 650a3195..c3e8a513 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -15,16 +15,29 @@ namespace xo { **/ class expect_expr_xs : public exprstate { public: - expect_expr_xs(); + explicit expect_expr_xs(bool allow_defs, + bool cxl_on_rightbrace); static void start(parserstatemachine * p_psm); + static void start(bool allow_defs, + bool cxl_on_rightbrace, + parserstatemachine * p_psm); virtual void on_lambda_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void on_def_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_leftparen_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void on_leftbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_symbol_token(const token_type & tk, parserstatemachine * p_psm) override; @@ -36,7 +49,19 @@ namespace xo { parserstatemachine * p_psm) override; private: - static std::unique_ptr make(); + static std::unique_ptr make(bool allow_defs, + bool cxl_on_rightbrace); + + private: + /* if true: allow a define-expression here */ + bool allow_defs_ = false; + /* if true: expecting either: + * - expression + * - right brace '}', in which case no expression + * if false: expecting + * - expression + */ + bool cxl_on_rightbrace_ = false; }; } /*namespace scm*/ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 3e79dee4..b22bf85f 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -33,6 +33,11 @@ namespace xo { **/ parenexpr, + /** handle sequence expression (aka block) + * see @ref sequence_xs + **/ + sequenceexpr, + expect_rhs_expression, expect_symbol, expect_type, @@ -146,6 +151,14 @@ namespace xo { virtual void on_rightparen_token(const token_type & tk, parserstatemachine * p_psm); + /** handle incoming '{' token **/ + virtual void on_leftbrace_token(const token_type & tk, + parserstatemachine * p_psm); + + /** handle incoming '}' token **/ + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm); + /** handle incoming operator token **/ virtual void on_operator_token(const token_type & tk, parserstatemachine * p_psm); diff --git a/include/xo/reader/sequence_xs.hpp b/include/xo/reader/sequence_xs.hpp new file mode 100644 index 00000000..a33cf3e1 --- /dev/null +++ b/include/xo/reader/sequence_xs.hpp @@ -0,0 +1,34 @@ +/** @file sequence_xs.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "exprstate.hpp" + +namespace xo { + namespace scm { + class sequence_xs : public exprstate { + public: + sequence_xs(); + + static void start(parserstatemachine * p_psm); + + virtual void on_expr(ref::brw expr, + parserstatemachine * p_psm) override; + + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + + private: + static std::unique_ptr make(); + + private: + std::vector> expr_v_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end sequence_xs.hpp **/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 83dc675d..5db87d7a 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -10,6 +10,7 @@ set(SELF_SRCS define_xs.cpp progress_xs.cpp paren_xs.cpp + sequence_xs.cpp exprseq_xs.cpp expect_expr_xs.cpp expect_symbol_xs.cpp diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 9896421e..c07c5d42 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -7,7 +7,9 @@ #include "parserstatemachine.hpp" #include "exprstatestack.hpp" #include "lambda_xs.hpp" +#include "define_xs.hpp" #include "paren_xs.hpp" +#include "sequence_xs.hpp" #include "progress_xs.hpp" #include "xo/expression/Lambda.hpp" #include "xo/expression/Constant.hpp" @@ -18,20 +20,46 @@ namespace xo { namespace scm { std::unique_ptr - expect_expr_xs::make() { - return std::make_unique(expect_expr_xs()); + expect_expr_xs::make(bool allow_defs, + bool cxl_on_rightbrace) + { + return std::make_unique(expect_expr_xs(allow_defs, + cxl_on_rightbrace)); } void - expect_expr_xs::start(parserstatemachine * p_psm) { - p_psm->push_exprstate(expect_expr_xs::make()); + expect_expr_xs::start(bool allow_defs, + bool cxl_on_rightbrace, + parserstatemachine * p_psm) { + p_psm->push_exprstate(expect_expr_xs::make(allow_defs, + cxl_on_rightbrace)); } - expect_expr_xs::expect_expr_xs() - : exprstate(exprstatetype::expect_rhs_expression) + void + expect_expr_xs::start(parserstatemachine * p_psm) { + start(false /*!allow_defs*/, + false /*!cxl_on_rightbrace*/, + p_psm); + } + + expect_expr_xs::expect_expr_xs(bool allow_defs, + bool cxl_on_rightbrace) + : exprstate(exprstatetype::expect_rhs_expression), + allow_defs_{allow_defs}, + cxl_on_rightbrace_{cxl_on_rightbrace} {} + void + expect_expr_xs::on_def_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (allow_defs_) + define_xs::start(p_psm); + else + exprstate::on_def_token(tk, p_psm); + } + void expect_expr_xs::on_lambda_token(const token_type & /*tk*/, parserstatemachine * p_psm) @@ -41,7 +69,6 @@ namespace xo { //constexpr const char * self_name = "exprstate::on_leftparen"; - /* push lparen_0 to remember to look for subsequent rightparen. */ lambda_xs::start(p_psm); } @@ -58,6 +85,34 @@ namespace xo { paren_xs::start(p_psm); } + void + expect_expr_xs::on_leftbrace_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + //constexpr const char * self_name = "exprstate::on_leftparen"; + + /* push lparen_0 to remember to look for subsequent rightparen. */ + sequence_xs::start(p_psm); + } + + void + expect_expr_xs::on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (cxl_on_rightbrace_) { + auto self = p_psm->pop_exprstate(); + + /* do not call .on_expr(), since '}' cancelled */ + + p_psm->top_exprstate().on_rightbrace_token(tk, p_psm); + } else { + exprstate::on_rightbrace_token(tk, p_psm); + } + } + void expect_expr_xs::on_symbol_token(const token_type & tk, parserstatemachine * p_psm) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 9721ede2..dfb490ea 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -33,6 +33,8 @@ namespace xo { return "lambdaexpr"; case exprstatetype::parenexpr: return "parenexpr"; + case exprstatetype::sequenceexpr: + return "sequenceexpr"; case exprstatetype::expect_rhs_expression: return "expect_rhs_expression"; case exprstatetype::expect_symbol: @@ -211,6 +213,30 @@ namespace xo { this->illegal_input_error(self_name, tk); } + void + exprstate::on_leftbrace_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_leftbrace_token"; + + this->illegal_input_error(self_name, tk); + } + + void + exprstate::on_rightbrace_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_rightbrace_token"; + + this->illegal_input_error(self_name, tk); + } + void exprstate::on_operator_token(const token_type & tk, parserstatemachine * /*p_psm*/) diff --git a/src/reader/sequence_xs.cpp b/src/reader/sequence_xs.cpp new file mode 100644 index 00000000..68694e53 --- /dev/null +++ b/src/reader/sequence_xs.cpp @@ -0,0 +1,78 @@ +/* @file sequence_xs.cpp */ + +#include "sequence_xs.hpp" +#include "parserstatemachine.hpp" +#include "expect_expr_xs.hpp" +#include "xo/expression/Sequence.hpp" + +namespace xo { + using xo::ast::Sequence; + + namespace scm { + std::unique_ptr + sequence_xs::make() { + return std::make_unique(sequence_xs()); + } + + void + sequence_xs::start(parserstatemachine * p_psm) { + p_psm->push_exprstate(sequence_xs::make()); + /* want to accept anything that starts an expression, + * except that } ends it + */ + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + + sequence_xs::sequence_xs() + : exprstate(exprstatetype::sequenceexpr) + {} + + void + sequence_xs::on_expr(ref::brw expr, + parserstatemachine * p_psm) + { + /* TODO: if expr is a DefineExpr, + * then need to rewrite... + * + * ...prefix + * DefineExpr(lhs_name, rhs) + * rest... + * + * becomes: + * + * Sequence( + * ...prefix, + * Apply(Lambda(gen999, [Variable(lhs_name, type(rhs))], sequencify(rest...)), + * rhs)) + * + * so amongst other things, + * helpful to have nested seequence_xs that propagates '}' instead of swallowing it. + */ + + this->expr_v_.push_back(expr.promote()); + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + + void + sequence_xs::on_rightbrace_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + auto self = p_psm->pop_exprstate(); + + /* make sequence from expressions seen at this level, + * and report it to parent + */ + auto expr = Sequence::make(this->expr_v_); + + p_psm->top_exprstate().on_expr(expr, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end sequence_xs.cpp */ From 7fad60290d9e8587f94a1aa234c275693bb0c08a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Aug 2024 10:52:51 -0400 Subject: [PATCH 181/191] xo-reader: handle sequence with embedded local vars --- include/xo/reader/let1_xs.hpp | 57 +++++++++++++++ include/xo/reader/sequence_xs.hpp | 15 +++- src/reader/CMakeLists.txt | 1 + src/reader/let1_xs.cpp | 116 ++++++++++++++++++++++++++++++ src/reader/sequence_xs.cpp | 44 ++++++++++-- 5 files changed, 225 insertions(+), 8 deletions(-) create mode 100644 include/xo/reader/let1_xs.hpp create mode 100644 src/reader/let1_xs.cpp diff --git a/include/xo/reader/let1_xs.hpp b/include/xo/reader/let1_xs.hpp new file mode 100644 index 00000000..4486869f --- /dev/null +++ b/include/xo/reader/let1_xs.hpp @@ -0,0 +1,57 @@ +/* file let1_xs.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" + +namespace xo { + namespace scm { + class let1_xs : public exprstate { + public: + + /** given local definition equivalent to + * def lhs_name = rhs + * rest... + * parse sequence of incoming expressions rest... (until '}') + * + * Result expression creates and inits @p lhs_name, + * then evaluates expressions that follow definition + * up to same-level '}' + **/ + static void start(const std::string & lhs_name, + const rp & rhs, + parserstatemachine * p_psm); + + virtual void on_expr(ref::brw expr, + parserstatemachine * p_psm) override; + + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + + private: + let1_xs(std::string lhs_name, + rp rhs); + + /** named ctor idiom **/ + static std::unique_ptr make(std::string lhs_name, + rp rhs); + + private: + /** name for new local variable **/ + std::string lhs_name_; + /** set initial value for @ref lhs_name_ from value of this expression **/ + rp rhs_; + + /** evaluate expressions in this sequence, in order, in environment + * with variable @ref lhs_name_ defined + **/ + std::vector> expr_v_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end let1_xs.hpp */ diff --git a/include/xo/reader/sequence_xs.hpp b/include/xo/reader/sequence_xs.hpp index a33cf3e1..b361bbf7 100644 --- a/include/xo/reader/sequence_xs.hpp +++ b/include/xo/reader/sequence_xs.hpp @@ -6,13 +6,22 @@ #pragma once #include "exprstate.hpp" +#include namespace xo { + namespace ast { class Sequence; } + namespace ast { class Lambda; } + namespace scm { class sequence_xs : public exprstate { public: - sequence_xs(); + using Sequence = xo::ast::Sequence; + using Lambda = xo::ast::Lambda; + public: + /** start parsing a sequence-expr. + * input begins with first expression in the sequence. + **/ static void start(parserstatemachine * p_psm); virtual void on_expr(ref::brw expr, @@ -22,9 +31,13 @@ namespace xo { parserstatemachine * p_psm) override; private: + sequence_xs(); + + /** named ctor idiom **/ static std::unique_ptr make(); private: + /** will build SequenceExpr from in-order contents of this vector **/ std::vector> expr_v_; }; } /*namespace scm*/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 5db87d7a..0a3dee3e 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -18,6 +18,7 @@ set(SELF_SRCS expect_formal_arglist_xs.cpp expect_type_xs.cpp lambda_xs.cpp + let1_xs.cpp envframestack.cpp envframe.cpp) diff --git a/src/reader/let1_xs.cpp b/src/reader/let1_xs.cpp new file mode 100644 index 00000000..f248d1dd --- /dev/null +++ b/src/reader/let1_xs.cpp @@ -0,0 +1,116 @@ +/* file let1_xs.cpp + * + * author: Roland Conybeare + */ + +#include "let1_xs.hpp" +#include "expect_expr_xs.hpp" +#include "parserstatemachine.hpp" +#include "xo/expression/Sequence.hpp" +#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/Apply.hpp" +#include "xo/expression/Lambda.hpp" + +namespace xo { + using Sequence = xo::ast::Sequence; + using DefineExpr = xo::ast::DefineExpr; + using Apply = xo::ast::Apply; + using Lambda = xo::ast::Lambda; + using LambdaAccess = xo::ast::LambdaAccess; + using Variable = xo::ast::Variable; + + namespace { + std::string gensym() { + return "genanotherxx"; + } + } + + namespace scm { + std::unique_ptr + let1_xs::make(std::string lhs_name, + rp rhs) + { + return std::make_unique(let1_xs(std::move(lhs_name), + std::move(rhs))); + } + + void + let1_xs::start(const std::string & lhs_name, + const rp & rhs, + parserstatemachine * p_psm) + { + p_psm->push_exprstate(let1_xs::make(std::move(lhs_name), + std::move(rhs))); + + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + + let1_xs::let1_xs(std::string lhs_name, + rp rhs) + : lhs_name_{std::move(lhs_name)}, + rhs_{std::move(rhs)} + {} + + void + let1_xs::on_expr(ref::brw expr, + parserstatemachine * p_psm) + { + ref::brw def_expr = DefineExpr::from(expr); + + if (def_expr) { + /** nested_start: control returns via + * .on_expr(x) + * with x something like: + * Apply(Lambda(gensym(), + * [Variable(def_expr->lhs_name(), + * def_expr->valuetype())], + * body...)) + * followed immediately by + * .on_rightbrace_token() + **/ + let1_xs::start(def_expr->lhs_name(), + def_expr->rhs(), + p_psm); + } else { + this->expr_v_.push_back(expr.promote()); + + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + } + + void + let1_xs::on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) + { + auto self = p_psm->pop_exprstate(); + + auto expr = Sequence::make(this->expr_v_); + + std::string argname = gensym(); + + rp lambda + = Lambda::make(this->lhs_name_, + {Variable::make(argname, + this->rhs_->valuetype())}, + expr); + + rp result + = Apply::make(lambda, {this->rhs_}); + + p_psm->top_exprstate().on_expr(result, p_psm); + + /* caller of let1_xs expects the same rightbrace '}' + * -- remember we pushed let1_xs to handle an embedded def-expr + * in a sequence + */ + p_psm->top_exprstate().on_rightbrace_token(tk, p_psm); + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end let1_xs.cpp */ diff --git a/src/reader/sequence_xs.cpp b/src/reader/sequence_xs.cpp index 68694e53..c9ee71f3 100644 --- a/src/reader/sequence_xs.cpp +++ b/src/reader/sequence_xs.cpp @@ -3,10 +3,12 @@ #include "sequence_xs.hpp" #include "parserstatemachine.hpp" #include "expect_expr_xs.hpp" +#include "let1_xs.hpp" +#include "xo/expression/DefineExpr.hpp" #include "xo/expression/Sequence.hpp" namespace xo { - using xo::ast::Sequence; + using xo::ast::DefineExpr; namespace scm { std::unique_ptr @@ -42,19 +44,47 @@ namespace xo { * * becomes: * + * /-- .outer_seq_expr_ + * v * Sequence( * ...prefix, - * Apply(Lambda(gen999, [Variable(lhs_name, type(rhs))], sequencify(rest...)), + * + * /-- .inner_lm_expr_ + * v + * Apply(Lambda(gen999, + * [Variable(lhs_name, type(rhs))], + * /-- .expr_v_ + * v + * sequencify(rest...)), * rhs)) * * so amongst other things, - * helpful to have nested seequence_xs that propagates '}' instead of swallowing it. + * helpful to have nested seequence_xs that propagates '}' + * instead of swallowing it. */ + ref::brw def_expr = DefineExpr::from(expr); - this->expr_v_.push_back(expr.promote()); - expect_expr_xs::start(true /*allow_defs*/, - true /*cxl_on_rightbrace*/, - p_psm); + if (def_expr) { + /** nested_start: control returns via + * .on_expr(x) + * with x something like: + * Apply(Lambda(gensym(), + * [Variable(def_expr->lhs_name(), + * def_expr->valuetype())], + * body...)) + * followed immediately by + * .on_rightbrace_token() + **/ + let1_xs::start(def_expr->lhs_name(), + def_expr->rhs(), + p_psm); + } else { + this->expr_v_.push_back(expr.promote()); + + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } } void From ec1e45d2ed5a9cb604dea1a12819de1fb73ff5cb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Aug 2024 16:18:22 -0400 Subject: [PATCH 182/191] xo-reader: bugfix: + missing exprstatetype.let1expr --- include/xo/reader/exprstate.hpp | 5 +++++ src/reader/exprstate.cpp | 2 ++ src/reader/let1_xs.cpp | 6 +++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index b22bf85f..5af05f86 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -38,6 +38,11 @@ namespace xo { **/ sequenceexpr, + /** handle let1 (single local variable) + * see @ref let1_xs + **/ + let1expr, + expect_rhs_expression, expect_symbol, expect_type, diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index dfb490ea..aa32b763 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -35,6 +35,8 @@ namespace xo { return "parenexpr"; case exprstatetype::sequenceexpr: return "sequenceexpr"; + case exprstatetype::let1expr: + return "let1expr"; case exprstatetype::expect_rhs_expression: return "expect_rhs_expression"; case exprstatetype::expect_symbol: diff --git a/src/reader/let1_xs.cpp b/src/reader/let1_xs.cpp index f248d1dd..e9c17651 100644 --- a/src/reader/let1_xs.cpp +++ b/src/reader/let1_xs.cpp @@ -49,7 +49,8 @@ namespace xo { let1_xs::let1_xs(std::string lhs_name, rp rhs) - : lhs_name_{std::move(lhs_name)}, + : exprstate(), + lhs_name_{std::move(lhs_name)}, rhs_{std::move(rhs)} {} @@ -57,6 +58,9 @@ namespace xo { let1_xs::on_expr(ref::brw expr, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + ref::brw def_expr = DefineExpr::from(expr); if (def_expr) { From 76f292d40db0d5ad341d93da797cc51265dfd463 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Aug 2024 16:18:53 -0400 Subject: [PATCH 183/191] xo-reader: bugfix: call on_{left,right}_brace_token() --- src/reader/exprstate.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index aa32b763..64aa65b2 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -308,8 +308,16 @@ namespace xo { case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: + assert(false); + break; + case tokentype::tk_leftbrace: + this->on_leftbrace_token(tk, p_psm); + return; + case tokentype::tk_rightbrace: + this->on_rightbrace_token(tk, p_psm); + return; case tokentype::tk_leftangle: case tokentype::tk_rightangle: From d88d2713db0260599d37b414244ad8ad419dba77 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Aug 2024 16:20:44 -0400 Subject: [PATCH 184/191] xo-reader: doc: ++ comments --- include/xo/reader/parserstatemachine.hpp | 3 +++ include/xo/reader/progress_xs.hpp | 9 ++++++++- src/reader/expect_expr_xs.cpp | 2 -- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index 3ad71b13..e23cd262 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -50,6 +50,9 @@ namespace xo { exprstatestack * p_stack_; /** stack of environment frames, one for each enclosing lambda **/ envframestack * p_env_stack_; + /** if non-null, store next non-nested complete expressions in + * *p_emit_expr + **/ rp * p_emit_expr_; }; } /*namespace scm*/ diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index b370a1f9..1c985ed3 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -11,7 +11,11 @@ namespace xo { namespace scm { - /* represent an infix operator */ + /** represent an infix operator. + * + * See @ref progress_xs::assemble_expr() for translation + * to Expression + **/ enum class optype { invalid = -1, @@ -26,6 +30,9 @@ namespace xo { extern const char * optype_descr(optype x); + /** report operator precedence. + * lowest operator precedence is 1 + **/ extern int precedence(optype x); diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index c07c5d42..b4383f0b 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -92,8 +92,6 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - //constexpr const char * self_name = "exprstate::on_leftparen"; - /* push lparen_0 to remember to look for subsequent rightparen. */ sequence_xs::start(p_psm); } From 00625ee063d388aae7bfe5662539cf1bf71a4559 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Aug 2024 16:21:54 -0400 Subject: [PATCH 185/191] xo-reader: debug: + log output --- src/reader/parserstatemachine.cpp | 8 ++++++++ src/reader/sequence_xs.cpp | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/src/reader/parserstatemachine.cpp b/src/reader/parserstatemachine.cpp index 9a7ce55d..2e2abd2c 100644 --- a/src/reader/parserstatemachine.cpp +++ b/src/reader/parserstatemachine.cpp @@ -32,11 +32,19 @@ namespace xo { void parserstatemachine::push_envframe(envframe x) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("frame", x)); + p_env_stack_->push_envframe(std::move(x)); } void parserstatemachine::pop_envframe() { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + p_env_stack_->pop_envframe(); } } /*namespace scm*/ diff --git a/src/reader/sequence_xs.cpp b/src/reader/sequence_xs.cpp index c9ee71f3..97aa0955 100644 --- a/src/reader/sequence_xs.cpp +++ b/src/reader/sequence_xs.cpp @@ -35,6 +35,11 @@ namespace xo { sequence_xs::on_expr(ref::brw expr, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("expr", expr.promote())); + /* TODO: if expr is a DefineExpr, * then need to rewrite... * From 1145830bb1a3a1abf3254a8ccb4d13d31b781e7f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Aug 2024 16:23:04 -0400 Subject: [PATCH 186/191] xo-parser: feat: + assign operator handling [wip, untested] --- include/xo/reader/progress_xs.hpp | 3 +++ src/reader/progress_xs.cpp | 28 ++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 1c985ed3..6e9db243 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -19,8 +19,11 @@ namespace xo { enum class optype { invalid = -1, + op_assign, + op_add, op_subtract, + op_multiply, op_divide, diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index ed873e35..fcb32142 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -4,10 +4,13 @@ #include "exprstatestack.hpp" #include "expect_expr_xs.hpp" #include "parserstatemachine.hpp" +#include "xo/expression/AssignExpr.hpp" #include "xo/expression/Apply.hpp" namespace xo { using xo::ast::Expression; + using xo::ast::AssignExpr; + using xo::ast::Variable; using xo::ast::Apply; namespace scm { @@ -16,6 +19,8 @@ namespace xo { switch (x) { case optype::invalid: return "?optype"; + case optype::op_assign: + return "op:="; case optype::op_add: return "op+"; case optype::op_subtract: @@ -37,13 +42,16 @@ namespace xo { case optype::n_optype: return 0; + case optype::op_assign: + return 1; + case optype::op_add: case optype::op_subtract: - return 1; + return 2; case optype::op_multiply: case optype::op_divide: - return 2; + return 3; } return 0; @@ -108,6 +116,22 @@ namespace xo { case optype::invalid: return this->lhs_; + case optype::op_assign: + { + ref::brw lhs = Variable::from(this->lhs_); + + if (!lhs) { + throw std::runtime_error + (tostr("progress_xs::assemble_expr", + " expect variable on lhs of assignment operator :=", + xtag("lhs", lhs_), + xtag("rhs", rhs_))); + } + + return AssignExpr::make(lhs.promote(), + this->rhs_); + } + case optype::op_add: return Apply::make_add2_f64(this->lhs_, this->rhs_); From 22d4c6c601065d9a5ccfc2df1ac6d3ff076e2e22 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Aug 2024 16:23:33 -0400 Subject: [PATCH 187/191] xo-reader: + block utest + assignment utest [wip, not passsing] --- src/reader/expect_expr_xs.cpp | 2 +- utest/reader.test.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index b4383f0b..f8a17836 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -188,7 +188,7 @@ namespace xo { scope log(XO_DEBUG(c_debug_flag)); log && log(xtag("exstype", this->exs_type_), - xtag("expr", expr)); + xtag("expr", expr.promote())); std::unique_ptr self = p_psm->pop_exprstate(); diff --git a/utest/reader.test.cpp b/utest/reader.test.cpp index 2c9a490d..d73fc972 100644 --- a/utest/reader.test.cpp +++ b/utest/reader.test.cpp @@ -18,7 +18,8 @@ namespace xo { //{"def foo : f64 = 2.0 * 3.14159265;"}, {"def foo = lambda (x : f64) 3.1415965;"}, {"def foo = lambda (x : f64, y : f64) 3.1415965;"}, - {"def foo = lambda (x : f64) x;"} + {"def foo = lambda (x : f64) x;"}, + {"def foo = lambda (x : f64) { def y = x * x; y; }"}, }; } From ac4ee7d6b85abab41c8efd5e9d33c465d39810a0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Aug 2024 00:38:05 -0400 Subject: [PATCH 188/191] xo-reader: misc bugfixes + logging [wip, utests not passing] --- include/xo/reader/define_xs.hpp | 5 +++ include/xo/reader/envframestack.hpp | 5 ++- include/xo/reader/exprstate.hpp | 9 ++++ include/xo/reader/exprstatestack.hpp | 1 + include/xo/reader/paren_xs.hpp | 9 ++++ include/xo/reader/parserstatemachine.hpp | 19 ++++++++ src/reader/define_xs.cpp | 57 ++++++++++++++++++++++-- src/reader/expect_expr_xs.cpp | 2 +- src/reader/expect_symbol_xs.cpp | 4 +- src/reader/exprstate.cpp | 2 + src/reader/exprstatestack.cpp | 4 +- src/reader/let1_xs.cpp | 5 +-- src/reader/paren_xs.cpp | 22 +++++++-- src/reader/parserstatemachine.cpp | 48 ++++++++++++++++++++ 14 files changed, 175 insertions(+), 17 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index ebb7b161..13b3d558 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -56,6 +56,11 @@ namespace xo { n_defexprstatetype, }; + extern const char * defexprstatetype_descr(defexprstatetype x); + + std::ostream & + operator<<(std::ostream & os, defexprstatetype x); + /** @class define_xs * @brief state to provide parsing of a define-expression **/ diff --git a/include/xo/reader/envframestack.hpp b/include/xo/reader/envframestack.hpp index ac933dae..e438f47f 100644 --- a/include/xo/reader/envframestack.hpp +++ b/include/xo/reader/envframestack.hpp @@ -65,7 +65,10 @@ namespace xo { inline std::ostream & operator<< (std::ostream & os, const envframestack * x) { - x->print(os); + if (x) + x->print(os); + else + os << "nullptr"; return os; } } /*namespace scm*/ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 5af05f86..8c5c9d6a 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -189,6 +189,15 @@ namespace xo { x.print(os); return os; } + + inline std::ostream & + operator<< (std::ostream & os, const exprstate * x) { + if (x) + x->print(os); + else + os << "nullptr"; + return os; + }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader/exprstatestack.hpp b/include/xo/reader/exprstatestack.hpp index c5ee0894..36fe15b4 100644 --- a/include/xo/reader/exprstatestack.hpp +++ b/include/xo/reader/exprstatestack.hpp @@ -6,6 +6,7 @@ #pragma once #include "exprstate.hpp" +#include "xo/indentlog/print/vector.hpp" namespace xo { namespace scm { diff --git a/include/xo/reader/paren_xs.hpp b/include/xo/reader/paren_xs.hpp index 429a2a6e..514074d1 100644 --- a/include/xo/reader/paren_xs.hpp +++ b/include/xo/reader/paren_xs.hpp @@ -19,6 +19,15 @@ namespace xo { n_parenexprstatetype, }; + extern const char * + parenexprstatetype_descr(parenexprstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, parenexprstatetype x) { + os << parenexprstatetype_descr(x); + return os; + } + /** @class paren_xs * @brief state machine for handling parentheses in expressions **/ diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index e23cd262..ac3c5cd8 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -21,6 +21,7 @@ namespace xo { public: using Expression = xo::ast::Expression; using Variable = xo::ast::Variable; + using token_type = token; public: parserstatemachine(exprstatestack * p_stack, @@ -42,6 +43,18 @@ namespace xo { void push_envframe(envframe x); void pop_envframe(); + // ----- parsing outputs ----- + + void on_symbol(const std::string & symbol); + + // ---- parsing inputs ----- + + void on_leftbrace_token(const token_type & tk); + void on_rightbrace_token(const token_type & tk); + + /** write human-readable representation on @p os **/ + void print(std::ostream & os) const; + public: /** stack of incomplete parser work. * generally speaking, push when to start new work for nested content; @@ -55,6 +68,12 @@ namespace xo { **/ rp * p_emit_expr_; }; + + inline std::ostream & + operator<<(std::ostream & os, const parserstatemachine & x) { + x.print(os); + return os; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 04c37c5b..88ddb9d3 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -9,6 +9,33 @@ namespace xo { namespace scm { + // ----- defexprstatetype ----- + + const char * + defexprstatetype_descr(defexprstatetype x) { + switch(x) { + case defexprstatetype::invalid: return "invalid"; + case defexprstatetype::def_0: return "def_0"; + case defexprstatetype::def_1: return "def_1"; + case defexprstatetype::def_2: return "def_2"; + case defexprstatetype::def_3: return "def_3"; + case defexprstatetype::def_4: return "def_4"; + case defexprstatetype::def_5: return "def_5"; + case defexprstatetype::def_6: return "def_6"; + case defexprstatetype::n_defexprstatetype: break; + } + + return "???defexprstatetype"; + } + + std::ostream & + operator<<(std::ostream & os, defexprstatetype x) { + os << defexprstatetype_descr(x); + return os; + } + + // ----- define_xs ----- + std::unique_ptr define_xs::make() { return std::make_unique(define_xs(DefineExprAccess::make_empty())); @@ -17,6 +44,9 @@ namespace xo { void define_xs::start(parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + p_psm->push_exprstate(define_xs::make()); p_psm->top_exprstate().on_def_token(token_type::def(), p_psm); } @@ -31,6 +61,11 @@ namespace xo { define_xs::on_expr(ref::brw expr, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log("defxs_type", defxs_type_); + if (this->defxs_type_ == defexprstatetype::def_5) { /* have all the ingredients to create an expression * representing a definition @@ -59,6 +94,11 @@ namespace xo { define_xs::on_symbol(const std::string & symbol_name, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log("defxs_type", defxs_type_); + if (this->defxs_type_ == defexprstatetype::def_1) { this->defxs_type_ = defexprstatetype::def_2; this->def_expr_->assign_lhs_name(symbol_name); @@ -72,6 +112,11 @@ namespace xo { define_xs::on_typedescr(TypeDescr td, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log("defxs_type", defxs_type_); + if (this->defxs_type_ == defexprstatetype::def_3) { this->defxs_type_ = defexprstatetype::def_4; this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, @@ -92,7 +137,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - //constexpr const char * self_name = "define_xs::on_def_token"; + log && log("defxs_type", defxs_type_); if (this->defxs_type_ == defexprstatetype::def_0) { this->defxs_type_ = defexprstatetype::def_1; @@ -110,7 +155,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - //constexpr const char * self_name = "define_xs::on_colon_token"; + log && log("defxs_type", defxs_type_); if (this->defxs_type_ == defexprstatetype::def_2) { this->defxs_type_ = defexprstatetype::def_3; @@ -128,7 +173,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - //constexpr const char * self_name = "exprstate::on_semicolon"; + log && log("defxs_type", defxs_type_); if (this->defxs_type_ == defexprstatetype::def_6) { rp expr = this->def_expr_; @@ -150,6 +195,8 @@ namespace xo { constexpr const char * self_name = "exprstate::on_singleassign"; + log && log("defxs_type", defxs_type_); + /* * def foo = 1 ; * def foo : f64 = 1 ; @@ -203,7 +250,9 @@ namespace xo { void define_xs::print(std::ostream & os) const { os << "top_exprstate().on_rightbrace_token(tk, p_psm); + p_psm->on_rightbrace_token(tk); } else { exprstate::on_rightbrace_token(tk, p_psm); } diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index 930d12b0..27a94b64 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -33,9 +33,7 @@ namespace xo { */ std::unique_ptr self = p_psm->pop_exprstate(); - - p_psm->top_exprstate().on_symbol(tk.text(), p_psm); - return; + p_psm->on_symbol(tk.text()); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 64aa65b2..f472b070 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -271,6 +271,7 @@ namespace xo { scope log(XO_DEBUG(c_debug_flag)); log && log(xtag("tk", tk)); log && log(xtag("state", *this)); + log && log(xtag("psm", *p_psm)); switch (tk.tk_type()) { @@ -405,6 +406,7 @@ namespace xo { void exprstate::print(std::ostream & os) const { os << ""; } diff --git a/src/reader/exprstatestack.cpp b/src/reader/exprstatestack.cpp index 07ca85bb..2e070c48 100644 --- a/src/reader/exprstatestack.cpp +++ b/src/reader/exprstatestack.cpp @@ -23,7 +23,7 @@ namespace xo { exprstatestack::push_exprstate(std::unique_ptr exs) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), - xtag("exs", *exs)); + xtag("exs", exs.get())); std::size_t z = stack_.size(); @@ -59,7 +59,7 @@ namespace xo { for (std::size_t i = 0, z = stack_.size(); i < z; ++i) { os << " [" << z-i-1 << "] " - << stack_[i] + << stack_[i].get() << std::endl; } diff --git a/src/reader/let1_xs.cpp b/src/reader/let1_xs.cpp index e9c17651..0afbd415 100644 --- a/src/reader/let1_xs.cpp +++ b/src/reader/let1_xs.cpp @@ -39,8 +39,7 @@ namespace xo { const rp & rhs, parserstatemachine * p_psm) { - p_psm->push_exprstate(let1_xs::make(std::move(lhs_name), - std::move(rhs))); + p_psm->push_exprstate(let1_xs::make(lhs_name, rhs)); expect_expr_xs::start(true /*allow_defs*/, true /*cxl_on_rightbrace*/, @@ -111,7 +110,7 @@ namespace xo { * -- remember we pushed let1_xs to handle an embedded def-expr * in a sequence */ - p_psm->top_exprstate().on_rightbrace_token(tk, p_psm); + p_psm->on_rightbrace_token(tk); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 5b1974cc..25af9ee2 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -8,8 +8,22 @@ namespace xo { namespace scm { + const char * + parenexprstatetype_descr(parenexprstatetype x) + { + switch(x) { + case parenexprstatetype::invalid: return "invalid"; + case parenexprstatetype::lparen_0: return "lparen_0"; + case parenexprstatetype::lparen_1: return "lparen_1"; + case parenexprstatetype::n_parenexprstatetype: break; + } + + return "???parenexprstatetype"; + } + paren_xs::paren_xs() - : parenxs_type_{parenexprstatetype::lparen_0} + : exprstate(exprstatetype::parenexpr), + parenxs_type_{parenexprstatetype::lparen_0} {} std::unique_ptr @@ -221,13 +235,15 @@ namespace xo { void paren_xs::print(std::ostream & os) const { os << ""; } - } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/parserstatemachine.cpp b/src/reader/parserstatemachine.cpp index 2e2abd2c..9ed21d0a 100644 --- a/src/reader/parserstatemachine.cpp +++ b/src/reader/parserstatemachine.cpp @@ -47,6 +47,54 @@ namespace xo { p_env_stack_->pop_envframe(); } + + void + parserstatemachine::on_symbol(const std::string & x) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("x", x), + xtag("psm", *this)); + + this->p_stack_ + ->top_exprstate().on_symbol(x, this); + } + + void + parserstatemachine::on_leftbrace_token(const token_type & tk) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk), + xtag("psm", *this)); + + this->p_stack_ + ->top_exprstate().on_leftbrace_token(tk, this); + } + + void + parserstatemachine::on_rightbrace_token(const token_type & tk) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk), + xtag("psm", *this)); + + this->p_stack_ + ->top_exprstate().on_rightbrace_token(tk, this); + } + + void + parserstatemachine::print(std::ostream & os) const { + os << ""; + } } /*namespace scm*/ } /*namespace xo*/ From bc30b34bc23cd5129096d89ea59d3c20062d6c84 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Aug 2024 09:33:58 -0400 Subject: [PATCH 189/191] xo-reader: + on_expr_with_semicolon() [wip, utest not passing] --- include/xo/reader/define_xs.hpp | 2 ++ include/xo/reader/expect_expr_xs.hpp | 6 ++++++ include/xo/reader/exprstate.hpp | 4 ++++ include/xo/reader/lambda_xs.hpp | 2 ++ include/xo/reader/parserstatemachine.hpp | 3 +++ src/reader/define_xs.cpp | 7 +++++++ src/reader/expect_expr_xs.cpp | 15 ++++++++++++++ src/reader/exprstate.cpp | 13 ++++++++++++ src/reader/lambda_xs.cpp | 8 ++++++++ src/reader/parserstatemachine.cpp | 26 ++++++++++++++++++++++++ src/reader/progress_xs.cpp | 4 ++-- 11 files changed, 88 insertions(+), 2 deletions(-) diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index 13b3d558..880dd309 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -81,6 +81,8 @@ namespace xo { virtual void on_expr(ref::brw expr, parserstatemachine * p_psm) override; + virtual void on_expr_with_semicolon(ref::brw expr, + parserstatemachine * p_psm) override; virtual void on_symbol(const std::string & symbol_name, parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index c3e8a513..646a803a 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -47,6 +47,12 @@ namespace xo { /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(ref::brw expr, parserstatemachine * p_psm) override; + /** update exprstate in response to a successfully-parsed subexpression, + * that's terminated by semicolon ';' + **/ + virtual void on_expr_with_semicolon(ref::brw expr, + parserstatemachine * p_psm) override; + private: static std::unique_ptr make(bool allow_defs, diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index 8c5c9d6a..a6acad1f 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -107,6 +107,10 @@ namespace xo { virtual void on_expr(ref::brw expr, parserstatemachine * p_psm); + /** update exprstate in response to a successfully-parsed subexpression, that ends with semicolon **/ + virtual void on_expr_with_semicolon(ref::brw expr, + parserstatemachine * p_psm); + /** update exprstate when expecting a symbol **/ virtual void on_symbol(const std::string & symbol, parserstatemachine * p_psm); diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 79c084ab..830135a3 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -48,6 +48,8 @@ namespace xo { parserstatemachine * p_psm) override; virtual void on_expr(ref::brw expr, parserstatemachine * p_psm) override; + virtual void on_expr_with_semicolon(ref::brw expr, + parserstatemachine * p_psm) override; virtual void on_semicolon_token(const token_type & tk, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index ac3c5cd8..065513c5 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -45,10 +45,13 @@ namespace xo { // ----- parsing outputs ----- + void on_expr(ref::brw expr); + void on_expr_with_semicolon(ref::brw expr); void on_symbol(const std::string & symbol); // ---- parsing inputs ----- + void on_semicolon_token(const token_type & tk); void on_leftbrace_token(const token_type & tk); void on_rightbrace_token(const token_type & tk); diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index 88ddb9d3..d251652a 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -88,6 +88,13 @@ namespace xo { } exprstate::on_expr(expr, p_psm); + void + define_xs::on_expr_with_semicolon(ref::brw expr, + parserstatemachine * p_psm) + { + this->on_expr(expr, p_psm); + /* semicolon is allowed to terminate def expr */ + this->on_semicolon_token(token_type::semicolon(), p_psm); } void diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 3fe2aacf..af27d720 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -195,6 +195,21 @@ namespace xo { p_psm->top_exprstate().on_expr(expr, p_psm); } /*on_expr*/ + void + expect_expr_xs::on_expr_with_semicolon(ref::brw expr, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr.promote())); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr_with_semicolon(expr); + } /*on_expr_with_semicolon*/ + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index f472b070..550e20d0 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -387,6 +387,19 @@ namespace xo { assert(false); } /*on_expr*/ + void + exprstate::on_expr_with_semicolon(ref::brw expr, + parserstatemachine * /*p_psm*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr)); + + assert(false); + } /*on_expr_with_semicolon*/ + void exprstate::on_symbol(const std::string & symbol_name, parserstatemachine * /*p_psm*/) diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 00fb5c0e..8aed4511 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -66,6 +66,14 @@ namespace xo { } } + void + lambda_xs::on_expr_with_semicolon(ref::brw expr, + parserstatemachine * p_psm) + { + this->on_expr(expr, p_psm); + this->on_semicolon_token(token_type::semicolon(), p_psm); + } + void lambda_xs::on_semicolon_token(const token_type & tk, parserstatemachine * p_psm) diff --git a/src/reader/parserstatemachine.cpp b/src/reader/parserstatemachine.cpp index 9ed21d0a..44700814 100644 --- a/src/reader/parserstatemachine.cpp +++ b/src/reader/parserstatemachine.cpp @@ -48,6 +48,32 @@ namespace xo { p_env_stack_->pop_envframe(); } + void + parserstatemachine::on_expr(ref::brw x) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("x", x), + xtag("psm", *this)); + + this->p_stack_ + ->top_exprstate().on_expr(x, this); + } + + void + parserstatemachine::on_expr_with_semicolon(ref::brw x) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("x", x), + xtag("psm", *this)); + + this->p_stack_ + ->top_exprstate().on_expr_with_semicolon(x, this); + } + void parserstatemachine::on_symbol(const std::string & x) { diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index fcb32142..d716bd0c 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -215,7 +215,7 @@ namespace xo { } void - progress_xs::on_semicolon_token(const token_type & tk, + progress_xs::on_semicolon_token(const token_type & /*tk*/, parserstatemachine * p_psm) { /* note: implementation parllels .on_rightparen_token() */ @@ -227,7 +227,7 @@ namespace xo { std::unique_ptr self = p_psm->pop_exprstate(); - p_psm->top_exprstate().on_expr(expr, p_psm); + p_psm->on_expr_with_semicolon(expr); /* control here on input like: * (1.234; From 84e6d3f347b23c0f109a06c74b6503d6d75312bf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Aug 2024 09:34:30 -0400 Subject: [PATCH 190/191] xo-reader: ++ logging --- include/xo/reader/exprstatestack.hpp | 5 ++++- include/xo/reader/lambda_xs.hpp | 11 +++++++++++ src/reader/define_xs.cpp | 24 ++++++++++++++---------- src/reader/expect_expr_xs.cpp | 5 +++-- src/reader/lambda_xs.cpp | 24 ++++++++++++++++++++++++ src/reader/paren_xs.cpp | 1 + src/reader/parserstatemachine.cpp | 13 +++++++++++++ src/reader/progress_xs.cpp | 10 ++++------ 8 files changed, 74 insertions(+), 19 deletions(-) diff --git a/include/xo/reader/exprstatestack.hpp b/include/xo/reader/exprstatestack.hpp index 36fe15b4..b4e57449 100644 --- a/include/xo/reader/exprstatestack.hpp +++ b/include/xo/reader/exprstatestack.hpp @@ -57,7 +57,10 @@ namespace xo { inline std::ostream & operator<< (std::ostream & os, const exprstatestack * x) { - x->print(os); + if (x) + x->print(os); + else + os << "nullptr"; return os; } } /*namespace scm*/ diff --git a/include/xo/reader/lambda_xs.hpp b/include/xo/reader/lambda_xs.hpp index 830135a3..728bc9e3 100644 --- a/include/xo/reader/lambda_xs.hpp +++ b/include/xo/reader/lambda_xs.hpp @@ -32,6 +32,15 @@ namespace xo { n_lambdastatetype }; + extern const char * + lambdastatetype_descr(lambdastatetype x); + + inline std::ostream & + operator<< (std::ostream & os, lambdastatetype x) { + os << lambdastatetype_descr(x); + return os; + } + /** @class lambda_xs * @brief parsing state-machine for a lambda-expression * @@ -53,6 +62,8 @@ namespace xo { virtual void on_semicolon_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void print(std::ostream & os) const override; + private: static std::unique_ptr make(); diff --git a/src/reader/define_xs.cpp b/src/reader/define_xs.cpp index d251652a..19f6d83d 100644 --- a/src/reader/define_xs.cpp +++ b/src/reader/define_xs.cpp @@ -64,7 +64,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - log && log("defxs_type", defxs_type_); + log && log(xtag("defxs_type", defxs_type_)); if (this->defxs_type_ == defexprstatetype::def_5) { /* have all the ingredients to create an expression @@ -84,10 +84,11 @@ namespace xo { rp def_expr = this->def_expr_; this->defxs_type_ = defexprstatetype::def_6; - return; + } else { + exprstate::on_expr(expr, p_psm); } + } - exprstate::on_expr(expr, p_psm); void define_xs::on_expr_with_semicolon(ref::brw expr, parserstatemachine * p_psm) @@ -177,6 +178,8 @@ namespace xo { define_xs::on_semicolon_token(const token_type & tk, parserstatemachine * p_psm) { + /* def expr consumes semicolon */ + constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -200,7 +203,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_singleassign"; + constexpr const char * self_name = "define_xs::on_singleassign_token"; log && log("defxs_type", defxs_type_); @@ -237,7 +240,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_rightparen"; + constexpr const char * self_name = "define_xs::on_rightparen"; this->illegal_input_error(self_name, tk); } @@ -249,7 +252,7 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); - constexpr const char * self_name = "exprstate::on_f64"; + constexpr const char * self_name = "define_xs::on_f64"; this->illegal_input_error(self_name, tk); } @@ -257,13 +260,14 @@ namespace xo { void define_xs::print(std::ostream & os) const { os << ""; } } /*namespace scm*/ diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index af27d720..3d238ede 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -31,7 +31,8 @@ namespace xo { void expect_expr_xs::start(bool allow_defs, bool cxl_on_rightbrace, - parserstatemachine * p_psm) { + parserstatemachine * p_psm) + { p_psm->push_exprstate(expect_expr_xs::make(allow_defs, cxl_on_rightbrace)); } @@ -192,7 +193,7 @@ namespace xo { std::unique_ptr self = p_psm->pop_exprstate(); - p_psm->top_exprstate().on_expr(expr, p_psm); + p_psm->on_expr(expr); } /*on_expr*/ void diff --git a/src/reader/lambda_xs.cpp b/src/reader/lambda_xs.cpp index 8aed4511..ab9b73d8 100644 --- a/src/reader/lambda_xs.cpp +++ b/src/reader/lambda_xs.cpp @@ -11,6 +11,22 @@ namespace xo { using xo::ast::Lambda; namespace scm { + const char * + lambdastatetype_descr(lambdastatetype x) { + switch(x) { + case lambdastatetype::invalid: return "invalid"; + case lambdastatetype::lm_0: return "lm_0"; + case lambdastatetype::lm_1: return "lm_1"; + case lambdastatetype::lm_2: return "lm_2"; + case lambdastatetype::lm_3: return "lm_3"; + default: break; + } + + return "???lambdastatetype"; + } + + // ----- lambda_xs - ---- + std::unique_ptr lambda_xs::make() { return std::make_unique(lambda_xs()); @@ -97,6 +113,14 @@ namespace xo { exprstate::on_semicolon_token(tk, p_psm); } + + void + lambda_xs::print(std::ostream & os) const { + os << ""; + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader/paren_xs.cpp b/src/reader/paren_xs.cpp index 25af9ee2..2c4ca484 100644 --- a/src/reader/paren_xs.cpp +++ b/src/reader/paren_xs.cpp @@ -235,6 +235,7 @@ namespace xo { void paren_xs::print(std::ostream & os) const { os << "top_exprstate().on_symbol(x, this); } + void + parserstatemachine::on_semicolon_token(const token_type & tk) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk), + xtag("psm", *this)); + + this->p_stack_ + ->top_exprstate().on_semicolon_token(tk, this); + } + void parserstatemachine::on_leftbrace_token(const token_type & tk) { diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index d716bd0c..47bf2c04 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -237,14 +237,11 @@ namespace xo { * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] * (see exprstate::on_f64()) * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] - * deliver expresssion to expect_rhs_expression.on_expr() - * (see exprstate::on_expr()) + * deliver expresssion to expect_rhs_expression.on_expr_with_semicolon() + * (see exprstate::on_expr_with_semicolon()) * d. expr_rhs_expression forwards expression to [lparen_0] - * e. lparen_0 advances to [lparen_1] - * f. now deliver semicolon; [lparen_1] rejects + * e. lparen_0 would advance to [lparen_1], but rejects semicolon */ - - p_psm->top_exprstate().on_semicolon_token(tk, p_psm); } void @@ -420,6 +417,7 @@ namespace xo { void progress_xs::print(std::ostream & os) const { os << " Date: Wed, 28 Aug 2024 12:58:49 -0400 Subject: [PATCH 191/191] xo-reader: ++ logging --- include/xo/reader/parserstatemachine.hpp | 1 + src/reader/expect_expr_xs.cpp | 16 +++++++++++++--- src/reader/expect_symbol_xs.cpp | 5 +++++ src/reader/exprstate.cpp | 8 ++++++++ src/reader/parserstatemachine.cpp | 13 +++++++++++++ src/reader/progress_xs.cpp | 3 +++ 6 files changed, 43 insertions(+), 3 deletions(-) diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index 065513c5..0e69d44c 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -52,6 +52,7 @@ namespace xo { // ---- parsing inputs ----- void on_semicolon_token(const token_type & tk); + void on_operator_token(const token_type & tk); void on_leftbrace_token(const token_type & tk); void on_rightbrace_token(const token_type & tk); diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index 3d238ede..1f07d131 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -55,10 +55,14 @@ namespace xo { expect_expr_xs::on_def_token(const token_type & tk, parserstatemachine * p_psm) { - if (allow_defs_) + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + if (allow_defs_) { define_xs::start(p_psm); - else + } else { exprstate::on_def_token(tk, p_psm); + } } void @@ -101,6 +105,9 @@ namespace xo { expect_expr_xs::on_rightbrace_token(const token_type & tk, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + if (cxl_on_rightbrace_) { auto self = p_psm->pop_exprstate(); @@ -116,7 +123,10 @@ namespace xo { expect_expr_xs::on_symbol_token(const token_type & tk, parserstatemachine * p_psm) { - /* todo: treat symbol as variable name */ + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk)); /* various possibilities when looking for rhs expression: * diff --git a/src/reader/expect_symbol_xs.cpp b/src/reader/expect_symbol_xs.cpp index 27a94b64..0e01924e 100644 --- a/src/reader/expect_symbol_xs.cpp +++ b/src/reader/expect_symbol_xs.cpp @@ -28,6 +28,11 @@ namespace xo { expect_symbol_xs::on_symbol_token(const token_type & tk, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk)); + /* have to do pop first, before sending symbol to * the o.g. symbol-requester */ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 550e20d0..77480dcb 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -394,9 +394,17 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); + const char * c_self_name = "exprstate::on_expr_with_semicolon"; + log && log(xtag("exstype", this->exs_type_), xtag("expr", expr)); + throw std::runtime_error + (tostr(c_self_name, + ": unexpected expression for parsing state", + xtag("expr", expr), + xtag("state", *this))); + assert(false); } /*on_expr_with_semicolon*/ diff --git a/src/reader/parserstatemachine.cpp b/src/reader/parserstatemachine.cpp index 814c3a3b..373e83e3 100644 --- a/src/reader/parserstatemachine.cpp +++ b/src/reader/parserstatemachine.cpp @@ -100,6 +100,19 @@ namespace xo { ->top_exprstate().on_semicolon_token(tk, this); } + void + parserstatemachine::on_operator_token(const token_type & tk) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk), + xtag("psm", *this)); + + this->p_stack_ + ->top_exprstate().on_operator_token(tk, this); + } + void parserstatemachine::on_leftbrace_token(const token_type & tk) { diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp index 47bf2c04..40d857b6 100644 --- a/src/reader/progress_xs.cpp +++ b/src/reader/progress_xs.cpp @@ -332,6 +332,9 @@ namespace xo { progress_xs::on_operator_token(const token_type & tk, parserstatemachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + constexpr const char * c_self_name = "progress_xs::on_operator_token"; if (op_type_ == optype::invalid) {