move out private stuff from CsState
parent
372b1055c5
commit
46b7ed6f83
156
cubescript.cc
156
cubescript.cc
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue