proper line infos at parse time
This commit is contained in:
parent
0f10c3e303
commit
604fd4e000
|
@ -8,11 +8,28 @@
|
|||
|
||||
namespace cscript {
|
||||
|
||||
static ostd::ConstCharRange cs_get_debug_fmt(
|
||||
GenState &gs, ostd::ConstCharRange fmt, ostd::CharRange buf
|
||||
) {
|
||||
ostd::CharRange r = buf;
|
||||
if (gs.src_name.empty()) {
|
||||
ostd::format(r, "%s:%d: %s", gs.src_name, gs.current_line, fmt);
|
||||
} else {
|
||||
ostd::format(r, "%d: %s", gs.current_line, fmt);
|
||||
}
|
||||
r.put('\0');
|
||||
return buf.data();
|
||||
}
|
||||
|
||||
template<typename ...A>
|
||||
static void cs_error_line(
|
||||
GenState &gs, ostd::ConstCharRange fmt, A &&...args
|
||||
) {
|
||||
throw CsErrorException(gs.cs, fmt, ostd::forward<A>(args)...);
|
||||
ostd::Array<char, 256> buf;
|
||||
auto rfmt = cs_get_debug_fmt(
|
||||
gs, fmt, ostd::CharRange(buf.data(), buf.size())
|
||||
);
|
||||
throw CsErrorException(gs.cs, rfmt, ostd::forward<A>(args)...);
|
||||
}
|
||||
|
||||
static ostd::ConstCharRange cs_parse_str(ostd::ConstCharRange str) {
|
||||
|
@ -36,7 +53,7 @@ static ostd::ConstCharRange cs_parse_str(ostd::ConstCharRange str) {
|
|||
|
||||
ostd::ConstCharRange GenState::get_str() {
|
||||
auto ln = source;
|
||||
source.pop_front();
|
||||
next_char();
|
||||
auto beg = source;
|
||||
for (; current(); next_char()) {
|
||||
switch (current()) {
|
||||
|
@ -176,8 +193,9 @@ static inline int cs_ret_code(int type, int def = 0) {
|
|||
static void compilestatements(
|
||||
GenState &gs, int rettype, int brak = '\0', int prevargs = 0
|
||||
);
|
||||
static inline ostd::ConstCharRange compileblock(
|
||||
GenState &gs, ostd::ConstCharRange p, int rettype = CsRetNull, int brak = '\0'
|
||||
static inline ostd::Pair<ostd::ConstCharRange, int> compileblock(
|
||||
GenState &gs, ostd::ConstCharRange p, int line,
|
||||
int rettype = CsRetNull, int brak = '\0'
|
||||
);
|
||||
|
||||
void GenState::gen_int(ostd::ConstCharRange word) {
|
||||
|
@ -188,7 +206,7 @@ void GenState::gen_float(ostd::ConstCharRange word) {
|
|||
gen_float(cs_parse_float(word));
|
||||
}
|
||||
|
||||
void GenState::gen_value(int wordtype, ostd::ConstCharRange word) {
|
||||
void GenState::gen_value(int wordtype, ostd::ConstCharRange word, int line) {
|
||||
switch (wordtype) {
|
||||
case CsValCany:
|
||||
if (!word.empty()) {
|
||||
|
@ -218,13 +236,13 @@ void GenState::gen_value(int wordtype, ostd::ConstCharRange word) {
|
|||
break;
|
||||
case CsValCond:
|
||||
if (!word.empty()) {
|
||||
compileblock(*this, word);
|
||||
compileblock(*this, word, line);
|
||||
} else {
|
||||
gen_null();
|
||||
}
|
||||
break;
|
||||
case CsValCode:
|
||||
compileblock(*this, word);
|
||||
compileblock(*this, word, line);
|
||||
break;
|
||||
case CsValIdent:
|
||||
gen_ident(word);
|
||||
|
@ -238,18 +256,23 @@ static inline void compileblock(GenState &gs) {
|
|||
gs.code.push(CsCodeEmpty);
|
||||
}
|
||||
|
||||
static inline ostd::ConstCharRange compileblock(
|
||||
GenState &gs, ostd::ConstCharRange p, int rettype, int brak
|
||||
static inline ostd::Pair<ostd::ConstCharRange, int> compileblock(
|
||||
GenState &gs, ostd::ConstCharRange p, int line, int rettype, int brak
|
||||
) {
|
||||
ostd::Size start = gs.code.size();
|
||||
gs.code.push(CsCodeBlock);
|
||||
gs.code.push(CsCodeOffset | ((start + 2) << 8));
|
||||
int retline = line;
|
||||
if (p) {
|
||||
ostd::ConstCharRange op = gs.source;
|
||||
int oldline = gs.current_line;
|
||||
gs.source = p;
|
||||
gs.current_line = line;
|
||||
compilestatements(gs, CsValAny, brak);
|
||||
p = gs.source;
|
||||
retline = gs.current_line;
|
||||
gs.source = op;
|
||||
gs.current_line = oldline;
|
||||
}
|
||||
if (gs.code.size() > start + 2) {
|
||||
gs.code.push(CsCodeExit | rettype);
|
||||
|
@ -258,7 +281,7 @@ static inline ostd::ConstCharRange compileblock(
|
|||
gs.code.resize(start);
|
||||
gs.code.push(CsCodeEmpty | rettype);
|
||||
}
|
||||
return p;
|
||||
return ostd::make_pair(p, retline);
|
||||
}
|
||||
|
||||
static inline void compileunescapestr(GenState &gs, bool macro = false) {
|
||||
|
@ -650,6 +673,7 @@ done:
|
|||
|
||||
static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
|
||||
char const *start = gs.source.data();
|
||||
int curline = gs.current_line;
|
||||
int concs = 0;
|
||||
for (int brak = 1; brak;) {
|
||||
switch (gs.skip_until("@\"/[]")) {
|
||||
|
@ -703,6 +727,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
|
|||
}
|
||||
if (concs) {
|
||||
start = gs.source.data();
|
||||
curline = gs.current_line;
|
||||
} else if (prevargs >= MaxResults) {
|
||||
gs.code.pop();
|
||||
}
|
||||
|
@ -719,11 +744,14 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
|
|||
case CsValPop:
|
||||
return;
|
||||
case CsValCode:
|
||||
case CsValCond:
|
||||
gs.source = compileblock(gs, ostd::ConstCharRange(
|
||||
case CsValCond: {
|
||||
auto ret = compileblock(gs, ostd::ConstCharRange(
|
||||
start, gs.source.data() + gs.source.size()
|
||||
), CsRetNull, ']');
|
||||
), curline, CsRetNull, ']');
|
||||
gs.source = ret.first;
|
||||
gs.current_line = ret.second;
|
||||
return;
|
||||
}
|
||||
case CsValIdent:
|
||||
gs.gen_ident(ostd::ConstCharRange(start, gs.source.data() - 1));
|
||||
return;
|
||||
|
@ -821,9 +849,10 @@ static bool compilearg(
|
|||
gs.get_str();
|
||||
break;
|
||||
case CsValCond: {
|
||||
int line = gs.current_line;
|
||||
auto s = gs.get_str_dup();
|
||||
if (!s.empty()) {
|
||||
compileblock(gs, s);
|
||||
compileblock(gs, s, line);
|
||||
} else {
|
||||
gs.gen_null();
|
||||
}
|
||||
|
@ -848,8 +877,9 @@ static bool compilearg(
|
|||
compileunescapestr(gs, true);
|
||||
break;
|
||||
default: {
|
||||
int line = gs.current_line;
|
||||
auto s = gs.get_str_dup();
|
||||
gs.gen_value(wordtype, s);
|
||||
gs.gen_value(wordtype, s, line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -902,19 +932,21 @@ static bool compilearg(
|
|||
return !gs.get_word().empty();
|
||||
}
|
||||
case CsValCond: {
|
||||
int line = gs.current_line;
|
||||
auto s = gs.get_word();
|
||||
if (s.empty()) {
|
||||
return false;
|
||||
}
|
||||
compileblock(gs, s);
|
||||
compileblock(gs, s, line);
|
||||
return true;
|
||||
}
|
||||
case CsValCode: {
|
||||
int line = gs.current_line;
|
||||
auto s = gs.get_word();
|
||||
if (s.empty()) {
|
||||
return false;
|
||||
}
|
||||
compileblock(gs, s);
|
||||
compileblock(gs, s, line);
|
||||
return true;
|
||||
}
|
||||
case CsValWord: {
|
||||
|
@ -925,11 +957,12 @@ static bool compilearg(
|
|||
return !w.empty();
|
||||
}
|
||||
default: {
|
||||
int line = gs.current_line;
|
||||
auto s = gs.get_word();
|
||||
if (s.empty()) {
|
||||
return false;
|
||||
}
|
||||
gs.gen_value(wordtype, s);
|
||||
gs.gen_value(wordtype, s, line);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1309,6 +1342,7 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
|||
for (;;) {
|
||||
gs.skip_comments();
|
||||
idname.clear();
|
||||
int curline = gs.current_line;
|
||||
bool more = compilearg(gs, CsValWord, prevargs, &idname);
|
||||
if (!more) {
|
||||
goto endstatement;
|
||||
|
@ -1415,7 +1449,7 @@ noid:
|
|||
break;
|
||||
}
|
||||
default:
|
||||
gs.gen_value(rettype, idname);
|
||||
gs.gen_value(rettype, idname, curline);
|
||||
break;
|
||||
}
|
||||
gs.code.push(CsCodeResult);
|
||||
|
|
|
@ -1577,8 +1577,7 @@ static void cs_run(
|
|||
CsValue &ret
|
||||
) {
|
||||
GenState gs(cs);
|
||||
gs.src_file = file;
|
||||
gs.src_str = code;
|
||||
gs.src_name = file;
|
||||
gs.code.reserve(64);
|
||||
/* FIXME range */
|
||||
gs.gen_main(code.data(), CsValAny);
|
||||
|
|
11
src/cs_vm.hh
11
src/cs_vm.hh
|
@ -113,11 +113,12 @@ struct GenState {
|
|||
CsState &cs;
|
||||
CsVector<ostd::Uint32> code;
|
||||
ostd::ConstCharRange source;
|
||||
ostd::ConstCharRange src_file, src_str;
|
||||
int current_line;
|
||||
ostd::ConstCharRange src_name;
|
||||
|
||||
GenState() = delete;
|
||||
GenState(CsState &csr):
|
||||
cs(csr), code(), source(nullptr), src_file(), src_str()
|
||||
cs(csr), code(), source(nullptr), current_line(1), src_name()
|
||||
{}
|
||||
|
||||
ostd::ConstCharRange get_str();
|
||||
|
@ -209,7 +210,8 @@ struct GenState {
|
|||
}
|
||||
|
||||
void gen_value(
|
||||
int wordtype, ostd::ConstCharRange word = ostd::ConstCharRange()
|
||||
int wordtype, ostd::ConstCharRange word = ostd::ConstCharRange(),
|
||||
int line = 0
|
||||
);
|
||||
|
||||
void gen_main(ostd::ConstCharRange s, int ret_type = CsValAny);
|
||||
|
@ -218,6 +220,9 @@ struct GenState {
|
|||
if (source.empty()) {
|
||||
return;
|
||||
}
|
||||
if (*source == '\n') {
|
||||
++current_line;
|
||||
}
|
||||
source.pop_front();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue