proper line infos at parse time
This commit is contained in:
parent
0f10c3e303
commit
604fd4e000
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
11
src/cs_vm.hh
11
src/cs_vm.hh
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue