diff --git a/command.cc b/command.cc index 8f5bd0be..4d41716f 100644 --- a/command.cc +++ b/command.cc @@ -758,7 +758,7 @@ static void cs_init_lib_base_var(CsState &cs) { }); cs.add_command("getalias", "s", [](CsState &cs, const char *name) { - result(cs, cs.get_alias(name).value_or("").data()); + cs.result->set_str(dup_ostr(cs.get_alias(name).value_or("").data())); }); } @@ -775,7 +775,7 @@ const char *parsestring(const char *p) { return p; } -int unescapestring(char *dst, const char *src, const char *end) { +int cs_str_unescape(char *dst, const char *src, const char *end) { char *start = dst; while (src < end) { int c = *src++; @@ -913,7 +913,7 @@ static inline void cutstring(const char *&p, ostd::ConstCharRange &s) { ostd::Vector &buf = strbuf[stridx]; buf.reserve(maxlen); - s = ostd::ConstCharRange(buf.data(), unescapestring(buf.data(), p, end)); + s = ostd::ConstCharRange(buf.data(), cs_str_unescape(buf.data(), p, end)); p = end; if (*p == '\"') p++; } @@ -922,7 +922,7 @@ static inline char *cutstring(const char *&p) { p++; const char *end = parsestring(p); char *buf = new char[end - p + 1]; - unescapestring(buf, p, end); + cs_str_unescape(buf, p, end); p = end; if (*p == '\"') p++; return buf; @@ -1087,13 +1087,13 @@ static inline const char *compileblock(GenState &gs, const char *p, int rettype return p; } -static inline void compileunescapestring(GenState &gs, const char *&p, bool macro = false) { +static inline void compileunescapestr(GenState &gs, const char *&p, bool macro = false) { p++; const char *end = parsestring(p); gs.code.push(macro ? CODE_MACRO : CODE_VAL | RET_STR); gs.code.reserve(gs.code.size() + (end - p) / sizeof(ostd::Uint32) + 1); char *buf = (char *)&gs.code[gs.code.size()]; - int len = unescapestring(buf, p, end); + int len = cs_str_unescape(buf, p, end); memset(&buf[len], 0, sizeof(ostd::Uint32) - len % sizeof(ostd::Uint32)); gs.code.back() |= len << 8; gs.code.advance(len / sizeof(ostd::Uint32) + 1); @@ -1628,11 +1628,11 @@ static bool compilearg(GenState &gs, const char *&p, int wordtype, int prevargs, break; case VAL_ANY: case VAL_STR: - compileunescapestring(gs, p); + compileunescapestr(gs, p); break; case VAL_CANY: case VAL_CSTR: - compileunescapestring(gs, p, true); + compileunescapestr(gs, p, true); break; default: { ostd::ConstCharRange s; @@ -3264,14 +3264,6 @@ const char *escapestring(const char *s) { return buf.data(); } -ICOMMAND(escape, "s", (CsState &cs, char *s), result(cs, escapestring(s))); -ICOMMAND(unescape, "s", (CsState &cs, char *s), { - int len = strlen(s); - char *d = new char[len + 1]; - unescapestring(d, s, &s[len]); - stringret(cs, d); -}); - const char *escapeid(const char *s) { const char *end = s + strcspn(s, "\"/;()[]@ \f\t\r\n\0"); return *end ? escapestring(s) : s; @@ -3367,7 +3359,7 @@ void init_lib_base(CsState &cs) { cs.add_command("?", "tTT", [](CsState &cs, TaggedValue *cond, TaggedValue *t, TaggedValue *f) { - result(cs, *(getbool(*cond) ? t : f)); + cs.result->set(*(getbool(*cond) ? t : f)); }); cs.add_command("cond", "ee2V", [](CsState &cs, TaggedValue *args, @@ -3385,7 +3377,7 @@ void init_lib_base(CsState &cs) { } }); -#define CS_CASE_COMMAND(name, fmt, type, acc, compare) \ +#define CS_CMD_CASE(name, fmt, type, acc, compare) \ cs.add_command(name, fmt "te2V", [](CsState &cs, TaggedValue *args, \ int numargs) { \ type val = acc; \ @@ -3398,19 +3390,19 @@ void init_lib_base(CsState &cs) { } \ }); - CS_CASE_COMMAND("case", "i", int, args[0].get_int(), + CS_CMD_CASE("case", "i", int, args[0].get_int(), ((args[i].type == VAL_NULL) || (args[i].get_int() == val))); - CS_CASE_COMMAND("casef", "f", float, args[0].get_float(), + CS_CMD_CASE("casef", "f", float, args[0].get_float(), ((args[i].type == VAL_NULL) || (args[i].get_float() == val))); - CS_CASE_COMMAND("cases", "s", const char *, args[0].get_str(), + CS_CMD_CASE("cases", "s", const char *, args[0].get_str(), ((args[i].type == VAL_NULL) || !strcmp(args[i].get_str(), val))); -#undef CS_CASE_COMMAND +#undef CS_CMD_CASE cs.add_command("pushif", "rTe", [](CsState &cs, Ident *id, TaggedValue *v, ostd::Uint32 *code) { @@ -3599,48 +3591,6 @@ const char *floatstr(float v) { #undef ICOMMANDSNAME #define ICOMMANDSNAME _stdcmd -void concat(CsState &cs, TaggedValue *v, int n) { - cs.result->set_str(conc(v, n, true)); -} -COMMAND(concat, "V"); - -void concatword(CsState &cs, TaggedValue *v, int n) { - cs.result->set_str(conc(v, n, false)); -} -COMMAND(concatword, "V"); - -void result(CsState &cs, TaggedValue &v) { - *cs.result = v; - v.type = VAL_NULL; -} - -void stringret(CsState &cs, char *s) { - cs.result->set_str(s); -} - -void result(CsState &cs, const char *s) { - cs.result->set_str(dup_ostr(s)); -} - -void format(CsState &cs, TaggedValue *args, int numargs) { - ostd::Vector s; - const char *f = args[0].get_str(); - while (*f) { - int c = *f++; - if (c == '%') { - int i = *f++; - if (i >= '1' && i <= '9') { - i -= '0'; - const char *sub = i < numargs ? args[i].get_str() : ""; - while (*sub) s.push(*sub++); - } else s.push(i); - } else s.push(c); - } - s.push('\0'); - cs.result->set_str(s.disown()); -} -COMMAND(format, "V"); - static const char *liststart = nullptr, *listend = nullptr, *listquotestart = nullptr, *listquoteend = nullptr; static inline void skiplist(const char *&p) { @@ -3716,7 +3666,7 @@ static inline ostd::String listelem(const char *start = liststart, const char *e ostd::Size len = end - start; ostd::String s; s.reserve(len); - if (*quotestart == '"') unescapestring(s.data(), start, end); + if (*quotestart == '"') cs_str_unescape(s.data(), start, end); else { memcpy(s.data(), start, len); s[len] = '\0'; @@ -3758,12 +3708,6 @@ void at(CsState &cs, TaggedValue *args, int numargs) { } COMMAND(at, "si1V"); -void substr(CsState &cs, char *s, int *start, int *count, int *numargs) { - int len = strlen(s), offset = ostd::clamp(*start, 0, len); - cs.result->set_str(dup_ostr(ostd::ConstCharRange(&s[offset], *numargs >= 3 ? ostd::clamp(*count, 0, len - offset) : len - offset))); -} -COMMAND(substr, "siiN"); - void sublist(CsState &cs, const char *s, int *skip, int *count, int *numargs) { int offset = ostd::max(*skip, 0), len = *numargs >= 3 ? ostd::max(*count, 0) : -1; for (int i = 0; i < offset; ++i) if (!parselist(s)) break; @@ -3821,7 +3765,7 @@ void listassoc(CsState &cs, Ident *id, const char *list, const ostd::Uint32 *bod ++n; setiter(*id, dup_ostr(ostd::ConstCharRange(start, end - start)), stack); if (cs.run_bool(body)) { - if (parselist(s, start, end, qstart)) stringret(cs, listelem(start, end, qstart).disown()); + if (parselist(s, start, end, qstart)) cs.result->set_str(listelem(start, end, qstart).disown()); break; } if (!parselist(s)) break; @@ -3853,7 +3797,7 @@ LISTFIND(listfind=s, "s", char, int len = (int)strlen(val), int(end - start) == init; \ for(const char *s = list, *start, *end, *qstart; parselist(s, start, end);) \ { \ - if(cmp) { if(parselist(s, start, end, qstart)) stringret(cs, listelem(start, end, qstart).disown()); return; } \ + if(cmp) { if(parselist(s, start, end, qstart)) cs.result->set_str(listelem(start, end, qstart).disown()); return; } \ if(!parselist(s)) break; \ } \ }); @@ -3972,7 +3916,7 @@ void prettylist(CsState &cs, const char *s, const char *conj) { for (int len = listlen(cs, s), n = 0; parselist(s, start, end, qstart); n++) { if (*qstart == '"') { p.reserve(p.size() + end - start); - p.advance(unescapestring(&p[p.size()], start, end)); + p.advance(cs_str_unescape(&p[p.size()], start, end)); } else p.push_n(start, end - start); if (n + 1 < len) { if (len > 2 || !conj[0]) p.push(','); @@ -4160,79 +4104,6 @@ void sortlist(CsState &cs, char *list, Ident *x, Ident *y, ostd::Uint32 *body, o COMMAND(sortlist, "srree"); ICOMMAND(uniquelist, "srre", (CsState &cs, char *list, Ident *x, Ident *y, ostd::Uint32 *body), sortlist(cs, list, x, y, nullptr, body)); -#define MATHCMD(name, fmt, type, op, initval, unaryop) \ - ICOMMANDS(name, #fmt "1V", (CsState &cs, TaggedValue *args, int numargs), \ - { \ - type val; \ - if(numargs >= 2) \ - { \ - val = args[0].fmt; \ - type val2 = args[1].fmt; \ - op; \ - for(int i = 2; i < numargs; i++) { val2 = args[i].fmt; op; } \ - } \ - else { val = numargs > 0 ? args[0].fmt : initval; unaryop; } \ - cs.result->set_##type(val); \ - }) -#define MATHICMDN(name, op, initval, unaryop) MATHCMD(#name, i, int, val = val op val2, initval, unaryop) -#define MATHICMD(name, initval, unaryop) MATHICMDN(name, name, initval, unaryop) -#define MATHFCMDN(name, op, initval, unaryop) MATHCMD(#name "f", f, float, val = val op val2, initval, unaryop) -#define MATHFCMD(name, initval, unaryop) MATHFCMDN(name, name, initval, unaryop) - -#define CMPCMD(name, fmt, type, op) \ - ICOMMANDS(name, #fmt "1V", (CsState &cs, TaggedValue *args, int numargs), \ - { \ - bool val; \ - if(numargs >= 2) \ - { \ - val = args[0].fmt op args[1].fmt; \ - for(int i = 2; i < numargs && val; i++) val = args[i-1].fmt op args[i].fmt; \ - } \ - else val = (numargs > 0 ? args[0].fmt : 0) op 0; \ - cs.result->set_int(int(val)); \ - }) -#define CMPICMDN(name, op) CMPCMD(#name, i, int, op) -#define CMPICMD(name) CMPICMDN(name, name) -#define CMPFCMDN(name, op) CMPCMD(#name "f", f, float, op) -#define CMPFCMD(name) CMPFCMDN(name, name) - -MATHICMD(+, 0, ); -MATHICMD(*, 1, ); -MATHICMD(-, 0, val = -val); -CMPICMDN(=, ==); -CMPICMD(!=); -CMPICMD(<); -CMPICMD(>); -CMPICMD(<=); -CMPICMD(>=); -MATHICMD(^, 0, val = ~val); -MATHICMDN(~, ^, 0, val = ~val); -MATHICMD(&, 0, ); -MATHICMD(|, 0, ); -MATHICMD(^~, 0, ); -MATHICMD(&~, 0, ); -MATHICMD(|~, 0, ); -MATHCMD("<<", i, int, val = val2 < 32 ? val << ostd::max(val2, 0) : 0, 0, ); -MATHCMD(">>", i, int, val >>= ostd::clamp(val2, 0, 31), 0, ); - -MATHFCMD(+, 0, ); -MATHFCMD(*, 1, ); -MATHFCMD(-, 0, val = -val); -CMPFCMDN(=, ==); -CMPFCMD(!=); -CMPFCMD(<); -CMPFCMD(>); -CMPFCMD(<=); -CMPFCMD(>=); - -#define DIVCMD(name, fmt, type, op) MATHCMD(#name, fmt, type, { if(val2) op; else val = 0; }, 0, ) - -DIVCMD(div, i, int, val /= val2); -DIVCMD(mod, i, int, val %= val2); -DIVCMD(divf, f, float, val /= val2); -DIVCMD(modf, f, float, val = fmod(val, val2)); -MATHCMD("pow", f, float, val = pow(val, val2), 0, ); - static constexpr float PI = 3.14159265358979f; static constexpr float RAD = PI / 180.0f; @@ -4305,63 +4176,126 @@ void init_lib_math(CsState &cs) { cs.add_command("ceil", "f", [](CsState &cs, float *v) { cs.result->set_float(ceil(*v)); }); -} -ICOMMAND(round, "ff", (CsState &cs, float *n, float *k), { - double step = *k; - double r = *n; - if (step > 0) { - r += step * (r < 0 ? -0.5 : 0.5); - r -= fmod(r, step); - } else r = r < 0 ? ceil(r - 0.5) : floor(r + 0.5); - cs.result->set_float(float(r)); -}); + cs.add_command("round", "ff", [](CsState &cs, float *n, float *k) { + double step = *k; + double r = *n; + if (step > 0) { + r += step * ((r < 0) ? -0.5 : 0.5); + r -= fmod(r, step); + } else { + r = (r < 0) ? ceil(r - 0.5) : floor(r + 0.5); + } + cs.result->set_float(float(r)); + }); -ICOMMAND(tohex, "ii", (CsState &cs, int *n, int *p), { - auto r = ostd::appender>(); - ostd::format(r, "0x%.*X", ostd::max(*p, 1), *n); - r.put('\0'); - stringret(cs, r.get().disown()); -}); - -#define CMPSCMD(name, op) \ - ICOMMAND(name, "s1V", (CsState &cs, TaggedValue *args, int numargs), \ - { \ - bool val; \ - if(numargs >= 2) \ - { \ - val = strcmp(args[0].s, args[1].s) op 0; \ - for(int i = 2; i < numargs && val; i++) val = strcmp(args[i-1].s, args[i].s) op 0; \ +#define CS_CMD_MATH(name, fmt, type, op, initval, unaryop) \ + cs.add_command(name, #fmt "1V", [](CsState &, TaggedValue *args, \ + int numargs) { \ + type val; \ + if (numargs >= 2) { \ + val = args[0].fmt; \ + type val2 = args[1].fmt; \ + op; \ + for (int i = 2; i < numargs; ++i) { \ + val2 = args[i].fmt; \ + op; \ + } \ + } else { \ + val = (numargs > 0) ? args[0].fmt : initval; \ + unaryop; \ } \ - else val = (numargs > 0 ? args[0].s[0] : 0) op 0; \ + }); + +#define CS_CMD_MATHIN(name, op, initval, unaryop) \ + CS_CMD_MATH(#name, i, int, val = val op val2, initval, unaryop) + +#define CS_CMD_MATHI(name, initval, unaryop) \ + CS_CMD_MATHIN(name, name, initval, unaryop) + +#define CS_CMD_MATHFN(name, op, initval, unaryop) \ + CS_CMD_MATH(#name "f", f, float, val = val op val2, initval, unaryop) + +#define CS_CMD_MATHF(name, initval, unaryop) \ + CS_CMD_MATHIN(name, name, initval, unaryop) + + CS_CMD_MATHI(+, 0, ); + CS_CMD_MATHI(*, 1, ); + CS_CMD_MATHI(-, 0, val = -val); + + CS_CMD_MATHI(^, 0, val = ~val); + CS_CMD_MATHIN(~, ^, 0, val = ~val); + CS_CMD_MATHI(&, 0, ); + CS_CMD_MATHI(|, 0, ); + CS_CMD_MATHI(^~, 0, ); + CS_CMD_MATHI(&~, 0, ); + CS_CMD_MATHI(|~, 0, ); + + CS_CMD_MATH("<<", i, int, { + val = (val2 < 32) ? (val << ostd::max(val2, 0)) : 0; + }, 0, ); + CS_CMD_MATH(">>", i, int, val >>= ostd::clamp(val2, 0, 31), 0, ); + + CS_CMD_MATHF(+, 0, ); + CS_CMD_MATHF(*, 1, ); + CS_CMD_MATHF(-, 0, val = -val); + +#define CS_CMD_DIV(name, fmt, type, op) \ + CS_CMD_MATH(#name, fmt, type, { if (val2) op; else val = 0; }, 0, ) + + CS_CMD_DIV(div, i, int, val /= val2); + CS_CMD_DIV(mod, i, int, val %= val2); + CS_CMD_DIV(divf, f, float, val /= val2); + CS_CMD_DIV(modf, f, float, val = fmod(val, val2)); + +#undef CS_CMD_DIV + + CS_CMD_MATH("pow", f, float, val = pow(val, val2), 0, ); + +#undef CS_CMD_MATHF +#undef CS_CMD_MATHFN +#undef CS_CMD_MATHI +#undef CS_CMD_MATHIN +#undef CS_CMD_MATH + +#define CS_CMD_CMP(name, fmt, type, op) \ + cs.add_command(name, #fmt "1V", [](CsState &cs, TaggedValue *args, \ + int numargs) { \ + bool val; \ + if (numargs >= 2) { \ + val = args[0].fmt op args[1].fmt; \ + for (int i = 2; i < numargs && val; ++i) \ + val = args[i-1].fmt op args[i].fmt; \ + } else \ + val = ((numargs > 0) ? args[0].fmt : 0) op 0; \ cs.result->set_int(int(val)); \ }) -CMPSCMD(strcmp, ==); -CMPSCMD(=s, ==); -CMPSCMD(!=s, !=); -CMPSCMD(s, >); -CMPSCMD(<=s, <=); -CMPSCMD(>=s, >=); +#define CS_CMD_CMPIN(name, op) CS_CMD_CMP(#name, i, int, op) +#define CS_CMD_CMPI(name) CS_CMD_CMPIN(name, name) +#define CS_CMD_CMPFN(name, op) CS_CMD_CMP(#name "f", f, float, op) +#define CS_CMD_CMPF(name) CS_CMD_CMPFN(name, name) -ICOMMAND(strstr, "ss", (CsState &cs, char *a, char *b), { char *s = strstr(a, b); cs.result->set_int(s ? s - a : -1); }); -ICOMMAND(strlen, "s", (CsState &cs, char *s), cs.result->set_int(strlen(s))); -ICOMMAND(strcode, "si", (CsState &cs, char *s, int *i), cs.result->set_int(*i > 0 ? (memchr(s, 0, *i) ? 0 : ostd::byte(s[*i])) : ostd::byte(s[0]))); -ICOMMAND(codestr, "i", (CsState &cs, int *i), { char *s = new char[2]; s[0] = char(*i); s[1] = '\0'; stringret(cs, s); }); + CS_CMD_CMPIN(=, ==); + CS_CMD_CMPI(!=); + CS_CMD_CMPI(<); + CS_CMD_CMPI(>); + CS_CMD_CMPI(<=); + CS_CMD_CMPI(>=); -#define STRMAPCOMMAND(name, map) \ - ICOMMAND(name, "s", (CsState &cs, char *s), \ - { \ - int len = strlen(s); \ - char *m = new char[len + 1]; \ - for (int i = 0; i < len; ++i) m[i] = map(s[i]); \ - m[len] = '\0'; \ - stringret(cs, m); \ - }) + CS_CMD_CMPFN(=, ==); + CS_CMD_CMPF(!=); + CS_CMD_CMPF(<); + CS_CMD_CMPF(>); + CS_CMD_CMPF(<=); + CS_CMD_CMPF(>=); -STRMAPCOMMAND(strlower, tolower); -STRMAPCOMMAND(strupper, toupper); +#undef CS_CMD_CMPF +#undef CS_CMD_CMPFN +#undef CS_CMD_CMPI +#undef CS_CMD_CMPIN +#undef CS_CMD_CMP +} char *strreplace(CsState &, const char *s, const char *oldval, const char *newval, const char *newval2) { ostd::Vector buf; @@ -4397,6 +4331,132 @@ void strsplice(CsState &cs, const char *s, const char *vals, int *skip, int *cou } COMMAND(strsplice, "ssii"); +void init_lib_list(CsState &) { +} + +void init_lib_string(CsState &cs) { + cs.add_command("strstr", "ss", [](CsState &cs, char *a, char *b) { + char *s = strstr(a, b); + cs.result->set_int(s ? (s - a) : -1); + }); + + cs.add_command("strlen", "s", [](CsState &cs, char *s) { + cs.result->set_int(strlen(s)); + }); + + cs.add_command("strcode", "si", [](CsState &cs, char *s, int *i) { + cs.result->set_int((*i > 0) + ? (memchr(s, '\0', *i) ? 0 : ostd::byte(s[*i])) + : ostd::byte(s[0])); + }); + + cs.add_command("codestr", "i", [](CsState &cs, int *i) { + char *s = new char[2]; + s[0] = char(*i); + s[1] = '\0'; + cs.result->set_str(s); + }); + + cs.add_command("strlower", "s", [](CsState &cs, char *s) { + ostd::Size len = strlen(s); + char *buf = new char[len + 1]; + for (ostd::Size i = 0; i < len; ++i) + buf[i] = tolower(s[i]); + buf[len] = '\0'; + cs.result->set_str(buf); + }); + + cs.add_command("strupper", "s", [](CsState &cs, char *s) { + ostd::Size len = strlen(s); + char *buf = new char[len + 1]; + for (ostd::Size i = 0; i < len; ++i) + buf[i] = toupper(s[i]); + buf[len] = '\0'; + cs.result->set_str(buf); + }); + + cs.add_command("escape", "s", [](CsState &cs, char *s) { + cs.result->set_str(dup_ostr(escapestring(s))); + }); + + cs.add_command("unescape", "s", [](CsState &cs, char *s) { + ostd::Size len = strlen(s); + char *buf = new char[len + 1]; + cs_str_unescape(buf, s, &s[len]); + cs.result->set_str(buf); + }); + + cs.add_command("concat", "V", [](CsState &cs, TaggedValue *v, int n) { + cs.result->set_str(conc(v, n, true)); + }); + + cs.add_command("concatworld", "V", [](CsState &cs, TaggedValue *v, + int n) { + cs.result->set_str(conc(v, n, false)); + }); + + cs.add_command("format", "V", [](CsState &cs, TaggedValue *v, int n) { + if (n <= 0) { + cs.result->set_str(dup_ostr("")); + return; + } + ostd::Vector s; + const char *f = v[0].get_str(); + while (*f) { + char c = *f++; + if (c == '%') { + char ic = *f++; + if (ic >= '1' && ic <= '9') { + int i = ic - '0'; + const char *sub = (i < n) ? v[i].get_str() : ""; + s.push_n(sub, strlen(sub)); + } else s.push(ic); + } else s.push(c); + } + s.push('\0'); + cs.result->set_str(s.disown()); + }); + + cs.add_command("tohex", "ii", [](CsState &cs, int *n, int *p) { + auto r = ostd::appender>(); + ostd::format(r, "0x%.*X", ostd::max(*p, 1), *n); + r.put('\0'); + cs.result->set_str(r.get().disown()); + }); + + cs.add_command("substr", "siiN", [](CsState &cs, char *s, int *start, + int *count, int *numargs) { + int len = strlen(s), offset = ostd::clamp(*start, 0, len); + cs.result->set_str(dup_ostr(ostd::ConstCharRange( + &s[offset], + (*numargs >= 3) ? ostd::clamp(*count, 0, len - offset) + : (len - offset)))); + }); + +#define CS_CMD_CMPS(name, op) \ + cs.add_command(#name, "s1V", [](CsState &cs, TaggedValue *args, \ + int numargs) { \ + bool val; \ + if (numargs >= 2) { \ + val = strcmp(args[0].s, args[1].s) op 0; \ + for (int i = 2; i < numargs && val; ++i) \ + val = strcmp(args[i-1].s, args[i].s) op 0; \ + } else \ + val = (numargs > 0 ? args[0].s[0] : 0) op 0; \ + cs.result->set_int(int(val)); \ + }) + + CS_CMD_CMPS(strcmp, ==); + CS_CMD_CMPS(=s, ==); + CS_CMD_CMPS(!=s, !=); + CS_CMD_CMPS(s, >); + CS_CMD_CMPS(<=s, <=); + CS_CMD_CMPS(>=s, >=); + +#undef CS_CMD_CMPS +} + void init_lib_shell(CsState &cs) { cs.add_command("shell", "C", [](CsState &cs, char *s) { cs.result->set_int(system(s)); diff --git a/command.hh b/command.hh index 9eeed056..32d60ec4 100644 --- a/command.hh +++ b/command.hh @@ -141,6 +141,11 @@ struct TaggedValue: IdentValue { id = val; } + void set(TaggedValue &tv) { + *this = tv; + tv.type = VAL_NULL; + } + const char *get_str() const; int get_int() const; float get_float() const; @@ -450,9 +455,6 @@ extern CsState cstate; extern const char *intstr(int v); extern const char *floatstr(float v); -extern void stringret(CsState &cs, char *s); -extern void result(CsState &cs, TaggedValue &v); -extern void result(CsState &cs, const char *s); static inline int parseint(const char *s) { return int(strtoul(s, nullptr, 0)); @@ -585,7 +587,6 @@ extern ostd::Uint32 *compilecode(const char *p); extern void keepcode(ostd::Uint32 *p); extern void freecode(ostd::Uint32 *p); -extern const char *getalias(const char *name); extern const char *escapestring(const char *s); extern const char *escapeid(const char *s); static inline const char *escapeid(Ident &id) { @@ -609,4 +610,6 @@ extern int listlen(CsState &cs, const char *s); void init_lib_base(CsState &cs); void init_lib_io(CsState &cs); void init_lib_math(CsState &cs); +void init_lib_string(CsState &cs); +void init_lib_list(CsState &cs); void init_lib_shell(CsState &cs); \ No newline at end of file