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

View File

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

View File

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

View File

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