error cleanup and always include lineinfo where possible

master
Daniel Kolesa 2016-09-10 16:06:01 +02:00
parent 3e0b35e427
commit dfe491e4b3
3 changed files with 61 additions and 58 deletions

View File

@ -8,13 +8,50 @@
namespace cscript {
static ostd::ConstCharRange cs_debug_line(
ostd::ConstCharRange p, ostd::ConstCharRange srcf, ostd::ConstCharRange srcs,
ostd::ConstCharRange fmt, ostd::CharRange buf
) {
if (srcs.empty()) {
return fmt;
}
ostd::Size num = 1;
ostd::ConstCharRange line(srcs);
for (;;) {
ostd::ConstCharRange end = ostd::find(line, '\n');
if (!end.empty()) {
line = ostd::slice_until(line, end);
}
if (&p[0] >= &line[0] && &p[0] <= &line[line.size()]) {
ostd::CharRange r(buf);
if (!srcf.empty()) {
ostd::format(r, "%s:%d: %s", srcf, num, fmt);
} else {
ostd::format(r, "%d: %s", num, fmt);
}
r.put('\0');
return buf.data(); /* trigger strlen */
}
if (end.empty()) {
break;
}
line = end;
line.pop_front();
++num;
}
return fmt;
}
template<typename ...A>
static void cs_error_line(
CsState &cs, ostd::ConstCharRange p, ostd::ConstCharRange fmt, A &&...args
GenState &gs, ostd::ConstCharRange p, ostd::ConstCharRange fmt, A &&...args
) {
ostd::Array<char, 256> buf;
auto rfmt = cs_debug_line(p, fmt, ostd::CharRange(buf.data(), buf.size()));
cs.error(rfmt, ostd::forward<A>(args)...);
auto rfmt = cs_debug_line(
p, gs.src_file, gs.src_str, fmt,
ostd::CharRange(buf.data(), buf.size())
);
gs.cs.error(rfmt, ostd::forward<A>(args)...);
}
char *cs_dup_ostr(ostd::ConstCharRange s) {
@ -797,7 +834,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
char c = gs.next_char();
switch (c) {
case '\0':
cs_error_line(gs.cs, line, "missing \"]\"");
cs_error_line(gs, line, "missing \"]\"");
return;
case '\"':
gs.source = parsestring(gs.source);
@ -825,7 +862,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
if (brak > level) {
continue;
} else if (brak < level) {
cs_error_line(gs.cs, line, "too many @s");
cs_error_line(gs, line, "too many @s");
return;
}
if (!concs && prevargs >= MaxResults) {
@ -1688,7 +1725,7 @@ endstatement:
case '\0':
if (c != brak) {
cs_error_line(
gs.cs, line, "missing \"%c\"", char(brak)
gs, line, "missing \"%c\"", char(brak)
);
return;
}
@ -1699,7 +1736,7 @@ endstatement:
if (c == brak) {
return;
}
cs_error_line(gs.cs, line, "unexpected \"%c\"", c);
cs_error_line(gs, line, "unexpected \"%c\"", c);
return;
case '/':
if (gs.current() == '/') {

View File

@ -33,42 +33,6 @@ static inline void cs_pop_alias(CsIdent *id) {
}
}
/* TODO: make thread_local later */
static ostd::ConstCharRange cs_src_file, cs_src_str;
ostd::ConstCharRange cs_debug_line(
ostd::ConstCharRange p, ostd::ConstCharRange fmt, ostd::CharRange buf
) {
if (cs_src_str.empty()) {
return fmt;
}
ostd::Size num = 1;
ostd::ConstCharRange line(cs_src_str);
for (;;) {
ostd::ConstCharRange end = ostd::find(line, '\n');
if (!end.empty()) {
line = ostd::slice_until(line, end);
}
if (&p[0] >= &line[0] && &p[0] <= &line[line.size()]) {
ostd::CharRange r(buf);
if (!cs_src_file.empty()) {
ostd::format(r, "%s:%d: %s", cs_src_file, num, fmt);
} else {
ostd::format(r, "%d: %s", num, fmt);
}
r.put('\0');
return buf.data(); /* trigger strlen */
}
if (end.empty()) {
break;
}
line = end;
line.pop_front();
++num;
}
return fmt;
}
CsStackState::CsStackState(CsStackStateNode *nd, bool gap):
p_node(nd), p_gap(gap)
{}
@ -1579,17 +1543,26 @@ void CsState::run(CsBytecode *code, CsValue &ret) {
runcode(*this, reinterpret_cast<ostd::Uint32 *>(code), ret);
}
void CsState::run(ostd::ConstCharRange code, CsValue &ret) {
GenState gs(*this);
static void cs_run(
CsState &cs, ostd::ConstCharRange file, ostd::ConstCharRange code,
CsValue &ret
) {
GenState gs(cs);
gs.src_file = file;
gs.src_str = code;
gs.code.reserve(64);
/* FIXME range */
gs.gen_main(code.data(), CsValAny);
runcode(*this, gs.code.data() + 1, ret);
runcode(cs, gs.code.data() + 1, ret);
if (int(gs.code[0]) >= 0x100) {
gs.code.disown();
}
}
void CsState::run(ostd::ConstCharRange code, CsValue &ret) {
cs_run(*this, ostd::ConstCharRange(), code, ret);
}
void CsState::run(CsIdent *id, CsValueRange args, CsValue &ret) {
int nargs = int(args.size());
ret.set_null();
@ -1754,7 +1727,6 @@ void CsState::run(CsIdent *id, CsValueRange args) {
static bool cs_run_file(
CsState &cs, ostd::ConstCharRange fname, CsValue &ret
) {
ostd::ConstCharRange old_src_file = cs_src_file, old_src_str = cs_src_str;
ostd::Box<char[]> buf;
ostd::Size len;
@ -1770,12 +1742,7 @@ static bool cs_run_file(
}
buf[len] = '\0';
ostd::ConstCharRange src_str = ostd::ConstCharRange(buf.get(), len);
cs_src_file = fname;
cs_src_str = src_str;
cs.run(src_str, ret);
cs_src_file = old_src_file;
cs_src_str = old_src_str;
cs_run(cs, fname, ostd::ConstCharRange(buf.get(), len), ret);
return true;
}

View File

@ -99,10 +99,6 @@ struct CsErrorException {
{}
};
ostd::ConstCharRange cs_debug_line(
ostd::ConstCharRange p, ostd::ConstCharRange fmt, ostd::CharRange buf
);
CsStackState cs_save_stack(CsState &cs);
template<typename ...A>
@ -119,9 +115,12 @@ struct GenState {
CsState &cs;
CsVector<ostd::Uint32> code;
char const *source;
ostd::ConstCharRange src_file, src_str;
GenState() = delete;
GenState(CsState &csr): cs(csr), code(), source(nullptr) {}
GenState(CsState &csr):
cs(csr), code(), source(nullptr), src_file(), src_str()
{}
void gen_str(ostd::ConstCharRange word, bool macro = false) {
if (word.size() <= 3 && !macro) {