remove buffer-writing cutstring/cutword
parent
93b2a59e58
commit
6f603a0b5c
102
cubescript.cc
102
cubescript.cc
|
@ -7,6 +7,7 @@
|
||||||
#include <ostd/algorithm.hh>
|
#include <ostd/algorithm.hh>
|
||||||
#include <ostd/format.hh>
|
#include <ostd/format.hh>
|
||||||
#include <ostd/array.hh>
|
#include <ostd/array.hh>
|
||||||
|
#include <ostd/memory.hh>
|
||||||
|
|
||||||
namespace cscript {
|
namespace cscript {
|
||||||
|
|
||||||
|
@ -1159,26 +1160,6 @@ static inline void skipcomments(char const *&p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ostd::Vector<char> strbuf[4];
|
|
||||||
static int stridx = 0;
|
|
||||||
|
|
||||||
static inline void cutstring(char const *&p, ostd::ConstCharRange &s) {
|
|
||||||
p++;
|
|
||||||
char const *end = parsestring(p);
|
|
||||||
int maxlen = int(end - p) + 1;
|
|
||||||
|
|
||||||
stridx = (stridx + 1) % 4;
|
|
||||||
ostd::Vector<char> &buf = strbuf[stridx];
|
|
||||||
buf.reserve(maxlen);
|
|
||||||
|
|
||||||
auto writer = buf.iter_cap();
|
|
||||||
s = ostd::ConstCharRange(buf.data(),
|
|
||||||
util::unescape_string(writer, ostd::ConstCharRange(p, end)));
|
|
||||||
writer.put('\0');
|
|
||||||
p = end;
|
|
||||||
if (*p == '\"') p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline char *cutstring(char const *&p) {
|
static inline char *cutstring(char const *&p) {
|
||||||
p++;
|
p++;
|
||||||
char const *end = parsestring(p);
|
char const *end = parsestring(p);
|
||||||
|
@ -1225,12 +1206,6 @@ char const *parseword(char const *p) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cutword(char const *&p, ostd::ConstCharRange &s) {
|
|
||||||
char const *op = p;
|
|
||||||
p = parseword(p);
|
|
||||||
s = ostd::ConstCharRange(op, p - op);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline char *cutword(char const *&p) {
|
static inline char *cutword(char const *&p) {
|
||||||
char const *word = p;
|
char const *word = p;
|
||||||
p = parseword(p);
|
p = parseword(p);
|
||||||
|
@ -1499,10 +1474,10 @@ bool TaggedValue::get_bool() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compilearg(GenState &gs, int wordtype, int prevargs = MaxResults, ostd::ConstCharRange *word = nullptr);
|
static bool compilearg(GenState &gs, int wordtype, int prevargs = MaxResults, ostd::Box<char[]> *word = nullptr);
|
||||||
|
|
||||||
static void compilelookup(GenState &gs, int ltype, int prevargs = MaxResults) {
|
static void compilelookup(GenState &gs, int ltype, int prevargs = MaxResults) {
|
||||||
ostd::ConstCharRange lookup;
|
ostd::Box<char[]> lookup;
|
||||||
gs.next_char();
|
gs.next_char();
|
||||||
switch (gs.current()) {
|
switch (gs.current()) {
|
||||||
case '(':
|
case '(':
|
||||||
|
@ -1513,13 +1488,13 @@ static void compilelookup(GenState &gs, int ltype, int prevargs = MaxResults) {
|
||||||
compilelookup(gs, VAL_CSTR, prevargs);
|
compilelookup(gs, VAL_CSTR, prevargs);
|
||||||
break;
|
break;
|
||||||
case '\"':
|
case '\"':
|
||||||
cutstring(gs.source, lookup);
|
lookup = ostd::Box<char[]>(cutstring(gs.source));
|
||||||
goto lookupid;
|
goto lookupid;
|
||||||
default: {
|
default: {
|
||||||
cutword(gs.source, lookup);
|
lookup = ostd::Box<char[]>(cutword(gs.source));
|
||||||
if (!lookup.size()) goto invalid;
|
if (!lookup) goto invalid;
|
||||||
lookupid:
|
lookupid:
|
||||||
Ident *id = gs.cs.new_ident(lookup);
|
Ident *id = gs.cs.new_ident(lookup.get());
|
||||||
if (id) switch (id->type) {
|
if (id) switch (id->type) {
|
||||||
case ID_VAR:
|
case ID_VAR:
|
||||||
gs.code.push(CODE_IVAR | cs_ret_code(ltype, RET_INT) | (id->index << 8));
|
gs.code.push(CODE_IVAR | cs_ret_code(ltype, RET_INT) | (id->index << 8));
|
||||||
|
@ -1656,7 +1631,7 @@ compilecomv:
|
||||||
default:
|
default:
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
gs.gen_str(lookup, true);
|
gs.gen_str(lookup.get(), true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1759,7 +1734,8 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compileblocksub(GenState &gs, int prevargs) {
|
static bool compileblocksub(GenState &gs, int prevargs) {
|
||||||
ostd::ConstCharRange lookup;
|
ostd::Box<char[]> lookup;
|
||||||
|
ostd::ConstCharRange lkup;
|
||||||
char const *op;
|
char const *op;
|
||||||
switch (gs.current()) {
|
switch (gs.current()) {
|
||||||
case '(':
|
case '(':
|
||||||
|
@ -1770,15 +1746,16 @@ static bool compileblocksub(GenState &gs, int prevargs) {
|
||||||
gs.code.push(CODE_LOOKUPMU);
|
gs.code.push(CODE_LOOKUPMU);
|
||||||
break;
|
break;
|
||||||
case '\"':
|
case '\"':
|
||||||
cutstring(gs.source, lookup);
|
lookup = ostd::Box<char[]>(cutstring(gs.source));
|
||||||
goto lookupid;
|
goto lookupid;
|
||||||
default: {
|
default: {
|
||||||
op = gs.source;
|
op = gs.source;
|
||||||
while (isalnum(gs.current()) || gs.current() == '_') gs.next_char();
|
while (isalnum(gs.current()) || gs.current() == '_') gs.next_char();
|
||||||
lookup = ostd::ConstCharRange(op, gs.source - op);
|
lkup = ostd::ConstCharRange(op, gs.source - op);
|
||||||
if (lookup.empty()) return false;
|
if (lkup.empty()) return false;
|
||||||
|
lookup = ostd::Box<char[]>(cs_dup_ostr(lkup));
|
||||||
lookupid:
|
lookupid:
|
||||||
Ident *id = gs.cs.new_ident(lookup);
|
Ident *id = gs.cs.new_ident(lookup.get());
|
||||||
if (id) switch (id->type) {
|
if (id) switch (id->type) {
|
||||||
case ID_VAR:
|
case ID_VAR:
|
||||||
gs.code.push(CODE_IVAR | (id->index << 8));
|
gs.code.push(CODE_IVAR | (id->index << 8));
|
||||||
|
@ -1793,7 +1770,7 @@ lookupid:
|
||||||
gs.code.push((id->index < MaxArguments ? CODE_LOOKUPMARG : CODE_LOOKUPM) | (id->index << 8));
|
gs.code.push((id->index < MaxArguments ? CODE_LOOKUPMARG : CODE_LOOKUPM) | (id->index << 8));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
gs.gen_str(lookup, true);
|
gs.gen_str(lookup.get(), true);
|
||||||
gs.code.push(CODE_LOOKUPMU);
|
gs.code.push(CODE_LOOKUPMU);
|
||||||
done:
|
done:
|
||||||
break;
|
break;
|
||||||
|
@ -1914,8 +1891,8 @@ done:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compilearg(GenState &gs, int wordtype, int prevargs, ostd::ConstCharRange *word) {
|
static bool compilearg(GenState &gs, int wordtype, int prevargs, ostd::Box<char[]> *word) {
|
||||||
ostd::ConstCharRange unused;
|
ostd::Box<char[]> unused;
|
||||||
if (!word) word = &unused;
|
if (!word) word = &unused;
|
||||||
skipcomments(gs.source);
|
skipcomments(gs.source);
|
||||||
switch (gs.current()) {
|
switch (gs.current()) {
|
||||||
|
@ -1939,7 +1916,7 @@ static bool compilearg(GenState &gs, int wordtype, int prevargs, ostd::ConstChar
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VAL_WORD:
|
case VAL_WORD:
|
||||||
cutstring(gs.source, *word);
|
*word = ostd::Box<char[]>(cutstring(gs.source));
|
||||||
break;
|
break;
|
||||||
case VAL_ANY:
|
case VAL_ANY:
|
||||||
case VAL_STR:
|
case VAL_STR:
|
||||||
|
@ -1950,9 +1927,9 @@ static bool compilearg(GenState &gs, int wordtype, int prevargs, ostd::ConstChar
|
||||||
compileunescapestr(gs, true);
|
compileunescapestr(gs, true);
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
ostd::ConstCharRange s;
|
char *s = cutstring(gs.source);
|
||||||
cutstring(gs.source, s);
|
|
||||||
gs.gen_value(wordtype, s);
|
gs.gen_value(wordtype, s);
|
||||||
|
delete[] s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2016,13 +1993,13 @@ static bool compilearg(GenState &gs, int wordtype, int prevargs, ostd::ConstChar
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case VAL_WORD:
|
case VAL_WORD:
|
||||||
cutword(gs.source, *word);
|
*word = ostd::Box<char[]>(cutword(gs.source));
|
||||||
return !word->empty();
|
return !!*word;
|
||||||
default: {
|
default: {
|
||||||
ostd::ConstCharRange s;
|
char *s = cutword(gs.source);
|
||||||
cutword(gs.source, s);
|
if (!s) return false;
|
||||||
if (s.empty()) return false;
|
|
||||||
gs.gen_value(wordtype, s);
|
gs.gen_value(wordtype, s);
|
||||||
|
delete[] s;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2031,11 +2008,11 @@ static bool compilearg(GenState &gs, int wordtype, int prevargs, ostd::ConstChar
|
||||||
|
|
||||||
static void compilestatements(GenState &gs, int rettype, int brak, int prevargs) {
|
static void compilestatements(GenState &gs, int rettype, int brak, int prevargs) {
|
||||||
char const *line = gs.source;
|
char const *line = gs.source;
|
||||||
ostd::ConstCharRange idname;
|
ostd::Box<char[]> idname;
|
||||||
int numargs;
|
int numargs;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
skipcomments(gs.source);
|
skipcomments(gs.source);
|
||||||
idname = ostd::ConstCharRange(nullptr, nullptr);
|
idname.reset();
|
||||||
bool more = compilearg(gs, VAL_WORD, prevargs, &idname);
|
bool more = compilearg(gs, VAL_WORD, prevargs, &idname);
|
||||||
if (!more) goto endstatement;
|
if (!more) goto endstatement;
|
||||||
skipcomments(gs.source);
|
skipcomments(gs.source);
|
||||||
|
@ -2049,8 +2026,8 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\0':
|
case '\0':
|
||||||
gs.next_char();
|
gs.next_char();
|
||||||
if (idname.data()) {
|
if (idname) {
|
||||||
Ident *id = gs.cs.new_ident(idname);
|
Ident *id = gs.cs.new_ident(idname.get());
|
||||||
if (id) switch (id->type) {
|
if (id) switch (id->type) {
|
||||||
case ID_ALIAS:
|
case ID_ALIAS:
|
||||||
if (!(more = compilearg(gs, VAL_ANY, prevargs))) gs.gen_str();
|
if (!(more = compilearg(gs, VAL_ANY, prevargs))) gs.gen_str();
|
||||||
|
@ -2069,35 +2046,36 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
||||||
gs.code.push(CODE_SVAR1 | (id->index << 8));
|
gs.code.push(CODE_SVAR1 | (id->index << 8));
|
||||||
goto endstatement;
|
goto endstatement;
|
||||||
}
|
}
|
||||||
gs.gen_str(idname, true);
|
gs.gen_str(idname.get(), true);
|
||||||
}
|
}
|
||||||
if (!(more = compilearg(gs, VAL_ANY))) gs.gen_str();
|
if (!(more = compilearg(gs, VAL_ANY))) gs.gen_str();
|
||||||
gs.code.push(CODE_ALIASU);
|
gs.code.push(CODE_ALIASU);
|
||||||
goto endstatement;
|
goto endstatement;
|
||||||
}
|
}
|
||||||
numargs = 0;
|
numargs = 0;
|
||||||
if (!idname.data()) {
|
if (!idname) {
|
||||||
noid:
|
noid:
|
||||||
while (numargs < MaxArguments && (more = compilearg(gs, VAL_CANY, prevargs + numargs))) numargs++;
|
while (numargs < MaxArguments && (more = compilearg(gs, VAL_CANY, prevargs + numargs))) numargs++;
|
||||||
gs.code.push(CODE_CALLU | (numargs << 8));
|
gs.code.push(CODE_CALLU | (numargs << 8));
|
||||||
} else {
|
} else {
|
||||||
Ident *id = gs.cs.idents.at(idname);
|
Ident *id = gs.cs.idents.at(idname.get());
|
||||||
if (!id) {
|
if (!id) {
|
||||||
if (!cs_check_num(idname)) {
|
if (!cs_check_num(idname.get())) {
|
||||||
gs.gen_str(idname, true);
|
gs.gen_str(idname.get(), true);
|
||||||
goto noid;
|
goto noid;
|
||||||
}
|
}
|
||||||
switch (rettype) {
|
switch (rettype) {
|
||||||
case VAL_ANY:
|
case VAL_ANY:
|
||||||
case VAL_CANY: {
|
case VAL_CANY: {
|
||||||
char *end = const_cast<char *>(idname.data());
|
char *end = idname.get();
|
||||||
int val = int(strtoul(idname.data(), &end, 0));
|
ostd::Size idlen = strlen(idname.get());
|
||||||
if (end < &idname[idname.size()]) gs.gen_str(idname, rettype == VAL_CANY);
|
int val = int(strtoul(idname.get(), &end, 0));
|
||||||
|
if (end < &idname[idlen]) gs.gen_str(idname.get(), rettype == VAL_CANY);
|
||||||
else gs.gen_int(val);
|
else gs.gen_int(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
gs.gen_value(rettype, idname);
|
gs.gen_value(rettype, idname.get());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gs.code.push(CODE_RESULT);
|
gs.code.push(CODE_RESULT);
|
||||||
|
|
Loading…
Reference in New Issue