2017-06-20 19:21:39 +00:00
|
|
|
#include <cubescript/cubescript.hh>
|
2021-03-23 00:45:35 +00:00
|
|
|
#include "cs_std.hh"
|
2021-03-23 21:17:25 +00:00
|
|
|
#include "cs_parser.hh"
|
2021-03-24 20:01:01 +00:00
|
|
|
#include "cs_state.hh"
|
2016-09-06 17:27:54 +00:00
|
|
|
|
2021-03-20 06:24:25 +00:00
|
|
|
#include <cmath>
|
2021-03-30 23:10:58 +00:00
|
|
|
#include <iterator>
|
2021-03-20 06:24:25 +00:00
|
|
|
|
2021-03-23 22:32:25 +00:00
|
|
|
namespace cubescript {
|
2016-09-06 17:27:54 +00:00
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
static std::string_view intstr(integer_type v, charbuf &buf) {
|
2021-03-20 06:24:25 +00:00
|
|
|
buf.reserve(32);
|
2021-04-06 19:23:17 +00:00
|
|
|
int n = snprintf(buf.data(), 32, INTEGER_FORMAT, v);
|
2021-03-20 06:24:25 +00:00
|
|
|
if (n > 32) {
|
|
|
|
buf.reserve(n + 1);
|
2021-04-06 19:23:17 +00:00
|
|
|
int nn = snprintf(buf.data(), n + 1, INTEGER_FORMAT, v);
|
2021-03-20 06:24:25 +00:00
|
|
|
if ((nn > n) || (nn <= 0)) {
|
|
|
|
n = -1;
|
|
|
|
} else {
|
|
|
|
n = nn;
|
|
|
|
}
|
2021-03-18 23:34:12 +00:00
|
|
|
}
|
2021-03-20 06:24:25 +00:00
|
|
|
if (n <= 0) {
|
2021-03-23 22:29:32 +00:00
|
|
|
throw internal_error{"format error"};
|
2021-03-20 06:24:25 +00:00
|
|
|
}
|
|
|
|
return std::string_view{buf.data(), std::size_t(n)};
|
2021-03-18 23:12:47 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
static std::string_view floatstr(float_type v, charbuf &buf) {
|
2021-03-20 06:24:25 +00:00
|
|
|
buf.reserve(32);
|
|
|
|
int n;
|
|
|
|
if (v == std::floor(v)) {
|
2021-03-23 22:29:32 +00:00
|
|
|
n = snprintf(buf.data(), 32, ROUND_FLOAT_FORMAT, v);
|
2021-03-20 06:24:25 +00:00
|
|
|
} else {
|
2021-03-23 22:29:32 +00:00
|
|
|
n = snprintf(buf.data(), 32, FLOAT_FORMAT, v);
|
2021-03-20 06:24:25 +00:00
|
|
|
}
|
|
|
|
if (n > 32) {
|
|
|
|
buf.reserve(n + 1);
|
|
|
|
int nn;
|
|
|
|
if (v == std::floor(v)) {
|
2021-03-23 22:29:32 +00:00
|
|
|
nn = snprintf(buf.data(), n + 1, ROUND_FLOAT_FORMAT, v);
|
2021-03-20 06:24:25 +00:00
|
|
|
} else {
|
2021-03-23 22:29:32 +00:00
|
|
|
nn = snprintf(buf.data(), n + 1, FLOAT_FORMAT, v);
|
2021-03-20 06:24:25 +00:00
|
|
|
}
|
|
|
|
if ((nn > n) || (nn <= 0)) {
|
|
|
|
n = -1;
|
|
|
|
} else {
|
|
|
|
n = nn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (n <= 0) {
|
2021-03-23 22:29:32 +00:00
|
|
|
throw internal_error{"format error"};
|
2021-03-18 23:34:12 +00:00
|
|
|
}
|
2021-03-20 06:24:25 +00:00
|
|
|
return std::string_view{buf.data(), std::size_t(n)};
|
2021-03-18 23:12:47 +00:00
|
|
|
}
|
|
|
|
|
2021-03-17 00:26:16 +00:00
|
|
|
template<typename T>
|
|
|
|
struct stor_priv_t {
|
2021-03-23 22:29:32 +00:00
|
|
|
internal_state *state;
|
2021-03-17 00:26:16 +00:00
|
|
|
T val;
|
|
|
|
};
|
|
|
|
|
2016-09-06 18:06:49 +00:00
|
|
|
template<typename T, typename U>
|
2021-03-24 01:42:33 +00:00
|
|
|
static inline T &csv_get(U *stor) {
|
2016-09-06 18:06:49 +00:00
|
|
|
/* ugly, but internal and unlikely to cause bugs */
|
2021-03-24 01:42:33 +00:00
|
|
|
return const_cast<T &>(std::launder(
|
|
|
|
reinterpret_cast<stor_priv_t<T> const *>(stor)
|
|
|
|
)->val);
|
2016-09-06 18:06:49 +00:00
|
|
|
}
|
|
|
|
|
2016-09-06 21:54:28 +00:00
|
|
|
template<typename T>
|
2021-03-24 01:42:33 +00:00
|
|
|
static inline void csv_cleanup(value_type tv, T *stor) {
|
2016-09-06 21:54:28 +00:00
|
|
|
switch (tv) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-03-24 01:42:33 +00:00
|
|
|
std::launder(reinterpret_cast<string_ref *>(stor))->~string_ref();
|
2016-09-06 21:54:28 +00:00
|
|
|
break;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::CODE: {
|
2021-03-21 17:45:59 +00:00
|
|
|
bcode_unref(csv_get<uint32_t *>(stor));
|
2016-09-06 21:54:28 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-05 02:10:39 +00:00
|
|
|
any_value::any_value(state &st): any_value(*state_p{st}.ts().istate) {}
|
2021-03-17 00:26:16 +00:00
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
any_value::any_value(internal_state &st):
|
|
|
|
p_stor(), p_type(value_type::NONE)
|
2021-03-17 00:26:16 +00:00
|
|
|
{
|
2021-03-24 01:42:33 +00:00
|
|
|
std::launder(reinterpret_cast<stor_priv_t<void *> *>(&p_stor))->state = &st;
|
2021-03-17 00:26:16 +00:00
|
|
|
}
|
2016-09-06 20:23:03 +00:00
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
any_value::~any_value() {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2016-09-06 20:57:10 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
any_value::any_value(any_value const &v): any_value(*v.get_state()) {
|
2016-09-06 20:23:03 +00:00
|
|
|
*this = v;
|
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
any_value::any_value(any_value &&v): any_value(*v.get_state()) {
|
2021-03-20 03:49:47 +00:00
|
|
|
*this = std::move(v);
|
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
any_value &any_value::operator=(any_value const &v) {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
p_type = value_type::NONE;
|
2016-09-06 20:23:03 +00:00
|
|
|
switch (v.get_type()) {
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
|
|
|
case value_type::IDENT:
|
2016-09-06 20:23:03 +00:00
|
|
|
p_type = v.p_type;
|
2016-09-06 20:57:10 +00:00
|
|
|
p_stor = v.p_stor;
|
2016-09-06 20:23:03 +00:00
|
|
|
break;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
|
|
|
p_type = value_type::STRING;
|
|
|
|
new (&p_stor) string_ref{
|
2021-03-24 01:42:33 +00:00
|
|
|
*std::launder(reinterpret_cast<string_ref const *>(&v.p_stor))
|
2021-03-17 01:47:34 +00:00
|
|
|
};
|
2016-09-06 20:23:03 +00:00
|
|
|
break;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::CODE:
|
2021-03-21 17:45:59 +00:00
|
|
|
set_code(v.get_code());
|
2016-09-06 20:23:03 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
any_value &any_value::operator=(any_value &&v) {
|
2021-03-20 03:49:47 +00:00
|
|
|
*this = v;
|
|
|
|
v.set_none();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
value_type any_value::get_type() const {
|
2016-09-06 17:27:54 +00:00
|
|
|
return p_type;
|
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
void any_value::set_integer(integer_type val) {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-04-05 22:54:46 +00:00
|
|
|
p_type = value_type::INTEGER;
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_get<integer_type>(&p_stor) = val;
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
void any_value::set_float(float_type val) {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
p_type = value_type::FLOAT;
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_get<float_type>(&p_stor) = val;
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
void any_value::set_string(std::string_view val) {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
new (&p_stor) string_ref{get_state(), val};
|
|
|
|
p_type = value_type::STRING;
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
void any_value::set_string(string_ref const &val) {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
new (&p_stor) string_ref{val};
|
|
|
|
p_type = value_type::STRING;
|
2021-03-17 20:46:37 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
void any_value::set_none() {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
p_type = value_type::NONE;
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-01 03:05:43 +00:00
|
|
|
void any_value::set_code(bcode_ref const &val) {
|
|
|
|
bcode *p = val;
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
p_type = value_type::CODE;
|
2021-04-01 03:05:43 +00:00
|
|
|
bcode_addref(p->get_raw());
|
|
|
|
csv_get<bcode *>(&p_stor) = p;
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
void any_value::set_ident(ident *val) {
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_cleanup(p_type, &p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
p_type = value_type::IDENT;
|
2021-03-24 01:42:33 +00:00
|
|
|
csv_get<ident *>(&p_stor) = val;
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
void any_value::force_none() {
|
|
|
|
if (get_type() == value_type::NONE) {
|
2016-09-06 17:27:54 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-03-18 19:55:14 +00:00
|
|
|
set_none();
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
void any_value::force_plain() {
|
|
|
|
switch (get_type()) {
|
|
|
|
case value_type::FLOAT:
|
|
|
|
case value_type::INTEGER:
|
|
|
|
case value_type::STRING:
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
force_none();
|
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
float_type any_value::force_float() {
|
|
|
|
float_type rf = 0.0f;
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-30 23:10:58 +00:00
|
|
|
rf = float_type(csv_get<integer_type>(&p_stor));
|
2016-09-06 17:27:54 +00:00
|
|
|
break;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-03-23 00:45:35 +00:00
|
|
|
rf = parse_float(
|
2021-03-24 01:42:33 +00:00
|
|
|
*std::launder(reinterpret_cast<string_ref const *>(&p_stor))
|
2021-03-20 01:26:37 +00:00
|
|
|
);
|
2016-09-06 17:27:54 +00:00
|
|
|
break;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
2021-03-24 01:42:33 +00:00
|
|
|
return csv_get<float_type>(&p_stor);
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
set_float(rf);
|
|
|
|
return rf;
|
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
integer_type any_value::force_integer() {
|
2021-03-23 22:29:32 +00:00
|
|
|
integer_type ri = 0;
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
2021-03-30 23:10:58 +00:00
|
|
|
ri = integer_type(std::floor(csv_get<float_type>(&p_stor)));
|
2016-09-06 17:27:54 +00:00
|
|
|
break;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-03-23 00:45:35 +00:00
|
|
|
ri = parse_int(
|
2021-03-24 01:42:33 +00:00
|
|
|
*std::launder(reinterpret_cast<string_ref const *>(&p_stor))
|
2021-03-20 01:26:37 +00:00
|
|
|
);
|
2016-09-06 17:27:54 +00:00
|
|
|
break;
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-24 01:42:33 +00:00
|
|
|
return csv_get<integer_type>(&p_stor);
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2021-04-05 22:54:46 +00:00
|
|
|
set_integer(ri);
|
2016-09-06 17:27:54 +00:00
|
|
|
return ri;
|
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
std::string_view any_value::force_string() {
|
2021-03-23 22:29:32 +00:00
|
|
|
charbuf rs{get_state()};
|
2021-03-20 06:24:25 +00:00
|
|
|
std::string_view str;
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
2021-03-24 01:42:33 +00:00
|
|
|
str = floatstr(csv_get<float_type>(&p_stor), rs);
|
2016-09-06 17:27:54 +00:00
|
|
|
break;
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-24 01:42:33 +00:00
|
|
|
str = intstr(csv_get<integer_type>(&p_stor), rs);
|
2016-09-06 17:27:54 +00:00
|
|
|
break;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-03-24 01:42:33 +00:00
|
|
|
return *std::launder(reinterpret_cast<string_ref const *>(&p_stor));
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
2021-03-20 06:24:25 +00:00
|
|
|
str = rs.str();
|
2016-09-06 17:27:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-04-05 22:54:46 +00:00
|
|
|
set_string(str);
|
2021-03-24 01:42:33 +00:00
|
|
|
return std::string_view(*std::launder(
|
|
|
|
reinterpret_cast<string_ref const *>(&p_stor)
|
|
|
|
));
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-01 03:05:43 +00:00
|
|
|
bcode_ref any_value::force_code(state &cs) {
|
2021-03-24 20:01:01 +00:00
|
|
|
switch (get_type()) {
|
|
|
|
case value_type::CODE:
|
2021-04-01 03:05:43 +00:00
|
|
|
return bcode_ref{csv_get<bcode *>(&p_stor)};
|
2021-03-24 20:01:01 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2021-04-08 22:41:55 +00:00
|
|
|
gen_state gs{state_p{cs}.ts()};
|
2021-04-08 23:03:29 +00:00
|
|
|
parser_state{state_p{cs}.ts(), gs}.gen_main(get_string());
|
2021-04-08 23:12:52 +00:00
|
|
|
auto bc = gs.steal_ref();
|
2021-03-24 20:01:01 +00:00
|
|
|
set_code(bc);
|
2021-04-08 23:12:52 +00:00
|
|
|
return bc;
|
2021-03-24 20:01:01 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 17:52:13 +00:00
|
|
|
ident &any_value::force_ident(state &cs) {
|
2021-03-24 20:01:01 +00:00
|
|
|
switch (get_type()) {
|
|
|
|
case value_type::IDENT:
|
2021-04-05 17:52:13 +00:00
|
|
|
return *csv_get<ident *>(&p_stor);
|
2021-03-24 20:01:01 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2021-04-05 17:52:13 +00:00
|
|
|
auto &id = state_p{cs}.ts().istate->new_ident(
|
2021-04-05 22:54:46 +00:00
|
|
|
cs, get_string(), IDENT_FLAG_UNKNOWN
|
2021-04-03 04:16:43 +00:00
|
|
|
);
|
2021-04-05 17:52:13 +00:00
|
|
|
set_ident(&id);
|
2021-03-24 20:01:01 +00:00
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
integer_type any_value::get_integer() const {
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
2021-03-24 01:42:33 +00:00
|
|
|
return integer_type(csv_get<float_type>(&p_stor));
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-24 01:42:33 +00:00
|
|
|
return csv_get<integer_type>(&p_stor);
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-03-23 00:45:35 +00:00
|
|
|
return parse_int(
|
2021-03-24 01:42:33 +00:00
|
|
|
*std::launder(reinterpret_cast<string_ref const *>(&p_stor))
|
2021-03-20 01:26:37 +00:00
|
|
|
);
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
float_type any_value::get_float() const {
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
2021-03-24 01:42:33 +00:00
|
|
|
return csv_get<float_type>(&p_stor);
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-24 01:42:33 +00:00
|
|
|
return float_type(csv_get<integer_type>(&p_stor));
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-03-23 00:45:35 +00:00
|
|
|
return parse_float(
|
2021-03-24 01:42:33 +00:00
|
|
|
*std::launder(reinterpret_cast<string_ref const *>(&p_stor))
|
2021-03-20 01:26:37 +00:00
|
|
|
);
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
|
2021-04-01 03:05:43 +00:00
|
|
|
bcode_ref any_value::get_code() const {
|
2021-03-23 22:29:32 +00:00
|
|
|
if (get_type() != value_type::CODE) {
|
2021-04-01 03:05:43 +00:00
|
|
|
return bcode_ref{};
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
2021-04-01 03:05:43 +00:00
|
|
|
return bcode_ref{csv_get<bcode *>(&p_stor)};
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
ident *any_value::get_ident() const {
|
|
|
|
if (get_type() != value_type::IDENT) {
|
2016-09-06 17:27:54 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
2021-03-24 01:42:33 +00:00
|
|
|
return csv_get<ident *>(&p_stor);
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
string_ref any_value::get_string() const {
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-03-24 01:42:33 +00:00
|
|
|
return *std::launder(reinterpret_cast<string_ref const *>(&p_stor));
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER: {
|
2021-03-23 22:29:32 +00:00
|
|
|
charbuf rs{get_state()};
|
|
|
|
return string_ref{
|
2021-03-24 01:42:33 +00:00
|
|
|
get_state(), intstr(csv_get<integer_type>(&p_stor), rs)
|
2021-03-23 22:29:32 +00:00
|
|
|
};
|
2021-03-20 06:24:25 +00:00
|
|
|
}
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT: {
|
|
|
|
charbuf rs{get_state()};
|
|
|
|
return string_ref{
|
2021-03-24 01:42:33 +00:00
|
|
|
get_state(), floatstr(csv_get<float_type>(&p_stor), rs)
|
2021-03-23 22:29:32 +00:00
|
|
|
};
|
2021-03-20 06:24:25 +00:00
|
|
|
}
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2021-03-23 22:29:32 +00:00
|
|
|
return string_ref{get_state(), ""};
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-05 22:54:46 +00:00
|
|
|
any_value any_value::get_plain() const {
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING:
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
2021-04-05 22:54:46 +00:00
|
|
|
return *this;
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2021-04-05 22:54:46 +00:00
|
|
|
return any_value{*get_state()};
|
2016-09-06 17:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
bool any_value::get_bool() const {
|
2016-09-06 17:27:54 +00:00
|
|
|
switch (get_type()) {
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
2021-03-24 01:42:33 +00:00
|
|
|
return csv_get<float_type>(&p_stor) != 0;
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-24 01:42:33 +00:00
|
|
|
return csv_get<integer_type>(&p_stor) != 0;
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::STRING: {
|
2021-03-24 01:42:33 +00:00
|
|
|
std::string_view s = *std::launder(
|
|
|
|
reinterpret_cast<string_ref const *>(&p_stor)
|
|
|
|
);
|
2021-03-23 22:29:32 +00:00
|
|
|
if (s.empty()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
std::string_view end = s;
|
|
|
|
integer_type ival = parse_int(end, &end);
|
|
|
|
if (end.empty()) {
|
|
|
|
return !!ival;
|
|
|
|
}
|
|
|
|
end = s;
|
|
|
|
float_type fval = parse_float(end, &end);
|
|
|
|
if (end.empty()) {
|
|
|
|
return !!fval;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2016-09-06 17:27:54 +00:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-23 01:00:11 +00:00
|
|
|
/* public utilities */
|
|
|
|
|
2021-03-23 22:29:32 +00:00
|
|
|
LIBCUBESCRIPT_EXPORT string_ref concat_values(
|
|
|
|
state &cs, std::span<any_value> vals, std::string_view sep
|
2021-03-23 01:00:11 +00:00
|
|
|
) {
|
2021-03-23 22:29:32 +00:00
|
|
|
charbuf buf{cs};
|
2021-03-23 01:00:11 +00:00
|
|
|
for (std::size_t i = 0; i < vals.size(); ++i) {
|
|
|
|
switch (vals[i].get_type()) {
|
2021-04-05 22:54:46 +00:00
|
|
|
case value_type::INTEGER:
|
2021-03-23 22:29:32 +00:00
|
|
|
case value_type::FLOAT:
|
|
|
|
case value_type::STRING:
|
2021-03-23 01:00:11 +00:00
|
|
|
std::ranges::copy(
|
2021-04-05 22:54:46 +00:00
|
|
|
any_value{vals[i]}.force_string(), std::back_inserter(buf)
|
2021-03-23 01:00:11 +00:00
|
|
|
);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == (vals.size() - 1)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
std::ranges::copy(sep, std::back_inserter(buf));
|
|
|
|
}
|
2021-03-23 22:29:32 +00:00
|
|
|
return string_ref{cs, buf.str()};
|
2021-03-23 01:00:11 +00:00
|
|
|
}
|
|
|
|
|
2021-03-23 22:32:25 +00:00
|
|
|
} /* namespace cubescript */
|