Commit a23e921a authored by Benoit Perrot's avatar Benoit Perrot
Browse files

Index: ChangeLog

from  Benoît Perrot  <benoit@lrde.epita.fr>

	Improve command identifiers recognition.

	* src/shell/cmd.hh: Rename
	(cmd_type_type, cmd_type_, get_type) as
	(identifier_type, id_, get_identifier) for readability.
	* src/shell/shell.hh (eat_word): Rename as 
	(eat_command_id) and move its implementation into...
	* src/shell/shell.cc: This file. Recognize uncomplete command
	identifiers and warn on ambiguity. Factor `build_cmd'.
parent 9312687f
2005-01-15 Benot Perrot <benoit@lrde.epita.fr>
Improve command identifiers recognition.
* src/shell/cmd.hh: Rename
(cmd_type_type, cmd_type_, get_type) as
(identifier_type, id_, get_identifier) for readability.
* src/shell/shell.hh (eat_word): Rename as
(eat_command_id) and move its implementation into...
* src/shell/shell.cc: This file. Recognize uncomplete command
identifiers and warn on ambiguity. Factor `build_cmd'.
2005-01-14 Benot Perrot <benoit@lrde.epita.fr>
Introduce unique_strings.
......
......@@ -32,25 +32,26 @@ namespace shell
class Cmd
{
public:
/// Command Type.
enum cmd_type_type
/// Command identifier.
enum identifier_type
{
cmd_unknown,
cmd_null,
cmd_load,
cmd_run,
cmd_quit,
cmd_continue,
cmd_break,
cmd_next,
cmd_print,
cmd_display,
cmd_undisplay,
cmd_dump,
cmd_mem,
cmd_backtrace,
cmd_nop_after_branch,
cmd_help
id_unknown,
id_ambiguous,
id_null,
id_load,
id_run,
id_quit,
id_continue,
id_break,
id_next,
id_print,
id_display,
id_undisplay,
id_dump,
id_mem,
id_backtrace,
id_nop_after_branch,
id_help
};
typedef std::list<std::string> list_args_type;
......@@ -59,8 +60,8 @@ namespace shell
\{ */
public:
/// Construct a Cmd.
Cmd(const cmd_type_type cmd_type):
cmd_type_(cmd_type)
Cmd(const identifier_type id):
id_(id)
{}
/// Destroy a Cmd.
......@@ -84,15 +85,15 @@ namespace shell
}
/// Return the Cmd type.
cmd_type_type get_type() const
identifier_type get_identifier() const
{
return cmd_type_;
return id_;
}
/** \} */
private:
/// The command type.
cmd_type_type cmd_type_;
/// The command identifier.
identifier_type id_;
/// List of arguments.
list_args_type list_args_;
......
......@@ -45,31 +45,21 @@ namespace shell
vm_(true, false)
{
map_token_["run"] = RUN;
map_token_["r"] = RUN;
map_token_["quit"] = QUIT;
map_token_["q"] = QUIT;
map_token_["break"] = BREAK;
map_token_["b"] = BREAK;
map_token_["continue"] = CONTINUE;
map_token_["c"] = CONTINUE;
map_token_["display"] = DISPLAY;
map_token_["dump"] = DUMP;
map_token_["d"] = DUMP;
map_token_["load"] = LOAD;
map_token_["l"] = LOAD;
map_token_["mem"] = MEM;
map_token_["m"] = MEM;
map_token_["backtrace"] = BACKTRACE;
map_token_["bt"] = BACKTRACE;
map_token_["next"] = NEXT;
map_token_["n"] = NEXT;
map_token_["print"] = PRINT;
map_token_["p"] = PRINT;
map_token_["undisplay"] = UNDISPLAY;
map_token_["nop-after-branch"] = NOP_AFTER_BRANCH;
map_token_["help"] = HELP;
map_token_["h"] = HELP;
map_token_["run"] = Cmd::id_run;
map_token_["quit"] = Cmd::id_quit;
map_token_["break"] = Cmd::id_break;
map_token_["continue"] = Cmd::id_continue;
map_token_["display"] = Cmd::id_display;
map_token_["dump"] = Cmd::id_dump;
map_token_["load"] = Cmd::id_load;
map_token_["mem"] = Cmd::id_mem;
map_token_["backtrace"] = Cmd::id_backtrace;
map_token_["bt"] = Cmd::id_backtrace;
map_token_["next"] = Cmd::id_next;
map_token_["print"] = Cmd::id_print;
map_token_["undisplay"] = Cmd::id_undisplay;
map_token_["nop-after-branch"] = Cmd::id_nop_after_branch;
map_token_["help"] = Cmd::id_help;
map_register_["zero"] = vm::Cpu::zero;
map_register_["at"] = vm::Cpu::at;
......@@ -108,7 +98,7 @@ namespace shell
void
Shell::run()
{
Cmd *command = new Cmd(Cmd::cmd_null);
Cmd *command = new Cmd(Cmd::id_null);
std::string line;
while (execute(*command) == 0 && misc::readline("(nolimips) ", line))
......@@ -122,8 +112,28 @@ namespace shell
}
}
if (command) // FIXME: seems useless
delete command;
delete command;
}
Cmd::identifier_type
Shell::eat_command_id(std::istringstream &iss)
{
std::string id = get_next_word(iss);
if (id.empty())
return Cmd::id_null;
map_token_type::const_iterator it = map_token_.lower_bound(id);
if (it == map_token_.end() || it->first.find(id) != 0)
return Cmd::id_unknown;
else
{
map_token_type::const_iterator next(it);
++next;
if (next != map_token_.end() && next->first.find(id) == 0)
return Cmd::id_ambiguous;
}
return it->second;
}
Cmd*
......@@ -131,13 +141,13 @@ namespace shell
{
std::istringstream iss(str);
Cmd* command = 0;
switch (eat_word(iss))
Cmd::identifier_type id = eat_command_id(iss);
switch (id)
{
case QUIT:
return new Cmd(Cmd::cmd_quit);
case RUN:
case Cmd::id_run:
{
command = new Cmd(Cmd::cmd_run);
command = new Cmd(Cmd::id_run);
std::string tmp = get_next_word(iss);
while (0 < tmp.length())
{
......@@ -146,9 +156,10 @@ namespace shell
}
return command;
}
case BREAK:
case Cmd::id_break:
{
command = new Cmd(Cmd::cmd_break);
command = new Cmd(Cmd::id_break);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
......@@ -164,15 +175,9 @@ namespace shell
delete command;
break;
}
case CONTINUE:
return new Cmd(Cmd::cmd_continue);
case NEXT:
return new Cmd(Cmd::cmd_next);
case DUMP:
return new Cmd(Cmd::cmd_dump);
case LOAD:
case Cmd::id_load:
{
command = new Cmd(Cmd::cmd_load);
command = new Cmd(Cmd::id_load);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
......@@ -182,45 +187,12 @@ namespace shell
command->push_arg(tmp);
return command;
}
case PRINT:
{
command = new Cmd(Cmd::cmd_print);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
delete command;
break;
}
// check tmp is a register
if (is_register(tmp))
{
command->push_arg(tmp);
return command;
}
delete command;
break;
}
case DISPLAY:
{
command = new Cmd(Cmd::cmd_display);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
delete command;
break;
}
// check tmp is a register
if (is_register(tmp))
{
command->push_arg(tmp);
return command;
}
delete command;
break;
}
case UNDISPLAY:
case Cmd::id_print:
case Cmd::id_display:
case Cmd::id_undisplay:
{
command = new Cmd(Cmd::cmd_undisplay);
command = new Cmd(id);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
......@@ -236,9 +208,10 @@ namespace shell
delete command;
break;
}
case MEM:
case Cmd::id_mem:
{
command = new Cmd(Cmd::cmd_mem);
command = new Cmd(Cmd::id_mem);
std::string tmp = get_next_word(iss);
if (tmp.empty())
{
......@@ -249,18 +222,22 @@ namespace shell
command->push_arg(tmp);
return command;
}
case BACKTRACE:
return new Cmd(Cmd::cmd_backtrace);
case NOP_AFTER_BRANCH:
return new Cmd(Cmd::cmd_nop_after_branch);
case HELP:
return new Cmd(Cmd::cmd_help);
case TERROR:
case EOL:
break;
case Cmd::id_quit:
case Cmd::id_continue:
case Cmd::id_next:
case Cmd::id_dump:
case Cmd::id_backtrace:
case Cmd::id_nop_after_branch:
case Cmd::id_help:
case Cmd::id_unknown:
case Cmd::id_ambiguous:
case Cmd::id_null:
return new Cmd(id);
}
return new Cmd(Cmd::cmd_unknown);
return new Cmd(Cmd::id_unknown);
}
......@@ -408,9 +385,14 @@ namespace shell
}
void
Shell::do_error() const
Shell::do_unknown() const
{
std::cerr << "Unknown command" << std::endl;
}
void
Shell::do_ambiguous() const
{
std::cerr << "Command error" << std::endl;
std::cerr << "Ambiguous command" << std::endl;
}
void
......@@ -452,52 +434,55 @@ namespace shell
int
Shell::execute(const Cmd &cmd)
{
switch (cmd.get_type())
switch (cmd.get_identifier())
{
case Cmd::cmd_quit:
case Cmd::id_quit:
return 1;
case Cmd::cmd_unknown:
do_error();
case Cmd::id_unknown:
do_unknown();
break;
case Cmd::id_ambiguous:
do_ambiguous();
break;
case Cmd::cmd_load:
case Cmd::id_load:
do_load(cmd);
break;
case Cmd::cmd_run:
case Cmd::id_run:
do_run();
break;
case Cmd::cmd_continue:
case Cmd::id_continue:
do_continue();
break;
case Cmd::cmd_next:
case Cmd::id_next:
do_next();
break;
case Cmd::cmd_dump:
case Cmd::id_dump:
do_dump();
break;
case Cmd::cmd_print:
case Cmd::id_print:
do_print(cmd);
break;
case Cmd::cmd_display:
case Cmd::id_display:
do_display(cmd);
break;
case Cmd::cmd_undisplay:
case Cmd::id_undisplay:
do_undisplay(cmd);
break;
case Cmd::cmd_mem:
case Cmd::id_mem:
do_mem();
break;
case Cmd::cmd_backtrace:
case Cmd::id_backtrace:
do_backtrace();
break;
case Cmd::cmd_break:
case Cmd::id_break:
do_break(cmd);
break;
case Cmd::cmd_nop_after_branch:
case Cmd::id_nop_after_branch:
do_nop_after_branch();
break;
case Cmd::cmd_null:
case Cmd::id_null:
break;
case Cmd::cmd_help:
case Cmd::id_help:
do_help();
}
return 0;
......
......@@ -49,26 +49,6 @@ bool isblank(int c);
namespace shell
{
/// Token word value.
enum shell_token_type
{
EOL = 0,
TERROR = 1,
RUN = 201,
QUIT = 202,
LOAD = 203,
BREAK = 204,
NEXT = 205,
CONTINUE = 206,
DISPLAY = 207,
UNDISPLAY = 208,
PRINT = 209,
DUMP = 210,
MEM = 211,
NOP_AFTER_BRANCH = 212,
HELP = 213,
BACKTRACE
};
/// Shell Class.
class Shell
......@@ -76,7 +56,7 @@ namespace shell
public:
/** \name Shortand type definition
\{ */
typedef std::map<std::string, shell_token_type> map_token_type;
typedef std::map<std::string, Cmd::identifier_type> map_token_type;
typedef std::map<std::string, vm::Cpu::kind_type> map_register_type;
typedef std::list<std::string> list_disp_type;
/** \} */
......@@ -190,17 +170,7 @@ namespace shell
}
/// Eat a word in the command line and return the corresponding keyword.
shell_token_type eat_word(std::istringstream &iss)
{
std::string cmd = get_next_word(iss);
if (cmd.empty())
return EOL;
map_token_type::const_iterator it = map_token_.find(cmd);
if (it != map_token_.end())
return it->second;
return TERROR;
}
Cmd::identifier_type eat_command_id(std::istringstream &iss);
/** \name Execution engine
\{ */
......@@ -220,7 +190,9 @@ namespace shell
void do_nop_after_branch();
void do_error() const;
void do_unknown() const;
void do_ambiguous() const;
void do_help() const;
int execute(const Cmd &cmd);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment