get rid of cs_string in codegen

master
Daniel Kolesa 2021-03-19 22:25:38 +01:00
parent b27f8dee91
commit 4e5e0f5de8
4 changed files with 54 additions and 31 deletions

View File

@ -17,9 +17,9 @@ ostd::string_range cs_gen_state::get_str() {
return ret.slice(1, ret.size() - 1); return ret.slice(1, ret.size() - 1);
} }
cs_string cs_gen_state::get_str_dup() { cs_charbuf cs_gen_state::get_str_dup() {
auto str = get_str(); auto str = get_str();
auto app = ostd::appender<cs_string>(); auto app = ostd::appender<cs_charbuf>(cs);
util::unescape_string(app, str); util::unescape_string(app, str);
return std::move(app.get()); return std::move(app.get());
} }
@ -204,11 +204,11 @@ static inline void compileunescapestr(cs_gen_state &gs) {
static bool compilearg( static bool compilearg(
cs_gen_state &gs, int wordtype, int prevargs = MaxResults, cs_gen_state &gs, int wordtype, int prevargs = MaxResults,
cs_string *word = nullptr cs_charbuf *word = nullptr
); );
static void compilelookup(cs_gen_state &gs, int ltype, int prevargs = MaxResults) { static void compilelookup(cs_gen_state &gs, int ltype, int prevargs = MaxResults) {
cs_string lookup; cs_charbuf lookup{gs.cs};
gs.next_char(); gs.next_char();
switch (gs.current()) { switch (gs.current()) {
case '(': case '(':
@ -222,12 +222,14 @@ static void compilelookup(cs_gen_state &gs, int ltype, int prevargs = MaxResults
break; break;
case '\"': case '\"':
lookup = gs.get_str_dup(); lookup = gs.get_str_dup();
lookup.push_back('\0');
goto lookupid; goto lookupid;
default: { default: {
lookup = gs.get_word(); lookup.append(gs.get_word());
if (lookup.empty()) goto invalid; if (lookup.empty()) goto invalid;
lookup.push_back('\0');
lookupid: lookupid:
cs_ident *id = gs.cs.new_ident(lookup); cs_ident *id = gs.cs.new_ident(lookup.str_term());
if (id) { if (id) {
switch (id->get_type()) { switch (id->get_type()) {
case cs_ident_type::IVAR: case cs_ident_type::IVAR:
@ -402,7 +404,7 @@ lookupid:
goto invalid; goto invalid;
} }
} }
gs.gen_str(lookup); gs.gen_str(lookup.str_term());
break; break;
} }
} }
@ -501,7 +503,7 @@ done:
} }
static bool compileblocksub(cs_gen_state &gs, int prevargs) { static bool compileblocksub(cs_gen_state &gs, int prevargs) {
cs_string lookup; cs_charbuf lookup{gs.cs};
switch (gs.current()) { switch (gs.current()) {
case '(': case '(':
if (!compilearg(gs, CS_VAL_ANY, prevargs)) { if (!compilearg(gs, CS_VAL_ANY, prevargs)) {
@ -516,14 +518,16 @@ static bool compileblocksub(cs_gen_state &gs, int prevargs) {
break; break;
case '\"': case '\"':
lookup = gs.get_str_dup(); lookup = gs.get_str_dup();
lookup.push_back('\0');
goto lookupid; goto lookupid;
default: { default: {
lookup = gs.read_macro_name(); lookup.append(gs.read_macro_name());
if (lookup.empty()) { if (lookup.empty()) {
return false; return false;
} }
lookup.push_back('\0');
lookupid: lookupid:
cs_ident *id = gs.cs.new_ident(lookup); cs_ident *id = gs.cs.new_ident(lookup.str_term());
if (id) { if (id) {
switch (id->get_type()) { switch (id->get_type()) {
case cs_ident_type::IVAR: case cs_ident_type::IVAR:
@ -547,7 +551,7 @@ lookupid:
break; break;
} }
} }
gs.gen_str(lookup); gs.gen_str(lookup.str_term());
gs.code.push_back(CS_CODE_LOOKUP_MU); gs.code.push_back(CS_CODE_LOOKUP_MU);
done: done:
break; break;
@ -701,7 +705,7 @@ static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) {
} }
static bool compilearg( static bool compilearg(
cs_gen_state &gs, int wordtype, int prevargs, cs_string *word cs_gen_state &gs, int wordtype, int prevargs, cs_charbuf *word
) { ) {
gs.skip_comments(); gs.skip_comments();
switch (gs.current()) { switch (gs.current()) {
@ -714,7 +718,8 @@ static bool compilearg(
size_t line = gs.current_line; size_t line = gs.current_line;
auto s = gs.get_str_dup(); auto s = gs.get_str_dup();
if (!s.empty()) { if (!s.empty()) {
compileblock(gs, s, line); s.push_back('\0');
compileblock(gs, s.str_term(), line);
} else { } else {
gs.gen_null(); gs.gen_null();
} }
@ -722,12 +727,13 @@ static bool compilearg(
} }
case CS_VAL_CODE: { case CS_VAL_CODE: {
auto s = gs.get_str_dup(); auto s = gs.get_str_dup();
compileblock(gs); s.push_back('\0');
compileblock(gs, s.str_term(), gs.current_line);
break; break;
} }
case CS_VAL_WORD: case CS_VAL_WORD:
if (word) { if (word) {
*word = gs.get_str_dup(); *word = std::move(gs.get_str_dup());
} }
break; break;
case CS_VAL_ANY: case CS_VAL_ANY:
@ -737,7 +743,8 @@ static bool compilearg(
default: { default: {
size_t line = gs.current_line; size_t line = gs.current_line;
auto s = gs.get_str_dup(); auto s = gs.get_str_dup();
gs.gen_value(wordtype, s, line); s.push_back('\0');
gs.gen_value(wordtype, s.str_term(), line);
break; break;
} }
} }
@ -806,7 +813,8 @@ static bool compilearg(
case CS_VAL_WORD: { case CS_VAL_WORD: {
auto w = gs.get_word(); auto w = gs.get_word();
if (word) { if (word) {
*word = w; word->clear();
word->append(w);
} }
return !w.empty(); return !w.empty();
} }
@ -1187,7 +1195,7 @@ static void compile_and_or(
} }
static void compilestatements(cs_gen_state &gs, int rettype, int brak, int prevargs) { static void compilestatements(cs_gen_state &gs, int rettype, int brak, int prevargs) {
cs_string idname; cs_charbuf idname{gs.cs};
for (;;) { for (;;) {
gs.skip_comments(); gs.skip_comments();
idname.clear(); idname.clear();
@ -1212,7 +1220,8 @@ static void compilestatements(cs_gen_state &gs, int rettype, int brak, int preva
case '\0': case '\0':
gs.next_char(); gs.next_char();
if (!idname.empty()) { if (!idname.empty()) {
cs_ident *id = gs.cs.new_ident(idname); idname.push_back('\0');
cs_ident *id = gs.cs.new_ident(idname.str_term());
if (id) { if (id) {
switch (id->get_type()) { switch (id->get_type()) {
case cs_ident_type::ALIAS: case cs_ident_type::ALIAS:
@ -1258,7 +1267,7 @@ static void compilestatements(cs_gen_state &gs, int rettype, int brak, int preva
break; break;
} }
} }
gs.gen_str(idname); gs.gen_str(idname.str_term());
} }
more = compilearg(gs, CS_VAL_ANY); more = compilearg(gs, CS_VAL_ANY);
if (!more) { if (!more) {
@ -1280,25 +1289,26 @@ noid:
} }
gs.code.push_back(CS_CODE_CALL_U | (numargs << 8)); gs.code.push_back(CS_CODE_CALL_U | (numargs << 8));
} else { } else {
cs_ident *id = gs.cs.get_ident(idname); idname.push_back('\0');
cs_ident *id = gs.cs.get_ident(idname.str_term());
if (!id) { if (!id) {
if (!cs_check_num(idname)) { if (!cs_check_num(idname.str_term())) {
gs.gen_str(idname); gs.gen_str(idname.str_term());
goto noid; goto noid;
} }
switch (rettype) { switch (rettype) {
case CS_VAL_ANY: { case CS_VAL_ANY: {
ostd::string_range end = idname; ostd::string_range end = idname.str_term();
cs_int val = cs_parse_int(end, &end); cs_int val = cs_parse_int(end, &end);
if (!end.empty()) { if (!end.empty()) {
gs.gen_str(idname); gs.gen_str(idname.str_term());
} else { } else {
gs.gen_int(val); gs.gen_int(val);
} }
break; break;
} }
default: default:
gs.gen_value(rettype, idname, curline); gs.gen_value(rettype, idname.str_term(), curline);
break; break;
} }
gs.code.push_back(CS_CODE_RESULT); gs.code.push_back(CS_CODE_RESULT);

View File

@ -100,6 +100,11 @@ struct cs_shared_state {
state->alloc(p, n, 0); state->alloc(p, n, 0);
} }
template<typename U>
bool operator==(allocator<U> const &a) {
return state == a.state;
}
cs_shared_state *state; cs_shared_state *state;
}; };
}; };
@ -192,6 +197,8 @@ struct cs_strman {
}; };
struct cs_charbuf { struct cs_charbuf {
cs_charbuf() = delete;
cs_charbuf(cs_shared_state &cs): cs_charbuf(cs_shared_state &cs):
buf{cs_shared_state::allocator<char>{&cs}} buf{cs_shared_state::allocator<char>{&cs}}
{} {}
@ -221,10 +228,16 @@ struct cs_charbuf {
return ostd::string_range{buf.data(), buf.data() + buf.size()}; return ostd::string_range{buf.data(), buf.data() + buf.size()};
} }
ostd::string_range str_term() {
return ostd::string_range{buf.data(), buf.data() + buf.size() - 1};
}
size_t size() const { return buf.size(); } size_t size() const { return buf.size(); }
bool empty() const { return buf.empty(); } bool empty() const { return buf.empty(); }
void clear() { buf.clear(); }
std::vector<char, cs_shared_state::allocator<char>> buf; std::vector<char, cs_shared_state::allocator<char>> buf;
}; };

View File

@ -154,7 +154,7 @@ struct cs_gen_state {
} }
ostd::string_range get_str(); ostd::string_range get_str();
cs_string get_str_dup(); cs_charbuf get_str_dup();
ostd::string_range get_word(); ostd::string_range get_word();

View File

@ -995,7 +995,7 @@ static inline void cs_loop_conc(
if (n <= 0 || !idv.has_alias()) { if (n <= 0 || !idv.has_alias()) {
return; return;
} }
cs_string s; cs_charbuf s{cs};
for (cs_int i = 0; i < n; ++i) { for (cs_int i = 0; i < n; ++i) {
idv.set_int(offset + i * step); idv.set_int(offset + i * step);
idv.push(); idv.push();
@ -1009,12 +1009,12 @@ static inline void cs_loop_conc(
break; break;
} }
if (space && i) { if (space && i) {
s += ' '; s.push_back(' ');
} }
s += ostd::string_range{v.get_str()}; s.append(v.get_str());
} }
end: end:
res.set_str(s); res.set_str(s.str());
} }
void cs_init_lib_base(cs_state &gcs) { void cs_init_lib_base(cs_state &gcs) {