EusLisp's standard top-level read-eval-print loop is controlled by eustop. When EusLisp is invoked, eustop tries to load the file named ".eusrc" in your home directory or the file specified by the EUSRC environment variable. It also tries to load a file named ".eusrc" in the current working directory. So, if you are in your home directory, note that .eusrc is loaded twice. Then EusLisp loads files specified in its argument list. After these loading, eustop enters normal interactive session.
When *standard-input* is connected to user's tty, eustop prints prompt generated by the toplevel-prompt function. The default toplevel-prompt prints "eus$ ". The effect of changing the definition of toplevel-prompt appears when eustop is invoked next time. One way to change the prompt from the first time is to define toplevel-prompt in your .eusrc file.
Inputs are read from *terminal-io* stream. If the input is parenthesized, it is taken as a lisp form and is evaluated by eval. Else if the first symbol of the input line has function definition, the line is automatically parenthesized and evaluated. If no function definition is found, then its special value is examined and the value is printed. If the symbol is unbound, the line is regarded as UNIX command and passed to sh (Bourn's shell). If sh cannot find corresponding unix command, ``command unrecognized" message is printed. Thus, eustop works both as a lisp interpreter and as a unix shell. If you do not wish to execute the input as UNIX command, you may escape the form by preceeding a comma ',' at the begining of the line. This is also useful to see the dynamic value binding when an error occured in the interpretive execution. Since EusLisp adopts lexical scope, we cannot examine the value of local variables outside of the scope unless they are declared special.
If the environment variable, USE_TOP_SELECTOR, is defined, the toplevel input is read in an asynchronous manner using the select library call. The input stream (*standard-input*) is registered to the *top-selector*, which is an instance of the port-selector class, together with the read-eval-print function (repsel) Therefore arrival of key inputs invokes the evaluation of the repsel. This feature is particularly useful when EusLisp is to handle multiple events, i.e., key inputs, X window events, and socket connection requests, at the same time. In order to exploit this asynchronous toplevel interaction, users should never write a code that blocks at the read operation. Instead, the input stream should be registered to the *top-selector* with its handler function by using the :add-port method. The handler function is expected to read from the stream, which is already known ready to return the input without blocking.
Note that Xwindow event handlers are defined to use the *top-selector* implicitly when USE_TOP_SELECTOR is defined, and user programs do not have to call x:window-main-loop at all to catch X events.
Using the time-out of the select call, users may define a timer handler. Each time the select call times out, the function bound to *timer-job* is invoked with no argument. The timer interval is defined by *top-selector-interval*, which is defaulted to 10.0 second. Note that the timer function invokation is not precisely periodic when there are inputs to the *top-selector*.
In the toplevel interaction, each line input is remembered in *history* vector with a sequence number. You can recall a specific input by ! function as if you were in csh. The difference from csh's history is, you need at least one white space between the exclamaition mark and the sequence number since ! is a function, and you can edit the line interactively with control keys, as in emacs.
^
D (EOF) terminates EusLisp normally.
To return abnormal termination code to upper level (usually a csh),
use exit with an appropriate condition code.
eustop sets a signal handler only for SIGINT and SIGPIPE, and other signals are not caught. Thus, signals such as SIGTERM or SIGQUIT cause EusLisp to terminate. In order to catch these signals to avoid termination, use unix:signal function to set user-defined signal handlers.
sigint-handler sig code [function]
euserror code message &rest arg [function]
exit &optional termination-code [function]
k-okada 2013-05-21