Index: ChangeLog
from Benoît Perrot <benoit(a)lrde.epita.fr>
shell::Cmd is a minimalist AST, shell::Shell is one of its
visitor.
* src/shell/cmd.hh: Move execution engine to...
* src/shell/shell.hh, src/shell/shell.cc: This class.
2004-07-18 Benoît Perrot <benoit(a)lrde.epita.fr>
Index: src/shell/cmd.hh
--- src/shell/cmd.hh (revision 118)
+++ src/shell/cmd.hh (working copy)
@@ -24,22 +24,8 @@
# define SHELL_CMD_HH
# include <list>
-# include <map>
-
# include <string>
-# include <sstream>
-# include <iostream>
-
-# include <algorithm>
-
-# include "common.hh"
-# include "modules.hh"
-# include "task/task_register.hh"
-# include "parse/libparse.hh"
-# include "vm/virtual_machine.hh"
-# include "shell/shell.hh"
-
namespace shell
{
/// Cmd Class.
@@ -72,238 +58,41 @@
\{ */
public:
/// Construct a Cmd.
- Cmd(const cmd_type_type cmd_type, Shell &sh):
- cmd_type_(cmd_type),
- sh_(sh)
- {
- }
+ Cmd(const cmd_type_type cmd_type):
+ cmd_type_(cmd_type)
+ {}
/// Destroy a Cmd.
~Cmd()
{}
/** \} */
+ /** \name Accessors
+ \{ */
+ public:
/// Add an argument
void push_arg(const std::string &arg)
{
list_args_.push_back(arg);
}
- /// Execute the Cmd.
- int execute()
- {
- switch (cmd_type_)
+ /// Return the list of arguments
+ const list_args_type & get_args() const
{
- case cmd_quit:
- return 1;
- case cmd_unknown:
- e_error();
- break;
- case cmd_load:
- e_load();
- break;
- case cmd_run:
- e_run();
- break;
- case cmd_continue:
- e_continue();
- break;
- case cmd_next:
- e_next();
- break;
- case cmd_dump:
- e_dump();
- break;
- case cmd_print:
- e_print();
- break;
- case cmd_display:
- e_display();
- break;
- case cmd_undisplay:
- e_undisplay();
- break;
- case cmd_mem:
- e_mem();
- break;
- case cmd_break:
- e_break();
- break;
- case cmd_nop_after_branch:
- e_nop_after_branch();
- break;
- case cmd_null:
- break;
- case cmd_help:
- e_help();
- }
- return 0;
+ return list_args_;
}
/// Return the Cmd type.
- cmd_type_type get_cmd_type() const
+ cmd_type_type get_type() const
{
return cmd_type_;
}
-
- /** \name Function to execute.
- \{ */
- private:
- void e_load()
- {
- // FIXME: introducing memory leak!
- filename = strdup(list_args_.begin()->c_str());
-
- //std::cerr << "#DEBUG: _load: filename == " << filename
<< std::endl;
-
- parse::tasks::parse();
- inst::tasks::prg_solve();
- sh_.vm_.load_program(* parse::tasks::program);
- }
-
- void e_run()
- {
- if (!parse::tasks::program)
- {
- std::cerr << "No program loaded." << std::endl;
- return;
- }
-
- if (sh_.vm_.get_status() != vm::VirtualMachine::halt)
- sh_.vm_.set_runnable();
- else
- {
- sh_.vm_.reset();
- sh_.vm_.set_runnable();
- }
- sh_.vm_.execute(false);
- }
-
- void e_continue()
- {
- if (!parse::tasks::program)
- {
- std::cerr << "No program loaded." << std::endl;
- return;
- }
-
- if (sh_.vm_.get_status() != vm::VirtualMachine::halt)
- {
- sh_.vm_.set_runnable();
- sh_.vm_.execute(false);
- }
- else
- std::cerr << "The program is not being run." << std::endl;
- }
-
- void e_next()
- {
- if (!parse::tasks::program)
- {
- std::cerr << "No program loaded." << std::endl;
- return;
- }
-
- if (sh_.vm_.get_status() != vm::VirtualMachine::halt)
- {
- sh_.vm_.set_run_next();
- sh_.vm_.execute(true);
- }
- else
- std::cerr << "The program is not being run." << std::endl;
- }
-
- void e_break()
- {
- if (!parse::tasks::program)
- {
- std::cerr << "No program loaded." << std::endl;
- return;
- }
-
- //std::cerr <<"#DEBUG: label = " << *label <<
std::endl;
-// sh_.vm_.add_break(*label);
- sh_.vm_.add_breakpoint(*list_args_.begin());
- }
-
- void e_display()
- {
- sh_.add_display(*list_args_.begin());
- }
-
- void e_undisplay()
- {
- sh_.remove_display(*list_args_.begin());
- }
-
- void e_dump()
- {
- std::cout << sh_.vm_ << std::endl;
- }
-
- void e_print()
- {
- std::cout
- << *list_args_.begin() << " = "
- << sh_.get_register(*list_args_.begin()) << std::endl;
- }
-
- void e_nop_after_branch()
- {
- parse::tasks::nop_after_branch();
- }
-
- void e_mem()
- {
-// const std::string* addr = *(list_args_.begin());
- //std::cout << "addr: " << *addr << " = "
<< sh_.vm_.get_memory_offset(atoi(addr->c_str())) << std::endl;
- }
-
- void e_error() const
- {
- std::cerr << "Command error" << std::endl;
- }
-
- void e_help() const
- {
- std::cout << "run <args>" << std::endl
- << "\trun the current loaded file with the specified arguments"
- << std::endl
- << "load <filename>" << std::endl
- << "\tload the specified filename" << std::endl
- << "break <label>" << std::endl
- << "\tenable a break point on a label" << std::endl
- << "quit" << std::endl
- << "\tquit the debugging session" << std::endl
- << "next" << std::endl
- << "\texecute the next asm line" << std::endl
- << "continue" << std::endl
- << "\tcontinue to the next breakpoint" << std::endl
- << "display <register>" << std::endl
- << "\tdisplay (and set displayable) a register value"
- << std::endl
- << "undisplay <register>" << std::endl
- << "\tundisplay a register" << std::endl
- << "print <register>" << std::endl
- << "\tprint a register value" << std::endl
- << "dump" << std::endl
- << "\tdump all the register value" << std::endl
- << "mem <addr>" << std::endl
- << "\tprint a the value of a memory region" << std::endl
- << "nop-after-branch" << std::endl
- << "\tenable Fill delay slot of branch instructions "
- << "with NOP" << std::endl;
- }
-
/** \} */
private:
/// The command type.
cmd_type_type cmd_type_;
- /// Link to shell class.
- Shell &sh_;
-
/// List of arguments.
list_args_type list_args_;
};
Index: src/shell/shell.hh
--- src/shell/shell.hh (revision 118)
+++ src/shell/shell.hh (working copy)
@@ -39,7 +39,7 @@
# include "task/task_register.hh"
# include "vm/virtual_machine.hh"
-
+# include "shell/cmd.hh"
namespace shell
{
@@ -63,15 +63,9 @@
HELP = 213
};
- /** Forward declaration. */
- class Cmd;
-
/// Shell Class.
class Shell
{
- /// friend class (dirty).
- friend class Cmd;
-
public:
/** \name Shortand type definition
\{ */
@@ -201,6 +195,29 @@
return TERROR;
}
+ /** \name Execution engine
+ \{ */
+ protected:
+ void do_load(const Cmd &cmd);
+ void do_run();
+ void do_continue();
+ void do_next();
+ void do_break(const Cmd &cmd);
+
+ void do_display(const Cmd &cmd);
+ void do_undisplay(const Cmd &cmd);
+ void do_dump();
+ void do_print(const Cmd &cmd);
+ void do_mem();
+
+ void do_nop_after_branch();
+
+ void do_error() const;
+ void do_help() const;
+
+ int execute(const Cmd &cmd);
+ /** \} */
+
private:
/// virtual machine link.
vm::VirtualMachine vm_;
Index: src/shell/shell.cc
--- src/shell/shell.cc (revision 118)
+++ src/shell/shell.cc (working copy)
@@ -19,6 +19,8 @@
#include "misc/readline.hh"
+#include "parse/libparse.hh"
+
#include "shell/shell.hh"
#include "shell/cmd.hh"
@@ -94,10 +96,10 @@
void
Shell::run()
{
- Cmd *command = new Cmd(Cmd::cmd_null, *this);
+ Cmd *command = new Cmd(Cmd::cmd_null);
std::string line;
- while ((command->execute() == 0) && misc::readline("(nolimips)
", line))
+ while (execute(*command) == 0 && misc::readline("(nolimips) ",
line))
{
display();
@@ -120,10 +122,10 @@
switch (eat_word(iss))
{
case QUIT:
- return new Cmd(Cmd::cmd_quit, *this);
+ return new Cmd(Cmd::cmd_quit);
case RUN:
{
- command = new Cmd(Cmd::cmd_run, *this);
+ command = new Cmd(Cmd::cmd_run);
std::string tmp = get_next_word(iss);
while (0 < tmp.length())
{
@@ -134,7 +136,7 @@
}
case BREAK:
{
- command = new Cmd(Cmd::cmd_break, *this);
+ command = new Cmd(Cmd::cmd_break);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
@@ -151,14 +153,14 @@
break;
}
case CONTINUE:
- return new Cmd(Cmd::cmd_continue, *this);
+ return new Cmd(Cmd::cmd_continue);
case NEXT:
- return new Cmd(Cmd::cmd_next, *this);
+ return new Cmd(Cmd::cmd_next);
case DUMP:
- return new Cmd(Cmd::cmd_dump, *this);
+ return new Cmd(Cmd::cmd_dump);
case LOAD:
{
- command = new Cmd(Cmd::cmd_load, *this);
+ command = new Cmd(Cmd::cmd_load);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
@@ -170,7 +172,7 @@
}
case PRINT:
{
- command = new Cmd(Cmd::cmd_print, *this);
+ command = new Cmd(Cmd::cmd_print);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
@@ -188,7 +190,7 @@
}
case DISPLAY:
{
- command = new Cmd(Cmd::cmd_display, *this);
+ command = new Cmd(Cmd::cmd_display);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
@@ -206,7 +208,7 @@
}
case UNDISPLAY:
{
- command = new Cmd(Cmd::cmd_undisplay, *this);
+ command = new Cmd(Cmd::cmd_undisplay);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
@@ -224,7 +226,7 @@
}
case MEM:
{
- command = new Cmd(Cmd::cmd_mem, *this);
+ command = new Cmd(Cmd::cmd_mem);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
@@ -236,15 +238,228 @@
return command;
}
case NOP_AFTER_BRANCH:
- return new Cmd(Cmd::cmd_nop_after_branch, *this);
+ return new Cmd(Cmd::cmd_nop_after_branch);
case HELP:
- return new Cmd(Cmd::cmd_help, *this);
+ return new Cmd(Cmd::cmd_help);
case TERROR:
case EOL:
break;
}
- return new Cmd(Cmd::cmd_unknown, *this);
+ return new Cmd(Cmd::cmd_unknown);
+ }
+
+
+ void
+ Shell::do_load(const Cmd &cmd)
+ {
+ // FIXME: introducing memory leak!
+ filename = strdup(cmd.get_args().begin()->c_str());
+
+ //std::cerr << "#DEBUG: _load: filename == " << filename
<< std::endl;
+
+ parse::tasks::parse();
+ inst::tasks::prg_solve();
+ vm_.load_program(* parse::tasks::program);
+ }
+
+ void
+ Shell::do_run()
+ {
+ if (!parse::tasks::program)
+ {
+ std::cerr << "No program loaded." << std::endl;
+ return;
+ }
+
+ if (vm_.get_status() != vm::VirtualMachine::halt)
+ vm_.set_runnable();
+ else
+ {
+ vm_.reset();
+ vm_.set_runnable();
+ }
+ vm_.execute(false);
+ }
+
+ void
+ Shell::do_continue()
+ {
+ if (!parse::tasks::program)
+ {
+ std::cerr << "No program loaded." << std::endl;
+ return;
+ }
+
+ if (vm_.get_status() != vm::VirtualMachine::halt)
+ {
+ vm_.set_runnable();
+ vm_.execute(false);
+ }
+ else
+ std::cerr << "The program is not being run." << std::endl;
+ }
+
+ void
+ Shell::do_next()
+ {
+ if (!parse::tasks::program)
+ {
+ std::cerr << "No program loaded." << std::endl;
+ return;
+ }
+
+ if (vm_.get_status() != vm::VirtualMachine::halt)
+ {
+ vm_.set_run_next();
+ vm_.execute(true);
+ }
+ else
+ std::cerr << "The program is not being run." << std::endl;
+ }
+
+ void
+ Shell::do_break(const Cmd &cmd)
+ {
+ if (!parse::tasks::program)
+ {
+ std::cerr << "No program loaded." << std::endl;
+ return;
+ }
+
+ //std::cerr <<"#DEBUG: label = " << *label << std::endl;
+ // sh_.vm_.add_break(*label);
+ vm_.add_breakpoint(*cmd.get_args().begin());
+ }
+
+ void
+ Shell::do_display(const Cmd &cmd)
+ {
+ add_display(*cmd.get_args().begin());
+ }
+
+ void
+ Shell::do_undisplay(const Cmd &cmd)
+ {
+ remove_display(*cmd.get_args().begin());
+ }
+
+ void
+ Shell::do_dump()
+ {
+ std::cout << vm_ << std::endl;
+ }
+
+ void
+ Shell::do_print(const Cmd &cmd)
+ {
+ std::cout
+ << *cmd.get_args().begin() << " = "
+ << get_register(*cmd.get_args().begin()) << std::endl;
+ }
+
+ void
+ Shell::do_nop_after_branch()
+ {
+ parse::tasks::nop_after_branch();
+ }
+
+ void
+ Shell::do_mem()
+ {
+ // const std::string* addr = *(list_args_.begin());
+ //std::cout << "addr: " << *addr << " = "
<< sh_.vm_.get_memory_offset(atoi(addr->c_str())) << std::endl;
+ }
+
+ void
+ Shell::do_error() const
+ {
+ std::cerr << "Command error" << std::endl;
+ }
+
+ void
+ Shell::do_help() const
+ {
+ std::cout
+ << "run <args>" << std::endl
+ << "\trun the current loaded file with the specified arguments"
+ << std::endl
+ << "load <filename>" << std::endl
+ << "\tload the specified filename" << std::endl
+ << "break <label>" << std::endl
+ << "\tenable a break point on a label" << std::endl
+ << "quit" << std::endl
+ << "\tquit the debugging session" << std::endl
+ << "next" << std::endl
+ << "\texecute the next asm line" << std::endl
+ << "continue" << std::endl
+ << "\tcontinue to the next breakpoint" << std::endl
+ << "display <register>" << std::endl
+ << "\tdisplay (and set displayable) a register value"
+ << std::endl
+ << "undisplay <register>" << std::endl
+ << "\tundisplay a register" << std::endl
+ << "print <register>" << std::endl
+ << "\tprint a register value" << std::endl
+ << "dump" << std::endl
+ << "\tdump all the register value" << std::endl
+ << "mem <addr>" << std::endl
+ << "\tprint a the value of a memory region" << std::endl
+ << "nop-after-branch" << std::endl
+ << "\tenable Fill delay slot of branch instructions "
+ << "with NOP" << std::endl;
+ }
+
+ /// Execute the Cmd.
+ int
+ Shell::execute(const Cmd &cmd)
+ {
+ switch (cmd.get_type())
+ {
+ case Cmd::cmd_quit:
+ return 1;
+ case Cmd::cmd_unknown:
+ do_error();
+ break;
+ case Cmd::cmd_load:
+ do_load(cmd);
+ break;
+ case Cmd::cmd_run:
+ do_run();
+ break;
+ case Cmd::cmd_continue:
+ do_continue();
+ break;
+ case Cmd::cmd_next:
+ do_next();
+ break;
+ case Cmd::cmd_dump:
+ do_dump();
+ break;
+ case Cmd::cmd_print:
+ do_print(cmd);
+ break;
+ case Cmd::cmd_display:
+ do_display(cmd);
+ break;
+ case Cmd::cmd_undisplay:
+ do_undisplay(cmd);
+ break;
+ case Cmd::cmd_mem:
+ do_mem();
+ break;
+ case Cmd::cmd_break:
+ do_break(cmd);
+ break;
+ case Cmd::cmd_nop_after_branch:
+ do_nop_after_branch();
+ break;
+ case Cmd::cmd_null:
+ break;
+ case Cmd::cmd_help:
+ do_help();
+ }
+ return 0;
}
} // namespace shell