Commit 2b94343f authored by Benoit Perrot's avatar Benoit Perrot
Browse files

Index: ChangeLog

from  Benoît Perrot  <benoit@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.
parent 843bf15e
2004-07-18 Benot Perrot <benoit@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 Benot Perrot <benoit@lrde.epita.fr>
* src/shell/shell.hh, src/shell.cc: Normalize string stream use.
......
......@@ -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 @@ namespace shell
\{ */
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()
/// Return the list of arguments
const list_args_type & get_args() const
{
switch (cmd_type_)
{
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_;
};
......
......@@ -19,6 +19,8 @@
#include "misc/readline.hh"
#include "parse/libparse.hh"
#include "shell/shell.hh"
#include "shell/cmd.hh"
......@@ -94,10 +96,10 @@ namespace shell
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 @@ namespace shell
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 @@ namespace shell
}
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 @@ namespace shell
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 @@ namespace shell
}
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 @@ namespace shell
}
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 @@ namespace shell
}
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 @@ namespace shell
}
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 @@ namespace shell
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
......@@ -39,7 +39,7 @@
# include "task/task_register.hh"
# include "vm/virtual_machine.hh"
# include "shell/cmd.hh"
namespace shell
{
......@@ -63,15 +63,9 @@ namespace shell
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 @@ namespace shell
return