return str;
};
+ auto consume_numeric = [&]() -> std::string {
+ std::string num = consume_while(is_integer);
+ if (pos < src.size() && src[pos] == '.' && pos + 1 < src.size() && is_integer(src[pos + 1])) {
+ ++pos; // Consume '.'
+ std::string frac = consume_while(is_integer);
+ num += "." + frac;
+ }
+ return num;
+ };
+
auto next_pos_is = [&](std::initializer_list<char> chars, size_t n = 1) -> bool {
if (pos + n >= src.size()) return false;
for (char c : chars) {
++pos; // Consume the operator
// Check for numbers following the unary operator
- std::string num = consume_while(is_integer);
+ std::string num = consume_numeric();
std::string value = std::string(1, ch) + num;
token::type t = num.empty() ? token::unary_operator : token::numeric_literal;
// JJ_DEBUG("consumed unary operator or numeric literal: '%s'", value.c_str());
// Numbers
if (is_integer(ch)) {
start_pos = pos;
- std::string num = consume_while(is_integer);
- if (pos < src.size() && src[pos] == '.' && pos + 1 < src.size() && is_integer(src[pos + 1])) {
- ++pos; // Consume '.'
- std::string frac = consume_while(is_integer);
- num += "." + frac;
- }
+ std::string num = consume_numeric();
// JJ_DEBUG("consumed numeric literal: '%s'", num.c_str());
tokens.push_back({token::numeric_literal, num, start_pos});
continue;
"Bob"
);
+ test_template(t, "negative float (not dot notation)",
+ "{{ -1.0 }}",
+ json::object(),
+ "-1.0"
+ );
+
test_template(t, "bracket notation",
"{{ user['name'] }}",
{{"user", {{"name", "Bob"}}}},