summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--i/marvin/src/interpreter/interpreter.cc36
-rw-r--r--i/marvin/src/interpreter/interpreter.hh13
-rw-r--r--i/marvin/src/interpreter/test_interpreter.cc21
3 files changed, 60 insertions, 10 deletions
diff --git a/i/marvin/src/interpreter/interpreter.cc b/i/marvin/src/interpreter/interpreter.cc
index bdc918a..0c067cf 100644
--- a/i/marvin/src/interpreter/interpreter.cc
+++ b/i/marvin/src/interpreter/interpreter.cc
@@ -30,15 +30,15 @@ Interpreter::~Interpreter (void)
{
for (Funcs::iterator i = funcs_.begin (); i != funcs_.end (); ++i)
{
- delete i->second;
+ delete i->second.func;
}
}
/// Add a function, Interpreter owns f.
void
-Interpreter::add (const std::string &s, Func *f)
+Interpreter::add (const std::string &s, Func *f, const std::string &desc)
{
- if (!funcs_.insert (Funcs::value_type (s, f)).second)
+ if (!funcs_.insert (Funcs::value_type (s, FuncDesc (f, desc))).second)
{
// Interpreter owns f, therefore, f must be deleted.
delete f;
@@ -47,6 +47,13 @@ Interpreter::add (const std::string &s, Func *f)
}
}
+/// Add a function without description, Interpreter owns f.
+void
+Interpreter::add (const std::string &s, Func *f)
+{
+ add (s, f, "");
+}
+
/// Call a function by name.
void
Interpreter::call (const std::string &s, const Args &a,
@@ -58,7 +65,7 @@ Interpreter::call (const std::string &s, const Args &a,
throw std::runtime_error ("function \'" + s + "\' does not exist");
try
{
- (*i->second) (a, dryrun);
+ (*i->second.func) (a, dryrun);
}
catch (const std::exception &e)
{
@@ -83,3 +90,24 @@ Interpreter::interpretFile (const std::string &file, bool dryrun/*false*/)
p.parseFile (file);
}
+/// Return an help string.
+std::string
+Interpreter::help (void) const
+{
+ std::string ret;
+ for (Funcs::const_iterator i = funcs_.begin (); i != funcs_.end (); ++i)
+ {
+ // Well, if you really want to implement this better, please do...
+ for (std::string::const_iterator j = i->second.desc.begin ();
+ j != i->second.desc.end (); j++)
+ {
+ if (*j == '\n')
+ ret += "\n ";
+ else
+ ret += *j;
+ }
+ ret += '\n';
+ }
+ return ret;
+}
+
diff --git a/i/marvin/src/interpreter/interpreter.hh b/i/marvin/src/interpreter/interpreter.hh
index 4164c28..1f6e688 100644
--- a/i/marvin/src/interpreter/interpreter.hh
+++ b/i/marvin/src/interpreter/interpreter.hh
@@ -51,14 +51,23 @@ class Interpreter
template<class T, typename F>
class MemFunc;
private:
+ struct FuncDesc
+ {
+ Func *func;
+ std::string desc;
+ FuncDesc (Func *func_, const std::string &desc_)
+ : func (func_), desc (desc_) { }
+ };
/// Type of the private function map.
- typedef std::map<std::string, Func *> Funcs;
+ typedef std::map<std::string, FuncDesc> Funcs;
/// The function map itself.
Funcs funcs_;
public:
/// Destructor.
~Interpreter (void);
/// Add a function, Interpreter owns f.
+ void add (const std::string &s, Func *f, const std::string &desc);
+ /// Add a function without description, Interpreter owns f.
void add (const std::string &s, Func *f);
/// Call a function by name.
void call (const std::string &s, const Args &a,
@@ -67,6 +76,8 @@ class Interpreter
void interpretString (const std::string &s, bool dryrun = false);
/// Interpret a file.
void interpretFile (const std::string &file, bool dryrun = false);
+ /// Return an help string.
+ std::string help (void) const;
/// Take all the template sophistications out of the programmer hands.
template<class T, typename F>
static Func *memFunc (T &i, F f);
diff --git a/i/marvin/src/interpreter/test_interpreter.cc b/i/marvin/src/interpreter/test_interpreter.cc
index d51357d..631d10d 100644
--- a/i/marvin/src/interpreter/test_interpreter.cc
+++ b/i/marvin/src/interpreter/test_interpreter.cc
@@ -86,11 +86,20 @@ class TestInterpreter
int main (void)
{
// Add functions.
- t.add ("a", Interpreter::memFunc (*this, &TestInterpreter::funcA));
- t.add ("b", Interpreter::memFunc (*this, &TestInterpreter::funcB));
- t.add ("c", Interpreter::memFunc (*this, &TestInterpreter::funcC));
- t.add ("d", Interpreter::memFunc (*this, &TestInterpreter::funcD));
- t.add ("e", Interpreter::memFunc (*this, &TestInterpreter::funcE));
+ t.add ("a", Interpreter::memFunc (*this, &TestInterpreter::funcA),
+ "a ARGS...\n"
+ "the wonderful `a' function taking any number of any arguments");
+ t.add ("b", Interpreter::memFunc (*this, &TestInterpreter::funcB),
+ "b\ntakes no argument");
+ t.add ("c", Interpreter::memFunc (*this, &TestInterpreter::funcC),
+ "c THE_MIGHTY_NUMBER\n"
+ "takes one integer");
+ t.add ("d", Interpreter::memFunc (*this, &TestInterpreter::funcD),
+ "d THE_STRING\n"
+ "takes one string");
+ t.add ("e", Interpreter::memFunc (*this, &TestInterpreter::funcE),
+ "e INT STRING DOUBLE\n"
+ "takes one integer, one string and one double");
// Make argument lists.
Interpreter::Args a[4];
a[1].push_back (71117);
@@ -98,6 +107,8 @@ class TestInterpreter
a[3].push_back (42);
a[3].push_back (std::string ("merguez"));
a[3].push_back (51.1664);
+ // Need help?
+ std::cout << t.help () << std::endl;
// Call all those wonderful functions.
call ("unknown", a[0]);
for (unsigned int i = 0; i < sizeof (a) / sizeof (a[0]); ++i)