header_utils
Loading...
Searching...
No Matches
sexps.h
1
4
5#pragma once
6
7#include "string_ops.h"
8#include "parsing.h"
9#include "ranges.h"
10#include <nlohmann/json.hpp>
11
13{
19
21 auto consume_value(std::string_view& sexp_str, std::array<char, 2> braces = { '[', ']' }) -> nlohmann::json;
22
24 auto consume_atom(std::string_view& sexp_str, char end_brace = ']') -> nlohmann::json;
25
28 auto consume_list(std::string_view& sexp_str, std::array<char, 2> braces = { '[', ']' }) -> nlohmann::json;
29
30 inline auto parse_value(std::string_view sexp_str, std::array<char, 2> braces = { '[', ']' }) -> nlohmann::json { return consume_value(sexp_str, braces); }
31 inline auto parse_atom(std::string_view sexp_str, char end_brace = ']') -> nlohmann::json { return consume_atom(sexp_str, end_brace); }
32 inline auto parse_list(std::string_view sexp_str, std::array<char, 2> braces = { '[', ']' }) -> nlohmann::json { return consume_list(sexp_str, braces); }
33
35}
36
38
40{
41 inline auto consume_atom(std::string_view& sexp_str, char end_brace) -> nlohmann::json
42 {
43 string_ops::trim_whitespace_left(sexp_str);
44
46 if (sexp_str.starts_with('\''))
47 return parsing::consume_c_string<'\''>(sexp_str).second;
48
49 if (sexp_str.starts_with('"'))
50 return parsing::consume_c_string<'"'>(sexp_str).second;
51
53 if (string_ops::consume(sexp_str, ','))
54 return nlohmann::json(",");
55
57 auto result = string_ops::consume_until_any(sexp_str,
59
60 if (result == "true") return true;
61 if (result == "false") return false;
62 if (result == "null") return nullptr;
63
65 {
66 nlohmann::json::number_integer_t num_result;
67 const auto fcres = string_ops::from_chars(result, num_result);
68 if (fcres.ec == std::errc{} && fcres.ptr == sexp_str.data())
69 {
70 string_ops::trim_whitespace_left(sexp_str);
71 return num_result;
72 }
73 }
74
75 {
76 nlohmann::json::number_unsigned_t num_result;
77 const auto fcres = string_ops::from_chars(result, num_result);
78 if (fcres.ec == std::errc{} && fcres.ptr == sexp_str.data())
79 {
80 string_ops::trim_whitespace_left(sexp_str);
81 return num_result;
82 }
83 }
84
85 {
86 nlohmann::json::number_float_t num_result;
87 const auto fcres = string_ops::from_chars(result, num_result);
88 if (fcres.ec == std::errc{} && fcres.ptr == sexp_str.data())
89 {
90 string_ops::trim_whitespace_left(sexp_str);
91 return num_result;
92 }
93 }
94
95 string_ops::trim_whitespace_left(sexp_str);
96 return result;
97 }
98
99 // TODO: '[e1; e2; e3]' -> '[[e1] [e2] [e3]]' or '{e1; e2; e3}' -> '[[e1] [e2] [e3]]'
100 inline auto consume_list(std::string_view& sexp_str, std::array<char, 2> braces) -> nlohmann::json
101 {
102 nlohmann::json result = nlohmann::json::array();
103 string_ops::trim_whitespace_left(sexp_str);
104 while (!sexp_str.empty() && !sexp_str.starts_with(braces[1]))
105 {
106 result.push_back(consume_value(sexp_str, braces));
107 string_ops::trim_whitespace_left(sexp_str);
108 }
109 std::ignore = string_ops::consume(sexp_str, braces[1]);
110 return result;
111 }
112
113 inline auto consume_value(std::string_view& sexp_str, std::array<char, 2> braces) -> nlohmann::json
114 {
115 string_ops::trim_whitespace_left(sexp_str);
116 if (string_ops::consume(sexp_str, braces[0]))
117 return consume_list(sexp_str, braces);
118 return consume_atom(sexp_str, braces[1]);
119 }
120
121}
constexpr auto whitespace_chars
All characters that match ascii::isspace.
Definition string_ops.h:399
auto consume_list(std::string_view &sexp_str, std::array< char, 2 > braces={ '[', ']' }) -> nlohmann::json
Consumes space-delimited elements until close-brace or end-of-string.
Definition sexps.h:100
auto consume_value(std::string_view &sexp_str, std::array< char, 2 > braces={ '[', ']' }) -> nlohmann::json
Consumes [list] or atom; a ',' (comma character) is considered its own atom.
Definition sexps.h:113
auto consume_atom(std::string_view &sexp_str, char end_brace=']') -> nlohmann::json
Consumes a space-delimited word, 'string' "literal", or 14.46 number.
Definition sexps.h:41
char consume(std::string_view &str)
Consumes and returns the first character in the str, or \0 if no more characters.
Definition string_ops.h:702
std::string_view consume_until_any(std::string_view &str, ARGS &&... args)
Consumes characters from the beginning of str until one is equal to any in the parameter pack,...
Definition string_ops.h:884
constexpr auto from_chars(std::string_view str, T &value, const int base=10) noexcept
A version of std::from_chars that takes a std::string_view as the first argument.