proper line infos at parse time

This commit is contained in:
q66 2016-09-22 01:44:35 +02:00
parent 0f10c3e303
commit 604fd4e000
3 changed files with 62 additions and 24 deletions

View file

@ -8,11 +8,28 @@
namespace cscript { 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> template<typename ...A>
static void cs_error_line( static void cs_error_line(
GenState &gs, ostd::ConstCharRange fmt, A &&...args 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) { 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() { ostd::ConstCharRange GenState::get_str() {
auto ln = source; auto ln = source;
source.pop_front(); next_char();
auto beg = source; auto beg = source;
for (; current(); next_char()) { for (; current(); next_char()) {
switch (current()) { switch (current()) {
@ -176,8 +193,9 @@ 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 ostd::ConstCharRange compileblock( static inline ostd::Pair<ostd::ConstCharRange, int> compileblock(
GenState &gs, ostd::ConstCharRange p, int rettype = CsRetNull, int brak = '\0' GenState &gs, ostd::ConstCharRange p, int line,
int rettype = CsRetNull, int brak = '\0'
); );
void GenState::gen_int(ostd::ConstCharRange word) { void GenState::gen_int(ostd::ConstCharRange word) {
@ -188,7 +206,7 @@ void GenState::gen_float(ostd::ConstCharRange word) {
gen_float(cs_parse_float(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) { switch (wordtype) {
case CsValCany: case CsValCany:
if (!word.empty()) { if (!word.empty()) {
@ -218,13 +236,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); compileblock(*this, word, line);
} else { } else {
gen_null(); gen_null();
} }
break; break;
case CsValCode: case CsValCode:
compileblock(*this, word); compileblock(*this, word, line);
break; break;
case CsValIdent: case CsValIdent:
gen_ident(word); gen_ident(word);
@ -238,18 +256,23 @@ static inline void compileblock(GenState &gs) {
gs.code.push(CsCodeEmpty); gs.code.push(CsCodeEmpty);
} }
static inline ostd::ConstCharRange compileblock( static inline ostd::Pair<ostd::ConstCharRange, int> compileblock(
GenState &gs, ostd::ConstCharRange p, int rettype, int brak GenState &gs, ostd::ConstCharRange p, int line, 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));
int retline = line;
if (p) { if (p) {
ostd::ConstCharRange op = gs.source; ostd::ConstCharRange op = gs.source;
int oldline = gs.current_line;
gs.source = p; gs.source = p;
gs.current_line = line;
compilestatements(gs, CsValAny, brak); compilestatements(gs, CsValAny, brak);
p = gs.source; p = gs.source;
retline = gs.current_line;
gs.source = op; gs.source = op;
gs.current_line = oldline;
} }
if (gs.code.size() > start + 2) { if (gs.code.size() > start + 2) {
gs.code.push(CsCodeExit | rettype); gs.code.push(CsCodeExit | rettype);
@ -258,7 +281,7 @@ static inline ostd::ConstCharRange compileblock(
gs.code.resize(start); gs.code.resize(start);
gs.code.push(CsCodeEmpty | rettype); gs.code.push(CsCodeEmpty | rettype);
} }
return p; return ostd::make_pair(p, retline);
} }
static inline void compileunescapestr(GenState &gs, bool macro = false) { static inline void compileunescapestr(GenState &gs, bool macro = false) {
@ -650,6 +673,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.data(); char const *start = gs.source.data();
int curline = gs.current_line;
int concs = 0; int concs = 0;
for (int brak = 1; brak;) { for (int brak = 1; brak;) {
switch (gs.skip_until("@\"/[]")) { switch (gs.skip_until("@\"/[]")) {
@ -703,6 +727,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
} }
if (concs) { if (concs) {
start = gs.source.data(); start = gs.source.data();
curline = gs.current_line;
} else if (prevargs >= MaxResults) { } else if (prevargs >= MaxResults) {
gs.code.pop(); gs.code.pop();
} }
@ -719,11 +744,14 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
case CsValPop: case CsValPop:
return; return;
case CsValCode: case CsValCode:
case CsValCond: case CsValCond: {
gs.source = compileblock(gs, ostd::ConstCharRange( auto ret = compileblock(gs, ostd::ConstCharRange(
start, gs.source.data() + gs.source.size() start, gs.source.data() + gs.source.size()
), CsRetNull, ']'); ), curline, CsRetNull, ']');
gs.source = ret.first;
gs.current_line = ret.second;
return; return;
}
case CsValIdent: case CsValIdent:
gs.gen_ident(ostd::ConstCharRange(start, gs.source.data() - 1)); gs.gen_ident(ostd::ConstCharRange(start, gs.source.data() - 1));
return; return;
@ -821,9 +849,10 @@ static bool compilearg(
gs.get_str(); gs.get_str();
break; break;
case CsValCond: { case CsValCond: {
int 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); compileblock(gs, s, line);
} else { } else {
gs.gen_null(); gs.gen_null();
} }
@ -848,8 +877,9 @@ static bool compilearg(
compileunescapestr(gs, true); compileunescapestr(gs, true);
break; break;
default: { default: {
int line = gs.current_line;
auto s = gs.get_str_dup(); auto s = gs.get_str_dup();
gs.gen_value(wordtype, s); gs.gen_value(wordtype, s, line);
break; break;
} }
} }
@ -902,19 +932,21 @@ static bool compilearg(
return !gs.get_word().empty(); return !gs.get_word().empty();
} }
case CsValCond: { case CsValCond: {
int line = gs.current_line;
auto s = gs.get_word(); auto s = gs.get_word();
if (s.empty()) { if (s.empty()) {
return false; return false;
} }
compileblock(gs, s); compileblock(gs, s, line);
return true; return true;
} }
case CsValCode: { case CsValCode: {
int line = gs.current_line;
auto s = gs.get_word(); auto s = gs.get_word();
if (s.empty()) { if (s.empty()) {
return false; return false;
} }
compileblock(gs, s); compileblock(gs, s, line);
return true; return true;
} }
case CsValWord: { case CsValWord: {
@ -925,11 +957,12 @@ static bool compilearg(
return !w.empty(); return !w.empty();
} }
default: { default: {
int line = gs.current_line;
auto s = gs.get_word(); auto s = gs.get_word();
if (s.empty()) { if (s.empty()) {
return false; return false;
} }
gs.gen_value(wordtype, s); gs.gen_value(wordtype, s, line);
return true; return true;
} }
} }
@ -1309,6 +1342,7 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
for (;;) { for (;;) {
gs.skip_comments(); gs.skip_comments();
idname.clear(); idname.clear();
int curline = gs.current_line;
bool more = compilearg(gs, CsValWord, prevargs, &idname); bool more = compilearg(gs, CsValWord, prevargs, &idname);
if (!more) { if (!more) {
goto endstatement; goto endstatement;
@ -1415,7 +1449,7 @@ noid:
break; break;
} }
default: default:
gs.gen_value(rettype, idname); gs.gen_value(rettype, idname, curline);
break; break;
} }
gs.code.push(CsCodeResult); gs.code.push(CsCodeResult);

View file

@ -1577,8 +1577,7 @@ static void cs_run(
CsValue &ret CsValue &ret
) { ) {
GenState gs(cs); GenState gs(cs);
gs.src_file = file; gs.src_name = file;
gs.src_str = code;
gs.code.reserve(64); gs.code.reserve(64);
/* FIXME range */ /* FIXME range */
gs.gen_main(code.data(), CsValAny); gs.gen_main(code.data(), CsValAny);

View file

@ -113,11 +113,12 @@ struct GenState {
CsState &cs; CsState &cs;
CsVector<ostd::Uint32> code; CsVector<ostd::Uint32> code;
ostd::ConstCharRange source; ostd::ConstCharRange source;
ostd::ConstCharRange src_file, src_str; int current_line;
ostd::ConstCharRange src_name;
GenState() = delete; GenState() = delete;
GenState(CsState &csr): 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(); ostd::ConstCharRange get_str();
@ -209,7 +210,8 @@ struct GenState {
} }
void gen_value( 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); void gen_main(ostd::ConstCharRange s, int ret_type = CsValAny);
@ -218,6 +220,9 @@ struct GenState {
if (source.empty()) { if (source.empty()) {
return; return;
} }
if (*source == '\n') {
++current_line;
}
source.pop_front(); source.pop_front();
} }