#ifndef CRUCIBLE_INTERP_H #define CRUCIBLE_INTERP_H #include "crucible/error.h" #include #include #include #include namespace crucible { using namespace std; struct ArgList : public vector { ArgList(const char **argv); // using vector::vector ... doesn't work: // error: ‘std::vector >::vector’ names constructor // Still doesn't work in 4.9 because it can't manage a conversion ArgList(const vector &&that); }; struct ArgActor { struct ArgActorBase { virtual void predicate(void *obj, string arg); }; template struct ArgActorDerived { function m_func; ArgActorDerived(decltype(m_func) func) : m_func(func) { } void predicate(void *obj, string arg) override { T &op = *(reinterpret_cast(obj)); m_func(op, obj); } }; template ArgActor(T, function func) : m_actor(make_shared(ArgActorDerived(func))) { } ArgActor() = default; void predicate(void *t, string arg) { if (m_actor) { m_actor->predicate(t, arg); } else { THROW_ERROR(invalid_argument, "null m_actor for predicate arg '" << arg << "'"); } } private: shared_ptr m_actor; }; struct ArgParser { ~ArgParser(); ArgParser(); void add_opt(string opt, ArgActor actor); template void parse(T t, const ArgList &args) { void *vt = &t; parse_backend(vt, args); } private: void parse_backend(void *t, const ArgList &args); map m_string_opts; }; struct Command { virtual ~Command(); virtual int exec(const ArgList &args) = 0; }; struct Proc : public Command { int exec(const ArgList &args) override; Proc(const function &f); private: function m_cmd; }; struct Interp { virtual ~Interp(); Interp(const map > &cmdlist); void add_command(const string &name, const shared_ptr &command); int exec(const ArgList &args); private: Interp(const Interp &) = delete; map > m_commands; }; }; #endif // CRUCIBLE_INTERP_H