diff --git a/books/bookvol0.pamphlet b/books/bookvol0.pamphlet index cbe733b..caca555 100644 --- a/books/bookvol0.pamphlet +++ b/books/bookvol0.pamphlet @@ -67820,4 +67820,3 @@ Springer-Verlag, New York, NY 1992 ISBN 0-387-97855-0 \end{thebibliography} \printindex \end{document} -> \ No newline at end of file diff --git a/books/bookvol5.pamphlet b/books/bookvol5.pamphlet index 850e46d..c2c2f17 100644 --- a/books/bookvol5.pamphlet +++ b/books/bookvol5.pamphlet @@ -23,6 +23,17 @@ \special{pdf:dest (#1) [ @thispage /FitH @ypos ]}} %% +%% cmdhead consolidates standard command page setup +%% +\newcommand{\cmdhead}[1]{% e.g. \cmdhead{name} +\chapter{)#1~Command}% +\label{#1}% +\index{#1}% +\section{#1 man page}% +\index{mapage!#1}% +\index{#1!manpage}} + +%% %% pagehead consolidates standard page indexing %% \newcommand{\pagehead}[2]{% e.g. \pagehead{name}{abb} @@ -80,6 +91,11 @@ \index{#2!#1}% #2} +%% these commands are used in the man page descriptions for each command +%% they should probably be replaced by other equivalents +\newcommand{\lanb}{{\tt [}} +\newcommand{\ranb}{{\tt ]}} +\newcommand{\vertline}{$|$} % struggle with latex figure-floating behavior \renewcommand\floatpagefraction{.9} @@ -345,15 +361,7 @@ information is initialized. @ \subsection{defun spad} -\begin{verbatim} -spad() == - -- starts the interpreter but does not read in profiles, etc. - $PrintCompilerMessageIfTrue: local - $inLispVM : local := nil - setOutputAlgebra "%initialize%" - runspad() - 'EndOfSpad -\end{verbatim} +Starts the interpreter but does not read in profiles, etc. <>= (defun |spad| () (prog (|$PrintCompilerMessageIfTrue| |$inLispVM|) @@ -368,14 +376,6 @@ spad() == @ \subsection{defun runspad} -\begin{verbatim} -runspad() == - mode:='restart - while mode='restart repeat - resetStackLimits() - CATCH($quitTag, CATCH('coerceFailure, - mode:=CATCH('top__level, ncTopLevel()))) -\end{verbatim} <>= (defun |runspad| () (prog (mode) @@ -395,34 +395,21 @@ runspad() == @ \subsection{defun ncTopLevel} -\begin{verbatim} -ncTopLevel() == --- Top-level read-parse-eval-print loop for the interpreter. Uses --- the Bill Burge's parser. - IN_-STREAM: fluid := CURINSTREAM - _*EOF_*: fluid := NIL - $InteractiveMode :fluid := true - $BOOT: fluid := NIL - $NEWSPAD: fluid := true - $SPAD: fluid := true - $e:fluid := $InteractiveFrame - ncIntLoop() -\end{verbatim} +Top-level read-parse-eval-print loop for the interpreter. Uses +the Bill Burge's parser. <>= (defun |ncTopLevel| () - (prog (|$e| $spad $newspad $boot |$InteractiveMode| *eof* in-stream) + (let (|$e| $spad $newspad $boot |$InteractiveMode| *eof* in-stream) (declare (special |$e| $spad $newspad $boot |$InteractiveMode| *eof* in-stream |$InteractiveFrame|)) - (return - (progn - (setq in-stream curinstream) - (setq *eof* nil) - (setq |$InteractiveMode| t) - (setq $boot nil) - (setq $newspad t) - (setq $spad t) - (setq |$e| |$InteractiveFrame|) - (|ncIntLoop|))))) + (setq in-stream curinstream) + (setq *eof* nil) + (setq |$InteractiveMode| t) + (setq $boot nil) + (setq $newspad t) + (setq $spad t) + (setq |$e| |$InteractiveFrame|) + (|ncIntLoop|))) @ \subsection{defun ncIntLoop} @@ -479,39 +466,6 @@ suppressed and input does not use piles. If this is true then the library loading routines might output messages and piles are expected on input (as from a file). \end{list} -\begin{verbatim} -SpadInterpretStream(str, source, interactive?) == - $fn : local := source - pile? := not interactive? - $libQuiet : local := not interactive? - $newcompMode : local := false --- following seems useless and causes ccl package problems --- $InteractiveMode : local := false - - $newcompErrorCount: local := 0 -- SMW Feb 2/90. - -- Used in highComplete, ncHardError etc. - - $okToExecuteMachineCode: local := true -- set false on error - $inclAssertions: local := ["AIX", "CommonLisp"] -- Jan 28/90 - - - $lastPos : local := $nopos ------------>!!! - $erMsgToss : local := false --------------->!!! - $ncMsgList : local := nil - - $systemCommandFunction : local := function InterpExecuteSpadSystemCommand - $shoeReadLineFunction : local := function serverReadLine - $promptMsg : local := 'S2CTP023 - - interactive? => - PRINC(MKPROMPT()) - intloopReadConsole('"", str) - [] - intloopInclude (source,0) - [] - - ----------------------------------------------------------------- -\end{verbatim} <>= (defun |SpadInterpretStream| (str source interactive?) (prog (|$promptMsg| |$shoeReadLineFunction| |$systemCommandFunction| @@ -694,9 +648,6 @@ Prefix a filename with the {\bf AXIOM} shell variable. @ \subsection{defun makeInitialModemapFrame} -\begin{verbatim} -makeInitialModemapFrame() == COPY $InitialModemapFrame -\end{verbatim} <>= (defun |makeInitialModemapFrame| () (copy |$InitialModemapFrame|)) @@ -753,8 +704,8 @@ NAG distribution back to the original form. If you need the NAG version you can push {\bf :tpd} on the {\bf *features*} variable before compiling this file. A correct call looks like: \begin{verbatim} -(in-package "BOOT") -(reroot "/spad/mnt/${SYS}") + (in-package "BOOT") + (reroot "/spad/mnt/${SYS}") \end{verbatim} where the [[${SYS}]] variable is the same one set at build time. <>= @@ -821,6 +772,46 @@ Thus, to see they copyright you type: New commands need to be added to this table. The command invoked will be the first entry of the pair and the ``user level'' of the command will be the second entry. + +See:\\ +\begin{itemize} +\item The \fnref{abbreviations} command +\item The \fnref{boot} command +\item The \fnref{browse} command +\item The \fnref{cd} command +\item The \fnref{clear} command +\item The \fnref{close} command +\item The \fnref{compiler} command +\item The \fnref{copyright} command +\item The \fnref{credits} command +\item The \fnref{display} command +\item The \fnref{edit} command +\item The \fnref{fin} command +\item The \fnref{frame} command +\item The \fnref{help} command +\item The \fnref{history} command +\item The \fnref{lisp} command +\item The \fnref{library} command +\item The \fnref{load} command +\item The \fnref{ltrace} command +\item The \fnref{pquit} command +\item The \fnref{quit} command +\item The \fnref{read} command +\item The \fnref{savesystem} command +\item The \fnref{set} command +\item The \fnref{show} command +\item The \fnref{spool} command +\item The \fnref{summary} command +\item The \fnref{synonym} command +\item The \fnref{system} command +\item The \fnref{trace} command +\item The \fnref{undo} command +\item The \fnref{what} command +\item The \fnref{with} command +\item The \fnref{workfiles} command +\item The \fnref{zsystemdevelopment} command +\end{itemize} + <>= (defvar |$systemCommands| nil) @@ -1082,8 +1073,802 @@ token in the string. If the string only 0 or more blanks it returns nil. (list (subseq x nonblank) ""))))) @ -\chapter{The Display Command} -\section{)display} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{abbreviations} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} compiler + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )abbreviation query \lanb{}{\it nameOrAbbrev}\ranb{}} +\item {\tt )abbreviation category {\it abbrev fullname} \lanb{})quiet\ranb{}} +\item {\tt )abbreviation domain {\it abbrev fullname} \lanb{})quiet\ranb{}} +\item {\tt )abbreviation package {\it abbrev fullname} \lanb{})quiet\ranb{}} +\item {\tt )abbreviation remove {\it nameOrAbbrev}} +\end{list} + +\par\noindent{\bf Command Description:} + +This command is used to query, set and remove abbreviations for category, +domain and package constructors. +Every constructor must have a unique abbreviation. +This abbreviation is part of the name of the subdirectory +under which the components of the compiled constructor are +stored. +%% BEGIN OBSOLETE +% It is this abbreviation that is used to bring compiled code into +% Axiom with the {\tt )load} command. +%% END OBSOLETE +Furthermore, by issuing this command you +let the system know what file to load automatically if you use a new +constructor. +Abbreviations must start with a letter and then be followed by +up to seven letters or digits. +Any letters appearing in the abbreviation must be in uppercase. + +When used with the {\tt query} argument, +\index{abbreviation query} +this command may be used to list the name +associated with a particular abbreviation or the abbreviation for a +constructor. +If no abbreviation or name is given, the names and corresponding +abbreviations for {\it all} constructors are listed. + +The following shows the abbreviation for the constructor {\tt List}: +\begin{verbatim} +)abbreviation query List +\end{verbatim} +The following shows the constructor name corresponding to the +abbreviation {\tt NNI}: +\begin{verbatim} +)abbreviation query NNI +\end{verbatim} +The following lists all constructor names and their abbreviations. +\begin{verbatim} +)abbreviation query +\end{verbatim} + +To add an abbreviation for a constructor, use this command with +{\tt category}, {\tt domain} or {\tt package}. +\index{abbreviation package} +\index{abbreviation domain} +\index{abbreviation category} +The following add abbreviations to the system for a +category, domain and package, respectively: +\begin{verbatim} +)abbreviation domain SET Set +)abbreviation category COMPCAT ComplexCategory +)abbreviation package LIST2MAP ListToMap +\end{verbatim} +If the {\tt )quiet} option is used, +no output is displayed from this command. +You would normally only define an abbreviation in a library source file. +If this command is issued for a constructor that has already been loaded, the +constructor will be reloaded next time it is referenced. In particular, you +can use this command to force the automatic reloading of constructors. + +To remove an abbreviation, the {\tt remove} argument is used. +\index{abbreviation remove} +This is usually +only used to correct a previous command that set an abbreviation for a +constructor name. +If, in fact, the abbreviation does exist, you are prompted +for confirmation of the removal request. +Either of the following commands +will remove the abbreviation {\tt VECTOR2} and the +constructor name {\tt VectorFunctions2} from the system: +\begin{verbatim} +)abbreviation remove VECTOR2 +)abbreviation remove VectorFunctions2 +\end{verbatim} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{boot} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} development + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )boot} {\it bootExpression} +\end{list} + +\par\noindent{\bf Command Description:} + +This command is used by Axiom system developers to execute +expressions written in the BOOT language. +For example, +\begin{verbatim} +)boot times3(x) == 3*x +\end{verbatim} +creates and compiles the Common Lisp function ``times3'' +obtained by translating the BOOT code. + +\par\noindent{\bf Also See:} +\fnref{fin}, +\fnref{lisp}, +\fnref{set}, and +\fnref{system} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{browse} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} development + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )browse} +\end{list} + +\par\noindent{\bf Command Description:} + +This command is used by Axiom system users to start the Axiom top +level loop listening for browser connections. + +\section{Overview} +The Axiom book on the help browser is a complete rewrite of the +hyperdoc mechanism. There are several components that were needed +to make this function. Most of the web browser components are +described in bookvol11.pamphlet. This portion describes some of +the design issues needed to support the interface. + +The axServer command takes a port (defaulting to 8085) and a +program to handle the browser interaction (defaulting to multiServ). +The axServer function opens the port, constructs the stream, and +passes the stream to multiServ. The multiServ loop processes one +interaction at a time. + +So the basic process is that the Axiom ``)browse'' command opens a +socket and listens for http requests. Based on the type of request +(either 'GET' or 'POST') and the content of the request, which is +one of: +\begin{itemize} +\item command - algebra request/response +\item lispcall - a lisp s-expression to be evaluated +\item showcall - an Axiom )show command +\end{itemize} +the multiServ function will call a handler function to evaluate +the command line and construct a response. GET requests result +in a new browser page. POST requests result in an inline result. + +Most responses contain the fields: +\begin{itemize} +\item stepnum - this is the Axiom step number +\item command - this is the original command from the browser +\item algebra - this is the Axiom 2D algebra output +\item mathml - this is the MathML version of the Axiom algebra +\item type - this is the type of the Axiom result +\end{itemize} + +\section{Browsers, MathML, and Fonts} +This work has the Firefox browser as its target. Firefox has built-in +support for MathML, javascript, and XMLHttpRequest handling. More details +are available in bookvol11.pamphlet but the very basic machinery for +communication with the browser involves a dance between the browser +and the multiServ function (see the axserver.spad.pamphlet). + +In particular, a simple request is embedded in a web page as: +\begin{verbatim} +
    +
  • + +
    +
  • +
+\end{verbatim} +which says that this is an html ``input'' field of type ``submit''. +The CSS display class is ``subbut'' which is of a different color +than the surrounding text to make it obvious that you can click on +this field. Clickable fields that have no response text are of class +``noresult''. + +The javascript call to ``makeRequest'' gives the ``id'' of this input +field, which must be unique in the page, as an argument. In this case, +the argument is 'p3'. The ``value'' field holds the display text which +will be passed back to Axiom as a command. + +When the result arrives the ``showanswer'' function will select out +the mathml field of the response, construct the ``id'' of the html +div to hold the response by concatenating the string ``ans'' (answer) +to the ``id'' of the request resulting, in this case, as ``ansp3''. +The ``showanswer'' function will find this div and replace it with a +div containing the mathml result. + +The ``makeRequest'' function is: +\begin{verbatim} + function makeRequest(arg) { + http_request = new XMLHttpRequest(); + var command = commandline(arg); + //alert(command); + http_request.open('POST', '127.0.0.1:8085', true); + http_request.onreadystatechange = handleResponse; + http_request.setRequestHeader('Content-Type', 'text/plain'); + http_request.send("command="+command); + return(false); +\end{verbatim} +It contains a request to open a local server connection to Axiom, +sets ``handleResponse'' as the function to call on reply, sets up +the type of request, fills in the command field, and sends off the +http request. + +When a response is received, the ``handleResponse'' function checks +for the correct reply state, strips out the important text, and +calls ``showanswer''. +\begin{verbatim} + function handleResponse() { + if (http_request.readyState == 4) { + if (http_request.status == 200) { + showanswer(http_request.responseText,'mathAns'); + } else + { + alert('There was a problem with the request.'+ http_request.statusText); + } + } + } +\end{verbatim} +See bookvol11.pamphlet for further details. + +\section{The axServer/multiServ loop} +The basic call to start an Axiom browser listener is: +\begin{verbatim} + )set message autoload off + )set output mathml on + axServer(8085,multiServ)$AXSERV +\end{verbatim} + +This call sets the port, opens a socket, attaches it to a stream, +and then calls ``multiServ'' with that stream. The ``multiServ'' +function loops serving web responses to that port. + +\section{The )browse command} +In order to make the whole process cleaner the function ``)browse'' +handles the details. This code creates the command-line function for )browse + +The browse function does the internal equivalent of the following 3 command +line statments: +\begin{verbatim} + )set message autoload off + )set output mathml on + axServer(8085,multiServ)$AXSERV +\end{verbatim} +which causes Axiom to start serving web pages on port 8085 + +For those unfamiliar with calling algebra from lisp there are a +few points to mention. + +The loadLib needs to be called to load the algebra code into the image. +Normally this is automatic but we are not using the interpreter so +we need to do this ``by hand''. + +Each algebra file contains a "constructor function" which builds the +domain, which is a vector, and then caches the vector so that every +call to the contructor returns an EQ vector, that is, the same vector. +In this case, we call the constructor $\vert$AxiomServer$\vert$ + +The axServer function was mangled internally to +$\vert$AXSERV;axServer;IMV;2$\vert$. +The multiServ function was mangled to $\vert$AXSERV;multiServ;SeV;3$\vert$ +Note well that if you change axserver.spad these names might change +which will generate the error message along the lines of: +\begin{verbatim} + System error: + The function $\vert$AXSERV;axServer;IMV;2$\vert$ is undefined. +\end{verbatim} + +To fix this you need to look at int/algebra/AXSERV.nrlib/code.lsp +and find the new mangled function name. A better solution would +be to dynamically look up the surface names in the domain vector. + +Each Axiom function expects the domain vector as the last argument. +This is not obvious from the call as the interpreter supplies it. +We must do that ``by hand''. + +We don't call the multiServ function. We pass it as a parameter to +the axServer function. When it does get called by the SPADCALL +macro it needs to be a lisp pair whose car is the function and +whose cdr is the domain vector. We construct that pair here as +the second argument to axServer. The third, hidden, argument to +axServer is the domain vector which we supply ``by hand''. + +The socket can be supplied on the command line but defaults to 8085. +Axiom supplies the arguments as a list. +<>= +(defun |browse| (socket) + (let (axserv browser) + (if socket + (setq socket (car socket)) + (setq socket 8085)) + (|set| '(|mes| |auto| |off|)) + (|set| '(|out| |mathml| |on|)) + (|loadLib| '|AxiomServer|) + (setq axserv (|AxiomServer|)) + (setq browser + (|AXSERV;axServer;IMV;2| socket + (cons #'|AXSERV;multiServ;SeV;3| axserv) axserv)))) + +@ +Now we have to bolt it into Axiom. This involves two lookups. + +We create the lisp pair +\begin{verbatim} + (|browse| . |development|) +\end{verbatim} +and cons it into the \$systemCommands command table. This allows the +command to be executed in development mode. This lookup decides if +this command is allowed. It also has the side-effect of putting the +command into the \$SYSCOMMANDS variable which is used to determine +if the token is a command. + +\section{The server support code} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{cd} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )cd} {\it directory} +\end{list} + +\par\noindent{\bf Command Description:} + +This command sets the Axiom working current directory. +The current directory is used for looking for +input files (for {\tt )read}), +Axiom library source files (for {\tt )compile}), +saved history environment files (for {\tt )history )restore}), +compiled Axiom library files (for {\tt )library}), and +files to edit (for {\tt )edit}). +It is also used for writing +spool files (via {\tt )spool}), +writing history input files (via {\tt )history )write}) and +history environment files (via {\tt )history )save}),and +compiled Axiom library files (via {\tt )compile}). +\index{read} +\index{compile} +\index{history )restore} +\index{edit} +\index{spool} +\index{history )write} +\index{history )save} + +If issued with no argument, this command sets the Axiom +current directory to your home directory. +If an argument is used, it must be a valid directory name. +Except for the ``{\tt )}'' at the beginning of the command, +this has the same syntax as the operating system {\tt cd} command. + +\par\noindent{\bf Also See:} +\fnref{compiler}, +\fnref{edit}, +\fnref{history}, +\fnref{library}, +\fnref{read}, and +\fnref{spool} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{clear} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )clear all} +\item{\tt )clear completely} +\item{\tt )clear properties all} +\item{\tt )clear properties} {\it obj1 \lanb{}obj2 ...\ranb{}} +\item{\tt )clear value all} +\item{\tt )clear value} {\it obj1 \lanb{}obj2 ...\ranb{}} +\item{\tt )clear mode all} +\item{\tt )clear mode} {\it obj1 \lanb{}obj2 ...\ranb{}} +\end{list} +\par\noindent{\bf Command Description:} + +This command is used to remove function and variable declarations, definitions +and values from the workspace. +To empty the entire workspace and reset the +step counter to 1, issue +\begin{verbatim} +)clear all +\end{verbatim} +To remove everything in the workspace but not reset the step counter, issue +\begin{verbatim} +)clear properties all +\end{verbatim} +To remove everything about the object {\tt x}, issue +\begin{verbatim} +)clear properties x +\end{verbatim} +To remove everything about the objects {\tt x, y} and {\tt f}, issue +\begin{verbatim} +)clear properties x y f +\end{verbatim} + +The word {\tt properties} may be abbreviated to the single letter +``{\tt p}''. +\begin{verbatim} +)clear p all +)clear p x +)clear p x y f +\end{verbatim} +All definitions of functions and values of variables may be removed by either +\begin{verbatim} +)clear value all +)clear v all +\end{verbatim} +This retains whatever declarations the objects had. To remove definitions and +values for the specific objects {\tt x, y} and {\tt f}, issue +\begin{verbatim} +)clear value x y f +)clear v x y f +\end{verbatim} +To remove the declarations of everything while leaving the definitions and +values, issue +\begin{verbatim} +)clear mode all +)clear m all +\end{verbatim} +To remove declarations for the specific objects {\tt x, y} and {\tt f}, issue +\begin{verbatim} +)clear mode x y f +)clear m x y f +\end{verbatim} +The {\tt )display names} and {\tt )display properties} commands may be used +to see what is currently in the workspace. + +The command +\begin{verbatim} +)clear completely +\end{verbatim} +does everything that {\tt )clear all} does, and also clears the internal +system function and constructor caches. + +\par\noindent{\bf Also See:} +\fnref{display}, +\fnref{history}, +\fnref{frame}, and +\fnref{undo} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{close} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{compiler} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} compiler + +\par\noindent{\bf Command Syntax:} + +\begin{list}{} +\item {\tt )compile} +\item {\tt )compile {\it fileName}} +\item {\tt )compile {\it fileName}.as} +\item {\tt )compile {\it directory/fileName}.as} +\item {\tt )compile {\it fileName}.ao} +\item {\tt )compile {\it directory/fileName}.ao} +\item {\tt )compile {\it fileName}.al} +\item {\tt )compile {\it directory/fileName}.al} +\item {\tt )compile {\it fileName}.lsp} +\item {\tt )compile {\it directory/fileName}.lsp} +\item {\tt )compile {\it fileName}.spad} +\item {\tt )compile {\it directory/fileName}.spad} +\item {\tt )compile {\it fileName} )new} +\item {\tt )compile {\it fileName} )old} +\item {\tt )compile {\it fileName} )translate} +\item {\tt )compile {\it fileName} )quiet} +\item {\tt )compile {\it fileName} )noquiet} +\item {\tt )compile {\it fileName} )moreargs} +\item {\tt )compile {\it fileName} )onlyargs} +\item {\tt )compile {\it fileName} )break} +\item {\tt )compile {\it fileName} )nobreak} +\item {\tt )compile {\it fileName} )library} +\item {\tt )compile {\it fileName} )nolibrary} +\item {\tt )compile {\it fileName} )vartrace} +\item {\tt )compile {\it fileName} )constructor} {\it nameOrAbbrev} +\end{list} + +\par\noindent{\bf Command Description:} + +You use this command to invoke the new Axiom library compiler or +the old Axiom system compiler. +The {\tt )compile} system command is actually a combination of +Axiom processing and a call to the Aldor compiler. +It is performing double-duty, acting as a front-end to +both the Aldor compiler and the old Axiom system +compiler. +(The old Axiom system compiler was written in Lisp and was +an integral part of the Axiom environment. +The Aldor compiler is written in C and executed by the operating system +when called from within Axiom.) + +This command compiles files with file extensions {\it .as, .ao} +and {\it .al} with the +Aldor compiler and files with file extension {\it .spad} with the +old Axiom system compiler. +It also can compile files with file extension {\it .lsp}. These +are assumed to be Lisp files genererated by the Aldor +compiler. +If you omit the file extension, the command looks to see if you +have specified the {\tt )new} or {\tt )old} option. +If you have given one of these options, the corresponding compiler +is used. +Otherwise, the command first looks in the standard system +directories for files with extension {\it .as, .ao} and {\it +.al} and then files with extension {\it .spad}. +The first file found has the appropriate compiler invoked on it. +If the command cannot find a matching file, an error message is +displayed and the command terminates. + +The {\tt )translate} option is used to invoke a special version +of the old system compiler that will translate a {\it .spad} file +to a {\it .as} file. That is, the {\it .spad} file will be parsed and +analyzed and a file using the new syntax will be created. By default, +the {\it .as} file is created in the same directory as the +{\it .spad} file. If that directory is not writable, the current +directory is used. If the current directory is not writable, an +error message is given and the command terminates. +Note that {\tt )translate} implies the {\tt )old} option so the +file extension can safely be omitted. If {\tt )translate} is +given, all other options are ignored. +Please be aware that the translation is not necessarily one +hundred percent complete or correct. +You should attempt to compile the output with the Aldor compiler +and make any necessary corrections. + +We now describe the options for the new Aldor compiler. + +The first thing {\tt )compile} does is look for a source code +filename among its arguments. +Thus +\begin{verbatim} +)compile mycode.as +)compile /u/jones/as/mycode.as +)compile mycode +\end{verbatim} +all invoke {\tt )compiler} on the file {\tt +/u/jones/as/mycode.as} if the current Axiom working +directory is {\tt /u/jones/as.} (Recall that you can set the +working directory via the {\tt )cd} command. If you don't set it +explicitly, it is the directory from which you started +Axiom.) + +This is frequently all you need to compile your file. +This simple command: +\begin{enumerate} +\item Invokes the Aldor compiler and produces Lisp output. +\item Calls the Lisp compiler if the Aldor compilation was +successful. +\item Uses the {\tt )library} command to tell Axiom about +the contents of your compiled file and arrange to have those +contents loaded on demand. +\end{enumerate} + +Should you not want the {\tt )library} command automatically +invoked, call {\tt )compile} with the {\tt )nolibrary} option. +For example, +\begin{verbatim} +)compile mycode.as )nolibrary +\end{verbatim} + +The general description of Aldor command line arguments is in +the Aldor documentation. +The default options used by the {\tt )compile} command can be +viewed and set using the {\tt )set compiler args} Axiom +system command. +The current defaults are +\begin{verbatim} +-O -Fasy -Fao -Flsp -laxiom -Mno-AXL_W_WillObsolete -DAxiom +\end{verbatim} +These options mean: +\begin{itemize} +\item {\tt -O}: perform all optimizations, +\item {\tt -Fasy}: generate a {\tt .asy} file, +\item {\tt -Fao}: generate a {\tt .ao} file, +\item {\tt -Flsp}: generate a {\tt .lsp} (Lisp) +file, +\index{Lisp!code generation} +\item {\tt -laxiom}: use the {\tt axiom} library {\tt libaxiom.al}, +\item {\tt -Mno-AXL\_W\_WillObsolete}: do not display messages +about older generated files becoming obsolete, and +\item {\tt -DAxiom}: define the global assertion {\tt Axiom} so that the +Aldor libraries for generating stand-alone code +are not accidentally used with Axiom. +\end{itemize} + +To supplement these default arguments, use the {\tt )moreargs} option on +{\tt )compile.} +For example, +\begin{verbatim} +)compile mycode.as )moreargs "-v" +\end{verbatim} +uses the default arguments and appends the {\tt -v} (verbose) +argument flag. +The additional argument specification {\bf must be enclosed in +double quotes.} + +To completely replace these default arguments for a particular +use of {\tt )compile}, use the {\tt )onlyargs} option. +For example, +\begin{verbatim} +)compile mycode.as )onlyargs "-v -O" +\end{verbatim} +only uses the {\tt -v} (verbose) and {\tt -O} (optimize) +arguments. +The argument specification {\bf must be enclosed in double quotes.} +In this example, Lisp code is not produced and so the compilation +output will not be available to Axiom. + +To completely replace the default arguments for all calls to {\tt +)compile} within your Axiom session, use {\tt )set compiler args.} +For example, to use the above arguments for all compilations, issue +\begin{verbatim} +)set compiler args "-v -O" +\end{verbatim} +Make sure you include the necessary {\tt -l} and {\tt -Y} +arguments along with those needed for Lisp file creation. +As above, {\bf the argument specification must be enclosed in double +quotes.} + +By default, the {\tt )library} system command {\it exposes} all +domains and categories it processes. +This means that the Axiom intepreter will consider those +domains and categories when it is trying to resolve a reference +to a function. +Sometimes domains and categories should not be exposed. +For example, a domain may just be used privately by another +domain and may not be meant for top-level use. +The {\tt )library} command should still be used, though, so that +the code will be loaded on demand. +In this case, you should use the {\tt )nolibrary} option on {\tt +)compile} and the {\tt )noexpose} option in the {\tt )library} +command. For example, +\begin{verbatim} +)compile mycode.as )nolibrary +)library mycode )noexpose +\end{verbatim} + +Once you have established your own collection of compiled code, +you may find it handy to use the {\tt )dir} option on the +{\tt )library} command. +This causes {\tt )library} to process all compiled code in the +specified directory. For example, +\begin{verbatim} +)library )dir /u/jones/as/quantum +\end{verbatim} +You must give an explicit directory after {\tt )dir}, even if you +want all compiled code in the current working directory +processed, e.g. +\begin{verbatim} +)library )dir . +\end{verbatim} + +The {\tt )compile} command works with several file extensions. We saw +above what happens when it is invoked on a file with extension {\tt +.as.} A {\tt .ao} file is a portable binary compiled version of a +{\tt .as} file, and {\tt )compile} simply passes the {\tt .ao} file +onto Aldor. The generated Lisp file is compiled and {\tt )library} +is automatically called, just as if you had specified a {\tt .as} file. + +A {\tt .al} file is an archive file containing {\tt .ao} files. The +archive is created (on Unix systems) with the {\tt ar} program. When +{\tt )compile} is given a {\tt .al} file, it creates a directory whose +name is based on that of the archive. For example, if you issue +\begin{verbatim} +)compile mylib.al +\end{verbatim} +the directory {\tt mylib.axldir} is created. All +members of the archive are unarchived into the +directory and {\tt )compile} is called on each {\tt .ao} file found. It +is your responsibility to remove the directory and its contents, if you +choose to do so. + +A {\tt .lsp} file is a Lisp source file, presumably, in our context, +generated by Aldor when called with the {\tt -Flsp} option. When +{\tt )compile} is used with a {\tt .lsp} file, the Lisp file is +compiled and {\tt )library} is called. You must also have present a +{\tt .asy} generated from the same source file. + +The following are descriptions of options for the old system compiler. + +You can compile category, domain, and package constructors +contained in files with file extension {\it .spad}. +You can compile individual constructors or every constructor +in a file. + +The full filename is remembered between invocations of this command and +{\tt )edit} commands. +The sequence of commands +\begin{verbatim} +)compile matrix.spad +)edit +)compile +\end{verbatim} +will call the compiler, edit, and then call the compiler again +on the file {\bf matrix.spad.} +If you do not specify a {\it directory,} the working current +directory is searched for the file. +If the file is not found, the standard system directories are searched. + +If you do not give any options, all constructors within a file are +compiled. +Each constructor should have an {\tt )abbreviation} command in +the file in which it is defined. +We suggest that you place the {\tt )abbreviation} commands at the +top of the file in the order in which the constructors are +defined. +The list of commands serves as a table of contents for the file. +\index{abbreviation} + +The {\tt )library} option causes directories containing the +compiled code for each constructor +to be created in the working current directory. +The name of such a directory consists of the constructor +abbreviation and the {\bf .nrlib} file extension. +For example, the directory containing the compiled code for +the {\tt MATRIX} constructor is called {\bf MATRIX.nrlib.} +The {\tt )nolibrary} option says that such files should not +be created. +The default is {\tt )library.} +Note that the semantics of {\tt )library} and {\tt )nolibrary} +for the new Aldor compiler and for the old system compiler are +completely different. + +The {\tt )vartrace} option causes the compiler to generate +extra code for the constructor to support conditional tracing of +variable assignments. Without +this option, this code is suppressed and one cannot use +the {\tt )vars} option for the trace command. + +The {\tt )constructor} option is used to +specify a particular constructor to compile. +All other constructors in the file are ignored. +The constructor name or abbreviation follows {\tt )constructor.} +Thus either +\begin{verbatim} +)compile matrix.spad )constructor RectangularMatrix +\end{verbatim} +or +\begin{verbatim} +)compile matrix.spad )constructor RMATRIX +\end{verbatim} +compiles the {\tt RectangularMatrix} constructor +defined in {\bf matrix.spad.} + +The {\tt )break} and {\tt )nobreak} options determine what +the old system compiler does when it encounters an error. +{\tt )break} is the default and it indicates that processing +should stop at the first error. +The value of the {\tt )set break} variable then controls what happens. + +\par\noindent{\bf Also See:} +{\tt )abbreviations}, +{\tt )edit}, and +{\tt )library} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{copyright} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{credits} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{display} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \begin{verbatim} )display abbreviations )display abbreviations [obj] @@ -1126,7 +1911,6 @@ The command \end{verbatim} will show all of the macros in the current workspace. - The command \begin{verbatim} )display names @@ -1321,10 +2105,15 @@ displayed. If the answer is either Y or YES we return true else nil. (cond ((|member| macro pmacs) (cond - (first (|sayBrightly| (cons '|%l| (cons "User-defined macros:" nil))) (setq first nil))) + (first (|sayBrightly| + (cons '|%l| (cons "User-defined macros:" nil))) (setq first nil))) (|displayParserMacro| macro)) ((|member| macro imacs) '|iterate|) - (t (|sayBrightly| (cons " " (cons '|%b| (cons macro (cons '|%d| (cons " is not a known Axiom macro." nil))))))))))) + (t (|sayBrightly| + (cons " " + (cons '|%b| + (cons macro + (cons '|%d| (cons " is not a known Axiom macro." nil))))))))))) (setq first t) (do ((t1 macros (cdr t1)) (macro nil)) ((or (atom t1) (progn (setq macro (car t1)) nil)) nil) @@ -1432,10 +2221,12 @@ next brace but the problem does not arise in practice. (defun cleanupLine (line) (do ((mark (search "{}" line) (search "{}" line))) ((null mark)) - (setq line (concatenate 'string (subseq line 0 mark) (subseq line (+ mark 2))))) + (setq line + (concatenate 'string (subseq line 0 mark) (subseq line (+ mark 2))))) (do ((mark (search "\\" line) (search "\\" line))) ((null mark)) - (setq line (concatenate 'string (subseq line 0 mark) (subseq line (+ mark 1))))) + (setq line + (concatenate 'string (subseq line 0 mark) (subseq line (+ mark 1))))) (do ((mark (search "spad{" line) (search "spad{" line))) ((null mark)) (let (left point mid right) @@ -1448,12 +2239,1015 @@ next brace but the problem does not arise in practice. @ -\chapter{The History Mechanism} -\section{)history} -\index{ugSysCmdhistory} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{edit} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )edit} \lanb{}{\it filename}\ranb{} +\end{list} +\par\noindent{\bf Command Description:} + +This command is used to edit files. +It works in conjunction with the {\tt )read} +and {\tt )compile} commands to remember the name +of the file on which you are working. +By specifying the name fully, you can edit any file you wish. +Thus +\begin{verbatim} +)edit /u/julius/matrix.input +\end{verbatim} +will place you in an editor looking at the file +{\tt /u/julius/matrix.input}. +\index{editing files} +By default, the editor is {\tt vi}, +\index{vi} +but if you have an EDITOR shell environment variable defined, that editor +will be used. +When Axiom is running under the X Window System, +it will try to open a separate {\tt xterm} running your editor if +it thinks one is necessary. +\index{Korn shell} +For example, under the Korn shell, if you issue +\begin{verbatim} +export EDITOR=emacs +\end{verbatim} +then the emacs +\index{emacs} +editor will be used by {\tt )edit}. + +If you do not specify a file name, the last file you edited, +read or compiled will be used. +If there is no ``last file'' you will be placed in the editor editing +an empty unnamed file. + +It is possible to use the {\tt )system} command to edit a file directly. +For example, +\begin{verbatim} +)system emacs /etc/rc.tcpip +\end{verbatim} +calls {\tt emacs} to edit the file. +\index{emacs} + +\par\noindent{\bf Also See:} +\fnref{system}, +\fnref{compiler}, and +\fnref{read} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{fin} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} development + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )fin} +\end{list} +\par\noindent{\bf Command Description:} + +This command is used by Axiom +developers to leave the Axiom system and return +to the underlying Common Lisp system. +To return to Axiom, issue the +``{\tt (\vertline{}spad\vertline{})}'' +function call to Common Lisp. + +\par\noindent{\bf Also See:} +\fnref{pquit} and +\fnref{quit} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{frame} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )frame new {\it frameName}} +\item{\tt )frame drop {\it [frameName]}} +\item{\tt )frame next} +\item{\tt )frame last} +\item{\tt )frame names} +\item{\tt )frame import {\it frameName} {\it [objectName1 [objectName2 ...]]}} +\item{\tt )set message frame on | off} +\item{\tt )set message prompt frame} +\end{list} + +\par\noindent{\bf Command Description:} + +A {\it frame} can be thought of as a logical session within the +physical session that you get when you start the system. You can +have as many frames as you want, within the limits of your computer's +storage, paging space, and so on. +Each frame has its own {\it step number}, {\it environment} and {\it history.} +You can have a variable named {\tt a} in one frame and it will +have nothing to do with anything that might be called {\tt a} in +any other frame. + +Some frames are created by the HyperDoc program and these can +have pretty strange names, since they are generated automatically. +\index{frame names} +To find out the names +of all frames, issue +\begin{verbatim} +)frame names +\end{verbatim} +It will indicate the name of the current frame. + +You create a new frame +\index{frame new} +``{\bf quark}'' by issuing +\begin{verbatim} +)frame new quark +\end{verbatim} +The history facility can be turned on by issuing either +{\tt )set history on} or {\tt )history )on}. +If the history facility is on and you are saving history information +in a file rather than in the Axiom environment +then a history file with filename {\bf quark.axh} will +be created as you enter commands. +If you wish to go back to what +you were doing in the +\index{frame next} +``{\bf initial}'' frame, use +\index{frame last} +\begin{verbatim} +)frame next +\end{verbatim} +or +\begin{verbatim} +)frame last +\end{verbatim} +to cycle through the ring of available frames to get back to +``{\bf initial}''. + +If you want to throw +away a frame (say ``{\bf quark}''), issue +\begin{verbatim} +)frame drop quark +\end{verbatim} +If you omit the name, the current frame is dropped. +\index{frame drop} + +If you do use frames with the history facility on and writing to a file, +you may want to delete some of the older history files. +\index{file!history} +These are directories, so you may want to issue a command like +{\tt rm -r quark.axh} to the operating system. + +You can bring things from another frame by using +\index{frame import} +{\tt )frame import}. +For example, to bring the {\tt f} and {\tt g} from the frame ``{\bf quark}'' +to the current frame, issue +\begin{verbatim} +)frame import quark f g +\end{verbatim} +If you want everything from the frame ``{\bf quark}'', issue +\begin{verbatim} +)frame import quark +\end{verbatim} +You will be asked to verify that you really want everything. + +There are two {\tt )set} flags +\index{set message frame} +to make it easier to tell where you are. +\begin{verbatim} +)set message frame on | off +\end{verbatim} +will print more messages about frames when it is set on. +By default, it is off. +\begin{verbatim} +)set message prompt frame +\end{verbatim} +will give a prompt +\index{set message prompt frame} +that looks like +\begin{verbatim} +initial (1) -> +\end{verbatim} +\index{prompt!with frame name} +when you start up. In this case, the frame name and step make up the +prompt. + +\par\noindent{\bf Also See:} +\fnref{history} and +\fnref{set} + +\section{Variables Used} +The frame mechanism uses several dollar variables. +\subsection{Primary variables} +Primary variables are those which exist solely to make the frame +mechanism work. + +The \$interpreterFrameName contains a symbol which is the name +of the current frame in use. + +The \$interpreterFrameRing contains a list of all of the existing +frames. The first frame on the list is the ``current'' frame. When +AXIOMsys is started directly there is only one frame named ``initial''. + +If the system is started under sman (using the axiom shell script, +for example), there are two frames, ``initial'' and ``frame0''. In +this case, ``frame0'' is the current frame. This can cause subtle +problems because functions defined in the axiom initialization file +(.axiom.input) will be defined in frame ``initial'' but the current +frame will be ``frame0''. They will appear to be undefined. However, +if the user does ``)frame next'' they can switch to the ``initial'' +frame and see the functions correctly defined. + +The \$frameMessages variable controls when frame messages will be +displayed. The variable is initially NIL. It can be set on (T) or off (NIL) +using the system command: +\begin{verbatim} + )set message frame on | off +\end{verbatim} +Setting frame messages on will output a line detailing the +current frame after every output is complete. + +\subsection{Used variables} + +The frame collects and uses a few top level variables. These are: +\$InteractiveFrame, \$IOindex, \$HiFiAccess, \$HistList, \$HistListLen, +\$HistListAct, \$HistRecord, \$internalHistoryTable, and \$localExposureData. + +These variables can also be changed by the frame mechanism when the user +requests changing to a different frame. + +\section{Data Structures} +\subsection{Frames and the Interpreter Frame Ring} + +Axiom has the notion of ``frames''. A frame is a data structure which +holds all the vital data from an Axiom session. There can be multiple +frames and these live in a top-level variable called +\$interpreterFrameRing. This variable holds a circular list of frames. +The parts of a frame and their initial, default values are: + +\begin{verbatim} + $interpreterFrameName a string, named on creation + $InteractiveFrame (list (list nil)) + $IOindex an integer, 1 + $HiFiAccess $HiFiAccess, see the variable description + $HistList $HistList, see the variable description + $HistListLen $HistListLen, see the variable description + $HistListAct $HistListAct, see the variable description + $HistRecord $HistRecord, see the variable description + $internalHistoryTable nil + $localExposureData a copy of $localExposureData +\end{verbatim} + +\section{Accessor Functions} +These could be macros but we wish to export them to the API code +in the algebra so we keep them as functions. +\subsection{0th Frame Component -- frameName} +\subsection{defun frameName} +<>= +(defun frameName (frame) + (car frame)) + +@ +\subsection{1st Frame Component -- frameInteractive} +<>= +(defun frameInteractive (frame) + (nth 1 frame)) + +@ +\subsection{2nd Frame Component -- frameIOIndex} +<>= +(defun frameIOIndex (frame) + (nth 2 frame)) + +@ +\subsection{3rd Frame Component -- frameHiFiAccess} +<>= +(defun frameHiFiAccess (frame) + (nth 3 frame)) + +@ +\subsection{4th Frame Component -- frameHistList} +<>= +(defun frameHistList (frame) + (nth 4 frame)) + +@ +\subsection{5th Frame Component -- frameHistListLen} +<>= +(defun frameHistListLen (frame) + (nth 5 frame)) + +@ +\subsection{6th Frame Component -- frameHistListAct} +<>= +(defun frameHistListAct (frame) + (nth 6 frame)) + +@ +\subsection{7th Frame Component -- frameHistRecord} +<>= +(defun frameHistRecord (frame) + (nth 7 frame)) + +@ +\subsection{8th Frame Component -- frameHistoryTable} +<>= +(defun frameHistoryTable (frame) + (nth 8 frame)) + +@ +\subsection{9th Frame Component -- frameExposureData} +<>= +(defun frameExposureData (frame) + (nth 9 frame)) + +@ + +\section{Variables Used} +\section{Data Structures} +\section{Functions} +\subsection{Initializing the Interpreter Frame Ring} + +Now that we know what a frame looks like we need a function to +initialize the list of frames. This function sets the initial frame +name to ``initial'' and creates a list of frames containing an empty +frame. This list is the interpreter frame ring and is not actually +circular but is managed as a circular list. + +As a final step we update the world from this frame. This has the +side-effect of resetting all the important global variables to their +initial values. + +<>= +(defun |initializeInterpreterFrameRing| () + (setq |$interpreterFrameName| '|initial|) + (setq |$interpreterFrameRing| + (list (|emptyInterpreterFrame| |$interpreterFrameName|))) + (|updateFromCurrentInterpreterFrame|) + nil) + +@ +\subsection{Creating a List of all of the Frame Names} +\subsection{defun frameNames} +This function simply walks across the frame in the frame ring and +returns a list of the name of each frame. +<>= +(defun |frameNames| () + (mapcar #'frameName |$interpreterFrameRing|)) + +@ -\index{history} +\subsection{Get Named Frame Environment (aka Interactive)} +If the frame is found we return the environment portion of the frame +otherwise we construct an empty environment and return it. +The initial values of an empty frame are created here. This function +returns a single frame that will be placed in the frame ring. +\subsection{defun frameEnvironment} +<>= +(defun |frameEnvironment| (fname) + (let ((frame (|findFrameInRing| fname))) + (if frame + (frameInteractive frame) + (list (list nil))))) + +@ +\subsection{defun emptyInterpreterFrame} +\begin{verbatim} +emptyInterpreterFrame(name) == + LIST(name, -- frame name + LIST LIST NIL, -- environment + 1, -- $IOindex + $HiFiAccess, -- $HiFiAccess + $HistList, -- $HistList + $HistListLen, -- $HistListLen + $HistListAct, -- $HistListAct + $HistRecord, -- $HistRecord + NIL, -- $internalHistoryTable + COPY_-SEQ $localExposureDataDefault -- $localExposureData + ) +\end{verbatim} +<>= +(defun |emptyInterpreterFrame| (name) + (list name + (list (list nil)) + 1 + |$HiFiAccess| + |$HistList| + |$HistListLen| + |$HistListAct| + |$HistRecord| + nil + (copy-seq |$localExposureDataDefault|))) +@ +\subsection{Collecting up the Environment into a Frame} + +We can collect up all the current environment information into +one frame element with this call. It creates a list of the current +values of the global variables and returns this as a frame element. + +\subsection{defun createCurrentInterpreterFrame} +<>= +(defun |createCurrentInterpreterFrame| () + (list + |$interpreterFrameName| + |$InteractiveFrame| + |$IOindex| + |$HiFiAccess| + |$HistList| + |$HistListLen| + |$HistListAct| + |$HistRecord| + |$internalHistoryTable| + |$localExposureData|)) + +@ +\subsection{Updating from the Current Frame} + +The frames are kept on a circular list. The first element on that +list is known as ``the current frame''. This will initialize all +of the interesting interpreter data structures from that frame. + +\subsection{defun updateFromCurrentInterpreterFrame} +\begin{verbatim} +updateFromCurrentInterpreterFrame() == + [$interpreterFrameName, _ + $InteractiveFrame, _ + $IOindex, _ + $HiFiAccess, _ + $HistList, _ + $HistListLen, _ + $HistListAct, _ + $HistRecord, _ + $internalHistoryTable, _ + $localExposureData _ + ] := first $interpreterFrameRing + if $frameMessages then + sayMessage ['" Current interpreter frame is called",:bright + $interpreterFrameName] + NIL +\end{verbatim} +<>= +(defun |updateFromCurrentInterpreterFrame| () + (let (tmp1) + (setq tmp1 (first |$interpreterFrameRing|)) + (setq |$interpreterFrameName| (nth 0 tmp1)) + (setq |$InteractiveFrame| (nth 1 tmp1)) + (setq |$IOindex| (nth 2 tmp1)) + (setq |$HiFiAccess| (nth 3 tmp1)) + (setq |$HistList| (nth 4 tmp1)) + (setq |$HistListLen| (nth 5 tmp1)) + (setq |$HistListAct| (nth 6 tmp1)) + (setq |$HistRecord| (nth 7 tmp1)) + (setq |$internalHistoryTable| (nth 8 tmp1)) + (setq |$localExposureData| (nth 9 tmp1)) + (when |$frameMessages| + (|sayMessage| + (cons " Current interpreter frame is called" |$interpreterFrameName|))))) + +@ +\subsection{Find a Frame in the Frame Ring by Name} +Each frame contains its name as the 0th element. We simply walk all +the frames and if we find one we return it. +\subsection{defun findFrameInRing} +\begin{verbatim} +findFrameInRing(name) == + val := NIL + for frame in $interpreterFrameRing repeat + CAR frame = name => + val := frame + return frame + val +\end{verbatim} +<>= +(defun |findFrameInRing| (name) + (block () + (dolist (frame |$interpreterFrameRing|) + (when (boot-equal (frameName frame) name) (return frame))))) + +@ +\subsection{Update the Current Interpreter Frame} + +This function collects the normal contents of the world into a +frame object, places it first on the frame list, and then sets +the current values of the world from the frame object. + +\subsection{defun updateCurrentInterpreterFrame} +\begin{verbatim} +updateCurrentInterpreterFrame() == + RPLACA($interpreterFrameRing,createCurrentInterpreterFrame()) + updateFromCurrentInterpreterFrame() + NIL +\end{verbatim} +<>= +(defun |updateCurrentInterpreterFrame| () + (rplaca |$interpreterFrameRing| (|createCurrentInterpreterFrame|)) + (|updateFromCurrentInterpreterFrame|) + nil) + +@ +\subsection{defun nextInterpreterFrame} + +This function updates the current frame to make sure all of the +current information is recorded. If there are more frame elements +in the list then this will destructively move the current frame +to the end of the list, that is, assume the frame list reads (1 2 3) +this function will destructively change it to (2 3 1). + +Note: the nconc2 function destructively inserts the second list at the +end of the first. +\begin{verbatim} +nextInterpreterFrame() == + updateCurrentInterpreterFrame() + null rest $interpreterFrameRing => NIL -- nothing to do + $interpreterFrameRing := + NCONC2(rest $interpreterFrameRing,[first $interpreterFrameRing]) + updateFromCurrentInterpreterFrame() +\end{verbatim} +<>= +(defun |nextInterpreterFrame| () + (when (cdr |$interpreterFrameRing|) + (setq |$interpreterFrameRing| + (nconc2 (cdr |$interpreterFrameRing|) + (list (car |$interpreterFrameRing|)))) + (|updateFromCurrentInterpreterFrame|))) + +@ +\subsection{defun changeToNamedInterpreterFrame} +\begin{verbatim} +changeToNamedInterpreterFrame(name) == + updateCurrentInterpreterFrame() + frame := findFrameInRing(name) + null frame => NIL + $interpreterFrameRing := [frame,:NREMOVE($interpreterFrameRing, frame)] + updateFromCurrentInterpreterFrame() +\end{verbatim} +<>= +(defun |changeToNamedInterpreterFrame| (name) + (prog (frame) + (return + (progn + (|updateCurrentInterpreterFrame|) + (spadlet frame (|findFrameInRing| name)) + (cond + ((null frame) + nil) + (t + (spadlet |$interpreterFrameRing| + (cons frame (nremove |$interpreterFrameRing| frame))) + (|updateFromCurrentInterpreterFrame|))))))) + +@ +\subsection{defun previousInterpreterFrame} +\begin{verbatim} +previousInterpreterFrame() == + updateCurrentInterpreterFrame() + null rest $interpreterFrameRing => NIL -- nothing to do + [:b,l] := $interpreterFrameRing + $interpreterFrameRing := NCONC2([l],b) + updateFromCurrentInterpreterFrame() +\end{verbatim} +<>= +(defun |previousInterpreterFrame| () + (prog (tmp1 l b) + (return + (progn + (|updateCurrentInterpreterFrame|) + (cond + ((null (cdr |$interpreterFrameRing|)) + nil) + (t + (spadlet tmp1 (reverse |$interpreterFrameRing|)) + (spadlet l (car tmp1)) + (spadlet b (nreverse (cdr tmp1))) + (spadlet |$interpreterFrameRing| (nconc2 (cons l nil) b)) + (|updateFromCurrentInterpreterFrame|))))))) + +@ +\subsection{defun addNewInterpreterFrame} +\begin{verbatim} +addNewInterpreterFrame(name) == + null name => throwKeyedMsg("S2IZ0018",NIL) + updateCurrentInterpreterFrame() + -- see if we already have one by that name + for f in $interpreterFrameRing repeat + name = frameName(f) => throwKeyedMsg("S2IZ0019",[name]) + initHistList() + $interpreterFrameRing := CONS(emptyInterpreterFrame(name), + $interpreterFrameRing) + updateFromCurrentInterpreterFrame() + _$ERASE histFileName() +\end{verbatim} +<>= +(defun |addNewInterpreterFrame| (name) + (seq + (cond + ((null name) + (|throwKeyedMsg| 'S2IZ0018 nil)) ; you must provide a name for new frame + (t + (|updateCurrentInterpreterFrame|) + (seq + (do ((tmp0 |$interpreterFrameRing| (cdr tmp0)) (f nil)) + ((or (atom tmp0) + (progn (setq f (car tmp0)) nil)) + nil) + (seq + (exit + (when (boot-equal name (frameName f)) + (exit + (|throwKeyedMsg| 'S2IZ0019 ; existing frame with same name + (cons name nil))))))) + (|initHistList|) + (spadlet |$interpreterFrameRing| + (cons (|emptyInterpreterFrame| name) |$interpreterFrameRing|)) + (|updateFromCurrentInterpreterFrame|) + ($erase (|histFileName|))))))) + +@ +\subsection{defun closeInterpreterFrame} +\begin{verbatim} +closeInterpreterFrame(name) == + -- if name = NIL then it means the current frame + null rest $interpreterFrameRing => + name and (name ^= $interpreterFrameName) => + throwKeyedMsg("S2IZ0020",[$interpreterFrameName]) + throwKeyedMsg("S2IZ0021",NIL) + if null name then $interpreterFrameRing := rest $interpreterFrameRing + else -- find the frame + found := nil + ifr := NIL + for f in $interpreterFrameRing repeat + found or (name ^= frameName(f)) => ifr := CONS(f,ifr) + found := true + not found => throwKeyedMsg("S2IZ0022",[name]) + _$ERASE makeHistFileName(name) + $interpreterFrameRing := nreverse ifr + updateFromCurrentInterpreterFrame() +\end{verbatim} +<>= +(defun |closeInterpreterFrame| (name) + (prog (ifr found) + (return + (seq + (cond + ((null (cdr |$interpreterFrameRing|)) + (cond + ((and name (nequal name |$interpreterFrameName|)) + (|throwKeyedMsg| 'S2IZ0020 ; 1 frame left. not the correct name. + (cons |$interpreterFrameName| nil))) + (t (|throwKeyedMsg| 'S2IZ0021 nil)))) ; only 1 frame left, not closed + (t + (cond + ((null name) + (spadlet |$interpreterFrameRing| (cdr |$interpreterFrameRing|))) + (t + (spadlet found nil) + (spadlet ifr nil) + (do ((tmp0 |$interpreterFrameRing| (cdr tmp0)) (f nil)) + ((or (atom tmp0) (progn (setq f (car tmp0)) nil)) nil) + (seq + (exit + (cond + ((or found (nequal name (frameName f))) + (spadlet ifr (cons f ifr))) + (t + (spadlet found t)))))) + (cond + ((null found) + (|throwKeyedMsg| 'S2IZ0022 (cons name nil))) + (t + ($erase (|makeHistFileName| name)) + (spadlet |$interpreterFrameRing| (nreverse ifr)))))) + (|updateFromCurrentInterpreterFrame|))))))) + +@ +\subsection{defun displayFrameNames} +\begin{verbatim} +displayFrameNames() == + fs := "append"/[ ['%l,'" ",:bright frameName f] for f in + $interpreterFrameRing] + sayKeyedMsg("S2IZ0024",[fs]) +\end{verbatim} +<>= +(defun |displayFrameNames| () + (prog (fs) + (return + (seq + (progn + (spadlet fs + (prog (tmp0) + (spadlet tmp0 NIL) + (return + (do ((tmp1 |$interpreterFrameRing| (cdr tmp1)) (f nil)) + ((or (atom tmp1) + (progn (setq f (car tmp1)) nil)) + tmp0) + (seq + (exit + (setq tmp0 + (append tmp0 (cons '|%l| + (cons (makestring " ") (|bright| (frameName f)))))))))))) + (|sayKeyedMsg| 'S2IZ0024 (cons fs nil))))))) ; frame names are ... + +@ +\subsection{defun importFromFrame} +\begin{verbatim} +importFromFrame args == + -- args should have the form [frameName,:varNames] + if args and atom args then args := [args] + null args => throwKeyedMsg("S2IZ0073",NIL) + [fname,:args] := args + not member(fname,frameNames()) => + throwKeyedMsg("S2IZ0074",[fname]) + fname = frameName first $interpreterFrameRing => + throwKeyedMsg("S2IZ0075",NIL) + fenv := frameEnvironment fname + null args => + x := UPCASE queryUserKeyedMsg("S2IZ0076",[fname]) + MEMQ(STRING2ID_-N(x,1),'(Y YES)) => + vars := NIL + for [v,:props] in CAAR fenv repeat + v = "--macros" => + for [m,:.] in props repeat vars := cons(m,vars) + vars := cons(v,vars) + importFromFrame [fname,:vars] + sayKeyedMsg("S2IZ0077",[fname]) + for v in args repeat + plist := GETALIST(CAAR fenv,v) + plist => + -- remove anything with the same name in the current frame + clearCmdParts ['propert,v] + for [prop,:val] in plist repeat + putHist(v,prop,val,$InteractiveFrame) + (m := get("--macros--",v,fenv)) => + putHist("--macros--",v,m,$InteractiveFrame) + sayKeyedMsg("S2IZ0079",[v,fname]) + sayKeyedMsg("S2IZ0078",[fname]) +\end{verbatim} +<>= +(defun |importFromFrame| (args) + (prog (temp1 fname fenv x v props vars plist prop val m) + (return + (seq + (progn + (when (and args (atom args)) + (spadlet args (cons args nil))) + (cond + ((null args) + (|throwKeyedMsg| 'S2IZ0073 nil)) ; missing frame name + (t + (spadlet temp1 args) + (spadlet fname (car temp1)) + (spadlet args (cdr temp1)) + (cond + ((null (|member| fname (|frameNames|))) + (|throwKeyedMsg| 'S2IZ0074 (cons fname nil))) ; not frame name + ((boot-equal fname (frameName (car |$interpreterFrameRing|))) + (|throwKeyedMsg| 'S2IZ0075 NIL)) ; cannot import from curr frame + (t + (spadlet fenv (|frameEnvironment| fname)) + (cond + ((null args) + (spadlet x + (upcase (|queryUserKeyedMsg| 'S2IZ0076 (cons fname nil)))) + ; import everything? + (cond + ((memq (string2id-n x 1) '(y yes)) + (spadlet vars nil) + (do ((tmp0 (caar fenv) (cdr tmp0)) (tmp1 nil)) + ((or (atom tmp0) + (progn (setq tmp1 (car tmp0)) nil) + (progn + (progn + (spadlet v (car tmp1)) + (spadlet props (cdr tmp1)) + tmp1) + nil)) + nil) + (seq + (exit + (cond + ((boot-equal v '|--macros|) + (do ((tmp2 props (cdr tmp2)) + (tmp3 nil)) + ((or (atom tmp2) + (progn (setq tmp3 (car tmp2)) nil) + (progn + (progn (spadlet m (car tmp3)) tmp3) + nil)) + nil) + (seq + (exit + (spadlet vars (cons m vars)))))) + (t (spadlet vars (cons v vars))))))) + (|importFromFrame| (cons fname vars))) + (t + (|sayKeyedMsg| 'S2IZ0077 (cons fname nil))))) + (t + (do ((tmp4 args (cdr tmp4)) (v nil)) + ((or (atom tmp4) (progn (setq v (car tmp4)) nil)) nil) + (seq + (exit + (progn + (spadlet plist (getalist (caar fenv) v)) + (cond + (plist + (|clearCmdParts| (cons '|propert| (cons v nil))) + (do ((tmp5 plist (cdr tmp5)) (tmp6 nil)) + ((or (atom tmp5) + (progn (setq tmp6 (car tmp5)) nil) + (progn + (progn + (spadlet prop (car tmp6)) + (spadlet val (cdr tmp6)) + tmp6) + nil)) + nil) + (seq + (exit (|putHist| v prop val |$InteractiveFrame|))))) + ((spadlet m (|get| '|--macros--| v fenv)) + (|putHist| '|--macros--| v m |$InteractiveFrame|)) + (t + (|sayKeyedMsg| 'S2IZ0079 ; frame not found + (cons v (cons fname nil))))))))) + (|sayKeyedMsg| 'S2IZ0078 ; import complete + (cons fname nil))))))))))))) + +@ +\subsection{defun frame} +\begin{verbatim} +-- the system command + +frame l == frameSpad2Cmd l +\end{verbatim} +<>= +(defun |frame| (l) + (|frameSpad2Cmd| l)) + +@ +\subsection{defun frameSpad2Cmd} +\begin{verbatim} +frameSpad2Cmd args == + frameArgs := '(drop import last names new next) + $options => throwKeyedMsg("S2IZ0016",['")frame"]) + null(args) => helpSpad2Cmd ['frame] + arg := selectOptionLC(first args,frameArgs,'optionError) + args := rest args + if args is [a] then args := a + if ATOM args then args := object2Identifier args + arg = 'drop => + args and PAIRP(args) => throwKeyedMsg("S2IZ0017",[args]) + closeInterpreterFrame(args) + arg = 'import => importFromFrame args + arg = 'last => previousInterpreterFrame() + arg = 'names => displayFrameNames() + arg = 'new => + args and PAIRP(args) => throwKeyedMsg("S2IZ0017",[args]) + addNewInterpreterFrame(args) + arg = 'next => nextInterpreterFrame() + + NIL +\end{verbatim} +<>= +(defun |frameSpad2Cmd| (args) + (prog (frameArgs arg a) + (return + (progn + (spadlet frameArgs '(|drop| |import| |last| |names| |new| |next|)) + (cond + (|$options| + (|throwKeyedMsg| 'S2IZ0016 ; frame command does not take options + (cons (makestring ")frame") nil))) + ((null args) + (|helpSpad2Cmd| (cons '|frame| nil))) + (t + (spadlet arg + (|selectOptionLC| (car args) frameArgs '|optionError|)) + (spadlet args (cdr args)) + (cond + ((and (pairp args) + (eq (qcdr args) nil) + (progn (spadlet a (qcar args)) t)) + (spadlet args a))) + (when (atom args) + (spadlet args (|object2Identifier| args))) + (cond + ((boot-equal arg '|drop|) + (cond + ((and args (pairp args)) + (|throwKeyedMsg| 'S2IZ0017 ; not a valid frame name + (cons args nil))) + (t (|closeInterpreterFrame| args)))) + ((boot-equal arg '|import|) + (|importFromFrame| args)) + ((boot-equal arg '|last|) + (|previousInterpreterFrame|)) + ((boot-equal arg '|names|) + (|displayFrameNames|)) + ((boot-equal arg '|new|) + (cond + ((and args (pairp args)) + (|throwKeyedMsg| 'S2IZ0017 ; not a valid frame name + (cons args nil))) + (t + (|addNewInterpreterFrame| args)))) + ((boot-equal arg '|next|) + (|nextInterpreterFrame|)) + (t nil)))))))) + +@ +\section{Frame File Messages} +<>= +S2IZ0016 + The %1b system command takes arguments but no options. +S2IZ0017 + %1b is not a valid frame name +S2IZ0018 + You must provide a name for the new frame. +S2IZ0019 + You cannot use the name %1b for a new frame because an existing + frame already has that name. +S2IZ0020 + There is only one frame active and therefore that cannot be closed. + Furthermore, the frame name you gave is not the name of the current frame. + The current frame is called %1b . +S2IZ0021 + The current frame is the only active one. Issue %b )clear all %d to + clear its contents. +S2IZ0022 + There is no frame called %1b and so your command cannot be + processed. +S2IZ0024 + The names of the existing frames are: %1 %l + The current frame is the first one listed. +S2IZ0073 + %b )frame import %d must be followed by the frame name. The names + of objects in that frame can then optionally follow the frame name. + For example, + %ceon %b )frame import calculus %d %ceoff + imports all objects in the %b calculus %d frame, and + %ceon %b )frame import calculus epsilon delta %d %ceoff + imports the objects named %b epsilon %d and %b delta %d from the + frame %b calculus %d . + Please note that if the current frame contained any information + about objects with these names, then that information would be + cleared before the import took place. +S2IZ0074 + You cannot import anything from the frame %1b because that is not + the name of an existing frame. +S2IZ0075 + You cannot import from the current frame (nor is there a need!). +S2IZ0076 + User verification required: + do you really want to import everything from the frame %1b ? + If so, please enter %b y %d or %b yes %d : +S2IZ0077 + On your request, AXIOM will not import everything from frame %1b. +S2IZ0078 + Import from frame %1b is complete. Please issue %b )display all %d + if you wish to see the contents of the current frame. +S2IZ0079 + AXIOM cannot import %1b from frame %2b because it cannot be found. +@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{help} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )help} +\item{\tt )help} {\it commandName} +\end{list} + +\par\noindent{\bf Command Description:} + +This command displays help information about system commands. +If you issue +\begin{verbatim} +)help +\end{verbatim} +then this very text will be shown. +You can also give the name or abbreviation of a system command +to display information about it. +For example, +\begin{verbatim} +)help clear +\end{verbatim} +will display the description of the {\tt )clear} system command. + +All this material is available in the Axiom User Guide +and in HyperDoc. +In HyperDoc, choose the {\bf Commands} item from the +{\bf Reference} menu. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{history} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \par\noindent{\bf User Level Required:} interpreter @@ -1521,15 +3315,14 @@ If an invalid step number is given, Axiom will signal an error. The {\it environment} information can either be saved in a file or entirely in memory (the default). Each frame -(\ref{ugSysCmdframe} on page~\pageref{ugSysCmdframe}) has its own history database. When it is kept in a file, some of it may also be kept in memory for efficiency. When the information is saved in a file, the name of the file is of the form {\bf FRAME.axh} where ``{\bf FRAME}'' is the name of the current frame. -The history file is placed in the current working directory -(see \ref{ugSysCmdcd} on page~\pageref{ugSysCmdcd}). +The history file is placed in the current working directory. + Note that these history database files are not text files (in fact, they are directories themselves), and so are not in human-readable format. @@ -1591,8 +3384,8 @@ for a file called {\bf last.axh}. \item[{\tt )save} {\it savedHistoryName}] is used to save a snapshot of the environment in a file. -This file is placed in the current working directory -(see \ref{ugSysCmdcd} on page~\pageref{ugSysCmdcd}). +This file is placed in the current working directory. + Use {\tt )history )restore} to restore the environment to the state preserved in the file. This option also creates an input file containing all the lines of input @@ -1631,19 +3424,19 @@ the contents. \end{description} \par\noindent{\bf Also See:} -{\tt )frame} \index{ugSysCmdframe}, -{\tt )read} \index{ugSysCmdread}, -{\tt )set} \index{ugSysCmdset}, and -{\tt )undo} \index{ugSysCmdundo}. +{\tt )frame}, +{\tt )read}, +{\tt )set}, and +{\tt )undo} History recording is done in two different ways: \begin{itemize} \item all changes in variable bindings (i.e. previous values) are - written to [[$HistList]], which is a circular list +written to [[$HistList]], which is a circular list \item all new bindings (including the binding to [[%]]) are written to a - file called [[histFileName()]] - one older session is accessible via the file [[$oldHistFileName()]] +file called [[histFileName()]] +one older session is accessible via the file [[$oldHistFileName()]] \end{itemize} \section{Variables Used} @@ -3938,934 +5731,836 @@ S2IH0038 You must specify a file name to the history write command @ -\chapter{The Frame Mechanism} -\section{)frame} -\label{TheFrameMechanism} -\index{TheFrameMechanism} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{library} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter + \par\noindent{\bf Command Syntax:} \begin{list}{} -\item{\tt )frame new {\it frameName}} -\item{\tt )frame drop {\it [frameName]}} -\item{\tt )frame next} -\item{\tt )frame last} -\item{\tt )frame names} -\item{\tt )frame import {\it frameName} {\it [objectName1 [objectName2 ...]]}} -\item{\tt )set message frame on | off} -\item{\tt )set message prompt frame} +\item{\tt )library {\it libName1 \lanb{}libName2 ...\ranb{}}} +\item{\tt )library )dir {\it dirName}} +\item{\tt )library )only {\it objName1 \lanb{}objlib2 ...\ranb{}}} +\item{\tt )library )noexpose} \end{list} \par\noindent{\bf Command Description:} -A {\it frame} can be thought of as a logical session within the -physical session that you get when you start the system. You can -have as many frames as you want, within the limits of your computer's -storage, paging space, and so on. -Each frame has its own {\it step number}, {\it environment} and {\it history.} -You can have a variable named {\tt a} in one frame and it will -have nothing to do with anything that might be called {\tt a} in -any other frame. +This command replaces the {\tt )load} system command that +was available in Axiom releases before version 2.0. +The {\tt )library} command makes available to Axiom the compiled +objects in the libraries listed. + +For example, if you {\tt )compile dopler.as} in your home +directory, issue {\tt )library dopler} to have Axiom look +at the library, determine the category and domain constructors present, +update the internal database with various properties of the +constructors, and arrange for the constructors to be +automatically loaded when needed. +If the {\tt )noexpose} option has not been given, the +constructors will be exposed (that is, available) in the current +frame. + +If you compiled a file with the old system compiler, you will +have an {\it nrlib} present, for example, {\it DOPLER.nrlib,} +where {\tt DOPLER} is a constructor abbreviation. +The command {\tt )library DOPLER} will then do the analysis and +database updates as above. + +To tell the system about all libraries in a directory, use +{\tt )library )dir dirName} where {\tt dirName} is an explicit +directory. +You may specify ``.'' as the directory, which means the current +directory from which you started the system or the one you set +via the {\tt )cd} command. The directory name is required. + +You may only want to tell the system about particular +constructors within a library. In this case, use the {\tt )only} +option. The command {\tt )library dopler )only Test1} will only +cause the {\sf Test1} constructor to be analyzed, autoloaded, +etc.. + +Finally, each constructor in a library are usually automatically exposed when the +{\tt )library} command is used. Use the {\tt )noexpose} +option if you not want them exposed. At a later time you can use +{\tt )set expose add constructor} to expose any hidden +constructors. + +{\bf Note for Axiom beta testers:} At various times this +command was called {\tt )local} and {\tt )with} before the name +{\tt )library} became the official name. -Some frames are created by the HyperDoc program and these can -have pretty strange names, since they are generated automatically. -\index{frame names} -To find out the names -of all frames, issue -\begin{verbatim} -)frame names -\end{verbatim} -It will indicate the name of the current frame. +\par\noindent{\bf Also See:} +\fnref{cd}, +\fnref{compiler}, +\fnref{frame}, and +\fnref{set} -You create a new frame -\index{frame new} -``{\bf quark}'' by issuing -\begin{verbatim} -)frame new quark -\end{verbatim} -The history facility can be turned on by issuing either -{\tt )set history on} or {\tt )history )on}. -If the history facility is on and you are saving history information -in a file rather than in the Axiom environment -then a history file with filename {\bf quark.axh} will -be created as you enter commands. -If you wish to go back to what -you were doing in the -\index{frame next} -``{\bf initial}'' frame, use -\index{frame last} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{lisp} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} development + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )lisp} {\it\lanb{}lispExpression\ranb{}} +\end{list} + +\par\noindent{\bf Command Description:} + +This command is used by Axiom system developers to have single +expressions evaluated by the Common Lisp system on which +Axiom is built. +The {\it lispExpression} is read by the Common Lisp reader and +evaluated. +If this expression is not complete (unbalanced parentheses, say), the reader +will wait until a complete expression is entered. + +Since this command is only useful for evaluating single expressions, the +{\tt )fin} +command may be used to drop out of Axiom into Common Lisp. + +\par\noindent{\bf Also See:} +\fnref{system}, +\fnref{boot}, and +\fnref{fin} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{load} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter +\par\noindent{\bf Command Description:} + +This command is obsolete. Use {\tt )library} instead. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{ltrace} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} development + +\par\noindent{\bf Command Syntax:} + +This command has the same arguments as options as the +{\tt )trace} command. + +\par\noindent{\bf Command Description:} + +This command is used by Axiom system developers to trace +Common Lisp or +BOOT functions. +It is not supported for general use. + +\par\noindent{\bf Also See:} +\fnref{boot}, +\fnref{lisp}, and +\fnref{trace} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{pquit} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )pquit} +\end{list} + +\par\noindent{\bf Command Description:} + +This command is used to terminate Axiom and return to the +operating system. +Other than by redoing all your computations or by +using the {\tt )history )restore} +command to try to restore your working environment, +you cannot return to Axiom in the same state. + +{\tt )pquit} differs from the {\tt )quit} in that it always asks for +confirmation that you want to terminate Axiom (the ``p'' is for +``protected''). +\index{quit} +When you enter the {\tt )pquit} command, Axiom responds +% +\begin{center} +Please enter {\bf y} or {\bf yes} if you really want to leave the interactive \\ +environment and return to the operating system: +\end{center} +% +If you respond with {\tt y} or {\tt yes}, you will see the message +% +\begin{center} +You are now leaving the Axiom interactive environment. \\ +Issue the command {\bf axiom} to the operating system to start a new session. +\end{center} +% +and Axiom will terminate and return you to the operating +system (or the environment from which you invoked the system). +If you responded with something other than {\tt y} or {\tt yes}, then +the message +% +\begin{center} +You have chosen to remain in the Axiom interactive environment. +\end{center} +% +will be displayed and, indeed, Axiom would still be running. + +\par\noindent{\bf Also See:} +\fnref{fin}, +\fnref{history}, +\fnref{close}, +\fnref{quit}, and +\fnref{system} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{quit} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )quit} +\item{\tt )set quit protected \vertline{} unprotected} +\end{list} + +\par\noindent{\bf Command Description:} + +This command is used to terminate Axiom and return to the +operating system. +Other than by redoing all your computations or by +using the {\tt )history )restore} +command to try to restore your working environment, +you cannot return to Axiom in the same state. + +{\tt )quit} differs from the {\tt )pquit} in that it asks for +\index{pquit} +confirmation only if the command \begin{verbatim} -)frame next +)set quit protected \end{verbatim} -or +has been issued. +\index{set quit protected} +Otherwise, {\tt )quit} will make Axiom terminate and return you +to the operating system (or the environment from which you invoked the +system). + +The default setting is {\tt )set quit protected} so that {\tt )quit} +and {\tt )pquit} behave in the same way. +If you do issue \begin{verbatim} -)frame last +)set quit unprotected \end{verbatim} -to cycle through the ring of available frames to get back to -``{\bf initial}''. +we +\index{set quit unprotected} +suggest that you do not (somehow) assign {\tt )quit} to be +executed when you press, say, a function key. -If you want to throw -away a frame (say ``{\bf quark}''), issue +\par\noindent{\bf Also See:} +\fnref{fin}, +\fnref{history}, +\fnref{close}, +\fnref{pquit}, and +\fnref{system} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{read} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )read} {\it \lanb{}fileName\ranb{}} +\item {\tt )read} {\it \lanb{}fileName\ranb{}} \lanb{}{\tt )quiet}\ranb{} \lanb{}{\tt )ifthere}\ranb{} +\end{list} +\par\noindent{\bf Command Description:} + +This command is used to read {\bf .input} files into Axiom. +\index{file!input} +The command \begin{verbatim} -)frame drop quark +)read matrix.input \end{verbatim} -If you omit the name, the current frame is dropped. -\index{frame drop} +will read the contents of the file {\bf matrix.input} into +Axiom. +The ``.input'' file extension is optional. -If you do use frames with the history facility on and writing to a file, -you may want to delete some of the older history files. -\index{file!history} -These are directories, so you may want to issue a command like -{\tt rm -r quark.axh} to the operating system. +This command remembers the previous file you edited, read or compiled. +If you do not specify a file name, the previous file will be read. -You can bring things from another frame by using -\index{frame import} -{\tt )frame import}. -For example, to bring the {\tt f} and {\tt g} from the frame ``{\bf quark}'' -to the current frame, issue +The {\tt )ifthere} option checks to see whether the {\bf .input} file +exists. +If it does not, the {\tt )read} command does nothing. +If you do not use this option and the file does not exist, +you are asked to give the name of an existing {\bf .input} file. + +The {\tt )quiet} option suppresses output while the file is being read. + +\par\noindent{\bf Also See:} +\fnref{compiler}, +\fnref{edit}, and +\fnref{history} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{savesystem} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{set} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\par\noindent{\bf User Level Required:} interpreter + +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )set} +\item {\tt )set} {\it label1 \lanb{}... labelN\ranb{}} +\item {\tt )set} {\it label1 \lanb{}... labelN\ranb{} newValue} +\end{list} +\par\noindent{\bf Command Description:} + +The {\tt )set} command is used to view or set system variables that +control what messages are displayed, the type of output desired, the +status of the history facility, the way Axiom user functions are +cached, and so on. +Since this collection is very large, we will not discuss them here. +Rather, we will show how the facility is used. +We urge you to explore the {\tt )set} options to familiarize yourself +with how you can modify your Axiom working environment. +There is a HyperDoc version of this same facility available from the +main HyperDoc menu. + + +The {\tt )set} command is command-driven with a menu display. +It is tree-structured. +To see all top-level nodes, issue {\tt )set} by itself. \begin{verbatim} -)frame import quark f g +)set \end{verbatim} -If you want everything from the frame ``{\bf quark}'', issue +Variables with values have them displayed near the right margin. +Subtrees of selections have ``{\tt ...}'' +displayed in the value field. +For example, there are many kinds of messages, so issue +{\tt )set message} to see the choices. \begin{verbatim} -)frame import quark +)set message \end{verbatim} -You will be asked to verify that you really want everything. - -There are two {\tt )set} flags -\index{set message frame} -to make it easier to tell where you are. +The current setting for the variable that displays +\index{computation timings!displaying} +whether computation times +\index{timings!displaying} +are displayed is visible in the menu displayed by the last command. +To see more information, issue \begin{verbatim} -)set message frame on | off +)set message time \end{verbatim} -will print more messages about frames when it is set on. -By default, it is off. +This shows that time printing is on now. +To turn it off, issue \begin{verbatim} -)set message prompt frame +)set message time off \end{verbatim} -will give a prompt -\index{set message prompt frame} -that looks like +\index{set message time} + +As noted above, not all settings have so many qualifiers. +For example, to change the {\tt )quit} command to being unprotected +(that is, you will not be prompted for verification), you need only issue \begin{verbatim} -initial (1) -> +)set quit unprotected \end{verbatim} -\index{prompt!with frame name} -when you start up. In this case, the frame name and step make up the -prompt. +\index{set quit unprotected} \par\noindent{\bf Also See:} -{\tt )history} \index{ugSysCmdhistory} and -{\tt )set} \index{ugSysCmdset}. +\fnref{quit} -\section{Variables Used} -The frame mechanism uses several dollar variables. -\subsection{Primary variables} -Primary variables are those which exist solely to make the frame -mechanism work. - -The \$interpreterFrameName contains a symbol which is the name -of the current frame in use. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{show} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -The \$interpreterFrameRing contains a list of all of the existing -frames. The first frame on the list is the ``current'' frame. When -AXIOMsys is started directly there is only one frame named ``initial''. +\par\noindent{\bf User Level Required:} interpreter -If the system is started under sman (using the axiom shell script, -for example), there are two frames, ``initial'' and ``frame0''. In -this case, ``frame0'' is the current frame. This can cause subtle -problems because functions defined in the axiom initialization file -(.axiom.input) will be defined in frame ``initial'' but the current -frame will be ``frame0''. They will appear to be undefined. However, -if the user does ``)frame next'' they can switch to the ``initial'' -frame and see the functions correctly defined. +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item {\tt )show {\it nameOrAbbrev}} +\item {\tt )show {\it nameOrAbbrev} )operations} +\item {\tt )show {\it nameOrAbbrev} )attributes} +\end{list} -The \$frameMessages variable controls when frame messages will be -displayed. The variable is initially NIL. It can be set on (T) or off (NIL) -using the system command: +\par\noindent{\bf Command Description:} +This command displays information about Axiom +domain, package and category {\it constructors}. +If no options are given, the {\tt )operations} option is assumed. +For example, \begin{verbatim} - )set message frame on | off +)show POLY +)show POLY )operations +)show Polynomial +)show Polynomial )operations +\end{verbatim} +each display basic information about the +{\tt Polynomial} domain constructor and then provide a +listing of operations. +Since {\tt Polynomial} requires a {\tt Ring} (for example, +{\tt Integer}) as argument, the above commands all refer +to a unspecified ring {\tt R}. +In the list of operations, {\tt \$} means +{\tt Polynomial(R)}. + +The basic information displayed includes the {\it signature} +of the constructor (the name and arguments), the constructor +{\it abbreviation}, the {\it exposure status} of the constructor, and the +name of the {\it library source file} for the constructor. + +If operation information about a specific domain is wanted, +the full or abbreviated domain name may be used. +For example, +\begin{verbatim} +)show POLY INT +)show POLY INT )operations +)show Polynomial Integer +)show Polynomial Integer )operations \end{verbatim} -Setting frame messages on will output a line detailing the -current frame after every output is complete. +are among the combinations that will +display the operations exported by the +domain {\tt Polynomial(Integer)} (as opposed to the general +{\it domain constructor} {\tt Polynomial}). +Attributes may be listed by using the {\tt )attributes} option. -\subsection{Used variables} +\par\noindent{\bf Also See:} +\fnref{display}, +\fnref{set}, and +\fnref{what} -The frame collects and uses a few top level variables. These are: -\$InteractiveFrame, \$IOindex, \$HiFiAccess, \$HistList, \$HistListLen, -\$HistListAct, \$HistRecord, \$internalHistoryTable, and \$localExposureData. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{spool} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -These variables can also be changed by the frame mechanism when the user -requests changing to a different frame. +\par\noindent{\bf User Level Required:} interpreter -\section{Data Structures} -\subsection{Frames and the Interpreter Frame Ring} +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )spool} \lanb{}{\it fileName}\ranb{} +\item{\tt )spool} +\end{list} -Axiom has the notion of ``frames''. A frame is a data structure which -holds all the vital data from an Axiom session. There can be multiple -frames and these live in a top-level variable called -\$interpreterFrameRing. This variable holds a circular list of frames. -The parts of a frame and their initial, default values are: +\par\noindent{\bf Command Description:} +This command is used to save {\it (spool)} all Axiom input and output +\index{file!spool} +into a file, called a {\it spool file.} +You can only have one spool file active at a time. +To start spool, issue this command with a filename. For example, \begin{verbatim} - $interpreterFrameName a string, named on creation - $InteractiveFrame (list (list nil)) - $IOindex an integer, 1 - $HiFiAccess $HiFiAccess, see the variable description - $HistList $HistList, see the variable description - $HistListLen $HistListLen, see the variable description - $HistListAct $HistListAct, see the variable description - $HistRecord $HistRecord, see the variable description - $internalHistoryTable nil - $localExposureData a copy of $localExposureData +)spool integrate.out \end{verbatim} +To stop spooling, issue {\tt )spool} with no filename. -\section{Accessor Functions} -These could be macros but we wish to export them to the API code -in the algebra so we keep them as functions. -\subsection{0th Frame Component -- frameName} -\subsection{defun frameName} -<>= -(defun frameName (frame) - (car frame)) - -@ -\subsection{1st Frame Component -- frameInteractive} -<>= -(defun frameInteractive (frame) - (nth 1 frame)) +If the filename is qualified with a directory, then the output will +be placed in that directory. +If no directory information is given, the spool file will be placed in the +\index{directory!for spool files} +{\it current directory.} +The current directory is the directory from which you started +Axiom or is the directory you specified using the +{\tt )cd} command. +\index{cd} -@ -\subsection{2nd Frame Component -- frameIOIndex} -<>= -(defun frameIOIndex (frame) - (nth 2 frame)) - -@ -\subsection{3rd Frame Component -- frameHiFiAccess} -<>= -(defun frameHiFiAccess (frame) - (nth 3 frame)) - -@ -\subsection{4th Frame Component -- frameHistList} -<>= -(defun frameHistList (frame) - (nth 4 frame)) - -@ -\subsection{5th Frame Component -- frameHistListLen} -<>= -(defun frameHistListLen (frame) - (nth 5 frame)) - -@ -\subsection{6th Frame Component -- frameHistListAct} -<>= -(defun frameHistListAct (frame) - (nth 6 frame)) - -@ -\subsection{7th Frame Component -- frameHistRecord} -<>= -(defun frameHistRecord (frame) - (nth 7 frame)) - -@ -\subsection{8th Frame Component -- frameHistoryTable} -<>= -(defun frameHistoryTable (frame) - (nth 8 frame)) - -@ -\subsection{9th Frame Component -- frameExposureData} -<>= -(defun frameExposureData (frame) - (nth 9 frame)) +\par\noindent{\bf Also See:} +\fnref{cd} -@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{summary} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Variables Used} -\section{Data Structures} -\section{Functions} -\subsection{Initializing the Interpreter Frame Ring} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{synonym} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -Now that we know what a frame looks like we need a function to -initialize the list of frames. This function sets the initial frame -name to ``initial'' and creates a list of frames containing an empty -frame. This list is the interpreter frame ring and is not actually -circular but is managed as a circular list. +\par\noindent{\bf User Level Required:} interpreter -As a final step we update the world from this frame. This has the -side-effect of resetting all the important global variables to their -initial values. +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )synonym} +\item{\tt )synonym} {\it synonym fullCommand} +\item{\tt )what synonyms} +\end{list} -<>= -(defun |initializeInterpreterFrameRing| () - (setq |$interpreterFrameName| '|initial|) - (setq |$interpreterFrameRing| - (list (|emptyInterpreterFrame| |$interpreterFrameName|))) - (|updateFromCurrentInterpreterFrame|) - nil) +\par\noindent{\bf Command Description:} -@ -\subsection{Creating a List of all of the Frame Names} -\subsection{defun frameNames} -This function simply walks across the frame in the frame ring and -returns a list of the name of each frame. +This command is used to create short synonyms for system command expressions. +For example, the following synonyms might simplify commands you often +use. \begin{verbatim} -frameNames() == [frameName f for f in $interpreterFrameRing] +)synonym save history )save +)synonym restore history )restore +)synonym mail system mail +)synonym ls system ls +)synonym fortran set output fortran \end{verbatim} -<>= -(defun |frameNames| () - (mapcar #'frameName |$interpreterFrameRing|)) - -@ - -\subsection{Get Named Frame Environment (aka Interactive)} -If the frame is found we return the environment portion of the frame -otherwise we construct an empty environment and return it. -The initial values of an empty frame are created here. This function -returns a single frame that will be placed in the frame ring. -\subsection{defun frameEnvironment} +Once defined, synonyms can be +used in place of the longer command expressions. +Thus \begin{verbatim} -frameEnvironment fname == - -- extracts the environment portion of a frame - -- if fname is not a valid frame name then the empty environment - -- is returned - fname = frameName first $interpreterFrameRing => $InteractiveFrame - ifr := rest $interpreterFrameRing - e := LIST LIST NIL - while ifr repeat - [f,:ifr] := ifr - if fname = frameName f then - e := CADR f - ifr := NIL - e +)fortran on \end{verbatim} -<>= -(defun |frameEnvironment| (fname) - (let ((frame (|findFrameInRing| fname))) - (if frame - (frameInteractive frame) - (list (list nil))))) - -@ -\subsection{defun emptyInterpreterFrame} +is the same as the longer \begin{verbatim} -emptyInterpreterFrame(name) == - LIST(name, -- frame name - LIST LIST NIL, -- environment - 1, -- $IOindex - $HiFiAccess, -- $HiFiAccess - $HistList, -- $HistList - $HistListLen, -- $HistListLen - $HistListAct, -- $HistListAct - $HistRecord, -- $HistRecord - NIL, -- $internalHistoryTable - COPY_-SEQ $localExposureDataDefault -- $localExposureData - ) +)set fortran output on +\end{verbatim} +To list all defined synonyms, issue either of +\begin{verbatim} +)synonyms +)what synonyms +\end{verbatim} +To list, say, all synonyms that contain the substring +``{\tt ap}'', issue +\begin{verbatim} +)what synonyms ap \end{verbatim} -<>= -(defun |emptyInterpreterFrame| (name) - (list name - (list (list nil)) - 1 - |$HiFiAccess| - |$HistList| - |$HistListLen| - |$HistListAct| - |$HistRecord| - nil - (copy-seq |$localExposureDataDefault|))) -@ -\subsection{Collecting up the Environment into a Frame} +\par\noindent{\bf Also See:} +\fnref{set} and +\fnref{what} -We can collect up all the current environment information into -one frame element with this call. It creates a list of the current -values of the global variables and returns this as a frame element. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{system} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{defun createCurrentInterpreterFrame} -\begin{verbatim} -createCurrentInterpreterFrame() == - LIST($interpreterFrameName, -- frame name - $InteractiveFrame, -- environment - $IOindex, -- $IOindex - $HiFiAccess, -- $HiFiAccess - $HistList, -- $HistList - $HistListLen, -- $HistListLen - $HistListAct, -- $HistListAct - $HistRecord, -- $HistRecord - $internalHistoryTable, -- $internalHistoryTable - $localExposureData -- $localExposureData - ) -\end{verbatim} -<>= -(defun |createCurrentInterpreterFrame| () - (list - |$interpreterFrameName| - |$InteractiveFrame| - |$IOindex| - |$HiFiAccess| - |$HistList| - |$HistListLen| - |$HistListAct| - |$HistRecord| - |$internalHistoryTable| - |$localExposureData|)) +\par\noindent{\bf User Level Required:} interpreter -@ -\subsection{Updating from the Current Frame} +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )system} {\it cmdExpression} +\end{list} -The frames are kept on a circular list. The first element on that -list is known as ``the current frame''. This will initialize all -of the interesting interpreter data structures from that frame. +\par\noindent{\bf Command Description:} -\subsection{defun updateFromCurrentInterpreterFrame} -\begin{verbatim} -updateFromCurrentInterpreterFrame() == - [$interpreterFrameName, _ - $InteractiveFrame, _ - $IOindex, _ - $HiFiAccess, _ - $HistList, _ - $HistListLen, _ - $HistListAct, _ - $HistRecord, _ - $internalHistoryTable, _ - $localExposureData _ - ] := first $interpreterFrameRing - if $frameMessages then - sayMessage ['" Current interpreter frame is called",:bright - $interpreterFrameName] - NIL -\end{verbatim} -<>= -(defun |updateFromCurrentInterpreterFrame| () - (let (tmp1) - (setq tmp1 (first |$interpreterFrameRing|)) - (setq |$interpreterFrameName| (nth 0 tmp1)) - (setq |$InteractiveFrame| (nth 1 tmp1)) - (setq |$IOindex| (nth 2 tmp1)) - (setq |$HiFiAccess| (nth 3 tmp1)) - (setq |$HistList| (nth 4 tmp1)) - (setq |$HistListLen| (nth 5 tmp1)) - (setq |$HistListAct| (nth 6 tmp1)) - (setq |$HistRecord| (nth 7 tmp1)) - (setq |$internalHistoryTable| (nth 8 tmp1)) - (setq |$localExposureData| (nth 9 tmp1)) - (when |$frameMessages| - (|sayMessage| - (cons " Current interpreter frame is called" |$interpreterFrameName|))))) +This command may be used to issue commands to the operating system while +remaining in Axiom. +The {\it cmdExpression} is passed to the operating system for +execution. + +To get an operating system shell, issue, for example, +{\tt )system sh}. +When you enter the key combination, +\fbox{\bf Ctrl}--\fbox{\bf D} +(pressing and holding the +\fbox{\bf Ctrl} key and then pressing the +\fbox{\bf D} key) +the shell will terminate and you will return to Axiom. +We do not recommend this way of creating a shell because +Common Lisp may field some interrupts instead of the shell. +If possible, use a shell running in another window. + +If you execute programs that misbehave you may not be able to return to +Axiom. +If this happens, you may have no other choice than to restart +Axiom and restore the environment via {\tt )history )restore}, if +possible. -@ -\subsection{Find a Frame in the Frame Ring by Name} -Each frame contains its name as the 0th element. We simply walk all -the frames and if we find one we return it. -\subsection{defun findFrameInRing} -\begin{verbatim} -findFrameInRing(name) == - val := NIL - for frame in $interpreterFrameRing repeat - CAR frame = name => - val := frame - return frame - val -\end{verbatim} -<>= -(defun |findFrameInRing| (name) - (block () - (dolist (frame |$interpreterFrameRing|) - (when (boot-equal (frameName frame) name) (return frame))))) +\par\noindent{\bf Also See:} +\fnref{boot}, +\fnref{fin}, +\fnref{lisp}, +\fnref{pquit}, and +\fnref{quit} -@ -\subsection{Update the Current Interpreter Frame} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{trace} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -This function collects the normal contents of the world into a -frame object, places it first on the frame list, and then sets -the current values of the world from the frame object. +\par\noindent{\bf User Level Required:} interpreter -\subsection{defun updateCurrentInterpreterFrame} -\begin{verbatim} -updateCurrentInterpreterFrame() == - RPLACA($interpreterFrameRing,createCurrentInterpreterFrame()) - updateFromCurrentInterpreterFrame() - NIL -\end{verbatim} -<>= -(defun |updateCurrentInterpreterFrame| () - (rplaca |$interpreterFrameRing| (|createCurrentInterpreterFrame|)) - (|updateFromCurrentInterpreterFrame|) - nil) +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )trace} +\item{\tt )trace )off} -@ -\subsection{defun nextInterpreterFrame} +\item{\tt )trace} {\it function \lanb{}options\ranb{}} +\item{\tt )trace} {\it constructor \lanb{}options\ranb{}} +\item{\tt )trace} {\it domainOrPackage \lanb{}options\ranb{}} +\end{list} +% +where options can be one or more of +% +\begin{list}{} +\item{\tt )after} {\it S-expression} +\item{\tt )before} {\it S-expression} +\item{\tt )break after} +\item{\tt )break before} +\item{\tt )cond} {\it S-expression} +\item{\tt )count} +\item{\tt )count} {\it n} +\item{\tt )depth} {\it n} +\item{\tt )local} {\it op1 \lanb{}... opN\ranb{}} +\item{\tt )nonquietly} +\item{\tt )nt} +\item{\tt )off} +\item{\tt )only} {\it listOfDataToDisplay} +\item{\tt )ops} +\item{\tt )ops} {\it op1 \lanb{}... opN \ranb{}} +\item{\tt )restore} +\item{\tt )stats} +\item{\tt )stats reset} +\item{\tt )timer} +\item{\tt )varbreak} +\item{\tt )varbreak} {\it var1 \lanb{}... varN \ranb{}} +\item{\tt )vars} +\item{\tt )vars} {\it var1 \lanb{}... varN \ranb{}} +\item{\tt )within} {\it executingFunction} +\end{list} -This function updates the current frame to make sure all of the -current information is recorded. If there are more frame elements -in the list then this will destructively move the current frame -to the end of the list, that is, assume the frame list reads (1 2 3) -this function will destructively change it to (2 3 1). +\par\noindent{\bf Command Description:} -Note: the nconc2 function destructively inserts the second list at the -end of the first. -\begin{verbatim} -nextInterpreterFrame() == - updateCurrentInterpreterFrame() - null rest $interpreterFrameRing => NIL -- nothing to do - $interpreterFrameRing := - NCONC2(rest $interpreterFrameRing,[first $interpreterFrameRing]) - updateFromCurrentInterpreterFrame() -\end{verbatim} -<>= -(defun |nextInterpreterFrame| () - (when (cdr |$interpreterFrameRing|) - (setq |$interpreterFrameRing| - (nconc2 (cdr |$interpreterFrameRing|) - (list (car |$interpreterFrameRing|)))) - (|updateFromCurrentInterpreterFrame|))) +This command is used to trace the execution of functions that make +up the Axiom system, functions defined by users, +and functions from the system library. +Almost all options are available for each type of function but +exceptions will be noted below. -@ -\subsection{defun changeToNamedInterpreterFrame} +To list all functions, constructors, domains and packages that are +traced, simply issue \begin{verbatim} -changeToNamedInterpreterFrame(name) == - updateCurrentInterpreterFrame() - frame := findFrameInRing(name) - null frame => NIL - $interpreterFrameRing := [frame,:NREMOVE($interpreterFrameRing, frame)] - updateFromCurrentInterpreterFrame() +)trace \end{verbatim} -<>= -(defun |changeToNamedInterpreterFrame| (name) - (prog (frame) - (return - (progn - (|updateCurrentInterpreterFrame|) - (spadlet frame (|findFrameInRing| name)) - (cond - ((null frame) - nil) - (t - (spadlet |$interpreterFrameRing| - (cons frame (nremove |$interpreterFrameRing| frame))) - (|updateFromCurrentInterpreterFrame|))))))) - -@ -\subsection{defun previousInterpreterFrame} +To untrace everything that is traced, issue \begin{verbatim} -previousInterpreterFrame() == - updateCurrentInterpreterFrame() - null rest $interpreterFrameRing => NIL -- nothing to do - [:b,l] := $interpreterFrameRing - $interpreterFrameRing := NCONC2([l],b) - updateFromCurrentInterpreterFrame() +)trace )off \end{verbatim} -<>= -(defun |previousInterpreterFrame| () - (prog (tmp1 l b) - (return - (progn - (|updateCurrentInterpreterFrame|) - (cond - ((null (cdr |$interpreterFrameRing|)) - nil) - (t - (spadlet tmp1 (reverse |$interpreterFrameRing|)) - (spadlet l (car tmp1)) - (spadlet b (nreverse (cdr tmp1))) - (spadlet |$interpreterFrameRing| (nconc2 (cons l nil) b)) - (|updateFromCurrentInterpreterFrame|))))))) +When a function is traced, the default system action is to display +the arguments to the function and the return value when the +function is exited. +Note that if a function is left via an action such as a {\tt THROW}, no +return value will be displayed. +Also, optimization of tail recursion may decrease the number of +times a function is actually invoked and so may cause less trace +information to be displayed. +Other information can be displayed or collected when a function is +traced and this is controlled by the various options. +Most options will be of interest only to Axiom system +developers. +If a domain or package is traced, the default action is to trace +all functions exported. -@ -\subsection{defun addNewInterpreterFrame} +Individual interpreter, lisp or boot +functions can be traced by listing their names after +{\tt )trace}. +Any options that are present must follow the functions to be +traced. \begin{verbatim} -addNewInterpreterFrame(name) == - null name => throwKeyedMsg("S2IZ0018",NIL) - updateCurrentInterpreterFrame() - -- see if we already have one by that name - for f in $interpreterFrameRing repeat - name = frameName(f) => throwKeyedMsg("S2IZ0019",[name]) - initHistList() - $interpreterFrameRing := CONS(emptyInterpreterFrame(name), - $interpreterFrameRing) - updateFromCurrentInterpreterFrame() - _$ERASE histFileName() +)trace f \end{verbatim} -<>= -(defun |addNewInterpreterFrame| (name) - (seq - (cond - ((null name) - (|throwKeyedMsg| 'S2IZ0018 nil)) ; you must provide a name for new frame - (t - (|updateCurrentInterpreterFrame|) - (seq - (do ((tmp0 |$interpreterFrameRing| (cdr tmp0)) (f nil)) - ((or (atom tmp0) - (progn (setq f (car tmp0)) nil)) - nil) - (seq - (exit - (when (boot-equal name (frameName f)) - (exit - (|throwKeyedMsg| 'S2IZ0019 ; existing frame with same name - (cons name nil))))))) - (|initHistList|) - (spadlet |$interpreterFrameRing| - (cons (|emptyInterpreterFrame| name) |$interpreterFrameRing|)) - (|updateFromCurrentInterpreterFrame|) - ($erase (|histFileName|))))))) - -@ -\subsection{defun closeInterpreterFrame} +traces the function {\tt f}. +To untrace {\tt f}, issue \begin{verbatim} -closeInterpreterFrame(name) == - -- if name = NIL then it means the current frame - null rest $interpreterFrameRing => - name and (name ^= $interpreterFrameName) => - throwKeyedMsg("S2IZ0020",[$interpreterFrameName]) - throwKeyedMsg("S2IZ0021",NIL) - if null name then $interpreterFrameRing := rest $interpreterFrameRing - else -- find the frame - found := nil - ifr := NIL - for f in $interpreterFrameRing repeat - found or (name ^= frameName(f)) => ifr := CONS(f,ifr) - found := true - not found => throwKeyedMsg("S2IZ0022",[name]) - _$ERASE makeHistFileName(name) - $interpreterFrameRing := nreverse ifr - updateFromCurrentInterpreterFrame() +)trace f )off \end{verbatim} -<>= -(defun |closeInterpreterFrame| (name) - (prog (ifr found) - (return - (seq - (cond - ((null (cdr |$interpreterFrameRing|)) - (cond - ((and name (nequal name |$interpreterFrameName|)) - (|throwKeyedMsg| 'S2IZ0020 ; 1 frame left. not the correct name. - (cons |$interpreterFrameName| nil))) - (t (|throwKeyedMsg| 'S2IZ0021 nil)))) ; only 1 frame left, not closed - (t - (cond - ((null name) - (spadlet |$interpreterFrameRing| (cdr |$interpreterFrameRing|))) - (t - (spadlet found nil) - (spadlet ifr nil) - (do ((tmp0 |$interpreterFrameRing| (cdr tmp0)) (f nil)) - ((or (atom tmp0) (progn (setq f (car tmp0)) nil)) nil) - (seq - (exit - (cond - ((or found (nequal name (frameName f))) - (spadlet ifr (cons f ifr))) - (t - (spadlet found t)))))) - (cond - ((null found) - (|throwKeyedMsg| 'S2IZ0022 (cons name nil))) - (t - ($erase (|makeHistFileName| name)) - (spadlet |$interpreterFrameRing| (nreverse ifr)))))) - (|updateFromCurrentInterpreterFrame|))))))) - -@ -\subsection{defun displayFrameNames} +Note that if a function name contains a special character, it will +be necessary to escape the character with an underscore +% \begin{verbatim} -displayFrameNames() == - fs := "append"/[ ['%l,'" ",:bright frameName f] for f in - $interpreterFrameRing] - sayKeyedMsg("S2IZ0024",[fs]) +)trace _/D_,1 \end{verbatim} -<>= -(defun |displayFrameNames| () - (prog (fs) - (return - (seq - (progn - (spadlet fs - (prog (tmp0) - (spadlet tmp0 NIL) - (return - (do ((tmp1 |$interpreterFrameRing| (cdr tmp1)) (f nil)) - ((or (atom tmp1) - (progn (setq f (car tmp1)) nil)) - tmp0) - (seq - (exit - (setq tmp0 - (append tmp0 (cons '|%l| - (cons (makestring " ") (|bright| (frameName f)))))))))))) - (|sayKeyedMsg| 'S2IZ0024 (cons fs nil))))))) ; frame names are ... - -@ -\subsection{defun importFromFrame} +% +To trace all domains or packages that are or will be created from a particular +constructor, give the constructor name or abbreviation after +{\tt )trace}. +% \begin{verbatim} -importFromFrame args == - -- args should have the form [frameName,:varNames] - if args and atom args then args := [args] - null args => throwKeyedMsg("S2IZ0073",NIL) - [fname,:args] := args - not member(fname,frameNames()) => - throwKeyedMsg("S2IZ0074",[fname]) - fname = frameName first $interpreterFrameRing => - throwKeyedMsg("S2IZ0075",NIL) - fenv := frameEnvironment fname - null args => - x := UPCASE queryUserKeyedMsg("S2IZ0076",[fname]) - MEMQ(STRING2ID_-N(x,1),'(Y YES)) => - vars := NIL - for [v,:props] in CAAR fenv repeat - v = "--macros" => - for [m,:.] in props repeat vars := cons(m,vars) - vars := cons(v,vars) - importFromFrame [fname,:vars] - sayKeyedMsg("S2IZ0077",[fname]) - for v in args repeat - plist := GETALIST(CAAR fenv,v) - plist => - -- remove anything with the same name in the current frame - clearCmdParts ['propert,v] - for [prop,:val] in plist repeat - putHist(v,prop,val,$InteractiveFrame) - (m := get("--macros--",v,fenv)) => - putHist("--macros--",v,m,$InteractiveFrame) - sayKeyedMsg("S2IZ0079",[v,fname]) - sayKeyedMsg("S2IZ0078",[fname]) +)trace MATRIX +)trace List Integer \end{verbatim} -<>= -(defun |importFromFrame| (args) - (prog (temp1 fname fenv x v props vars plist prop val m) - (return - (seq - (progn - (when (and args (atom args)) - (spadlet args (cons args nil))) - (cond - ((null args) - (|throwKeyedMsg| 'S2IZ0073 nil)) ; missing frame name - (t - (spadlet temp1 args) - (spadlet fname (car temp1)) - (spadlet args (cdr temp1)) - (cond - ((null (|member| fname (|frameNames|))) - (|throwKeyedMsg| 'S2IZ0074 (cons fname nil))) ; not frame name - ((boot-equal fname (frameName (car |$interpreterFrameRing|))) - (|throwKeyedMsg| 'S2IZ0075 NIL)) ; cannot import from curr frame - (t - (spadlet fenv (|frameEnvironment| fname)) - (cond - ((null args) - (spadlet x - (upcase (|queryUserKeyedMsg| 'S2IZ0076 (cons fname nil)))) - ; import everything? - (cond - ((memq (string2id-n x 1) '(y yes)) - (spadlet vars nil) - (do ((tmp0 (caar fenv) (cdr tmp0)) (tmp1 nil)) - ((or (atom tmp0) - (progn (setq tmp1 (car tmp0)) nil) - (progn - (progn - (spadlet v (car tmp1)) - (spadlet props (cdr tmp1)) - tmp1) - nil)) - nil) - (seq - (exit - (cond - ((boot-equal v '|--macros|) - (do ((tmp2 props (cdr tmp2)) - (tmp3 nil)) - ((or (atom tmp2) - (progn (setq tmp3 (car tmp2)) nil) - (progn - (progn (spadlet m (car tmp3)) tmp3) - nil)) - nil) - (seq - (exit - (spadlet vars (cons m vars)))))) - (t (spadlet vars (cons v vars))))))) - (|importFromFrame| (cons fname vars))) - (t - (|sayKeyedMsg| 'S2IZ0077 (cons fname nil))))) - (t - (do ((tmp4 args (cdr tmp4)) (v nil)) - ((or (atom tmp4) (progn (setq v (car tmp4)) nil)) nil) - (seq - (exit - (progn - (spadlet plist (getalist (caar fenv) v)) - (cond - (plist - (|clearCmdParts| (cons '|propert| (cons v nil))) - (do ((tmp5 plist (cdr tmp5)) (tmp6 nil)) - ((or (atom tmp5) - (progn (setq tmp6 (car tmp5)) nil) - (progn - (progn - (spadlet prop (car tmp6)) - (spadlet val (cdr tmp6)) - tmp6) - nil)) - nil) - (seq - (exit (|putHist| v prop val |$InteractiveFrame|))))) - ((spadlet m (|get| '|--macros--| v fenv)) - (|putHist| '|--macros--| v m |$InteractiveFrame|)) - (t - (|sayKeyedMsg| 'S2IZ0079 ; frame not found - (cons v (cons fname nil))))))))) - (|sayKeyedMsg| 'S2IZ0078 ; import complete - (cons fname nil))))))))))))) +% +The first command traces all domains currently instantiated with +{\tt Matrix}. +If additional domains are instantiated with this constructor +(for example, if you have used {\tt Matrix(Integer)} and +{\tt Matrix(Float)}), they will be automatically traced. +The second command traces {\tt List(Integer)}. +It is possible to trace individual functions in a domain or +package. +See the {\tt )ops} option below. + +The following are the general options for the {\tt )trace} +command. -@ -\subsection{defun frame} -\begin{verbatim} --- the system command +%!! system command parser doesn't treat general s-expressions correctly, +%!! I recommand not documenting )after )before and )cond +\begin{description} +%\item[{\tt )after} {\it S-expression}] +%causes the given Common Lisp {\it S-expression} to be +%executed after exiting the traced function. + +%\item[{\tt )before} {\it S-expression}] +%causes the given Common Lisp {\it S-expression} to be +%executed before entering the traced function. + +\item[{\tt )break after}] +causes a Common Lisp break loop to be entered after +exiting the traced function. + +\item[{\tt )break before}] +causes a Common Lisp break loop to be entered before +entering the traced function. + +\item[{\tt )break}] +is the same as {\tt )break before}. + +%\item[{\tt )cond} {\it S-expression}] +%causes trace information to be shown only if the given +%Common Lisp {\it S-expression} evaluates to non-NIL. For +%example, the following command causes the system function +%{\tt resolveTT} to be traced but to have the information +%displayed only if the value of the variable +%{\tt \$reportBottomUpFlag} is non-NIL. +%\begin{verbatim} +%)trace resolveTT )cond \_\$reportBottomUpFlag} +%\end{verbatim} + +\item[{\tt )count}] +causes the system to keep a count of the number of times the +traced function is entered. The total can be displayed with +{\tt )trace )stats} and cleared with {\tt )trace )stats reset}. + +\item[{\tt )count} {\it n}] +causes information about the traced function to be displayed for +the first {\it n} executions. After the \it n-th execution, the +function is untraced. + +\item[{\tt )depth} {\it n}] +causes trace information to be shown for only {\it n} levels of +recursion of the traced function. The command +\begin{verbatim} +)trace fib )depth 10 +\end{verbatim} +will cause the display of only 10 levels of trace information for +the recursive execution of a user function {\bf fib}. + +\item[{\tt )math}] +causes the function arguments and return value to be displayed in the +Axiom monospace two-dimensional math format. + +\item[{\tt )nonquietly}] +causes the display of additional messages when a function is +traced. + +\item[{\tt )nt}] +This suppresses all normal trace information. This option is +useful if the {\tt )count} or {\tt )timer} options are used and +you are interested in the statistics but not the function calling +information. -frame l == frameSpad2Cmd l -\end{verbatim} -<>= -(defun |frame| (l) - (|frameSpad2Cmd| l)) +\item[{\tt )off}] +causes untracing of all or specific functions. Without an +argument, all functions, constructors, domains and packages are +untraced. Otherwise, the given functions and other objects +are untraced. To +immediately retrace the untraced functions, issue {\tt )trace +)restore}. + +\item[{\tt )only} {\it listOfDataToDisplay}] +causes only specific trace information to be shown. The items are +listed by using the following abbreviations: +\begin{description} +\item[a] display all arguments +\item[v] display return value +\item[1] display first argument +\item[2] display second argument +\item[15] display the 15th argument, and so on +\end{description} +\end{description} +\begin{description} -@ -\subsection{defun frameSpad2Cmd} -\begin{verbatim} -frameSpad2Cmd args == - frameArgs := '(drop import last names new next) - $options => throwKeyedMsg("S2IZ0016",['")frame"]) - null(args) => helpSpad2Cmd ['frame] - arg := selectOptionLC(first args,frameArgs,'optionError) - args := rest args - if args is [a] then args := a - if ATOM args then args := object2Identifier args - arg = 'drop => - args and PAIRP(args) => throwKeyedMsg("S2IZ0017",[args]) - closeInterpreterFrame(args) - arg = 'import => importFromFrame args - arg = 'last => previousInterpreterFrame() - arg = 'names => displayFrameNames() - arg = 'new => - args and PAIRP(args) => throwKeyedMsg("S2IZ0017",[args]) - addNewInterpreterFrame(args) - arg = 'next => nextInterpreterFrame() +\item[{\tt )restore}] +causes the last untraced functions to be retraced. If additional +options are present, they are added to those previously in effect. + +\item[{\tt )stats}] +causes the display of statistics collected by the use of the +{\tt )count} and {\tt )timer} options. + +\item[{\tt )stats reset}] +resets to 0 the statistics collected by the use of the +{\tt )count} and {\tt )timer} options. + +\item[{\tt )timer}] +causes the system to keep a count of execution times for the +traced function. The total can be displayed with {\tt )trace +)stats} and cleared with {\tt )trace )stats reset}. + +%!! only for lisp, boot, may not work in any case, recommend removing +%\item[{\tt )varbreak}] +%causes a Common Lisp break loop to be entered after +%the assignment to any variable in the traced function. + +\item[{\tt )varbreak} {\it var1 \lanb{}... varN\ranb{}}] +causes a Common Lisp break loop to be entered after +the assignment to any of the listed variables in the traced +function. + +\item[{\tt )vars}] +causes the display of the value of any variable after it is +assigned in the traced function. +Note that library code must +have been compiled +using the {\tt )vartrace} option in order +to support this option. + +\item[{\tt )vars} {\it var1 \lanb{}... varN\ranb{}}] +causes the display of the value of any of the specified variables +after they are assigned in the traced function. +Note that library code must +have been compiled +using the {\tt )vartrace} option in order +to support this option. + +\item[{\tt )within} {\it executingFunction}] +causes the display of trace information only if the traced +function is called when the given {\it executingFunction} is running. +\end{description} - NIL +The following are the options for tracing constructors, domains +and packages. + +\begin{description} +\item[{\tt )local} {\it \lanb{}op1 \lanb{}... opN\ranb{}\ranb{}}] +causes local functions of the constructor to be traced. Note that +to untrace an individual local function, you must use the fully +qualified internal name, using the escape character +{\tt \_} before the semicolon. +\begin{verbatim} +)trace FRAC )local +)trace FRAC_;cancelGcd )off \end{verbatim} -<>= -(defun |frameSpad2Cmd| (args) - (prog (frameArgs arg a) - (return - (progn - (spadlet frameArgs '(|drop| |import| |last| |names| |new| |next|)) - (cond - (|$options| - (|throwKeyedMsg| 'S2IZ0016 ; frame command does not take options - (cons (makestring ")frame") nil))) - ((null args) - (|helpSpad2Cmd| (cons '|frame| nil))) - (t - (spadlet arg - (|selectOptionLC| (car args) frameArgs '|optionError|)) - (spadlet args (cdr args)) - (cond - ((and (pairp args) - (eq (qcdr args) nil) - (progn (spadlet a (qcar args)) t)) - (spadlet args a))) - (when (atom args) - (spadlet args (|object2Identifier| args))) - (cond - ((boot-equal arg '|drop|) - (cond - ((and args (pairp args)) - (|throwKeyedMsg| 'S2IZ0017 ; not a valid frame name - (cons args nil))) - (t (|closeInterpreterFrame| args)))) - ((boot-equal arg '|import|) - (|importFromFrame| args)) - ((boot-equal arg '|last|) - (|previousInterpreterFrame|)) - ((boot-equal arg '|names|) - (|displayFrameNames|)) - ((boot-equal arg '|new|) - (cond - ((and args (pairp args)) - (|throwKeyedMsg| 'S2IZ0017 ; not a valid frame name - (cons args nil))) - (t - (|addNewInterpreterFrame| args)))) - ((boot-equal arg '|next|) - (|nextInterpreterFrame|)) - (t nil)))))))) -@ -\section{Frame File Messages} -<>= -S2IZ0016 - The %1b system command takes arguments but no options. -S2IZ0017 - %1b is not a valid frame name -S2IZ0018 - You must provide a name for the new frame. -S2IZ0019 - You cannot use the name %1b for a new frame because an existing - frame already has that name. -S2IZ0020 - There is only one frame active and therefore that cannot be closed. - Furthermore, the frame name you gave is not the name of the current frame. - The current frame is called %1b . -S2IZ0021 - The current frame is the only active one. Issue %b )clear all %d to - clear its contents. -S2IZ0022 - There is no frame called %1b and so your command cannot be - processed. -S2IZ0024 - The names of the existing frames are: %1 %l - The current frame is the first one listed. -S2IZ0073 - %b )frame import %d must be followed by the frame name. The names - of objects in that frame can then optionally follow the frame name. - For example, - %ceon %b )frame import calculus %d %ceoff - imports all objects in the %b calculus %d frame, and - %ceon %b )frame import calculus epsilon delta %d %ceoff - imports the objects named %b epsilon %d and %b delta %d from the - frame %b calculus %d . - Please note that if the current frame contained any information - about objects with these names, then that information would be - cleared before the import took place. -S2IZ0074 - You cannot import anything from the frame %1b because that is not - the name of an existing frame. -S2IZ0075 - You cannot import from the current frame (nor is there a need!). -S2IZ0076 - User verification required: - do you really want to import everything from the frame %1b ? - If so, please enter %b y %d or %b yes %d : -S2IZ0077 - On your request, AXIOM will not import everything from frame %1b. -S2IZ0078 - Import from frame %1b is complete. Please issue %b )display all %d - if you wish to see the contents of the current frame. -S2IZ0079 - AXIOM cannot import %1b from frame %2b because it cannot be found. -@ -\chapter{The Undo Mechanism} -\section{)undo} -\index{ugSysCmdundo} +\item[{\tt )ops} {\it op1 \lanb{}... opN\ranb{}}] +By default, all operations from a domain or package are traced +when the domain or package is traced. This option allows you to +specify that only particular operations should be traced. The +command +% +\begin{verbatim} +)trace Integer )ops min max _+ _- +\end{verbatim} +% +traces four operations from the domain {\tt Integer}. Since +{\tt +} and {\tt -} are special +characters, it is necessary +to escape them with an underscore. +\end{description} -\index{undo} +\par\noindent{\bf Also See:} +\fnref{boot}, +\fnref{lisp}, and +\fnref{ltrace} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{undo} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \par\noindent{\bf User Level Required:} interpreter @@ -4932,8 +6627,8 @@ created by the last {\tt )undo} command. This file consists of all user input lines, excluding those backtracked over due to a previous {\tt )undo}. -\par\noindent{\bf Also See:} -{\tt )history} \index{ugSysCmdhistory}. +\par\noindent{\bf Also See:} \fnref{history} + The command {\tt )history )write} will eliminate the ``undone'' command lines of your program. \section{Variables Used} @@ -5689,219 +7384,127 @@ removeUndoLines u == --called by writeInputLines @ -\chapter{The Spad Server Mechanism} -<>= -(defvar $openServerIfTrue t "t means try starting an open server") -(defconstant $SpadServerName "/tmp/.d" "the name of the spad server socket") -(defvar |$SpadServer| nil "t means Scratchpad acts as a remote server") - -@ - -\pagehead{openserver}{openserver} -This is a cover function for the C code used for communication interface. -<>= -(defun openserver (name) - (open_server name)) - -@ - -\chapter{The Help Browser Mechanism} -The Axiom book on the help browser is a complete rewrite of the -hyperdoc mechanism. There are several components that were needed -to make this function. Most of the web browser components are -described in bookvol11.pamphlet. This portion describes some of -the design issues needed to support the interface. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{what} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -The axServer command takes a port (defaulting to 8085) and a -program to handle the browser interaction (defaulting to multiServ). -The axServer function opens the port, constructs the stream, and -passes the stream to multiServ. The multiServ loop processes one -interaction at a time. - -So the basic process is that the Axiom ``)browse'' command opens a -socket and listens for http requests. Based on the type of request -(either 'GET' or 'POST') and the content of the request, which is -one of: -\begin{itemize} -\item command - algebra request/response -\item lispcall - a lisp s-expression to be evaluated -\item showcall - an Axiom )show command -\end{itemize} -the multiServ function will call a handler function to evaluate -the command line and construct a response. GET requests result -in a new browser page. POST requests result in an inline result. +\par\noindent{\bf User Level Required:} interpreter -Most responses contain the fields: -\begin{itemize} -\item stepnum - this is the Axiom step number -\item command - this is the original command from the browser -\item algebra - this is the Axiom 2D algebra output -\item mathml - this is the MathML version of the Axiom algebra -\item type - this is the type of the Axiom result -\end{itemize} +\par\noindent{\bf Command Syntax:} +\begin{list}{} +\item{\tt )what categories} {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\item{\tt )what commands } {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\item{\tt )what domains } {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\item{\tt )what operations} {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\item{\tt )what packages } {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\item{\tt )what synonym } {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\item{\tt )what things } {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\item{\tt )apropos } {\it pattern1} \lanb{}{\it pattern2 ...\ranb{}} +\end{list} -\section{Browsers, MathML, and Fonts} -This work has the Firefox browser as its target. Firefox has built-in -support for MathML, javascript, and XMLHttpRequest handling. More details -are available in bookvol11.pamphlet but the very basic machinery for -communication with the browser involves a dance between the browser -and the multiServ function (see the axserver.spad.pamphlet). +\par\noindent{\bf Command Description:} -In particular, a simple request is embedded in a web page as: +This command is used to display lists of things in the system. The +patterns are all strings and, if present, restrict the contents of the +lists. Only those items that contain one or more of the strings as +substrings are displayed. For example, \begin{verbatim} -
    -
  • - -
    -
  • -
+)what synonym \end{verbatim} -which says that this is an html ``input'' field of type ``submit''. -The CSS display class is ``subbut'' which is of a different color -than the surrounding text to make it obvious that you can click on -this field. Clickable fields that have no response text are of class -``noresult''. - -The javascript call to ``makeRequest'' gives the ``id'' of this input -field, which must be unique in the page, as an argument. In this case, -the argument is 'p3'. The ``value'' field holds the display text which -will be passed back to Axiom as a command. - -When the result arrives the ``showanswer'' function will select out -the mathml field of the response, construct the ``id'' of the html -div to hold the response by concatenating the string ``ans'' (answer) -to the ``id'' of the request resulting, in this case, as ``ansp3''. -The ``showanswer'' function will find this div and replace it with a -div containing the mathml result. - -The ``makeRequest'' function is: +displays all command synonyms, \begin{verbatim} - function makeRequest(arg) { - http_request = new XMLHttpRequest(); - var command = commandline(arg); - //alert(command); - http_request.open('POST', '127.0.0.1:8085', true); - http_request.onreadystatechange = handleResponse; - http_request.setRequestHeader('Content-Type', 'text/plain'); - http_request.send("command="+command); - return(false); +)what synonym ver \end{verbatim} -It contains a request to open a local server connection to Axiom, -sets ``handleResponse'' as the function to call on reply, sets up -the type of request, fills in the command field, and sends off the -http request. - -When a response is received, the ``handleResponse'' function checks -for the correct reply state, strips out the important text, and -calls ``showanswer''. +displays all command synonyms containing the substring ``{\tt ver}'', \begin{verbatim} - function handleResponse() { - if (http_request.readyState == 4) { - if (http_request.status == 200) { - showanswer(http_request.responseText,'mathAns'); - } else - { - alert('There was a problem with the request.'+ http_request.statusText); - } - } - } +)what synonym ver pr \end{verbatim} -See bookvol11.pamphlet for further details. - -\section{The axServer/multiServ loop} -The basic call to start an Axiom browser listener is: +displays all command synonyms +containing the substring ``{\tt ver}'' or the substring +``{\tt pr}''. +Output similar to the following will be displayed \begin{verbatim} - )set message autoload off - )set output mathml on - axServer(8085,multiServ)$AXSERV -\end{verbatim} +---------------- System Command Synonyms ----------------- -This call sets the port, opens a socket, attaches it to a stream, -and then calls ``multiServ'' with that stream. The ``multiServ'' -function loops serving web responses to that port. +user-defined synonyms satisfying patterns: + ver pr -\section{The )browse command} -In order to make the whole process cleaner the function ``)browse'' -handles the details. This code creates the command-line function for )browse - -The browse function does the internal equivalent of the following 3 command -line statments: -\begin{verbatim} - )set message autoload off - )set output mathml on - axServer(8085,multiServ)$AXSERV + )apr ........................... )what things + )apropos ....................... )what things + )prompt ........................ )set message prompt + )version ....................... )lisp *yearweek* \end{verbatim} -which causes Axiom to start serving web pages on port 8085 -For those unfamiliar with calling algebra from lisp there are a -few points to mention. +Several other things can be listed with the {\tt )what} command: -The loadLib needs to be called to load the algebra code into the image. -Normally this is automatic but we are not using the interpreter so -we need to do this ``by hand''. - -Each algebra file contains a "constructor function" which builds the -domain, which is a vector, and then caches the vector so that every -call to the contructor returns an EQ vector, that is, the same vector. -In this case, we call the constructor $\vert$AxiomServer$\vert$ +\begin{description} +\item[{\tt categories}] displays a list of category constructors. +\index{what categories} +\item[{\tt commands}] displays a list of system commands available at your +user-level. +\index{what commands} +Your user-level +\index{user-level} +is set via the {\tt )set userlevel} command. +\index{set userlevel} +To get a description of a particular command, such as ``{\tt )what}'', issue +{\tt )help what}. +\item[{\tt domains}] displays a list of domain constructors. +\index{what domains} +\item[{\tt operations}] displays a list of operations in the system library. +\index{what operations} +It is recommended that you qualify this command with one or +more patterns, as there are thousands of operations available. For +example, say you are looking for functions that involve computation of +eigenvalues. To find their names, try {\tt )what operations eig}. +A rather large list of operations is loaded into the workspace when +this command is first issued. This list will be deleted when you +clear the workspace via {\tt )clear all} or {\tt )clear completely}. +It will be re-created if it is needed again. +\item[{\tt packages}] displays a list of package constructors. +\index{what packages} +\item[{\tt synonym}] lists system command synonyms. +\index{what synonym} +\item[{\tt things}] displays all of the above types for items containing +\index{what things} +the pattern strings as substrings. +The command synonym {\tt )apropos} is equivalent to +\index{apropos} +{\tt )what things}. +\end{description} -The axServer function was mangled internally to -$\vert$AXSERV;axServer;IMV;2$\vert$. -The multiServ function was mangled to $\vert$AXSERV;multiServ;SeV;3$\vert$ -Note well that if you change axserver.spad these names might change -which will generate the error message along the lines of: -\begin{verbatim} - System error: - The function $\vert$AXSERV;axServer;IMV;2$\vert$ is undefined. -\end{verbatim} +\par\noindent{\bf Also See:} +\fnref{display}, +\fnref{set}, and +\fnref{show} -To fix this you need to look at int/algebra/AXSERV.nrlib/code.lsp -and find the new mangled function name. A better solution would -be to dynamically look up the surface names in the domain vector. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{with} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -Each Axiom function expects the domain vector as the last argument. -This is not obvious from the call as the interpreter supplies it. -We must do that ``by hand''. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{workfiles} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -We don't call the multiServ function. We pass it as a parameter to -the axServer function. When it does get called by the SPADCALL -macro it needs to be a lisp pair whose car is the function and -whose cdr is the domain vector. We construct that pair here as -the second argument to axServer. The third, hidden, argument to -axServer is the domain vector which we supply ``by hand''. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cmdhead{zsystemdevelopment} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -The socket can be supplied on the command line but defaults to 8085. -Axiom supplies the arguments as a list. -<>= -(defun |browse| (socket) - (let (axserv browser) - (if socket - (setq socket (car socket)) - (setq socket 8085)) - (|set| '(|mes| |auto| |off|)) - (|set| '(|out| |mathml| |on|)) - (|loadLib| '|AxiomServer|) - (setq axserv (|AxiomServer|)) - (setq browser - (|AXSERV;axServer;IMV;2| socket - (cons #'|AXSERV;multiServ;SeV;3| axserv) axserv)))) +\chapter{The Spad Server Mechanism} +<>= +(defvar $openServerIfTrue t "t means try starting an open server") +(defconstant $SpadServerName "/tmp/.d" "the name of the spad server socket") +(defvar |$SpadServer| nil "t means Scratchpad acts as a remote server") @ -Now we have to bolt it into Axiom. This involves two lookups. -We create the lisp pair -\begin{verbatim} -(|browse| . |development|) -\end{verbatim} -and cons it into the \$systemCommands command table. This allows the -command to be executed in development mode. This lookup decides if -this command is allowed. It also has the side-effect of putting the -command into the \$SYSCOMMANDS variable which is used to determine -if the token is a command. +\pagehead{openserver}{openserver} +This is a cover function for the C code used for communication interface. +<>= +(defun openserver (name) + (open_server name)) -\section{The server support code} +@ \chapter{Axiom Build-time Functions} \subsection{defun spad-save} diff --git a/changelog b/changelog index 4f70b09..d1d652d 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,6 @@ +20090302 tpd src/axiom-website/patches.html 20090302.01.tpd.patch +20090302 tpd books/bookvol5 add user command documentation +20090302 tpd books/bookvol0 fix typo 20090228 tpd src/axiom-website/patches.html 20090228.01.tpd.patch 20090228 tpd lsp/Makefile add patch for read-char-no-hang 20090228 tpd zips/gcl-2.6.8pre3.o.read.d.patch fix read-char-no-hang hang diff --git a/src/axiom-website/patches.html b/src/axiom-website/patches.html index f2372ac..c71f4fc 100644 --- a/src/axiom-website/patches.html +++ b/src/axiom-website/patches.html @@ -979,5 +979,7 @@ bookvol5 remove duplicate function
bookvol4 Hyperdoc tutorial on making new pages
20090228.01.tpd.patch gcl-2.6.8pre3.o.read.d.patch fix read-char-no-hang
+20090302.01.tpd.patch +bookvol5 add user command documentation