From bbe7e518f1583be6a7039de589705cb3d3df5ec0 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 11 Jun 2024 01:38:02 +0900 Subject: [PATCH] Add new member function template `take_until` and `take_while` Signed-off-by: yamacir-kit --- README.md | 6 +-- VERSION | 2 +- include/meevax/kernel/textual_input_port.hpp | 30 +++++++++++-- src/kernel/textual_input_port.cpp | 47 +++++++------------- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 7cca43593..504b31e7b 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Procedures for each standard are provided by the following R7RS-style libraries: cmake -B build -DCMAKE_BUILD_TYPE=Release cd build make package -sudo apt install build/meevax_0.5.202_amd64.deb +sudo apt install build/meevax_0.5.203_amd64.deb ``` or @@ -122,9 +122,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |-------------|------------- -| `all` | Build shared-library `libmeevax.0.5.202.so` and executable `meevax` +| `all` | Build shared-library `libmeevax.0.5.203.so` and executable `meevax` | `test` | Test executable `meevax` -| `package` | Generate debian package `meevax_0.5.202_amd64.deb` +| `package` | Generate debian package `meevax_0.5.203_amd64.deb` | `install` | Copy files into `/usr/local` directly ## Usage diff --git a/VERSION b/VERSION index ea4d26ec1..1ffc6a293 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.202 +0.5.203 diff --git a/include/meevax/kernel/textual_input_port.hpp b/include/meevax/kernel/textual_input_port.hpp index f81cce507..ad80daf01 100644 --- a/include/meevax/kernel/textual_input_port.hpp +++ b/include/meevax/kernel/textual_input_port.hpp @@ -97,13 +97,35 @@ inline namespace kernel */ auto take_character() -> character; - auto take_digits(character = {}) -> std::string; + auto take_nested_block_comment(character = {}, character = {}) -> void; - auto take_line(std::istream::char_type = '\n') -> std::string; + auto take_token(character = {}) -> std::string; + + template + auto take_until(F satisfy, character c = {}) + { + auto s = static_cast(c); - auto take_nested_block_comment(character = {}, character = {}) -> void; // TODO return std::string + while (get_ready() and not satisfy(c = take_character())) + { + s += c; + } - auto take_token(character = {}) -> std::string; + return s; + } + + template + auto take_while(F satisfy, character c = {}) + { + auto s = static_cast(c); + + while (get_ready() and satisfy(peek_character())) + { + s += take_character(); + } + + return s; + } virtual auto istream() -> std::istream & = 0; diff --git a/src/kernel/textual_input_port.cpp b/src/kernel/textual_input_port.cpp index f0cb4960d..1dbc73dee 100644 --- a/src/kernel/textual_input_port.cpp +++ b/src/kernel/textual_input_port.cpp @@ -144,7 +144,7 @@ inline namespace kernel auto textual_input_port::get_line() -> object { - if (auto s = take_line(); istream().eof()) + if (auto s = take_until([](auto c) { return c == '\n'; }); istream().eof()) { return eof_object; } @@ -192,6 +192,11 @@ inline namespace kernel auto textual_input_port::read(character c0) -> object { + auto is_digit = [](auto c) + { + return std::isdigit(c); + }; + while (not peek_character().is_eof()) { switch (auto const c1 = c0 ? c0 : take_character()) @@ -221,7 +226,7 @@ inline namespace kernel } else { - take_line(); + take_until([](auto c) { return c == '\n'; }); } return read(); @@ -247,7 +252,7 @@ inline namespace kernel case '8': case '9': { - auto n = take_digits(c2); + auto n = take_while(is_digit, c2); switch (auto c = take_character()) { @@ -312,7 +317,7 @@ inline namespace kernel return exact(read()); // NOTE: Same as #,(exact (read)) case 'f': - switch (std::stoi(take_digits())) + switch (std::stoi(take_while(is_digit, character('0')))) { case 32: return make(read()); @@ -339,7 +344,7 @@ inline namespace kernel } case 's': - switch (auto const n = take_digits(); std::stoi(n)) + switch (auto n = take_while(is_digit); std::stoi(n)) { case 8: return make(read()); @@ -363,7 +368,7 @@ inline namespace kernel return t; case 'u': - switch (auto const n = take_digits(); std::stoi(n)) + switch (auto const n = take_while(is_digit); std::stoi(n)) { case 8: return make(read()); @@ -428,7 +433,7 @@ inline namespace kernel catch (std::integral_constant const&) { let const x = read(); - take_line(')'); + take_until([](auto c) { return c == ')'; }); return x; } @@ -446,7 +451,7 @@ inline namespace kernel } case ';': // 0x3B - take_line(); + take_until([](auto c) { return c == '\n'; }); break; case '`': // 0x60 @@ -558,14 +563,11 @@ inline namespace kernel case 'r': s.vector.emplace_back('\r'); break; case 't': s.vector.emplace_back('\t'); break; case 'v': s.vector.emplace_back('\v'); break; - case 'x': s.vector.emplace_back(lexical_cast(std::hex, take_line(';'))); break; + case 'x': s.vector.emplace_back(lexical_cast(std::hex, take_until([](auto c) { return c == ';'; }))); break; case '\n': case '\r': - while (std::isspace(peek_character())) - { - take_character(); - } + take_while([](auto c) { return std::isspace(c); }); break; default: @@ -620,25 +622,6 @@ inline namespace kernel } } - auto textual_input_port::take_digits(character c) -> std::string - { - auto s = static_cast(c); - - while (std::isdigit(peek_character())) - { - s += take_character(); - } - - return s.length() ? s : "0"; - } - - auto textual_input_port::take_line(std::istream::char_type delimiter) -> std::string - { - auto s = std::string(); - std::getline(istream(), s, delimiter); - return s; - } - auto textual_input_port::take_nested_block_comment(character sharp, character vertical_line) -> void { while (not peek_character().is_eof())