From 14c03b7c26ff06835fca631eed6a3e308946321a Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sun, 18 Oct 2026 08:16:01 +0000 Subject: feat(lib): add experimental _EXP_STRING backed by std::string Co-Authored-By: Claude Opus 5.5 --- pseudocode-lib/_exp_string.cc | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 pseudocode-lib/_exp_string.cc (limited to 'pseudocode-lib/_exp_string.cc') diff --git a/pseudocode-lib/_exp_string.cc b/pseudocode-lib/_exp_string.cc new file mode 100644 index 0000000..248b718 --- /dev/null +++ b/pseudocode-lib/_exp_string.cc @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include + +extern "C" int __cps_user_line; + +namespace { +template +decltype(auto) checked(Operation &&Op) { + try { + return std::forward(Op)(); + } catch (const std::exception &Error) { + std::fprintf(stderr, "[Fatal] line %d: %s\n", __cps_user_line, Error.what()); + throw 0; + } +} +std::string &text(void *Handle) { return *static_cast(Handle); } +} + +extern "C" { +void *_exp_string_impl_new() { + return checked([] { return new std::string; }); +} +void *_exp_string_impl_copy(void *Other) { + return checked([&] { return new std::string(text(Other)); }); +} +void *_exp_string_impl_from_cstr(const char *Text) { + return checked([&] { return new std::string(Text); }); +} +void *_exp_string_impl_from_count_char(long long Count, char Ch) { + return checked([&] { + if (Count < 0) throw std::invalid_argument("negative string length"); + return new std::string(static_cast(Count), Ch); + }); +} +void _exp_string_impl_delete(void *Handle) { + checked([&] { delete static_cast(Handle); }); +} +void _exp_string_impl_assign(void *Target, void *Other) { + checked([&] { text(Target) = text(Other); }); +} +void _exp_string_impl_assign_cstr(void *Target, const char *Text) { + checked([&] { text(Target) = Text; }); +} +void _exp_string_impl_concat(void *Target, void *A, void *B) { + checked([&] { text(Target) = text(A) + text(B); }); +} +void _exp_string_impl_from_int(void *Target, long long Number) { + checked([&] { text(Target) = std::to_string(Number); }); +} +void _exp_string_impl_from_real(void *Target, double Number) { + checked([&] { text(Target) = std::to_string(Number); }); +} +double _exp_string_impl_to_real(void *Handle) { + return checked([&] { + std::size_t Consumed = 0; + double Number = std::stod(text(Handle), &Consumed); + if (Consumed != text(Handle).size()) + throw std::invalid_argument("unconsumed characters in string conversion"); + return Number; + }); +} +long long _exp_string_impl_length(void *Handle) { + return checked([&] { return static_cast(text(Handle).size()); }); +} +void _exp_string_impl_output(void *Handle) { + checked([&] { + const auto &Text = text(Handle); + std::fwrite(Text.data(), 1, Text.size(), stdout); + std::fputc('\n', stdout); + }); +} +} -- cgit v1.3.1-4-g156e