use ConstCharRange for source

master
Daniel Kolesa 2016-09-22 01:07:43 +02:00
parent 5527025d5c
commit b3110c30b9
3 changed files with 50 additions and 49 deletions

View File

@ -35,9 +35,9 @@ static ostd::ConstCharRange cs_parse_str(ostd::ConstCharRange str) {
} }
ostd::ConstCharRange GenState::get_str() { ostd::ConstCharRange GenState::get_str() {
char const *ln = source; auto ln = source;
char const *beg = source + 1; source.pop_front();
source = beg; auto beg = source;
for (; current(); next_char()) { for (; current(); next_char()) {
switch (current()) { switch (current()) {
case '\r': case '\r':
@ -53,7 +53,7 @@ ostd::ConstCharRange GenState::get_str() {
} }
} }
done: done:
auto ret = ostd::ConstCharRange(beg, source); auto ret = ostd::slice_until(beg, source);
if (current() != '\"') { if (current() != '\"') {
cs_error_line(*this, "unfinished string '%s'", ln); cs_error_line(*this, "unfinished string '%s'", ln);
} }
@ -73,7 +73,7 @@ CsString GenState::get_str_dup(bool unescape) {
} }
ostd::ConstCharRange GenState::read_macro_name() { ostd::ConstCharRange GenState::read_macro_name() {
char const *op = source; auto op = source;
char c = current(); char c = current();
if (!isalpha(c) && (c != '_')) { if (!isalpha(c) && (c != '_')) {
return nullptr; return nullptr;
@ -81,7 +81,7 @@ ostd::ConstCharRange GenState::read_macro_name() {
for (; isalnum(c) || (c == '_'); c = current()) { for (; isalnum(c) || (c == '_'); c = current()) {
next_char(); next_char();
} }
return ostd::ConstCharRange(op, source); return ostd::slice_until(op, source);
} }
char GenState::skip_until(ostd::ConstCharRange chars) { char GenState::skip_until(ostd::ConstCharRange chars) {
@ -120,32 +120,34 @@ void GenState::skip_comments() {
} }
} }
static char const *parseword(char const *p) { static ostd::ConstCharRange parseword(ostd::ConstCharRange p) {
for (;;) { for (;;) {
p += strcspn(p, "\"/;()[] \t\r\n\0"); p = ostd::find_one_of(p, ostd::ConstCharRange("\"/;()[] \t\r\n"));
switch (p[0]) { if (p.empty()) {
return p;
}
switch (*p) {
case '"': case '"':
case ';': case ';':
case ' ': case ' ':
case '\t': case '\t':
case '\r': case '\r':
case '\n': case '\n':
case '\0':
return p; return p;
case '/': case '/':
if (p[1] == '/') { if ((p.size() > 1) && (p[1] == '/')) {
return p; return p;
} }
break; break;
case '[': case '[':
p = parseword(p + 1); p = parseword(p + 1);
if (*p != ']') { if (p.empty() || (*p != ']')) {
return p; return p;
} }
break; break;
case '(': case '(':
p = parseword(p + 1); p = parseword(p + 1);
if (*p != ')') { if (p.empty() || (*p != ')')) {
return p; return p;
} }
break; break;
@ -159,12 +161,9 @@ static char const *parseword(char const *p) {
} }
ostd::ConstCharRange GenState::get_word() { ostd::ConstCharRange GenState::get_word() {
char const *beg = source; auto beg = source;
source = parseword(source); source = parseword(source);
if (source != beg) { return ostd::slice_until(beg, source);
return ostd::ConstCharRange(beg, source);
}
return nullptr;
} }
static inline int cs_ret_code(int type, int def = 0) { static inline int cs_ret_code(int type, int def = 0) {
@ -177,8 +176,8 @@ static inline int cs_ret_code(int type, int def = 0) {
static void compilestatements( static void compilestatements(
GenState &gs, int rettype, int brak = '\0', int prevargs = 0 GenState &gs, int rettype, int brak = '\0', int prevargs = 0
); );
static inline char const *compileblock( static inline ostd::ConstCharRange compileblock(
GenState &gs, char const *p, int rettype = CsRetNull, int brak = '\0' GenState &gs, ostd::ConstCharRange p, int rettype = CsRetNull, int brak = '\0'
); );
void GenState::gen_int(ostd::ConstCharRange word) { void GenState::gen_int(ostd::ConstCharRange word) {
@ -219,13 +218,13 @@ void GenState::gen_value(int wordtype, ostd::ConstCharRange word) {
break; break;
case CsValCond: case CsValCond:
if (!word.empty()) { if (!word.empty()) {
compileblock(*this, word.data()); compileblock(*this, word);
} else { } else {
gen_null(); gen_null();
} }
break; break;
case CsValCode: case CsValCode:
compileblock(*this, word.data()); compileblock(*this, word);
break; break;
case CsValIdent: case CsValIdent:
gen_ident(word); gen_ident(word);
@ -239,14 +238,14 @@ static inline void compileblock(GenState &gs) {
gs.code.push(CsCodeEmpty); gs.code.push(CsCodeEmpty);
} }
static inline char const *compileblock( static inline ostd::ConstCharRange compileblock(
GenState &gs, char const *p, int rettype, int brak GenState &gs, ostd::ConstCharRange p, int rettype, int brak
) { ) {
ostd::Size start = gs.code.size(); ostd::Size start = gs.code.size();
gs.code.push(CsCodeBlock); gs.code.push(CsCodeBlock);
gs.code.push(CsCodeOffset | ((start + 2) << 8)); gs.code.push(CsCodeOffset | ((start + 2) << 8));
if (p) { if (p) {
char const *op = gs.source; ostd::ConstCharRange op = gs.source;
gs.source = p; gs.source = p;
compilestatements(gs, CsValAny, brak); compilestatements(gs, CsValAny, brak);
p = gs.source; p = gs.source;
@ -650,7 +649,7 @@ done:
} }
static void compileblockmain(GenState &gs, int wordtype, int prevargs) { static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
char const *start = gs.source; char const *start = gs.source.data();
int concs = 0; int concs = 0;
for (int brak = 1; brak;) { for (int brak = 1; brak;) {
switch (gs.skip_until("@\"/[]")) { switch (gs.skip_until("@\"/[]")) {
@ -675,7 +674,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
brak--; brak--;
break; break;
case '@': { case '@': {
char const *esc = gs.source; char const *esc = gs.source.data();
int level = 0; int level = 0;
while (gs.current() == '@') { while (gs.current() == '@') {
++level; ++level;
@ -703,28 +702,30 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
concs++; concs++;
} }
if (concs) { if (concs) {
start = gs.source; start = gs.source.data();
} else if (prevargs >= MaxResults) { } else if (prevargs >= MaxResults) {
gs.code.pop(); gs.code.pop();
} }
break; break;
}
default: default:
gs.next_char(); gs.next_char();
break; break;
}
} }
} }
if (gs.source - 1 > start) { if (gs.source.data() - 1 > start) {
if (!concs) { if (!concs) {
switch (wordtype) { switch (wordtype) {
case CsValPop: case CsValPop:
return; return;
case CsValCode: case CsValCode:
case CsValCond: case CsValCond:
gs.source = compileblock(gs, start, CsRetNull, ']'); gs.source = compileblock(gs, ostd::ConstCharRange(
start, gs.source.data() + gs.source.size()
), CsRetNull, ']');
return; return;
case CsValIdent: case CsValIdent:
gs.gen_ident(ostd::ConstCharRange(start, gs.source - 1)); gs.gen_ident(ostd::ConstCharRange(start, gs.source.data() - 1));
return; return;
} }
} }
@ -735,12 +736,12 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
case CsValCany: case CsValCany:
case CsValCond: case CsValCond:
compileblockstr( compileblockstr(
gs, ostd::ConstCharRange(start, gs.source - 1), true gs, ostd::ConstCharRange(start, gs.source.data() - 1), true
); );
break; break;
default: default:
compileblockstr( compileblockstr(
gs, ostd::ConstCharRange(start, gs.source - 1), concs > 0 gs, ostd::ConstCharRange(start, gs.source.data() - 1), concs > 0
); );
break; break;
} }
@ -758,26 +759,26 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
} }
switch (wordtype) { switch (wordtype) {
case CsValPop: case CsValPop:
if (concs || gs.source - 1 > start) { if (concs || gs.source.data() - 1 > start) {
gs.code.push(CsCodePop); gs.code.push(CsCodePop);
} }
break; break;
case CsValCond: case CsValCond:
if (!concs && gs.source - 1 <= start) { if (!concs && gs.source.data() - 1 <= start) {
gs.gen_null(); gs.gen_null();
} else { } else {
gs.code.push(CsCodeCond); gs.code.push(CsCodeCond);
} }
break; break;
case CsValCode: case CsValCode:
if (!concs && gs.source - 1 <= start) { if (!concs && gs.source.data() - 1 <= start) {
compileblock(gs); compileblock(gs);
} else { } else {
gs.code.push(CsCodeCompile); gs.code.push(CsCodeCompile);
} }
break; break;
case CsValIdent: case CsValIdent:
if (!concs && gs.source - 1 <= start) { if (!concs && gs.source.data() - 1 <= start) {
gs.gen_ident(); gs.gen_ident();
} else { } else {
gs.code.push(CsCodeIdentU); gs.code.push(CsCodeIdentU);
@ -785,7 +786,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
break; break;
case CsValCstring: case CsValCstring:
case CsValCany: case CsValCany:
if (!concs && gs.source - 1 <= start) { if (!concs && gs.source.data() - 1 <= start) {
gs.gen_str(ostd::ConstCharRange(), true); gs.gen_str(ostd::ConstCharRange(), true);
} }
break; break;
@ -793,13 +794,13 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
case CsValNull: case CsValNull:
case CsValAny: case CsValAny:
case CsValWord: case CsValWord:
if (!concs && gs.source - 1 <= start) { if (!concs && gs.source.data() - 1 <= start) {
gs.gen_str(); gs.gen_str();
} }
break; break;
default: default:
if (!concs) { if (!concs) {
if (gs.source - 1 <= start) { if (gs.source.data() - 1 <= start) {
gs.gen_value(wordtype); gs.gen_value(wordtype);
} else { } else {
gs.code.push(CsCodeForce | (wordtype << CsCodeRet)); gs.code.push(CsCodeForce | (wordtype << CsCodeRet));
@ -822,7 +823,7 @@ static bool compilearg(
case CsValCond: { case CsValCond: {
auto s = gs.get_str_dup(); auto s = gs.get_str_dup();
if (!s.empty()) { if (!s.empty()) {
compileblock(gs, s.data()); compileblock(gs, s);
} else { } else {
gs.gen_null(); gs.gen_null();
} }
@ -830,7 +831,7 @@ static bool compilearg(
} }
case CsValCode: { case CsValCode: {
auto s = gs.get_str_dup(); auto s = gs.get_str_dup();
compileblock(gs, s.data()); compileblock(gs);
break; break;
} }
case CsValWord: case CsValWord:
@ -905,7 +906,7 @@ static bool compilearg(
if (s.empty()) { if (s.empty()) {
return false; return false;
} }
compileblock(gs, CsString(s).data()); compileblock(gs, s);
return true; return true;
} }
case CsValCode: { case CsValCode: {
@ -913,7 +914,7 @@ static bool compilearg(
if (s.empty()) { if (s.empty()) {
return false; return false;
} }
compileblock(gs, CsString(s).data()); compileblock(gs, s);
return true; return true;
} }
case CsValWord: { case CsValWord: {
@ -928,7 +929,7 @@ static bool compilearg(
if (s.empty()) { if (s.empty()) {
return false; return false;
} }
gs.gen_value(wordtype, CsString(s)); gs.gen_value(wordtype, s);
return true; return true;
} }
} }
@ -1548,7 +1549,7 @@ endstatement:
} }
void GenState::gen_main(ostd::ConstCharRange s, int ret_type) { void GenState::gen_main(ostd::ConstCharRange s, int ret_type) {
source = s.data(); source = s;
code.push(CsCodeStart); code.push(CsCodeStart);
compilestatements(*this, CsValAny); compilestatements(*this, CsValAny);
code.push(CsCodeExit | ((ret_type < CsValAny) ? (ret_type << CsCodeRet) : 0)); code.push(CsCodeExit | ((ret_type < CsValAny) ? (ret_type << CsCodeRet) : 0));

View File

@ -220,7 +220,7 @@ namespace util {
case '\n': case '\n':
return str; return str;
case '/': case '/':
if (str[1] == '/') { if ((str.size() > 1) && (str[1] == '/')) {
return str; return str;
} }
break; break;

View File

@ -112,7 +112,7 @@ constexpr ostd::Size CsTypeStorageSize =
struct GenState { struct GenState {
CsState &cs; CsState &cs;
CsVector<ostd::Uint32> code; CsVector<ostd::Uint32> code;
char const *source; ostd::ConstCharRange source;
ostd::ConstCharRange src_file, src_str; ostd::ConstCharRange src_file, src_str;
GenState() = delete; GenState() = delete;