diff --git a/cubescript.cc b/cubescript.cc index 81e30cb3..88b50883 100644 --- a/cubescript.cc +++ b/cubescript.cc @@ -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("numargs", MaxArguments, 0, 0); + id = new_ivar("numargs", MaxArguments, 0, 0); assert(id->get_index() == NumargsIdx); - id = add_ident("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(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(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(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( + 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(""))); }); } diff --git a/cubescript.hh b/cubescript.hh index 36c1a13d..7a7345ef 100644 --- a/cubescript.hh +++ b/cubescript.hh @@ -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; +using CsCommandCb = ostd::Function; 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 - T *add_ident(A &&...args) { - return static_cast(add_ident(new T(ostd::forward(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); diff --git a/tools/repl.cc b/tools/repl.cc index 56bee6b2..9d2eaf83 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -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("PROMPT", "> "); - auto prompt2 = cs.add_ident("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 &) {