move out private stuff from CsState

master
Daniel Kolesa 2015-08-12 18:50:02 +01:00
parent 372b1055c5
commit 46b7ed6f83
2 changed files with 89 additions and 92 deletions

View File

@ -6,6 +6,7 @@
#include <ostd/algorithm.hh> #include <ostd/algorithm.hh>
#include <ostd/format.hh> #include <ostd/format.hh>
#include <ostd/array.hh>
namespace cscript { namespace cscript {
@ -159,6 +160,68 @@ CsState::~CsState() {
} }
} }
ostd::ConstCharRange cs_debug_line(CsState &cs,
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 = line.slice(0, line.distance_front(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;
}
if (end.empty()) break;
line = end;
line.pop_front();
++num;
}
return fmt;
}
void cs_debug_alias(CsState &cs) {
if (!cs.dbgalias) return;
int total = 0, depth = 0;
for (IdentLink *l = cs.stack; l != &cs.noalias; l = l->next) total++;
for (IdentLink *l = cs.stack; l != &cs.noalias; l = l->next) {
Ident *id = l->id;
++depth;
if (depth < cs.dbgalias)
ostd::err.writefln(" %d) %s", total - depth + 1, id->name);
else if (l->next == &cs.noalias)
ostd::err.writefln(depth == cs.dbgalias ? " %d) %s"
: " ..%d) %s",
total - depth + 1, id->name);
}
}
template<typename ...A>
void cs_debug_code(CsState &cs, ostd::ConstCharRange fmt, A &&...args) {
if (cs.nodebug) return;
ostd::err.writefln(fmt, ostd::forward<A>(args)...);
cs_debug_alias(cs);
}
template<typename ...A>
void cs_debug_code_line(CsState &cs, ostd::ConstCharRange p,
ostd::ConstCharRange fmt, A &&...args) {
if (cs.nodebug) return;
ostd::Array<char, 256> buf;
ostd::err.writefln(cs_debug_line(cs, p, fmt, ostd::CharRange(buf.data(),
buf.size())),
ostd::forward<A>(args)...);
cs_debug_alias(cs);
}
void CsState::clear_override(Ident &id) { void CsState::clear_override(Ident &id) {
if (!(id.flags & IDF_OVERRIDDEN)) return; if (!(id.flags & IDF_OVERRIDDEN)) return;
switch (id.type) { switch (id.type) {
@ -197,7 +260,8 @@ Ident *CsState::new_ident(ostd::ConstCharRange name, int flags) {
Ident *id = idents.at(name); Ident *id = idents.at(name);
if (!id) { if (!id) {
if (cs_check_num(name)) { if (cs_check_num(name)) {
debug_code("number %s is not a valid identifier name", name); cs_debug_code(*this, "number %s is not a valid identifier name",
name);
return dummy; return dummy;
} }
id = add_ident(ID_ALIAS, name, flags); id = add_ident(ID_ALIAS, name, flags);
@ -231,7 +295,7 @@ bool CsState::reset_var(ostd::ConstCharRange name) {
Ident *id = idents.at(name); Ident *id = idents.at(name);
if (!id) return false; if (!id) return false;
if (id->flags & IDF_READONLY) { if (id->flags & IDF_READONLY) {
debug_code("variable %s is read only", id->name); cs_debug_code(*this, "variable %s is read only", id->name);
return false; return false;
} }
clear_override(*id); clear_override(*id);
@ -269,12 +333,13 @@ void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
set_var_str_checked(id, v.get_str()); set_var_str_checked(id, v.get_str());
break; break;
default: default:
debug_code("cannot redefine builtin %s with an alias", id->name); cs_debug_code(*this, "cannot redefine builtin %s with an alias",
id->name);
break; break;
} }
v.cleanup(); v.cleanup();
} else if (cs_check_num(name)) { } else if (cs_check_num(name)) {
debug_code("cannot alias number %s", name); cs_debug_code(*this, "cannot alias number %s", name);
v.cleanup(); v.cleanup();
} else { } else {
add_ident(ID_ALIAS, name, v, identflags); add_ident(ID_ALIAS, name, v, identflags);
@ -560,49 +625,6 @@ void Ident::clean_code() {
} }
} }
ostd::ConstCharRange CsState::debug_line(ostd::ConstCharRange p,
ostd::ConstCharRange fmt,
ostd::CharRange buf) {
if (src_str.empty()) return fmt;
ostd::Size num = 1;
ostd::ConstCharRange line(src_str);
for (;;) {
ostd::ConstCharRange end = ostd::find(line, '\n');
if (!end.empty())
line = line.slice(0, line.distance_front(end));
if (&p[0] >= &line[0] && &p[0] <= &line[line.size()]) {
ostd::CharRange r(buf);
if (!src_file.empty())
ostd::format(r, "%s:%d: %s", src_file, num, fmt);
else
ostd::format(r, "%d: %s", num, fmt);
r.put('\0');
return buf;
}
if (end.empty()) break;
line = end;
line.pop_front();
++num;
}
return fmt;
}
void CsState::debug_alias() {
if (!dbgalias) return;
int total = 0, depth = 0;
for (IdentLink *l = stack; l != &noalias; l = l->next) total++;
for (IdentLink *l = stack; l != &noalias; l = l->next) {
Ident *id = l->id;
++depth;
if (depth < dbgalias)
ostd::err.writefln(" %d) %s", total - depth + 1, id->name);
else if (l->next == &noalias)
ostd::err.writefln(depth == dbgalias ? " %d) %s"
: " ..%d) %s",
total - depth + 1, id->name);
}
}
void Ident::push_arg(const TaggedValue &v, IdentStack &st) { void Ident::push_arg(const TaggedValue &v, IdentStack &st) {
st.val = val; st.val = val;
st.valtype = valtype; st.valtype = valtype;
@ -692,7 +714,7 @@ template<typename SF, typename RF, typename CF>
bool cs_override_var(CsState &cs, Ident *id, SF sf, RF rf, CF cf) { bool cs_override_var(CsState &cs, Ident *id, SF sf, RF rf, CF cf) {
if ((cs.identflags & IDF_OVERRIDDEN) || (id->flags & IDF_OVERRIDE)) { if ((cs.identflags & IDF_OVERRIDDEN) || (id->flags & IDF_OVERRIDE)) {
if (id->flags & IDF_PERSIST) { if (id->flags & IDF_PERSIST) {
cs.debug_code("cannot override persistent variable '%s'", cs_debug_code(cs, "cannot override persistent variable '%s'",
id->name); id->name);
return false; return false;
} }
@ -828,18 +850,18 @@ int cs_clamp_var(CsState &cs, Ident *id, int v) {
v = id->maxval; v = id->maxval;
else else
return v; return v;
cs.debug_code((id->flags & IDF_HEX) cs_debug_code(cs, (id->flags & IDF_HEX)
? ((id->minval <= 255) ? ((id->minval <= 255)
? "valid range for '%s' is %d..0x%X" ? "valid range for '%s' is %d..0x%X"
: "valid range for '%s' is 0x%X..0x%X") : "valid range for '%s' is 0x%X..0x%X")
: "valid range for '%s' is %d..%d", : "valid range for '%s' is %d..%d",
id->name, id->minval, id->maxval); id->name, id->minval, id->maxval);
return v; return v;
} }
void CsState::set_var_int_checked(Ident *id, int v) { void CsState::set_var_int_checked(Ident *id, int v) {
if (id->flags & IDF_READONLY) { if (id->flags & IDF_READONLY) {
debug_code("variable '%s' is read only", id->name); cs_debug_code(*this, "variable '%s' is read only", id->name);
return; return;
} }
bool success = cs_override_var(*this, id, bool success = cs_override_var(*this, id,
@ -871,14 +893,14 @@ float cs_clamp_fvar(CsState &cs, Ident *id, float v) {
v = id->maxvalf; v = id->maxvalf;
else else
return v; return v;
cs.debug_code("valid range for '%s' is %s..%s", floatstr(id->minvalf), cs_debug_code(cs, "valid range for '%s' is %s..%s", floatstr(id->minvalf),
floatstr(id->maxvalf)); floatstr(id->maxvalf));
return v; return v;
} }
void CsState::set_var_float_checked(Ident *id, float v) { void CsState::set_var_float_checked(Ident *id, float v) {
if (id->flags & IDF_READONLY) { if (id->flags & IDF_READONLY) {
debug_code("variable '%s' is read only", id->name); cs_debug_code(*this, "variable '%s' is read only", id->name);
return; return;
} }
bool success = cs_override_var(*this, id, bool success = cs_override_var(*this, id,
@ -894,7 +916,7 @@ void CsState::set_var_float_checked(Ident *id, float v) {
void CsState::set_var_str_checked(Ident *id, ostd::ConstCharRange v) { void CsState::set_var_str_checked(Ident *id, ostd::ConstCharRange v) {
if (id->flags & IDF_READONLY) { if (id->flags & IDF_READONLY) {
debug_code("variable '%s' is read only", id->name); cs_debug_code(*this, "variable '%s' is read only", id->name);
return; return;
} }
bool success = cs_override_var(*this, id, bool success = cs_override_var(*this, id,
@ -1776,7 +1798,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
char c = gs.next_char(); char c = gs.next_char();
switch (c) { switch (c) {
case '\0': case '\0':
gs.cs.debug_code_line(line, "missing \"]\""); cs_debug_code_line(gs.cs, line, "missing \"]\"");
gs.source--; gs.source--;
goto done; goto done;
case '\"': case '\"':
@ -1797,7 +1819,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
while (gs.current() == '@') gs.next_char(); while (gs.current() == '@') gs.next_char();
int level = gs.source - (esc - 1); int level = gs.source - (esc - 1);
if (brak > level) continue; if (brak > level) continue;
else if (brak < level) gs.cs.debug_code_line(line, "too many @s"); else if (brak < level) cs_debug_code_line(gs.cs, line, "too many @s");
if (!concs && prevargs >= MAX_RESULTS) gs.code.push(CODE_ENTER); if (!concs && prevargs >= MAX_RESULTS) gs.code.push(CODE_ENTER);
if (concs + 2 > MAX_ARGUMENTS) { if (concs + 2 > MAX_ARGUMENTS) {
gs.code.push(CODE_CONCW | RET_STR | (concs << 8)); gs.code.push(CODE_CONCW | RET_STR | (concs << 8));
@ -2319,14 +2341,14 @@ endstatement:
char c = gs.next_char(); char c = gs.next_char();
switch (c) { switch (c) {
case '\0': case '\0':
if (c != brak) gs.cs.debug_code_line(line, "missing \"%c\"", brak); if (c != brak) cs_debug_code_line(gs.cs, line, "missing \"%c\"", brak);
gs.source--; gs.source--;
return; return;
case ')': case ')':
case ']': case ']':
if (c == brak) return; if (c == brak) return;
gs.cs.debug_code_line(line, "unexpected \"%c\"", c); cs_debug_code_line(gs.cs, line, "unexpected \"%c\"", c);
break; break;
case '/': case '/':
@ -2604,7 +2626,7 @@ static int rundepth = 0;
static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, TaggedValue &result) { static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, TaggedValue &result) {
result.set_null(); result.set_null();
if (rundepth >= MAXRUNDEPTH) { if (rundepth >= MAXRUNDEPTH) {
cs.debug_code("exceeded recursion limit"); cs_debug_code(cs, "exceeded recursion limit");
return skipcode(code, result); return skipcode(code, result);
} }
++rundepth; ++rundepth;
@ -2950,7 +2972,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
} \ } \
default: arg.cleanup(); nval; continue; \ default: arg.cleanup(); nval; continue; \
} \ } \
cs.debug_code("unknown alias lookup: %s", arg.s); \ cs_debug_code(cs, "unknown alias lookup: %s", arg.s); \
arg.cleanup(); \ arg.cleanup(); \
nval; \ nval; \
continue; \ continue; \
@ -2963,7 +2985,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
case CODE_LOOKUP|RET_STR: case CODE_LOOKUP|RET_STR:
#define LOOKUP(aval) { \ #define LOOKUP(aval) { \
Ident *id = cs.identmap[op>>8]; \ Ident *id = cs.identmap[op>>8]; \
if(id->flags&IDF_UNKNOWN) cs.debug_code("unknown alias lookup: %s", id->name); \ if(id->flags&IDF_UNKNOWN) cs_debug_code(cs, "unknown alias lookup: %s", id->name); \
aval; \ aval; \
continue; \ continue; \
} }
@ -3207,7 +3229,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
Ident *id = cs.identmap[op >> 13]; Ident *id = cs.identmap[op >> 13];
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
if (id->flags & IDF_UNKNOWN) { if (id->flags & IDF_UNKNOWN) {
cs.debug_code("unknown command: %s", id->name); cs_debug_code(cs, "unknown command: %s", id->name);
FORCERESULT; FORCERESULT;
} }
CALLALIAS(cs, result); CALLALIAS(cs, result);
@ -3245,7 +3267,7 @@ litval:
if (!id) { if (!id) {
noid: noid:
if (cs_check_num(idarg.s)) goto litval; if (cs_check_num(idarg.s)) goto litval;
cs.debug_code("unknown command: %s", idarg.s); cs_debug_code(cs, "unknown command: %s", idarg.s);
result.force_null(); result.force_null();
FORCERESULT; FORCERESULT;
} }
@ -3319,7 +3341,7 @@ void CsState::run_ret(Ident *id, ostd::PointerRange<TaggedValue> args,
++rundepth; ++rundepth;
TaggedValue *prevret = result; TaggedValue *prevret = result;
result = &ret; result = &ret;
if (rundepth > MAXRUNDEPTH) debug_code("exceeded recursion limit"); if (rundepth > MAXRUNDEPTH) cs_debug_code(*this, "exceeded recursion limit");
else if (id) switch (id->type) { else if (id) switch (id->type) {
default: default:
if (!id->fun) break; if (!id->fun) break;

View File

@ -4,7 +4,6 @@
#include <ostd/types.hh> #include <ostd/types.hh>
#include <ostd/string.hh> #include <ostd/string.hh>
#include <ostd/vector.hh> #include <ostd/vector.hh>
#include <ostd/array.hh>
#include <ostd/keyset.hh> #include <ostd/keyset.hh>
#include <ostd/range.hh> #include <ostd/range.hh>
#include <ostd/utility.hh> #include <ostd/utility.hh>
@ -370,24 +369,6 @@ struct CsState {
bool run_file(ostd::ConstCharRange fname, bool msg = true); bool run_file(ostd::ConstCharRange fname, bool msg = true);
template<typename ...A>
void debug_code(ostd::ConstCharRange fmt, A &&...args) {
if (nodebug) return;
ostd::err.writefln(fmt, ostd::forward<A>(args)...);
debug_alias();
}
template<typename ...A>
void debug_code_line(ostd::ConstCharRange p,
ostd::ConstCharRange fmt, A &&...args) {
if (nodebug) return;
ostd::Array<char, 256> buf;
ostd::err.writefln(debug_line(p, fmt, ostd::CharRange(buf.data(),
buf.size())),
ostd::forward<A>(args)...);
debug_alias();
}
void set_alias(ostd::ConstCharRange name, TaggedValue &v); void set_alias(ostd::ConstCharRange name, TaggedValue &v);
void set_var_int(ostd::ConstCharRange name, int v, void set_var_int(ostd::ConstCharRange name, int v,
@ -420,12 +401,6 @@ struct CsState {
void print_var_str(Ident *id, ostd::ConstCharRange s); void print_var_str(Ident *id, ostd::ConstCharRange s);
ostd::Uint32 *compile(ostd::ConstCharRange code); ostd::Uint32 *compile(ostd::ConstCharRange code);
private:
void debug_alias();
ostd::ConstCharRange debug_line(ostd::ConstCharRange p,
ostd::ConstCharRange fmt,
ostd::CharRange buf);
}; };
void bcode_ref(ostd::Uint32 *p); void bcode_ref(ostd::Uint32 *p);