From 23fb22e020353717e0b3ff511f1467a208ef7ba9 Mon Sep 17 00:00:00 2001 From: Lexy Plt Date: Mon, 2 Mar 2026 12:43:50 +0100 Subject: [PATCH 1/2] feat(format builtin): new format specifiers for lists --- CHANGELOG.md | 6 + src/arkreactor/Builtins/String.cpp | 165 +++++++++++++++++- .../runtime/format_list_invalid.ark | 1 + .../runtime/format_list_invalid.expected | 6 + .../runtime/format_list_invalid_debug.ark | 1 + .../format_list_invalid_debug.expected | 6 + .../runtime/format_list_invalid_na.ark | 1 + .../runtime/format_list_invalid_na.expected | 6 + .../resources/LangSuite/string-tests.ark | 11 +- 9 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.expected diff --git a/CHANGELOG.md b/CHANGELOG.md index 06be61d64..1deabebf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ ### Added - new debugger commands: `stack ` and `locals ` to print the values on the stack and in the current locals scope +- custom format specifiers for lists: + - `:n` to remove surrounding brackets, + - `:c` / `:nc` to use `, ` as a separator instead of ` `, + - `:l` / `:nl` to use `\n` as a separator, + - `:?s` to format as an escaped quoted string, + - `:s` to format as a quoted string ### Changed diff --git a/src/arkreactor/Builtins/String.cpp b/src/arkreactor/Builtins/String.cpp index e74edbf85..79a7aff5e 100644 --- a/src/arkreactor/Builtins/String.cpp +++ b/src/arkreactor/Builtins/String.cpp @@ -1,20 +1,172 @@ #include #include +#include #include #include +#include +#include #include +#include #include #include #include +struct value_wrapper +{ + const Ark::Value& value; + Ark::VM* vm_ptr; +}; + +template <> +struct fmt::formatter +{ +private: + fmt::basic_string_view opening_bracket_ = fmt::detail::string_literal {}; + fmt::basic_string_view closing_bracket_ = fmt::detail::string_literal {}; + fmt::basic_string_view separator_ = fmt::detail::string_literal {}; + bool is_debug = false; + fmt::formatter underlying_; + +public: + void set_brackets(const fmt::basic_string_view open, const fmt::basic_string_view close) + { + opening_bracket_ = open; + closing_bracket_ = close; + } + + void set_separator(const fmt::basic_string_view sep) + { + separator_ = sep; + } + + format_parse_context::iterator parse(fmt::format_parse_context& ctx) + { + auto it = ctx.begin(); + const auto end = ctx.end(); + if (it == end) + return underlying_.parse(ctx); + + switch (detail::to_ascii(*it)) + { + case 'n': + set_brackets({}, {}); + ++it; + if (it == end) + report_error("invalid format specifier"); + if (*it == '}') + return it; + if (*it != 'c' && *it != 'l') + report_error("invalid format specifier. Expected either :nc or :nl"); + [[fallthrough]]; + + case 'c': + if (*it == 'c') + { + set_separator(fmt::detail::string_literal {}); + ++it; + return it; + } + [[fallthrough]]; + + case 'l': + set_separator(fmt::detail::string_literal {}); + ++it; + return it; + + case '?': + is_debug = true; + set_brackets({}, {}); + ++it; + if (it == end || *it != 's') + report_error("invalid format specifier. Expected :?s, not :?"); + [[fallthrough]]; + + case 's': + if (!is_debug) + { + set_brackets(fmt::detail::string_literal {}, + fmt::detail::string_literal {}); + set_separator({}); + } + ++it; + return it; + + default: + break; + } + + if (it != end && *it != '}') + { + if (*it != ':') + report_error("invalid format specifier"); + ++it; + } + + ctx.advance_to(it); + return underlying_.parse(ctx); + } + + template + auto write_debug_string(Output& out, It it, Sentinel end, Ark::VM* vm_ptr) const -> Output + { + auto buf = fmt::basic_memory_buffer(); + for (; it != end; ++it) + { + auto formatted = it->toString(*vm_ptr); + buf.append(formatted); + } + auto specs = fmt::format_specs(); + specs.set_type(fmt::presentation_type::debug); + return fmt::detail::write( + out, + fmt::basic_string_view(buf.data(), buf.size()), + specs); + } + + fmt::format_context::iterator format(const value_wrapper& value, fmt::format_context& ctx) const + { + auto out = ctx.out(); + auto it = fmt::detail::range_begin(value.value.constList()); + const auto end = fmt::detail::range_end(value.value.constList()); + if (is_debug) + return write_debug_string(out, it, end, value.vm_ptr); + + out = fmt::detail::copy(opening_bracket_, out); + for (int i = 0; it != end; ++it) + { + if (i > 0) + out = fmt::detail::copy(separator_, out); + ctx.advance_to(out); + auto&& item = *it; + auto formatted = item.toString(*value.vm_ptr); + out = underlying_.format(formatted, ctx); + ++i; + } + out = detail::copy(closing_bracket_, out); + return out; + } +}; + namespace Ark::internal::Builtins::String { /** * @name format * @brief Format a String given replacements - * @details https://fmt.dev/12.0/syntax/ + * @details See [fmt.dev](https://fmt.dev/12.0/syntax/) for syntax. + * =details-begin + * In the case of lists, we have custom specifiers: + * - `n` removes surrounding brackets, uses ' ' as a separator + * - `?s` debug format. The list is formatted as an escaped string + * - `s` string format. The list is formatted as a string + * - `c` changes the separator to ', ' + * - `l` changes the separator to '\n' + * + * `n` can be combined with either `c` and `l` (which are mutually exclusive): `nc`, `nl`. + * + * The underlying formatter is the one of strings, so you can write `::<10` to align all elements left in a 10 char wide block each. + * =details-end * @param format the String to format * @param values as any argument as you need, of any valid ArkScript type * =begin @@ -49,6 +201,17 @@ namespace Ark::internal::Builtins::String store.push_back("true"); else if (it->valueType() == ValueType::False) store.push_back("false"); + else if (it->valueType() == ValueType::List) + { + // std::vector r; + // std::ranges::transform( + // it->list(), + // std::back_inserter(r), + // [&vm](const Value& val) -> value_wrapper { + // return value_wrapper { val, vm }; + // }); + store.push_back(value_wrapper { *it, vm }); + } else store.push_back(it->toString(*vm)); } diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.ark new file mode 100644 index 000000000..845bd71b4 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.ark @@ -0,0 +1 @@ +(print (format "{:d}" [])) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.expected new file mode 100644 index 000000000..8fefe45d6 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.expected @@ -0,0 +1,6 @@ +format: can not format "{:d}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid.ark:1 + 1 | (print (format "{:d}" [])) + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.ark new file mode 100644 index 000000000..f51cc17a3 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.ark @@ -0,0 +1 @@ +(print (format "{:?}" [])) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.expected new file mode 100644 index 000000000..496a69194 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.expected @@ -0,0 +1,6 @@ +format: can not format "{:?}" (1 argument provided) because of invalid format specifier. Expected :?s, not :? + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_debug.ark:1 + 1 | (print (format "{:?}" [])) + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.ark new file mode 100644 index 000000000..f86ffd2fc --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.ark @@ -0,0 +1 @@ +(print (format "{:na}" [])) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.expected new file mode 100644 index 000000000..e19daa93c --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.expected @@ -0,0 +1,6 @@ +format: can not format "{:na}" (1 argument provided) because of invalid format specifier. Expected either :nc or :nl + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_list_invalid_na.ark:1 + 1 | (print (format "{:na}" [])) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/LangSuite/string-tests.ark b/tests/unittests/resources/LangSuite/string-tests.ark index d297f2474..b94ec6ff2 100644 --- a/tests/unittests/resources/LangSuite/string-tests.ark +++ b/tests/unittests/resources/LangSuite/string-tests.ark @@ -58,4 +58,13 @@ (test:case "format strings" { (test:eq "nilfalsetrue" (format "{}{}{}" nil false true)) - (test:eq "CProcedure" (format "{}" print)) })}) + (test:eq "CProcedure" (format "{}" print)) + (test:eq (format "{::}" ["hel\tlo" 1 nil true]) "[hel lo 1 nil true]") + (test:eq (format "{:n}" ["hel\tlo" 1 nil true]) "hel lo 1 nil true") + (test:eq (format "{:?s}" ["hel\tlo" 1 nil true]) "\"hel\\tlo1niltrue\"") + (test:eq (format "{:s}" ["hel\tlo" 1 nil true]) "\"hel lo1niltrue\"") + (test:eq (format "{:c}" ["hel\tlo" 1 nil true]) "[hel lo, 1, nil, true]") + (test:eq (format "{:l}" ["hel\tlo" 1 nil true]) "[hel lo\n1\nnil\ntrue]") + (test:eq (format "{:nc}" ["hel\tlo" 1 nil true]) "hel lo, 1, nil, true") + (test:eq (format "{:nl}" ["hel\tlo" 1 nil true]) "hel lo\n1\nnil\ntrue") + (test:eq (format "{::<10}" ["hel\tlo" 1 nil true]) "[hel lo 1 nil true ]") })}) From 313fbdde9f52178eb37f18b3352ae8b712b3d470 Mon Sep 17 00:00:00 2001 From: Lexy Plt Date: Mon, 2 Mar 2026 18:03:47 +0100 Subject: [PATCH 2/2] feat(format builtin): support integer format specifiers when the given number can be represented as one --- CHANGELOG.md | 1 + src/arkreactor/Builtins/String.cpp | 36 +++++++++++++++---- .../runtime/format_double_b.ark | 1 + .../runtime/format_double_b.expected | 6 ++++ .../runtime/format_double_c.ark | 1 + .../runtime/format_double_c.expected | 6 ++++ .../runtime/format_double_d.ark | 1 + .../runtime/format_double_d.expected | 6 ++++ .../runtime/format_double_hashtag_b.ark | 1 + .../runtime/format_double_hashtag_b.expected | 6 ++++ .../runtime/format_double_hashtag_upper_b.ark | 1 + .../format_double_hashtag_upper_b.expected | 6 ++++ .../runtime/format_double_hashtag_upper_x.ark | 1 + .../format_double_hashtag_upper_x.expected | 6 ++++ .../runtime/format_double_hashtag_x.ark | 1 + .../runtime/format_double_hashtag_x.expected | 6 ++++ .../runtime/format_double_o.ark | 1 + .../runtime/format_double_o.expected | 6 ++++ .../runtime/format_double_upper_b.ark | 1 + .../runtime/format_double_upper_b.expected | 6 ++++ .../runtime/format_double_upper_x.ark | 1 + .../runtime/format_double_upper_x.expected | 6 ++++ .../runtime/format_double_x.ark | 1 + .../runtime/format_double_x.expected | 6 ++++ .../resources/LangSuite/string-tests.ark | 32 ++++++++++++----- 25 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.expected create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.ark create mode 100644 tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.expected diff --git a/CHANGELOG.md b/CHANGELOG.md index 1deabebf2..28bc4138b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - `:l` / `:nl` to use `\n` as a separator, - `:?s` to format as an escaped quoted string, - `:s` to format as a quoted string +- `format` can use format specifiers for integers: `b`, `#b`, `B`, `#B`, `c`, `d`, `o`, `x`, `#x`, `X`, and `#X` if the argument is an integer ### Changed diff --git a/src/arkreactor/Builtins/String.cpp b/src/arkreactor/Builtins/String.cpp index 79a7aff5e..16a880bd0 100644 --- a/src/arkreactor/Builtins/String.cpp +++ b/src/arkreactor/Builtins/String.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include #include @@ -17,6 +17,7 @@ struct value_wrapper { const Ark::Value& value; Ark::VM* vm_ptr; + bool nested = false; }; template <> @@ -27,6 +28,7 @@ struct fmt::formatter fmt::basic_string_view closing_bracket_ = fmt::detail::string_literal {}; fmt::basic_string_view separator_ = fmt::detail::string_literal {}; bool is_debug = false; + bool is_literal_str = false; fmt::formatter underlying_; public: @@ -89,6 +91,7 @@ struct fmt::formatter set_brackets(fmt::detail::string_literal {}, fmt::detail::string_literal {}); set_separator({}); + is_literal_str = true; } ++it; return it; @@ -133,18 +136,33 @@ struct fmt::formatter if (is_debug) return write_debug_string(out, it, end, value.vm_ptr); - out = fmt::detail::copy(opening_bracket_, out); + if ((is_literal_str && !value.nested) || !is_literal_str) + out = fmt::detail::copy(opening_bracket_, out); + for (int i = 0; it != end; ++it) { if (i > 0) out = fmt::detail::copy(separator_, out); ctx.advance_to(out); + auto&& item = *it; - auto formatted = item.toString(*value.vm_ptr); - out = underlying_.format(formatted, ctx); + if (item.valueType() == Ark::ValueType::List) + { + // if :s, do not put surrounding "" here + format({ item, value.vm_ptr, /* nested= */ true }, ctx); + } + else + { + std::string formatted = item.toString(*value.vm_ptr); + out = underlying_.format(formatted, ctx); + } + ++i; } - out = detail::copy(closing_bracket_, out); + + if ((is_literal_str && !value.nested) || !is_literal_str) + out = detail::copy(closing_bracket_, out); + return out; } }; @@ -194,7 +212,13 @@ namespace Ark::internal::Builtins::String if (it->valueType() == ValueType::String) store.push_back(it->stringRef()); else if (it->valueType() == ValueType::Number) - store.push_back(it->number()); + { + double int_part; + if (std::modf(it->number(), &int_part) == 0.0) + store.push_back(static_cast(it->number())); + else + store.push_back(it->number()); + } else if (it->valueType() == ValueType::Nil) store.push_back("nil"); else if (it->valueType() == ValueType::True) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.ark new file mode 100644 index 000000000..19b33aef0 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.ark @@ -0,0 +1 @@ +(print (format "{:b}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.expected new file mode 100644 index 000000000..d85c27814 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.expected @@ -0,0 +1,6 @@ +format: can not format "{:b}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_b.ark:1 + 1 | (print (format "{:b}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.ark new file mode 100644 index 000000000..2362133d4 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.ark @@ -0,0 +1 @@ +(print (format "{:c}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.expected new file mode 100644 index 000000000..34d9a8b53 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.expected @@ -0,0 +1,6 @@ +format: can not format "{:c}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_c.ark:1 + 1 | (print (format "{:c}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.ark new file mode 100644 index 000000000..0088033ce --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.ark @@ -0,0 +1 @@ +(print (format "{:d}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.expected new file mode 100644 index 000000000..0d68383ff --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.expected @@ -0,0 +1,6 @@ +format: can not format "{:d}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_d.ark:1 + 1 | (print (format "{:d}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.ark new file mode 100644 index 000000000..4a724ccb7 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.ark @@ -0,0 +1 @@ +(print (format "{:#b}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.expected new file mode 100644 index 000000000..0d4ebb9f9 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.expected @@ -0,0 +1,6 @@ +format: can not format "{:#b}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_b.ark:1 + 1 | (print (format "{:#b}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.ark new file mode 100644 index 000000000..8f6c207af --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.ark @@ -0,0 +1 @@ +(print (format "{:#B}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.expected new file mode 100644 index 000000000..7c65ac038 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.expected @@ -0,0 +1,6 @@ +format: can not format "{:#B}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_b.ark:1 + 1 | (print (format "{:#B}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.ark new file mode 100644 index 000000000..91fab2776 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.ark @@ -0,0 +1 @@ +(print (format "{:#X}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.expected new file mode 100644 index 000000000..2526be080 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.expected @@ -0,0 +1,6 @@ +format: can not format "{:#X}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_upper_x.ark:1 + 1 | (print (format "{:#X}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.ark new file mode 100644 index 000000000..181daa423 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.ark @@ -0,0 +1 @@ +(print (format "{:#x}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.expected new file mode 100644 index 000000000..8522f33e1 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.expected @@ -0,0 +1,6 @@ +format: can not format "{:#x}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_hashtag_x.ark:1 + 1 | (print (format "{:#x}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.ark new file mode 100644 index 000000000..63bad4e91 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.ark @@ -0,0 +1 @@ +(print (format "{:o}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.expected new file mode 100644 index 000000000..7e41bc17b --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.expected @@ -0,0 +1,6 @@ +format: can not format "{:o}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_o.ark:1 + 1 | (print (format "{:o}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.ark new file mode 100644 index 000000000..bfd062d13 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.ark @@ -0,0 +1 @@ +(print (format "{:B}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.expected new file mode 100644 index 000000000..c83556e99 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.expected @@ -0,0 +1,6 @@ +format: can not format "{:B}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_b.ark:1 + 1 | (print (format "{:B}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.ark new file mode 100644 index 000000000..cd8ba91bf --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.ark @@ -0,0 +1 @@ +(print (format "{:X}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.expected new file mode 100644 index 000000000..f24ae27f8 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.expected @@ -0,0 +1,6 @@ +format: can not format "{:X}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_upper_x.ark:1 + 1 | (print (format "{:X}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.ark b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.ark new file mode 100644 index 000000000..0d4914731 --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.ark @@ -0,0 +1 @@ +(print (format "{:x}" 65.1)) diff --git a/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.expected b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.expected new file mode 100644 index 000000000..135b33a6d --- /dev/null +++ b/tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.expected @@ -0,0 +1,6 @@ +format: can not format "{:x}" (1 argument provided) because of invalid format specifier + +In file tests/unittests/resources/DiagnosticsSuite/runtime/format_double_x.ark:1 + 1 | (print (format "{:x}" 65.1)) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | diff --git a/tests/unittests/resources/LangSuite/string-tests.ark b/tests/unittests/resources/LangSuite/string-tests.ark index b94ec6ff2..5c87b4aef 100644 --- a/tests/unittests/resources/LangSuite/string-tests.ark +++ b/tests/unittests/resources/LangSuite/string-tests.ark @@ -59,12 +59,26 @@ (test:case "format strings" { (test:eq "nilfalsetrue" (format "{}{}{}" nil false true)) (test:eq "CProcedure" (format "{}" print)) - (test:eq (format "{::}" ["hel\tlo" 1 nil true]) "[hel lo 1 nil true]") - (test:eq (format "{:n}" ["hel\tlo" 1 nil true]) "hel lo 1 nil true") - (test:eq (format "{:?s}" ["hel\tlo" 1 nil true]) "\"hel\\tlo1niltrue\"") - (test:eq (format "{:s}" ["hel\tlo" 1 nil true]) "\"hel lo1niltrue\"") - (test:eq (format "{:c}" ["hel\tlo" 1 nil true]) "[hel lo, 1, nil, true]") - (test:eq (format "{:l}" ["hel\tlo" 1 nil true]) "[hel lo\n1\nnil\ntrue]") - (test:eq (format "{:nc}" ["hel\tlo" 1 nil true]) "hel lo, 1, nil, true") - (test:eq (format "{:nl}" ["hel\tlo" 1 nil true]) "hel lo\n1\nnil\ntrue") - (test:eq (format "{::<10}" ["hel\tlo" 1 nil true]) "[hel lo 1 nil true ]") })}) + + (test:eq (format "{}" ["hel\tlo" 1 nil [true "a" 2]]) "[hel lo 1 nil [true a 2]]") + (test:eq (format "{::}" ["hel\tlo" 1 nil [true "a" 2]]) "[hel lo 1 nil [true a 2]]") + (test:eq (format "{:n}" ["hel\tlo" 1 nil [true "a" 2]]) "hel lo 1 nil true a 2") + (test:eq (format "{:?s}" ["hel\tlo" 1 nil [true "a" 2]]) "\"hel\\tlo1nil[true \\\"a\\\" 2]\"") + (test:eq (format "{:s}" ["hel\tlo" 1 nil [true "a" 2]]) "\"hel lo1niltruea2\"") + (test:eq (format "{:c}" ["hel\tlo" 1 nil [true "a" 2]]) "[hel lo, 1, nil, [true, a, 2]]") + (test:eq (format "{:l}" ["hel\tlo" 1 nil [true "a" 2]]) "[hel lo\n1\nnil\n[true\na\n2]]") + (test:eq (format "{:nc}" ["hel\tlo" 1 nil [true "a" 2]]) "hel lo, 1, nil, true, a, 2") + (test:eq (format "{:nl}" ["hel\tlo" 1 nil [true "a" 2]]) "hel lo\n1\nnil\ntrue\na\n2") + (test:eq (format "{::<5}" ["hello" 1 nil [true "a" 2]]) "[hello 1 nil [true a 2 ]]") + + (test:eq (format "{:b}" 65) "1000001") + (test:eq (format "{:#b}" 65) "0b1000001") + (test:eq (format "{:B}" 65) "1000001") + (test:eq (format "{:#B}" 65) "0B1000001") + (test:eq (format "{:c}" 65) "A") + (test:eq (format "{:d}" 65) "65") + (test:eq (format "{:o}" 65) "101") + (test:eq (format "{:x}" 63) "3f") + (test:eq (format "{:#x}" 63) "0x3f") + (test:eq (format "{:X}" 63) "3F") + (test:eq (format "{:#X}" 63) "0X3F") })})