From ead494e465c3f4b30a6b2bf6739822ecf1418f60 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 2 Feb 2025 17:22:16 +0100 Subject: [PATCH] Invocation: Argument-spec evaluation sufficiently complete for now Some additional tests to challenge the parser, which seems to work well. Without extended analysis into the usage of those node specifications, it is pointless to expand further on its capabilities. For now, it is sufficient to have a foundation for hash-computation in place. __Note__: found a nifty way to give lib::Several an easy toString rendering, without cranking up the header inclusion load. --- src/lib/format-util.hpp | 25 ++++++-- src/lib/several.hpp | 15 +++++ src/steam/engine/proc-node.cpp | 2 +- src/steam/engine/proc-node.hpp | 6 ++ tests/core/steam/engine/node-meta-test.cpp | 44 ++++++++----- tests/library/several-builder-test.cpp | 2 + wiki/thinkPad.ichthyo.mm | 75 +++++++++++++--------- 7 files changed, 118 insertions(+), 51 deletions(-) diff --git a/src/lib/format-util.hpp b/src/lib/format-util.hpp index f0f48b413..1f0fd8bf8 100644 --- a/src/lib/format-util.hpp +++ b/src/lib/format-util.hpp @@ -188,12 +188,12 @@ namespace util { * absolutely generic (In fact that was the reason why I * gave up and just rolled our own `join` utility) */ - template + template inline string - join (CON&& coll, string const& delim =", ") + join (COLL&& coll, string const& delim =", ") { - using Coll = typename lib::meta::Strip::TypePlain; - _RangeIter range(std::forward(coll)); // copies when CON is reference + using Coll = typename lib::meta::Strip::TypePlain; + _RangeIter range(std::forward(coll)); // copies when CON is reference auto strings = stringify (std::move (range.iter)); if (!strings) return ""; @@ -242,5 +242,22 @@ namespace util { } + + /** one-argument variant that can be forward declared... */ + template + inline string + toStringParen (COLL&& coll) + { + return "("+join (forward (coll))+")"; + } + + template + inline string + toStringBracket (COLL&& coll) + { + return "["+join (forward (coll))+"]"; + } + + } // namespace util #endif /*LIB_FORMAT_UTIL_H*/ diff --git a/src/lib/several.hpp b/src/lib/several.hpp index e9570df6c..10d079dd0 100644 --- a/src/lib/several.hpp +++ b/src/lib/several.hpp @@ -57,6 +57,10 @@ #include #include +namespace util { + template + std::string toStringBracket (COLL&& coll); +} namespace lib { @@ -179,6 +183,9 @@ namespace lib { return *this; } + explicit + operator std::string() const; + size_t size() const { @@ -248,5 +255,13 @@ namespace lib { }; + /** generic string rendering delegated to `util::toString(elm)` */ + template + inline + Several::operator std::string() const + { + return util::toStringBracket (*this); + } + } // namespace lib #endif diff --git a/src/steam/engine/proc-node.cpp b/src/steam/engine/proc-node.cpp index 560c31f4a..32fd8cacc 100644 --- a/src/steam/engine/proc-node.cpp +++ b/src/steam/engine/proc-node.cpp @@ -322,7 +322,7 @@ namespace engine { ProcID::ArgModel ProcID::genArgModel() { - auto argListSyntax = accept_bracket(accept_repeated(COMMA, specTermSyntax)); + auto argListSyntax = accept_bracket(accept_repeated(0,MAX_NODE_ARG, COMMA, specTermSyntax)); auto argSpecSyntax = accept(argListSyntax) .opt(argListSyntax) .bind([](auto model) -> ProcID::ArgModel diff --git a/src/steam/engine/proc-node.hpp b/src/steam/engine/proc-node.hpp index 6436f5b8d..634cd5955 100644 --- a/src/steam/engine/proc-node.hpp +++ b/src/steam/engine/proc-node.hpp @@ -129,6 +129,12 @@ namespace engine { using OptionalBuff = std::optional; + /** arbitrary safety limit on fain-in / fan-out + * @note expect lower limits in practice caused by AllocationCluster */ + const size_t MAX_NODE_ARG = LUMIERA_MAX_ORDINAL_NUMBER / 2; + + + class Port : util::NonCopyable { diff --git a/tests/core/steam/engine/node-meta-test.cpp b/tests/core/steam/engine/node-meta-test.cpp index 11d266695..5b224306d 100644 --- a/tests/core/steam/engine/node-meta-test.cpp +++ b/tests/core/steam/engine/node-meta-test.cpp @@ -34,7 +34,7 @@ namespace engine{ namespace test { using std::abs; - using util::join; +// using util::join; @@ -51,8 +51,8 @@ namespace test { } - /** @test TODO evaluation of processing-spec for a ProcID - * @todo WIP 1/25 🔁 define ⟶ 🔁 implement + /** @test evaluation of processing-spec for a ProcID + * @todo 1/25 ✔ define ⟶ ✔ implement */ void verify_ID_specification() @@ -82,24 +82,34 @@ namespace test { ProcID::ArgModel arg1 = p1.genArgModel(); ProcID::ArgModel arg2 = p2.genArgModel(); ProcID::ArgModel arg3 = p3.genArgModel(); -SHOW_EXPR(join (arg1.iArg)) -SHOW_EXPR(join (arg1.oArg)) -SHOW_EXPR(join (arg2.iArg)) -SHOW_EXPR(join (arg2.oArg)) -SHOW_EXPR(join (arg3.iArg)) -SHOW_EXPR(join (arg3.oArg)) - CHECK (join (arg1.iArg) == ""_expect ); - CHECK (join (arg1.oArg) == "arg"_expect ); // only one argument list -> used for output - CHECK (join (arg2.iArg) == ""_expect ); - CHECK (join (arg2.oArg) == "a1, a2"_expect ); - CHECK (join (arg3.iArg) == "in, in, in"_expect ); // repetition-abbreviation of arguments unfolded - CHECK (join (arg3.oArg) == "o1, o2, o2"_expect ); - UNIMPLEMENTED ("parse and evaluate"); + CHECK (not arg1.hasInArgs()); + CHECK (not arg2.hasInArgs()); + CHECK (arg1.outArity() == 1); + CHECK (arg2.outArity() == 2); + CHECK (arg3.outArity() == 3); + CHECK (arg3.inArity() == 3); + CHECK (arg1.iArg == "[]"_expect ); + CHECK (arg1.oArg == "[arg]"_expect ); // only one argument list -> used for output + CHECK (arg2.iArg == "[]"_expect ); + CHECK (arg2.oArg == "[a1, a2]"_expect ); + CHECK (arg3.iArg == "[in, in, in]"_expect ); // repetition-abbreviation of arguments unfolded + CHECK (arg3.oArg == "[o1, o2, o2]"_expect ); + + // give the spec-parser a rough time.... + string nastySpec = "(\":-)\"/2,std::tuple/3,{oh,RLY?}/2,\\\")"; + auto hairyModel = ProcID::describe("○", nastySpec).genArgModel(); + CHECK (hairyModel.outArity() == 8); + CHECK (hairyModel.inArity() == 0); + CHECK (hairyModel.oArg == "[\":-)\", \":-)\", " + "std::tuple, " + "std::tuple, " + "std::tuple, " + "{oh,RLY?}, {oh,RLY?}, \\\"]"_expect); } /** @test TODO aspects of node definition relevant for the ProcID - * @todo WIP 1/25 🔁 define ⟶ implement + * @todo WIP 2/25 🔁 define ⟶ implement */ void verify_ID_properties() diff --git a/tests/library/several-builder-test.cpp b/tests/library/several-builder-test.cpp index 2ee0bc1a7..9d7aa3986 100644 --- a/tests/library/several-builder-test.cpp +++ b/tests/library/several-builder-test.cpp @@ -36,6 +36,7 @@ using std::array; using lib::explore; using util::isLimited; +using util::toString; using util::isnil; using util::join; @@ -161,6 +162,7 @@ namespace test{ CHECK (elms.back() == 13); CHECK (elms[3] == 3); CHECK (join (elms,"-") == "1-1-2-3-5-8-13"_expect); + CHECK (toString(elms) == "[1, 1, 2, 3, 5, 8, 13]"_expect); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index bf4a8cbdd..281c45724 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -105306,8 +105306,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - + + @@ -105341,9 +105341,13 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + - - + + + @@ -105386,6 +105390,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + @@ -105427,9 +105432,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - + + + + @@ -105496,7 +105502,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -105511,8 +105517,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - + + + + @@ -105539,7 +105547,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + + + @@ -105563,9 +105573,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + - + @@ -105606,7 +105616,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -105630,8 +105640,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) ...wenn man's genau bedenkt: wäre praktisch äquivalent

- - +
@@ -105653,15 +105662,14 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) in einer LL-Syntax kann man nicht mit einer optionalen Struktur beginnen, die sich erst im Rückblick auf die ganze Zeile aufklärt

- - +
- - - + + + @@ -105705,8 +105713,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + + @@ -105754,8 +105763,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) Pipeline zum Aufbereiten der Argumente an

- - + @@ -105769,13 +105777,13 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) Aber trotzdem immer noch nicht der leiseste Hauch von Erinnerung, was ich damals gemeint habe....

- -
+
- + + @@ -105785,11 +105793,14 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)

+
- + + - + + @@ -105821,6 +105832,12 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + +