From 4b6c284ea13a7bafac68cf4d75e8a88960c7760d Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Tue, 23 Mar 2021 02:00:11 +0100 Subject: [PATCH] separate cs_parser.cc, drop cs_util.cc --- src/cs_gen.cc | 6 +- src/{cs_util.cc => cs_parser.cc} | 223 ++++++++++++++----------------- src/cs_val.cc | 26 ++++ src/cs_vm.cc | 8 +- src/lib_str.cc | 4 +- src/meson.build | 2 +- 6 files changed, 135 insertions(+), 134 deletions(-) rename src/{cs_util.cc => cs_parser.cc} (50%) diff --git a/src/cs_gen.cc b/src/cs_gen.cc index 0926010..8173220 100644 --- a/src/cs_gen.cc +++ b/src/cs_gen.cc @@ -12,7 +12,7 @@ namespace cscript { std::string_view cs_gen_state::get_str() { size_t nl; char const *beg = source; - source = util::parse_string( + source = cs_parse_string( cs, std::string_view{source, std::size_t(send - source)}, nl ); current_line += nl - 1; @@ -92,7 +92,7 @@ void cs_gen_state::skip_comments() { std::string_view cs_gen_state::get_word() { char const *beg = source; - source = util::parse_word( + source = cs_parse_word( cs, std::string_view{source, std::size_t(send - source)} ); return std::string_view{beg, std::size_t(source - beg)}; @@ -484,7 +484,7 @@ static bool compileblockstr(cs_gen_state &gs, char const *str, char const *send) break; case '\"': { char const *start = str; - str = util::parse_string( + str = cs_parse_string( gs.cs, std::string_view{str, send} ); memcpy(&buf[len], start, std::size_t(str - start)); diff --git a/src/cs_util.cc b/src/cs_parser.cc similarity index 50% rename from src/cs_util.cc rename to src/cs_parser.cc index 3f634ba..d0b6083 100644 --- a/src/cs_util.cc +++ b/src/cs_parser.cc @@ -1,116 +1,115 @@ #include -#include "cs_vm.hh" -#include "cs_strman.hh" -#include -#include -#include -#include +#include "cs_std.hh" namespace cscript { -namespace util { - LIBCUBESCRIPT_EXPORT char const *parse_string( - cs_state &cs, std::string_view str, size_t &nlines - ) { - size_t nl = 0; - nlines = nl; - if (str.empty() || (str.front() != '\"')) { - return str.data(); - } - char const *beg = str.begin(); - char const *end = str.end(); - char const *orig = beg++; - ++nl; - while (beg != end) { - switch (*beg) { - case '\r': - case '\n': - case '\"': +/* string/word parsers are also useful to have public */ + +LIBCUBESCRIPT_EXPORT char const *cs_parse_string( + cs_state &cs, std::string_view str, size_t &nlines +) { + size_t nl = 0; + nlines = nl; + if (str.empty() || (str.front() != '\"')) { + return str.data(); + } + char const *beg = str.begin(); + char const *end = str.end(); + char const *orig = beg++; + ++nl; + while (beg != end) { + switch (*beg) { + case '\r': + case '\n': + case '\"': + goto end; + case '^': + case '\\': { + bool needn = (*beg == '\\'); + if (++beg == end) { goto end; - case '^': - case '\\': { - bool needn = (*beg == '\\'); - if (++beg == end) { - goto end; - } - if ((*beg == '\r') || (*beg == '\n')) { - char c = *beg++; - ++nl; - if ((beg != end) && (c == '\r') && (*beg == '\n')) { - ++beg; - } - } else if (needn) { - goto end; - } else { + } + if ((*beg == '\r') || (*beg == '\n')) { + char c = *beg++; + ++nl; + if ((beg != end) && (c == '\r') && (*beg == '\n')) { ++beg; } - continue; + } else if (needn) { + goto end; + } else { + ++beg; } - default: - break; + continue; } - ++beg; + default: + break; } + ++beg; + } end: - nlines = nl; - if ((beg == end) || (*beg != '\"')) { - throw cs_error( - cs, "unfinished string '%s'", - std::string_view{orig, std::size_t(beg - orig)} - ); - } - return ++beg; + nlines = nl; + if ((beg == end) || (*beg != '\"')) { + throw cs_error( + cs, "unfinished string '%s'", + std::string_view{orig, std::size_t(beg - orig)} + ); } + return ++beg; +} - LIBCUBESCRIPT_EXPORT char const *parse_word(cs_state &cs, std::string_view str) { - char const *it = str.begin(); - char const *end = str.end(); - for (; it != end; ++it) { - std::string_view chrs{"\"/;()[] \t\r\n"}; - it = std::find_first_of(it, end, chrs.begin(), chrs.end()); - if (it == end) { - return it; - } - switch (*it) { - case '"': - case ';': - case ' ': - case '\t': - case '\r': - case '\n': - return it; - case '/': - if (((end - it) > 1) && (it[1] == '/')) { - return it; - } - break; - case '[': - ++it; - it = parse_word(cs, std::string_view{ - it, std::size_t(end - it) - }); - if ((it == end) || (*it != ']')) { - throw cs_error(cs, "missing \"]\""); - } - break; - case '(': - ++it; - it = parse_word(cs, std::string_view{ - it, std::size_t(end - it) - }); - if ((it == end) || (*it != ')')) { - throw cs_error(cs, "missing \")\""); - } - break; - case ']': - case ')': - return it; - } +LIBCUBESCRIPT_EXPORT char const *cs_parse_word( + cs_state &cs, std::string_view str +) { + char const *it = str.begin(); + char const *end = str.end(); + for (; it != end; ++it) { + std::string_view chrs{"\"/;()[] \t\r\n"}; + it = std::find_first_of(it, end, chrs.begin(), chrs.end()); + if (it == end) { + return it; + } + switch (*it) { + case '"': + case ';': + case ' ': + case '\t': + case '\r': + case '\n': + return it; + case '/': + if (((end - it) > 1) && (it[1] == '/')) { + return it; + } + break; + case '[': + ++it; + it = cs_parse_word(cs, std::string_view{ + it, std::size_t(end - it) + }); + if ((it == end) || (*it != ']')) { + throw cs_error(cs, "missing \"]\""); + } + break; + case '(': + ++it; + it = cs_parse_word(cs, std::string_view{ + it, std::size_t(end - it) + }); + if ((it == end) || (*it != ')')) { + throw cs_error(cs, "missing \")\""); + } + break; + case ']': + case ')': + return it; } - return it; } -} /* namespace util */ + return it; +} + +/* list parser public implementation */ LIBCUBESCRIPT_EXPORT bool cs_list_parser::parse() { skip_until_item(); @@ -120,7 +119,7 @@ LIBCUBESCRIPT_EXPORT bool cs_list_parser::parse() { switch (*p_input_beg) { case '"': { char const *qi = p_input_beg; - p_input_beg = util::parse_string(*p_state, get_input()); + p_input_beg = cs_parse_string(*p_state, get_input()); p_quoted_item = std::string_view{qi, p_input_beg}; p_item = p_quoted_item.substr(1, p_quoted_item.size() - 2); break; @@ -143,7 +142,7 @@ LIBCUBESCRIPT_EXPORT bool cs_list_parser::parse() { case '"': /* the quote is needed in str parsing */ --p_input_beg; - p_input_beg = util::parse_string(*p_state, get_input()); + p_input_beg = cs_parse_string(*p_state, get_input()); break; case '/': if ( @@ -180,7 +179,7 @@ endblock: case ']': return false; default: { - char const *e = util::parse_word(*p_state, get_input()); + char const *e = cs_parse_word(*p_state, get_input()); p_quoted_item = p_item = std::string_view{p_input_beg, e}; p_input_beg = e; break; @@ -230,28 +229,4 @@ LIBCUBESCRIPT_EXPORT void cs_list_parser::skip_until_item() { } } -LIBCUBESCRIPT_EXPORT cs_strref value_list_concat( - cs_state &cs, std::span vals, std::string_view sep -) { - cs_charbuf buf{cs}; - for (std::size_t i = 0; i < vals.size(); ++i) { - switch (vals[i].get_type()) { - case cs_value_type::INT: - case cs_value_type::FLOAT: - case cs_value_type::STRING: - std::ranges::copy( - cs_value{vals[i]}.force_str(), std::back_inserter(buf) - ); - break; - default: - break; - } - if (i == (vals.size() - 1)) { - break; - } - std::ranges::copy(sep, std::back_inserter(buf)); - } - return cs_strref{cs, buf.str()}; -} - } /* namespace cscript */ diff --git a/src/cs_val.cc b/src/cs_val.cc index 553bac0..03b7153 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -427,4 +427,30 @@ bool cs_stacked_value::pop() { return true; } +/* public utilities */ + +LIBCUBESCRIPT_EXPORT cs_strref cs_concat_values( + cs_state &cs, std::span vals, std::string_view sep +) { + cs_charbuf buf{cs}; + for (std::size_t i = 0; i < vals.size(); ++i) { + switch (vals[i].get_type()) { + case cs_value_type::INT: + case cs_value_type::FLOAT: + case cs_value_type::STRING: + std::ranges::copy( + cs_value{vals[i]}.force_str(), std::back_inserter(buf) + ); + break; + default: + break; + } + if (i == (vals.size() - 1)) { + break; + } + std::ranges::copy(sep, std::back_inserter(buf)); + } + return cs_strref{cs, buf.str()}; +} + } /* namespace cscript */ diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 0b76545..d7defe3 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -230,7 +230,7 @@ static inline void callcommand( case 'C': { i = std::max(i + 1, numargs); cs_value tv{cs}; - tv.set_str(value_list_concat( + tv.set_str(cs_concat_values( cs, std::span{args, std::size_t(i)}, " " )); static_cast(id)->call( @@ -1146,7 +1146,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) { result.force_none(); { cs_value tv{cs}; - tv.set_str(value_list_concat(cs, std::span{ + tv.set_str(cs_concat_values(cs, std::span{ &args[offset], callargs }, " ")); id->call(cs, std::span{&tv, 1}, result); @@ -1165,7 +1165,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) { case CS_CODE_CONC_W | CS_RET_FLOAT: case CS_CODE_CONC_W | CS_RET_INT: { std::size_t numconc = op >> 8; - auto buf = value_list_concat( + auto buf = cs_concat_values( cs, std::span{&args[numargs - numconc], numconc}, ((op & CS_CODE_OP_MASK) == CS_CODE_CONC) ? " " : "" ); @@ -1181,7 +1181,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) { case CS_CODE_CONC_M | CS_RET_FLOAT: case CS_CODE_CONC_M | CS_RET_INT: { std::size_t numconc = op >> 8; - auto buf = value_list_concat( + auto buf = cs_concat_values( cs, std::span{&args[numargs - numconc], numconc} ); numargs = numargs - numconc; diff --git a/src/lib_str.cc b/src/lib_str.cc index 77a9dc4..9b2e19d 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -90,11 +90,11 @@ void cs_init_lib_string(cs_state &cs) { }); cs.new_command("concat", "V", [](auto &ccs, auto args, auto &res) { - res.set_str(value_list_concat(ccs, args, " ")); + res.set_str(cs_concat_values(ccs, args, " ")); }); cs.new_command("concatword", "V", [](auto &ccs, auto args, auto &res) { - res.set_str(value_list_concat(ccs, args)); + res.set_str(cs_concat_values(ccs, args)); }); cs.new_command("format", "V", [](auto &ccs, auto args, auto &res) { diff --git a/src/meson.build b/src/meson.build index d6aaefc..9960f48 100644 --- a/src/meson.build +++ b/src/meson.build @@ -8,10 +8,10 @@ libcubescript_src = [ 'cs_error.cc', 'cs_gen.cc', 'cs_ident.cc', + 'cs_parser.cc', 'cs_state.cc', 'cs_std.cc', 'cs_strman.cc', - 'cs_util.cc', 'cs_val.cc', 'cs_vm.cc', 'cubescript.cc',