many cleanups and api updates

master
Daniel Kolesa 2016-09-02 18:01:25 +01:00
parent 6aca518614
commit d36d24808c
3 changed files with 161 additions and 145 deletions

View File

@ -97,14 +97,12 @@ CsAlias::CsAlias(ostd::ConstCharRange name, CsValue const &v, int fl):
{}
CsCommand::CsCommand(
int tp, ostd::ConstCharRange name, ostd::ConstCharRange args,
int nargs, CmdFunc f
ostd::ConstCharRange name, ostd::ConstCharRange args,
int nargs, CsCommandCb f
):
CsIdent(CsIdentType::command, name, 0),
p_cargs(cs_dup_ostr(args)), p_numargs(nargs), cb_cftv(ostd::move(f))
{
p_type = tp;
}
{}
bool CsIdent::is_alias() const {
return get_type() == CsIdentType::alias;
@ -269,12 +267,82 @@ CsState::CsState() {
CsIdent *id = new_ident("//dummy");
assert(id->get_index() == DummyIdx);
id = add_ident<CsIvar>("numargs", MaxArguments, 0, 0);
id = new_ivar("numargs", MaxArguments, 0, 0);
assert(id->get_index() == NumargsIdx);
id = add_ident<CsIvar>("dbgalias", 0, 1000, 4);
id = new_ivar("dbgalias", 0, 1000, 4);
assert(id->get_index() == DbgaliasIdx);
add_command("do", "e", [this](CsValueRange args, CsValue &res) {
run_ret(args[0].get_code(), res);
})->p_type = ID_DO;
add_command("doargs", "e", [this](CsValueRange args, CsValue &res) {
if (p_stack != &noalias) {
cs_do_args(*this, [&]() { run_ret(args[0].get_code(), res); });
} else {
run_ret(args[0].get_code(), res);
}
})->p_type = ID_DOARGS;
add_command("if", "tee", [this](CsValueRange args, CsValue &res) {
run_ret((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
})->p_type = ID_IF;
add_command("result", "T", [](CsValueRange args, CsValue &res) {
CsValue &v = args[0];
res = v;
v.set_null();
})->p_type = ID_RESULT;
add_command("!", "t", [](CsValueRange args, CsValue &res) {
res.set_int(!args[0].get_bool());
})->p_type = ID_NOT;
add_command("&&", "E1V", [this](CsValueRange args, CsValue &res) {
if (args.empty()) {
res.set_int(1);
} else {
for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) {
res.cleanup();
}
CsBytecode *code = args[i].get_code();
if (code) {
run_ret(code, res);
} else {
res = args[i];
}
if (!res.get_bool()) {
break;
}
}
}
})->p_type = ID_AND;
add_command("||", "E1V", [this](CsValueRange args, CsValue &res) {
if (args.empty()) {
res.set_int(0);
} else {
for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) {
res.cleanup();
}
CsBytecode *code = args[i].get_code();
if (code) {
run_ret(code, res);
} else {
res = args[i];
}
if (res.get_bool()) {
break;
}
}
}
})->p_type = ID_OR;
add_command("local", nullptr, nullptr)->p_type = ID_LOCAL;
cs_init_lib_base(*this);
}
@ -352,7 +420,7 @@ CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) {
);
return identmap[DummyIdx];
}
id = add_ident<CsAlias>(name, flags);
id = add_ident(new CsAlias(name, flags));
}
return id;
}
@ -377,6 +445,26 @@ CsIdent *CsState::force_ident(CsValue &v) {
return identmap[DummyIdx];
}
CsIvar *CsState::new_ivar(
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v, CsVarCb f, int flags
) {
return add_ident(new CsIvar(n, m, x, v, ostd::move(f), flags))->get_ivar();
}
CsFvar *CsState::new_fvar(
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v, CsVarCb f, int flags
) {
return add_ident(new CsFvar(n, m, x, v, ostd::move(f), flags))->get_fvar();
}
CsSvar *CsState::new_svar(
ostd::ConstCharRange n, CsString v, CsVarCb f, int flags
) {
return add_ident(
new CsSvar(n, ostd::move(v), ostd::move(f), flags)
)->get_svar();
}
bool CsState::reset_var(ostd::ConstCharRange name) {
CsIdent *id = get_ident(name);
if (!id) {
@ -431,7 +519,7 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue &v) {
cs_debug_code(*this, "cannot alias number %s", name);
v.cleanup();
} else {
add_ident<CsAlias>(name, v, identflags);
add_ident(new CsAlias(name, v, identflags));
}
}
@ -1111,9 +1199,8 @@ void CsState::set_var_str_checked(CsSvar *sv, ostd::ConstCharRange v) {
sv->changed();
}
static bool cs_add_command(
CsState &cs, ostd::ConstCharRange name, ostd::ConstCharRange args,
CmdFunc func, int type = ID_COMMAND
CsCommand *CsState::add_command(
ostd::ConstCharRange name, ostd::ConstCharRange args, CsCommandCb func
) {
int nargs = 0;
for (ostd::ConstCharRange fmt(args); !fmt.empty(); ++fmt) {
@ -1151,21 +1238,16 @@ static bool cs_add_command(
"builtin %s declared with illegal type: %c",
name, fmt.front()
);
return false;
return nullptr;
}
}
cs.add_ident<CsCommand>(type, name, args, nargs, ostd::move(func));
return true;
}
bool CsState::add_command(
ostd::ConstCharRange name, ostd::ConstCharRange args, CmdFunc func
) {
return cs_add_command(*this, name, args, ostd::move(func));
return static_cast<CsCommand *>(
add_ident(new CsCommand(name, args, nargs, ostd::move(func)))
);
}
void cs_init_lib_io(CsState &cs) {
cs_add_command(cs, "exec", "sb", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("exec", "sb", [&cs](CsValueRange args, CsValue &res) {
auto file = args[0].get_strr();
bool ret = cs.run_file(file);
if (!ret) {
@ -1178,7 +1260,7 @@ void cs_init_lib_io(CsState &cs) {
}
});
cs_add_command(cs, "echo", "C", [](CsValueRange args, CsValue &) {
cs.add_command("echo", "C", [](CsValueRange args, CsValue &) {
ostd::writeln(args[0].get_strr());
});
}
@ -1228,79 +1310,11 @@ static inline void cs_loop_conc(
}
void cs_init_lib_base(CsState &cs) {
cs_add_command(cs, "do", "e", [&cs](CsValueRange args, CsValue &res) {
cs.run_ret(args[0].get_code(), res);
}, ID_DO);
cs_add_command(cs, "doargs", "e", [&cs](CsValueRange args, CsValue &res) {
if (cs.p_stack != &cs.noalias) {
cs_do_args(cs, [&]() { cs.run_ret(args[0].get_code(), res); });
} else {
cs.run_ret(args[0].get_code(), res);
}
}, ID_DOARGS);
cs_add_command(cs, "if", "tee", [&cs](CsValueRange args, CsValue &res) {
cs.run_ret((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
}, ID_IF);
cs_add_command(cs, "result", "T", [](CsValueRange args, CsValue &res) {
CsValue &v = args[0];
res = v;
v.set_null();
}, ID_RESULT);
cs_add_command(cs, "!", "t", [](CsValueRange args, CsValue &res) {
res.set_int(!args[0].get_bool());
}, ID_NOT);
cs_add_command(cs, "&&", "E1V", [&cs](CsValueRange args, CsValue &res) {
if (args.empty()) {
res.set_int(1);
} else {
for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) {
res.cleanup();
}
CsBytecode *code = args[i].get_code();
if (code) {
cs.run_ret(code, res);
} else {
res = args[i];
}
if (!res.get_bool()) {
break;
}
}
}
}, ID_AND);
cs_add_command(cs, "||", "E1V", [&cs](CsValueRange args, CsValue &res) {
if (args.empty()) {
res.set_int(0);
} else {
for (ostd::Size i = 0; i < args.size(); ++i) {
if (i) {
res.cleanup();
}
CsBytecode *code = args[i].get_code();
if (code) {
cs.run_ret(code, res);
} else {
res = args[i];
}
if (res.get_bool()) {
break;
}
}
}
}, ID_OR);
cs_add_command(cs, "?", "tTT", [](CsValueRange args, CsValue &res) {
cs.add_command("?", "tTT", [](CsValueRange args, CsValue &res) {
res.set(args[0].get_bool() ? args[1] : args[2]);
});
cs_add_command(cs, "cond", "ee2V", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("cond", "ee2V", [&cs](CsValueRange args, CsValue &res) {
for (ostd::Size i = 0; i < args.size(); i += 2) {
if ((i + 1) < args.size()) {
if (cs.run_bool(args[i].get_code())) {
@ -1314,7 +1328,7 @@ void cs_init_lib_base(CsState &cs) {
}
});
cs_add_command(cs, "case", "ite2V", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("case", "ite2V", [&cs](CsValueRange args, CsValue &res) {
CsInt val = args[0].get_int();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if (
@ -1327,7 +1341,7 @@ void cs_init_lib_base(CsState &cs) {
}
});
cs_add_command(cs, "casef", "fte2V", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("casef", "fte2V", [&cs](CsValueRange args, CsValue &res) {
CsFloat val = args[0].get_float();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if (
@ -1340,7 +1354,7 @@ void cs_init_lib_base(CsState &cs) {
}
});
cs_add_command(cs, "cases", "ste2V", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("cases", "ste2V", [&cs](CsValueRange args, CsValue &res) {
CsString val = args[0].get_str();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if (
@ -1353,7 +1367,7 @@ void cs_init_lib_base(CsState &cs) {
}
});
cs_add_command(cs, "pushif", "rTe", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("pushif", "rTe", [&cs](CsValueRange args, CsValue &res) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
return;
@ -1365,132 +1379,132 @@ void cs_init_lib_base(CsState &cs) {
}
});
cs_add_command(cs, "loop", "rie", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loop", "rie", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), 0, args[1].get_int(), 1, nullptr,
args[2].get_code()
);
});
cs_add_command(cs, "loop+", "riie", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loop+", "riie", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
nullptr, args[3].get_code()
);
});
cs_add_command(cs, "loop*", "riie", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loop*", "riie", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), 0, args[1].get_int(), args[2].get_int(),
nullptr, args[3].get_code()
);
});
cs_add_command(cs, "loop+*", "riiie", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loop+*", "riiie", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), nullptr, args[4].get_code()
);
});
cs_add_command(cs, "loopwhile", "riee", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loopwhile", "riee", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), 0, args[1].get_int(), 1,
args[2].get_code(), args[3].get_code()
);
});
cs_add_command(cs, "loopwhile+", "riiee", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loopwhile+", "riiee", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
args[3].get_code(), args[4].get_code()
);
});
cs_add_command(cs, "loopwhile*", "riiee", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loopwhile*", "riiee", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
args[3].get_code(), args[4].get_code()
);
});
cs_add_command(cs, "loopwhile+*", "riiiee", [&cs](CsValueRange args, CsValue &) {
cs.add_command("loopwhile+*", "riiiee", [&cs](CsValueRange args, CsValue &) {
cs_do_loop(
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), args[4].get_code(), args[5].get_code()
);
});
cs_add_command(cs, "while", "ee", [&cs](CsValueRange args, CsValue &) {
cs.add_command("while", "ee", [&cs](CsValueRange args, CsValue &) {
CsBytecode *cond = args[0].get_code(), *body = args[1].get_code();
while (cs.run_bool(cond)) {
cs.run_int(body);
}
});
cs_add_command(cs, "loopconcat", "rie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcat", "rie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
args[2].get_code(), true
);
});
cs_add_command(cs, "loopconcat+", "riie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcat+", "riie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
args[3].get_code(), true
);
});
cs_add_command(cs, "loopconcat*", "riie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcat*", "riie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
args[3].get_code(), true
);
});
cs_add_command(cs, "loopconcat+*", "riiie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcat+*", "riiie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), args[4].get_code(), true
);
});
cs_add_command(cs, "loopconcatword", "rie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcatword", "rie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
args[2].get_code(), false
);
});
cs_add_command(cs, "loopconcatword+", "riie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcatword+", "riie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
args[3].get_code(), false
);
});
cs_add_command(cs, "loopconcatword*", "riie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcatword*", "riie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
args[3].get_code(), false
);
});
cs_add_command(cs, "loopconcatword+*", "riiie", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("loopconcatword+*", "riiie", [&cs](CsValueRange args, CsValue &res) {
cs_loop_conc(
cs, res, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
args[2].get_int(), args[4].get_code(), false
);
});
cs_add_command(cs, "nodebug", "e", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("nodebug", "e", [&cs](CsValueRange args, CsValue &res) {
++cs.nodebug;
cs.run_ret(args[0].get_code(), res);
--cs.nodebug;
});
cs_add_command(cs, "push", "rTe", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("push", "rTe", [&cs](CsValueRange args, CsValue &res) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
return;
@ -1500,36 +1514,34 @@ void cs_init_lib_base(CsState &cs) {
cs.run_ret(args[2].get_code(), res);
});
cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL);
cs_add_command(cs, "resetvar", "s", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("resetvar", "s", [&cs](CsValueRange args, CsValue &res) {
res.set_int(cs.reset_var(args[0].get_strr()));
});
cs_add_command(cs, "alias", "sT", [&cs](CsValueRange args, CsValue &) {
cs.add_command("alias", "sT", [&cs](CsValueRange args, CsValue &) {
CsValue &v = args[1];
cs.set_alias(args[0].get_strr(), v);
v.set_null();
});
cs_add_command(cs, "getvarmin", "s", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("getvarmin", "s", [&cs](CsValueRange args, CsValue &res) {
res.set_int(cs.get_var_min_int(args[0].get_strr()).value_or(0));
});
cs_add_command(cs, "getvarmax", "s", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("getvarmax", "s", [&cs](CsValueRange args, CsValue &res) {
res.set_int(cs.get_var_max_int(args[0].get_strr()).value_or(0));
});
cs_add_command(cs, "getfvarmin", "s", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("getfvarmin", "s", [&cs](CsValueRange args, CsValue &res) {
res.set_float(cs.get_var_min_float(args[0].get_strr()).value_or(0.0f));
});
cs_add_command(cs, "getfvarmax", "s", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("getfvarmax", "s", [&cs](CsValueRange args, CsValue &res) {
res.set_float(cs.get_var_max_float(args[0].get_strr()).value_or(0.0f));
});
cs_add_command(cs, "identexists", "s", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("identexists", "s", [&cs](CsValueRange args, CsValue &res) {
res.set_int(cs.have_ident(args[0].get_strr()));
});
cs_add_command(cs, "getalias", "s", [&cs](CsValueRange args, CsValue &res) {
cs.add_command("getalias", "s", [&cs](CsValueRange args, CsValue &res) {
res.set_str(ostd::move(cs.get_alias_val(args[0].get_strr()).value_or("")));
});
}

View File

@ -219,8 +219,7 @@ struct OSTD_EXPORT CsIvar: CsVar {
private:
CsIvar(
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v,
CsVarCb f = CsVarCb(), int flags = 0
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v, CsVarCb f, int flags
);
CsInt p_storage, p_minval, p_maxval, p_overrideval;
@ -238,7 +237,7 @@ struct OSTD_EXPORT CsFvar: CsVar {
private:
CsFvar(
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v,
CsVarCb f = CsVarCb(), int flags = 0
CsVarCb f, int flags
);
CsFloat p_storage, p_minval, p_maxval, p_overrideval;
@ -251,10 +250,7 @@ struct OSTD_EXPORT CsSvar: CsVar {
void set_value(CsString val);
private:
CsSvar(
ostd::ConstCharRange n, CsString v, CsVarCb f = CsVarCb(),
int flags = 0
);
CsSvar(ostd::ConstCharRange n, CsString v, CsVarCb f, int flags);
CsString p_storage, p_overrideval;
};
@ -295,7 +291,7 @@ private:
CsValue p_val;
};
using CmdFunc = ostd::Function<void(CsValueRange, CsValue &)>;
using CsCommandCb = ostd::Function<void(CsValueRange, CsValue &)>;
struct CsCommand: CsIdent {
friend struct CsState;
@ -310,12 +306,12 @@ struct CsCommand: CsIdent {
char *p_cargs;
int p_numargs;
CmdFunc cb_cftv;
CsCommandCb cb_cftv;
private:
CsCommand(
int type, ostd::ConstCharRange name, ostd::ConstCharRange args,
int numargs, CmdFunc func
ostd::ConstCharRange name, ostd::ConstCharRange args,
int numargs, CsCommandCb func
);
};
@ -355,10 +351,18 @@ struct OSTD_EXPORT CsState {
CsIdent *new_ident(ostd::ConstCharRange name, int flags = IDF_UNKNOWN);
CsIdent *force_ident(CsValue &v);
template<typename T, typename ...A>
T *add_ident(A &&...args) {
return static_cast<T *>(add_ident(new T(ostd::forward<A>(args)...)));
}
CsIvar *new_ivar(
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v,
CsVarCb f = CsVarCb(), int flags = 0
);
CsFvar *new_fvar(
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v,
CsVarCb f = CsVarCb(), int flags = 0
);
CsSvar *new_svar(
ostd::ConstCharRange n, CsString v,
CsVarCb f = CsVarCb(), int flags = 0
);
CsIdent *get_ident(ostd::ConstCharRange name) {
CsIdent **id = idents.at(name);
@ -383,8 +387,8 @@ struct OSTD_EXPORT CsState {
bool reset_var(ostd::ConstCharRange name);
void touch_var(ostd::ConstCharRange name);
bool add_command(
ostd::ConstCharRange name, ostd::ConstCharRange args, CmdFunc func
CsCommand *add_command(
ostd::ConstCharRange name, ostd::ConstCharRange args, CsCommandCb func
);
CsString run_str(CsBytecode *code);

View File

@ -163,8 +163,8 @@ static CsCommand *get_hint_cmd(ostd::ConstCharRange buf) {
#include "tools/edit_fallback.hh"
static void do_tty(CsState &cs) {
auto prompt = cs.add_ident<CsSvar>("PROMPT", "> ");
auto prompt2 = cs.add_ident<CsSvar>("PROMPT2", ">> ");
auto prompt = cs.new_svar("PROMPT", "> ");
auto prompt2 = cs.new_svar("PROMPT2", ">> ");
bool do_exit = false;
cs.add_command("quit", "", [&do_exit](auto, auto &) {