Go backward to Adding RHS functions.
Go up to I/O.
Go forward to Adding Help screens.
Adding user interface commands
==============================
In addition to I/O routines and RHS functions, you can also add your own user
interface commands. Each Soar command has a corresponding C function to
handle it. The commands/functions should be installed at system startup time
via calls to add_command(). To install your own command, alter hooks.c as
follows:
/* ADD THE FOLLOWING DECLARATION */
extern bool my_C_function (void);
void system_startup_hook (void) {
...etc...
/* ADD THE FOLLOWING LINE */
add_command ("my-command-name", my_C_function);
...etc...
}
Soar's command dispatching loop will invoke your user interface routine
(my_C_function) when somebody types "my-command-name".
User interface commands should call Soar's *lexer* to read their arguments.
This section assumes a basic familiarity with what a lexer does, etc. (If
you've taken a class in compiler construction you should be fine; if not, you
can probably induce what's going on by studying some of the Soar command
functions in interface.c.) In Soar, the current lexeme is stored in the
global variable lexeme (see soar.h for details); calling get_lexeme()
replaces it with the next lexeme in the input stream.
One oddity about the lexer is that you can tell it whether or not to allow
identifiers in the input stream. Before your user interface function is
called, the lexer has been told to allow identifiers. If you call
set_lexer_allow_ids(FALSE), then when the lexer sees something like G37 it
will read it as a symbolic constant, rather than an identifier. This is
useful in commands that expect only production names as arguments.
When your user interface function is called, the current lexeme will be the
command name. Your function should call the lexer to read its arguments,
etc. If everything is successful, the function should return TRUE and should
exit with the current lexeme being the closing right parenthesis (otherwise
the command dispatcher will print an error message about extra arguments
being given). If an error occurs, your function should return FALSE.
Note: user interface functions don't have to worry about whether the user
typed them surrounded with parentheses. The optional parentheses stuff is
handled by the command dispatcher. User interface functions should assume
the command is invoked *with* parentheses; i.e., they should keep reading
arguments until the current lexeme is a closing right parenthesis.
If a user interface routine needs to create a symbol, it should do so via one
of the functions described in Section See Adding RHS functions, such as
make_sym_constant().
Rather than give an example interface routine here, you are referred to the
file interface.c. It contains the routines for all the Soar commands. Some
particularly simple examples are the "d", "ms", and "{user-select}" commands.