further clean up list parser api
parent
82d366366e
commit
2f3d5ea938
|
@ -652,29 +652,37 @@ private:
|
||||||
bool p_pushed;
|
bool p_pushed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LIBCUBESCRIPT_EXPORT cs_list_parse_state {
|
struct LIBCUBESCRIPT_EXPORT cs_list_parser {
|
||||||
cs_list_parse_state(std::string_view s = std::string_view{}):
|
cs_list_parser(cs_state &cs, std::string_view s = std::string_view{}):
|
||||||
input_beg{s.data()}, input_end{s.data() + s.size()}
|
p_state{&cs}, p_input_beg{s.data()}, p_input_end{s.data() + s.size()}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void set_input(std::string_view s) {
|
void set_input(std::string_view s) {
|
||||||
input_beg = s.data();
|
p_input_beg = s.data();
|
||||||
input_end = s.data() + s.size();
|
p_input_end = s.data() + s.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view get_input() const {
|
std::string_view get_input() const {
|
||||||
return std::string_view{input_beg, std::size_t(input_end - input_beg)};
|
return std::string_view{p_input_beg, p_input_end};
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *input_beg, *input_end;
|
bool parse();
|
||||||
std::string_view item{};
|
std::size_t count();
|
||||||
std::string_view quoted_item{};
|
|
||||||
};
|
|
||||||
|
|
||||||
LIBCUBESCRIPT_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs);
|
cs_strref get_item() const;
|
||||||
LIBCUBESCRIPT_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs);
|
|
||||||
LIBCUBESCRIPT_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs);
|
std::string_view get_raw_item() const { return p_item; }
|
||||||
LIBCUBESCRIPT_EXPORT void list_find_item(cs_list_parse_state &ps);
|
std::string_view get_quoted_item() const { return p_quoted_item; }
|
||||||
|
|
||||||
|
void skip_until_item();
|
||||||
|
|
||||||
|
private:
|
||||||
|
cs_state *p_state;
|
||||||
|
char const *p_input_beg, *p_input_end;
|
||||||
|
|
||||||
|
std::string_view p_item{};
|
||||||
|
std::string_view p_quoted_item{};
|
||||||
|
};
|
||||||
|
|
||||||
LIBCUBESCRIPT_EXPORT cs_strref value_list_concat(
|
LIBCUBESCRIPT_EXPORT cs_strref value_list_concat(
|
||||||
cs_state &cs, std::span<cs_value> vals,
|
cs_state &cs, std::span<cs_value> vals,
|
||||||
|
|
105
src/cs_util.cc
105
src/cs_util.cc
|
@ -432,48 +432,46 @@ end:
|
||||||
}
|
}
|
||||||
} /* namespace util */
|
} /* namespace util */
|
||||||
|
|
||||||
LIBCUBESCRIPT_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs) {
|
LIBCUBESCRIPT_EXPORT bool cs_list_parser::parse() {
|
||||||
list_find_item(ps);
|
skip_until_item();
|
||||||
if (ps.input_beg == ps.input_end) {
|
if (p_input_beg == p_input_end) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (*ps.input_beg) {
|
switch (*p_input_beg) {
|
||||||
case '"': {
|
case '"': {
|
||||||
char const *qi = ps.input_beg;
|
char const *qi = p_input_beg;
|
||||||
ps.input_beg = util::parse_string(cs, ps.get_input());
|
p_input_beg = util::parse_string(*p_state, get_input());
|
||||||
ps.quoted_item = std::string_view{
|
p_quoted_item = std::string_view{qi, p_input_beg};
|
||||||
qi, std::size_t(ps.input_beg - qi)
|
p_item = p_quoted_item.substr(1, p_quoted_item.size() - 2);
|
||||||
};
|
|
||||||
ps.item = ps.quoted_item.substr(1, ps.quoted_item.size() - 2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '(':
|
case '(':
|
||||||
case '[': {
|
case '[': {
|
||||||
char btype = *ps.input_beg;
|
char btype = *p_input_beg;
|
||||||
int brak = 1;
|
int brak = 1;
|
||||||
char const *ibeg = ps.input_beg++;
|
char const *ibeg = p_input_beg++;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
std::string_view chrs{"\"/;()[]"};
|
std::string_view chrs{"\"/;()[]"};
|
||||||
ps.input_beg = std::find_first_of(
|
p_input_beg = std::find_first_of(
|
||||||
ps.input_beg, ps.input_end, chrs.begin(), chrs.end()
|
p_input_beg, p_input_end, chrs.begin(), chrs.end()
|
||||||
);
|
);
|
||||||
if (ps.input_beg == ps.input_end) {
|
if (p_input_beg == p_input_end) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
char c = *ps.input_beg++;
|
char c = *p_input_beg++;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '"':
|
case '"':
|
||||||
/* the quote is needed in str parsing */
|
/* the quote is needed in str parsing */
|
||||||
--ps.input_beg;
|
--p_input_beg;
|
||||||
ps.input_beg = util::parse_string(cs, ps.get_input());
|
p_input_beg = util::parse_string(*p_state, get_input());
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
if (
|
if (
|
||||||
(ps.input_beg != ps.input_end) &&
|
(p_input_beg != p_input_end) &&
|
||||||
(*ps.input_beg == '/')
|
(*p_input_beg == '/')
|
||||||
) {
|
) {
|
||||||
ps.input_beg = std::find(
|
p_input_beg = std::find(
|
||||||
ps.input_beg, ps.input_end, '\n'
|
p_input_beg, p_input_end, '\n'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -494,67 +492,61 @@ LIBCUBESCRIPT_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endblock:
|
endblock:
|
||||||
ps.item = std::string_view{
|
p_item = std::string_view{ibeg + 1, p_input_beg - 1};
|
||||||
ibeg + 1, std::size_t(ps.input_beg - ibeg - 2)
|
p_quoted_item = std::string_view{ibeg, p_input_beg};
|
||||||
};
|
|
||||||
ps.quoted_item = std::string_view{
|
|
||||||
ibeg, std::size_t(ps.input_beg - ibeg)
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ')':
|
case ')':
|
||||||
case ']':
|
case ']':
|
||||||
return false;
|
return false;
|
||||||
default: {
|
default: {
|
||||||
char const *e = util::parse_word(cs, ps.get_input());
|
char const *e = util::parse_word(*p_state, get_input());
|
||||||
ps.quoted_item = ps.item = std::string_view{
|
p_quoted_item = p_item = std::string_view{p_input_beg, e};
|
||||||
ps.input_beg, std::size_t(e - ps.input_beg)
|
p_input_beg = e;
|
||||||
};
|
|
||||||
ps.input_beg = e;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_find_item(ps);
|
skip_until_item();
|
||||||
if ((ps.input_beg != ps.input_end) && (*ps.input_beg == ';')) {
|
if ((p_input_beg != p_input_end) && (*p_input_beg == ';')) {
|
||||||
++ps.input_beg;
|
++p_input_beg;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBCUBESCRIPT_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs) {
|
LIBCUBESCRIPT_EXPORT std::size_t cs_list_parser::count() {
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
while (list_parse(ps, cs)) {
|
while (parse()) {
|
||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBCUBESCRIPT_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) {
|
LIBCUBESCRIPT_EXPORT cs_strref cs_list_parser::get_item() const {
|
||||||
if (!ps.quoted_item.empty() && (ps.quoted_item.front() == '"')) {
|
if (!p_quoted_item.empty() && (p_quoted_item.front() == '"')) {
|
||||||
cs_charbuf buf{cs};
|
cs_charbuf buf{*p_state};
|
||||||
util::unescape_string(std::back_inserter(buf), ps.item);
|
util::unescape_string(std::back_inserter(buf), p_item);
|
||||||
return cs_strref{cs, buf.str()};
|
return cs_strref{*p_state, buf.str()};
|
||||||
}
|
}
|
||||||
return cs_strref{cs, ps.item};
|
return cs_strref{*p_state, p_item};
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBCUBESCRIPT_EXPORT void list_find_item(cs_list_parse_state &ps) {
|
LIBCUBESCRIPT_EXPORT void cs_list_parser::skip_until_item() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (ps.input_beg != ps.input_end) {
|
while (p_input_beg != p_input_end) {
|
||||||
char c = *ps.input_beg;
|
char c = *p_input_beg;
|
||||||
if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) {
|
if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) {
|
||||||
++ps.input_beg;
|
++p_input_beg;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ps.input_end - ps.input_beg) < 2) {
|
if ((p_input_end - p_input_beg) < 2) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((ps.input_beg[0] != '/') || (ps.input_beg[1]) != '/') {
|
if ((p_input_beg[0] != '/') || (p_input_beg[1]) != '/') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ps.input_beg = std::find(ps.input_beg, ps.input_end, '\n');
|
p_input_beg = std::find(p_input_beg, p_input_end, '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,19 +558,18 @@ LIBCUBESCRIPT_EXPORT cs_strref value_list_concat(
|
||||||
switch (vals[i].get_type()) {
|
switch (vals[i].get_type()) {
|
||||||
case cs_value_type::INT:
|
case cs_value_type::INT:
|
||||||
case cs_value_type::FLOAT:
|
case cs_value_type::FLOAT:
|
||||||
case cs_value_type::STRING: {
|
case cs_value_type::STRING:
|
||||||
cs_value v{vals[i]};
|
std::ranges::copy(
|
||||||
auto str = v.force_str();
|
cs_value{vals[i]}.force_str(), std::back_inserter(buf)
|
||||||
std::copy(str.begin(), str.end(), std::back_inserter(buf));
|
);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == (vals.size() - 1)) {
|
if (i == (vals.size() - 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::copy(sep.begin(), sep.end(), std::back_inserter(buf));
|
std::ranges::copy(sep, std::back_inserter(buf));
|
||||||
}
|
}
|
||||||
return cs_strref{cs, buf.str()};
|
return cs_strref{cs, buf.str()};
|
||||||
}
|
}
|
||||||
|
|
165
src/lib_list.cc
165
src/lib_list.cc
|
@ -36,13 +36,13 @@ static inline void cs_list_find(
|
||||||
) {
|
) {
|
||||||
cs_int n = 0, skip = args[2].get_int();
|
cs_int n = 0, skip = args[2].get_int();
|
||||||
T val = cs_arg_val<T>::get(args[1]);
|
T val = cs_arg_val<T>::get(args[1]);
|
||||||
for (cs_list_parse_state p{args[0].get_str()}; list_parse(p, cs); ++n) {
|
for (cs_list_parser p{cs, args[0].get_str()}; p.parse(); ++n) {
|
||||||
if (cmp(p, val)) {
|
if (cmp(p, val)) {
|
||||||
res.set_int(n);
|
res.set_int(n);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < skip; ++i) {
|
for (int i = 0; i < skip; ++i) {
|
||||||
if (!list_parse(p, cs)) {
|
if (!p.parse()) {
|
||||||
goto notfound;
|
goto notfound;
|
||||||
}
|
}
|
||||||
++n;
|
++n;
|
||||||
|
@ -57,14 +57,14 @@ static inline void cs_list_assoc(
|
||||||
cs_state &cs, std::span<cs_value> args, cs_value &res, F cmp
|
cs_state &cs, std::span<cs_value> args, cs_value &res, F cmp
|
||||||
) {
|
) {
|
||||||
T val = cs_arg_val<T>::get(args[1]);
|
T val = cs_arg_val<T>::get(args[1]);
|
||||||
for (cs_list_parse_state p{args[0].get_str()}; list_parse(p, cs);) {
|
for (cs_list_parser p{cs, args[0].get_str()}; p.parse();) {
|
||||||
if (cmp(p, val)) {
|
if (cmp(p, val)) {
|
||||||
if (list_parse(p, cs)) {
|
if (p.parse()) {
|
||||||
res.set_str(list_get_item(p, cs));
|
res.set_str(p.get_item());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!list_parse(p, cs)) {
|
if (!p.parse()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ static void cs_loop_list_conc(
|
||||||
}
|
}
|
||||||
cs_charbuf r{cs};
|
cs_charbuf r{cs};
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (cs_list_parse_state p{list}; list_parse(p, cs); ++n) {
|
for (cs_list_parser p{cs, list}; p.parse(); ++n) {
|
||||||
idv.set_str(list_get_item(p, cs));
|
idv.set_str(p.get_item());
|
||||||
idv.push();
|
idv.push();
|
||||||
if (n && space) {
|
if (n && space) {
|
||||||
r.push_back(' ');
|
r.push_back(' ');
|
||||||
|
@ -105,8 +105,8 @@ int cs_list_includes(
|
||||||
cs_state &cs, std::string_view list, std::string_view needle
|
cs_state &cs, std::string_view list, std::string_view needle
|
||||||
) {
|
) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (cs_list_parse_state p{list}; list_parse(p, cs);) {
|
for (cs_list_parser p{cs, list}; p.parse();) {
|
||||||
if (p.item == needle) {
|
if (p.get_raw_item() == needle) {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
++offset;
|
++offset;
|
||||||
|
@ -127,12 +127,12 @@ static inline void cs_list_merge(
|
||||||
if (Swap) {
|
if (Swap) {
|
||||||
std::swap(list, elems);
|
std::swap(list, elems);
|
||||||
}
|
}
|
||||||
for (cs_list_parse_state p{list}; list_parse(p, cs);) {
|
for (cs_list_parser p{cs, list}; p.parse();) {
|
||||||
if (cmp(cs_list_includes(cs, elems, p.item), 0)) {
|
if (cmp(cs_list_includes(cs, elems, p.get_raw_item()), 0)) {
|
||||||
if (!buf.empty()) {
|
if (!buf.empty()) {
|
||||||
buf.push_back(' ');
|
buf.push_back(' ');
|
||||||
}
|
}
|
||||||
buf.append(p.quoted_item);
|
buf.append(p.get_quoted_item());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.set_str(buf.str());
|
res.set_str(buf.str());
|
||||||
|
@ -142,30 +142,32 @@ static void cs_init_lib_list_sort(cs_state &cs);
|
||||||
|
|
||||||
void cs_init_lib_list(cs_state &gcs) {
|
void cs_init_lib_list(cs_state &gcs) {
|
||||||
gcs.new_command("listlen", "s", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listlen", "s", [](auto &cs, auto args, auto &res) {
|
||||||
cs_list_parse_state p{args[0].get_str()};
|
res.set_int(cs_int(cs_list_parser{cs, args[0].get_str()}.count()));
|
||||||
res.set_int(cs_int(list_count(p, cs)));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
gcs.new_command("at", "si1V", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("at", "si1V", [](auto &cs, auto args, auto &res) {
|
||||||
if (args.empty()) {
|
if (args.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cs_strref str = args[0].get_str();
|
if (args.size() <= 1) {
|
||||||
cs_list_parse_state p{str};
|
res = args[0];
|
||||||
p.item = str;
|
return;
|
||||||
|
}
|
||||||
|
auto str = args[0].get_str();
|
||||||
|
cs_list_parser p{cs, str};
|
||||||
for (size_t i = 1; i < args.size(); ++i) {
|
for (size_t i = 1; i < args.size(); ++i) {
|
||||||
p.set_input(str);
|
p.set_input(str);
|
||||||
cs_int pos = args[i].get_int();
|
cs_int pos = args[i].get_int();
|
||||||
for (; pos > 0; --pos) {
|
for (; pos > 0; --pos) {
|
||||||
if (!list_parse(p, cs)) {
|
if (!p.parse()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos > 0 || !list_parse(p, cs)) {
|
if (pos > 0 || !p.parse()) {
|
||||||
p.item = p.quoted_item = std::string_view{};
|
p.set_input("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.set_str(list_get_item(p, cs));
|
res.set_str(p.get_item());
|
||||||
});
|
});
|
||||||
|
|
||||||
gcs.new_command("sublist", "siiN", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("sublist", "siiN", [](auto &cs, auto args, auto &res) {
|
||||||
|
@ -176,26 +178,28 @@ void cs_init_lib_list(cs_state &gcs) {
|
||||||
cs_int offset = std::max(skip, cs_int(0)),
|
cs_int offset = std::max(skip, cs_int(0)),
|
||||||
len = (numargs >= 3) ? std::max(count, cs_int(0)) : -1;
|
len = (numargs >= 3) ? std::max(count, cs_int(0)) : -1;
|
||||||
|
|
||||||
cs_list_parse_state p{args[0].get_str()};
|
cs_list_parser p{cs, args[0].get_str()};
|
||||||
for (cs_int i = 0; i < offset; ++i) {
|
for (cs_int i = 0; i < offset; ++i) {
|
||||||
if (!list_parse(p, cs)) break;
|
if (!p.parse()) break;
|
||||||
}
|
}
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
list_find_item(p);
|
p.skip_until_item();
|
||||||
}
|
}
|
||||||
res.set_str(p.get_input());
|
res.set_str(p.get_input());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *list = p.get_input().data();
|
char const *list = p.get_input().data();
|
||||||
p.quoted_item = std::string_view{};
|
if (len > 0 && p.parse()) {
|
||||||
if (len > 0 && list_parse(p, cs)) {
|
while (--len > 0 && p.parse());
|
||||||
while (--len > 0 && list_parse(p, cs));
|
} else {
|
||||||
|
res.set_str("");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
std::string_view quote = p.quoted_item;
|
auto quote = p.get_quoted_item();
|
||||||
char const *qend = !quote.empty() ? "e[quote.size()] : list;
|
auto *qend = "e[quote.size()];
|
||||||
res.set_str(std::string_view{list, std::size_t(qend - list)});
|
res.set_str(std::string_view{list, qend});
|
||||||
});
|
});
|
||||||
|
|
||||||
gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) {
|
||||||
|
@ -206,9 +210,9 @@ void cs_init_lib_list(cs_state &gcs) {
|
||||||
}
|
}
|
||||||
auto body = args[2].get_code();
|
auto body = args[2].get_code();
|
||||||
int n = -1;
|
int n = -1;
|
||||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs);) {
|
for (cs_list_parser p{cs, args[1].get_str()}; p.parse();) {
|
||||||
++n;
|
++n;
|
||||||
idv.set_str(p.item);
|
idv.set_str(p.get_raw_item());
|
||||||
idv.push();
|
idv.push();
|
||||||
if (cs.run(body).get_bool()) {
|
if (cs.run(body).get_bool()) {
|
||||||
res.set_int(cs_int(n));
|
res.set_int(cs_int(n));
|
||||||
|
@ -225,17 +229,17 @@ void cs_init_lib_list(cs_state &gcs) {
|
||||||
}
|
}
|
||||||
auto body = args[2].get_code();
|
auto body = args[2].get_code();
|
||||||
int n = -1;
|
int n = -1;
|
||||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs);) {
|
for (cs_list_parser p{cs, args[1].get_str()}; p.parse();) {
|
||||||
++n;
|
++n;
|
||||||
idv.set_str(p.item);
|
idv.set_str(p.get_raw_item());
|
||||||
idv.push();
|
idv.push();
|
||||||
if (cs.run(body).get_bool()) {
|
if (cs.run(body).get_bool()) {
|
||||||
if (list_parse(p, cs)) {
|
if (p.parse()) {
|
||||||
res.set_str(list_get_item(p, cs));
|
res.set_str(p.get_item());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!list_parse(p, cs)) {
|
if (!p.parse()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,44 +247,44 @@ void cs_init_lib_list(cs_state &gcs) {
|
||||||
|
|
||||||
gcs.new_command("listfind=", "i", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listfind=", "i", [](auto &cs, auto args, auto &res) {
|
||||||
cs_list_find<cs_int>(
|
cs_list_find<cs_int>(
|
||||||
cs, args, res, [](cs_list_parse_state const &p, cs_int val) {
|
cs, args, res, [](cs_list_parser const &p, cs_int val) {
|
||||||
return cs_parse_int(p.item) == val;
|
return cs_parse_int(p.get_raw_item()) == val;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
gcs.new_command("listfind=f", "f", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listfind=f", "f", [](auto &cs, auto args, auto &res) {
|
||||||
cs_list_find<cs_float>(
|
cs_list_find<cs_float>(
|
||||||
cs, args, res, [](cs_list_parse_state const &p, cs_float val) {
|
cs, args, res, [](cs_list_parser const &p, cs_float val) {
|
||||||
return cs_parse_float(p.item) == val;
|
return cs_parse_float(p.get_raw_item()) == val;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
gcs.new_command("listfind=s", "s", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listfind=s", "s", [](auto &cs, auto args, auto &res) {
|
||||||
cs_list_find<std::string_view>(
|
cs_list_find<std::string_view>(
|
||||||
cs, args, res, [](cs_list_parse_state const &p, std::string_view val) {
|
cs, args, res, [](cs_list_parser const &p, std::string_view val) {
|
||||||
return p.item == val;
|
return p.get_raw_item() == val;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
gcs.new_command("listassoc=", "i", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listassoc=", "i", [](auto &cs, auto args, auto &res) {
|
||||||
cs_list_assoc<cs_int>(
|
cs_list_assoc<cs_int>(
|
||||||
cs, args, res, [](cs_list_parse_state const &p, cs_int val) {
|
cs, args, res, [](cs_list_parser const &p, cs_int val) {
|
||||||
return cs_parse_int(p.item) == val;
|
return cs_parse_int(p.get_raw_item()) == val;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
gcs.new_command("listassoc=f", "f", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listassoc=f", "f", [](auto &cs, auto args, auto &res) {
|
||||||
cs_list_assoc<cs_float>(
|
cs_list_assoc<cs_float>(
|
||||||
cs, args, res, [](cs_list_parse_state const &p, cs_float val) {
|
cs, args, res, [](cs_list_parser const &p, cs_float val) {
|
||||||
return cs_parse_float(p.item) == val;
|
return cs_parse_float(p.get_raw_item()) == val;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
gcs.new_command("listassoc=s", "s", [](auto &cs, auto args, auto &res) {
|
gcs.new_command("listassoc=s", "s", [](auto &cs, auto args, auto &res) {
|
||||||
cs_list_assoc<std::string_view>(
|
cs_list_assoc<std::string_view>(
|
||||||
cs, args, res, [](cs_list_parse_state const &p, std::string_view val) {
|
cs, args, res, [](cs_list_parser const &p, std::string_view val) {
|
||||||
return p.item == val;
|
return p.get_raw_item() == val;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -292,8 +296,8 @@ void cs_init_lib_list(cs_state &gcs) {
|
||||||
}
|
}
|
||||||
auto body = args[2].get_code();
|
auto body = args[2].get_code();
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs); ++n) {
|
for (cs_list_parser p{cs, args[1].get_str()}; p.parse(); ++n) {
|
||||||
idv.set_str(list_get_item(p, cs));
|
idv.set_str(p.get_item());
|
||||||
idv.push();
|
idv.push();
|
||||||
switch (cs.run_loop(body)) {
|
switch (cs.run_loop(body)) {
|
||||||
case cs_loop_state::BREAK:
|
case cs_loop_state::BREAK:
|
||||||
|
@ -314,10 +318,10 @@ end:
|
||||||
}
|
}
|
||||||
auto body = args[3].get_code();
|
auto body = args[3].get_code();
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (cs_list_parse_state p{args[2].get_str()}; list_parse(p, cs); n += 2) {
|
for (cs_list_parser p{cs, args[2].get_str()}; p.parse(); n += 2) {
|
||||||
idv1.set_str(list_get_item(p, cs));
|
idv1.set_str(p.get_item());
|
||||||
if (list_parse(p, cs)) {
|
if (p.parse()) {
|
||||||
idv2.set_str(list_get_item(p, cs));
|
idv2.set_str(p.get_item());
|
||||||
} else {
|
} else {
|
||||||
idv2.set_str("");
|
idv2.set_str("");
|
||||||
}
|
}
|
||||||
|
@ -343,15 +347,15 @@ end:
|
||||||
}
|
}
|
||||||
auto body = args[4].get_code();
|
auto body = args[4].get_code();
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (cs_list_parse_state p{args[3].get_str()}; list_parse(p, cs); n += 3) {
|
for (cs_list_parser p{cs, args[3].get_str()}; p.parse(); n += 3) {
|
||||||
idv1.set_str(list_get_item(p, cs));
|
idv1.set_str(p.get_item());
|
||||||
if (list_parse(p, cs)) {
|
if (p.parse()) {
|
||||||
idv2.set_str(list_get_item(p, cs));
|
idv2.set_str(p.get_item());
|
||||||
} else {
|
} else {
|
||||||
idv2.set_str("");
|
idv2.set_str("");
|
||||||
}
|
}
|
||||||
if (list_parse(p, cs)) {
|
if (p.parse()) {
|
||||||
idv3.set_str(list_get_item(p, cs));
|
idv3.set_str(p.get_item());
|
||||||
} else {
|
} else {
|
||||||
idv3.set_str("");
|
idv3.set_str("");
|
||||||
}
|
}
|
||||||
|
@ -393,14 +397,14 @@ end:
|
||||||
auto body = args[2].get_code();
|
auto body = args[2].get_code();
|
||||||
cs_charbuf r{cs};
|
cs_charbuf r{cs};
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs); ++n) {
|
for (cs_list_parser p{cs, args[1].get_str()}; p.parse(); ++n) {
|
||||||
idv.set_str(p.item);
|
idv.set_str(p.get_raw_item());
|
||||||
idv.push();
|
idv.push();
|
||||||
if (cs.run(body).get_bool()) {
|
if (cs.run(body).get_bool()) {
|
||||||
if (r.size()) {
|
if (r.size()) {
|
||||||
r.push_back(' ');
|
r.push_back(' ');
|
||||||
}
|
}
|
||||||
r.append(p.quoted_item);
|
r.append(p.get_quoted_item());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.set_str(r.str());
|
res.set_str(r.str());
|
||||||
|
@ -413,8 +417,8 @@ end:
|
||||||
}
|
}
|
||||||
auto body = args[2].get_code();
|
auto body = args[2].get_code();
|
||||||
int n = 0, r = 0;
|
int n = 0, r = 0;
|
||||||
for (cs_list_parse_state p{args[1].get_str()}; list_parse(p, cs); ++n) {
|
for (cs_list_parser p{cs, args[1].get_str()}; p.parse(); ++n) {
|
||||||
idv.set_str(p.item);
|
idv.set_str(p.get_raw_item());
|
||||||
idv.push();
|
idv.push();
|
||||||
if (cs.run(body).get_bool()) {
|
if (cs.run(body).get_bool()) {
|
||||||
r++;
|
r++;
|
||||||
|
@ -427,14 +431,15 @@ end:
|
||||||
cs_charbuf buf{cs};
|
cs_charbuf buf{cs};
|
||||||
std::string_view s = args[0].get_str();
|
std::string_view s = args[0].get_str();
|
||||||
std::string_view conj = args[1].get_str();
|
std::string_view conj = args[1].get_str();
|
||||||
cs_list_parse_state p{s};
|
cs_list_parser p{cs, s};
|
||||||
size_t len = list_count(p, cs);
|
size_t len = p.count();
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (p.set_input(s); list_parse(p, cs); ++n) {
|
for (p.set_input(s); p.parse(); ++n) {
|
||||||
if (!p.quoted_item.empty() && (p.quoted_item.front() == '"')) {
|
auto qi = p.get_quoted_item();
|
||||||
util::unescape_string(std::back_inserter(buf), p.item);
|
if (!qi.empty() && (qi.front() == '"')) {
|
||||||
|
util::unescape_string(std::back_inserter(buf), p.get_raw_item());
|
||||||
} else {
|
} else {
|
||||||
buf.append(p.item);
|
buf.append(p.get_raw_item());
|
||||||
}
|
}
|
||||||
if ((n + 1) < len) {
|
if ((n + 1) < len) {
|
||||||
if ((len > 2) || conj.empty()) {
|
if ((len > 2) || conj.empty()) {
|
||||||
|
@ -472,13 +477,13 @@ end:
|
||||||
std::string_view s = args[0].get_str();
|
std::string_view s = args[0].get_str();
|
||||||
std::string_view vals = args[1].get_str();
|
std::string_view vals = args[1].get_str();
|
||||||
char const *list = s.data();
|
char const *list = s.data();
|
||||||
cs_list_parse_state p{s};
|
cs_list_parser p{cs, s};
|
||||||
for (cs_int i = 0; i < offset; ++i) {
|
for (cs_int i = 0; i < offset; ++i) {
|
||||||
if (!list_parse(p, cs)) {
|
if (!p.parse()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::string_view quote = p.quoted_item;
|
std::string_view quote = p.get_quoted_item();
|
||||||
char const *qend = !quote.empty() ? "e[quote.size()] : list;
|
char const *qend = !quote.empty() ? "e[quote.size()] : list;
|
||||||
cs_charbuf buf{cs};
|
cs_charbuf buf{cs};
|
||||||
if (qend > list) {
|
if (qend > list) {
|
||||||
|
@ -491,11 +496,11 @@ end:
|
||||||
buf.append(vals);
|
buf.append(vals);
|
||||||
}
|
}
|
||||||
for (cs_int i = 0; i < len; ++i) {
|
for (cs_int i = 0; i < len; ++i) {
|
||||||
if (!list_parse(p, cs)) {
|
if (!p.parse()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_find_item(p);
|
p.skip_until_item();
|
||||||
if (!p.get_input().empty()) {
|
if (!p.get_input().empty()) {
|
||||||
switch (p.get_input().front()) {
|
switch (p.get_input().front()) {
|
||||||
case ')':
|
case ')':
|
||||||
|
@ -547,8 +552,8 @@ static void cs_list_sort(
|
||||||
cs_valbuf<ListSortItem> items{cs};
|
cs_valbuf<ListSortItem> items{cs};
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
|
|
||||||
for (cs_list_parse_state p{list}; list_parse(p, cs);) {
|
for (cs_list_parser p{cs, list}; p.parse();) {
|
||||||
ListSortItem item = { p.item, p.quoted_item };
|
ListSortItem item = { p.get_raw_item(), p.get_quoted_item() };
|
||||||
items.push_back(item);
|
items.push_back(item);
|
||||||
total += item.quote.size();
|
total += item.quote.size();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue