Go to the first, previous, next, last section, table of contents.


Type Specifics Files

As mentioned up front VLS gets its flexibility through the use of Lisp type specifics files. This chapter expands on the syntax and semantics of these files.

The reader should note that since Lisp type specifics files can be modified or substituted by the user the command descriptions in this document depend on the original VLS packaged Lisp type specifics files.

Given Specifics Files

VLS provides a set of Lisp type specifics files in the VLS installed directory under the subdirectory types. These files all have the .el file extension but only for the purpose of Elisp formatting, they are not Elisp files. For example types/allegro.el. Note however that some specifics files actually load some Lisp specific Elisp code. Such Elisp code is under the directory types/elisp, for example types/elisp/allegro.el.

Format of Specifics Files

Lisp type specifics files are not Elisp source files. They are files that are strictly interpreted by VLS when running a VLS Lisp shell. The only reason for giving them an .el extension is so that they will be in Elisp mode for formatting. And they sometimes do contain some Elisp code. And entry in a Lisp type specifics file can one of four things:

1. A string
2. A list who's first entry is another list
3. A list who's first entry is a symbol
4. An Elisp comment

Anything else, for the time being, is ignored.

In the case of (1.), a string is interpreted as an absolute or relative path name of another Lisp type specifics file to be interpreted by VLS. In the case of (2.), a list whose first element is a list then it is interpreted as a list of Lisp specifics parameters to be interpreted by VLS. In the case of (3.), a list whose first element is a symbol the list is considered to be an Elisp s-expression and it is just evaluated by Elisp. In the case of (4.), Elisp comments are just ignored.

Specifics Parameter Forms

As mentioned in the previous section a Lisp Specifics file with an entry of a list who's first entry is a list is interpreted by VLS as a list of Lisp specifics parameters. Each sublist entry is a list of the form

(parameter-symbol parameter-value)

Where parameter-symbol is the symbol referenced by the VLS code to get a specific Lisp parameter value to support some VLS generalized action. This is the key to the flexibility of VLS and what allows VLS to provide a "vanilla" Lisp shell capability, that is the capability to adapt to any flavor of Lisp without changing the way things work in VLS. The parameter-value then can be one of five things

1. An Elisp specifics string
2. An Elisp s-expression that returns a specifics string
3. An Elisp list of specifics strings
4. An Elisp s-expression that returns a list of specifics strings
5. Any Elisp value

In the first four cases above the semantics of a "specifics string" is an Elisp string that VLS can send to the current List process where it will be interpreted as a legitimate input. In the case of (3.) and (4.) a list of specifics strings means that VLS should send that list sequentially to the current Lisp process.

In the case of (2.) and (4.) VLS will evaluate the Elisp s-expression for either a specifics string or a list of specifics strings. And in the case of (2.) and (4.) the Elisp s-expression can reference the locally bound variable arg which is bound to the raw Emacs prefix argument (nil, a number or list of a number). In some cases VLS will dispatch on the Emacs prefix argument but in others the specifics parameter is expected to do that dispatching in its Elisp code. In some cases where a VLS command will dispatch on the prefix argument or does not need the prefix argument it may pass some other value in the arg local variable. Also if there needs to be more that one argument the rest are passed in a local variable args which is a list of the rest of the arguments. This document will indicate how each parameter must interpret the arg and args variable, See section Command Specifics Parameters.

The cases (1.) through (4.) above are meant for the command parameters classified in the previous section that by convention have a c: prefix. The cases of (1.) and (2.) also apply to the Lisp probe specifics parameters with a prefix of p:. Lisp probes should not use cases (3.) or (4.) since a single return value is required for probes. The case of (5.) is for variables with a prefix of v: and mechanism with a prefix of m:.

In all cases of specifics parameters recursion can be used. That is to say, a parameter-value can refer to a previously established parameter-value recursively. And any such recursively referenced parameters must have been defined otherwise the parameter-value will be an Elisp nil. The reference is done by invoking the VLS function vls-spec

Function: vls-spec Meaning: Given a parameter-symbol will return its parameter-value.

An example of this is the Common Lisp reset to top level message parameter

(c:reset-top-message 
  "(progn (format t \"Reset to top level\") (values))")

where for example the Allegro specifics parameter c:top-listener references this value

(c:top-listener (list ":reset" (vls-spec 'c:reset-top-message)))

The reader may wonder why strings are used in cases (1.) through (4.) instead of just s-expressions, since after all VLS only talks to Lisp processes. There are two reasons for this. First is that the syntax of some forms in any particular Lisp may not have a representation in Elisp forms. And second, some modern Lisp implementations add easy typing conveniences interpreted by their Lisp listeners in special cases, like break loops. And in these cases the easy typing conveniences are usually non-legitimate s-expressions.

Lisp Specifics Parameters

As a convention VLS Lisp specifics parameters are named with Elisp symbols that start with the following letter prefixes

c: command
m: mechanism
p: probe
v: variable

Although a convention every specifics parameter symbol name must have a colon as the second character. This is to insure that internal specifics parameter symbols will never accidentally clash with these specifics parameter symbols.

If the symbol if prefixed with a "c:" it means that the symbol defines a command parameter used by Lisp shell commands. The "p:" prefix means that the symbol defines a probe command sent to the current Lisp shell for collecting some information about the Lisp process. The "v:" prefix means that its symbol defines a variable used by VLS having a value specific to the type of Lisp. The "m:" prefix means its parameter value contains some internal VLS mechanism that is peculiar to the specific type of Lisp. It is helpful to classify the specifics parameters in this way and the subsections in this section are based on this classification.

Command Specifics Parameters

When you execute a VLS command in a VLS Lisp shell buffer, like vls-back-trace, it dispatches a command to the current Lisp process using the value of one of the specifics parameters in this subsection. These parameters must be a form that resolves to a string or strings that represents a legitimate expression that will be interpreted by the current Lisp process without error, Specifics Parameter Forms. If a prefix argument is specified it is passed in arg. If other than a prefix argument is passed in arg or args it is explained separately for each parameter.

Lisp Specific Parameter: c:apropos Meaning: Used by the vls-apropos command to do an apropos on the symbol that point in on. The symbol is passed as the first of args.

Lisp Specific Parameter: c:back-trace Meaning: Used by the vls-back-trace command to print a stack back-trace when in a break handler. Prefix arguments should do something implementation dependent and useful with the execution stack, like print out a more or less detailed stack or more or less of a stack.

Lisp Specific Parameter: c:compile-file Meaning: Used by the vls-compile-file command to compile the current buffer's file in the current Lisp process. The file string is passed in arg.

Lisp Specific Parameter: c:current-frame Meaning: Used by the vls-current-frame command to print out information about the current stack frame in the current Lisp shell buffer.

Lisp Specific Parameter: c:compile Meaning: Used by various commands to compile a definition who's symbol name is passed in arg.

Lisp Specific Parameter: c:describe Meaning: Used by the vls-describe command to describe the symbol that point in on. The symbol is passed as the first of args.

Lisp Specific Parameter: c:down-stack Meaning: Used by the vls-down-stack command to move down the run time stack one frame; meaning to make that frame the current frame. A positive integer prefix argument N should move down N frames. A C-u prefix argument should move to the bottom of the stack.

Lisp Specific Parameter: c:exit-lisp Meaning: Used by the vls-exit-lisp command to exit the Lisp process.

Lisp Specific Parameter: c:focus-process Meaning: For Lisps that have multiprocessing and access to a process list, this parameter is used by the vls-focus-process command to focus a Lisp listener on the first process in a process list. A numeric prefix argument N should focus the Nth process in a process list. A C-u prefix argument should print the process list in the current Lisp shell buffer.

Lisp Specific Parameter: c:help Meaning: Used by the vls-help command to print out a list of commands used by the current Lisp in the current Lisp context. Typically these are abbreviated commands as opposed to proper s-expressions, but they don't have to be.

Lisp Specific Parameter: p:in-package Meaning: For Lisps that have a symbol package system this expression should put the current Lisp process in a given package. The package string is passed in arg.

Lisp Specific Parameter: c:load-file-print Meaning: Used by the vls-load-source and vls-load-source-or-binary commands to load the file passed in arg and to print the results of each s-expression in the file.

Lisp Specific Parameter: c:load-file Meaning: Used by the vls-load-source and vls-load-source-or-binary commands to load the file passed in arg.

Lisp Specific Parameter: c:message Meaning: An expression that prints a given message using the current Lisp process in the current Lisp buffer. The message string is passed in arg. This expression should not return a value if possible.

Lisp Specific Parameter: c:pop-listener Meaning: Used by the vls-reset-listener command to "pop" the current listener into the previous listener. The prefix argument argis always an integer N and it means to pop the listeners to the Nth previous listener. For example if the current Lisp was in a break listener and typed an expression that signaled an error into another break listener, this command were arg = 1 would pop back to the first break listener.

Lisp Specific Parameter: c:reset-top-message Meaning: If needed, used by the c:top-listener specifics parameter to include a string s-expression that will print that the Lisp process is at top level after the first parameter's s-expression actually puts the process in top level.

Lisp Specific Parameter: c:return-frame Meaning: Used by the vls-return-frame command (usually during a break loop) to return nil to the current stack frame call and continue the computation. If a non-nil value is passed in the local arg variable then return that value and do the same.

Lisp Specific Parameter: c:step-next Meaning: Used by the vls-step command to step the Lisp stepper one step. If the arg is an integer N then step N times.

Lisp Specific Parameter: c:step-over Meaning: Used by the vls-step command to evaluate the current expression in non-stepping mode and continue stepping.

Lisp Specific Parameter: c:top-listener Meaning: Used by the vls-reset-listener command to pop the current Lisp into the top level listener regardless of how many listeners nested deep the current Lisp process is.

Lisp Specific Parameter: c:up-stack Meaning: Used by the vls-up-stack command to move up the run time stack one frame; meaning to make that frame the current frame. A positive integer prefix argument N should move up N frames. A C-u prefix argument should move to the top of the stack.

Lisp Specific Parameter: c:var-print Meaning: This expression should pretty print if possible or just print if not possible a given variable in the current Lisp buffer. The variable string is passed in arg.

Lisp Specific Parameter: p:var-reset Meaning: This expression should a reset the value for a given variable and then print that the given variable name was reset and its new value. The variable name string will be passed in arg. The reset value will be based on the data type of the variable value. So if the type is number it should be 0, if the type is a list it should be the empty list, if the type is a string it should be the empty string, ... etc.

Lisp Specific Parameter: c:var-value Meaning: Used by the vls-var-value command to return the value of a local variable in a stack frame.

Lisp Specific Parameter: c:what-error Meaning: Used by the vls-what-error command to print the current error being handled by the Lisp process.

Lisp Specific Parameter: c:what-package Meaning: For Lisps that have a symbol package system this parameter is used by the vls-what-package command to display the current package in the current Lisp process.

Mechanism Specifics Parameters

Some specifics parameters are needed for VLS internal mechanisms, such as adding specific documentation strings to VLS functions. This section describes those parameters.

Lisp Specific Parameter: m:more-doc Meaning: Indicates more documentation string is to be added to the vanilla documentation string of VLS commands. Its value must be a list of two element lists were each two element list is of the form

(function-name additional-doc-string)

where function-name is a VLS function that needs additional specific documentation added to the vanilla documentation of function-name and additional-doc-string is that additional documentation string. A common use is to add additional documentation for command prefix arguments that have slightly different meaning for each specific Lisp type.

Lisp Specific Parameter: m:replace-doc Meaning: Indicates two things. First, different from m:more-doc where more documentation is added to the vanilla string, the whole vanilla documentation string is replaced by this string. Its value must be a list of two element lists were each two element list is of the form

(function-name replacement-doc-string)

where function-name is a VLS function that will have its documentation replaced by replacement-doc-string. And thus, second and equally important, since replacing the whole command documentation VLS assumes that any predefined logic of the command should not be used and instead the a VLS types parameter named function-name will return a value being a string that is sent to the current Lisp process. Note that in this case any Elisp logic for the command, if even needed, must be performed by the Elisp code, if any, specified as the parameter value. Also note that this implies that whenever a m:replace-doc parameter is specified a function-name parameter must be specified; otherwise the replaced command will refuse to execute with an error.

The m:replace-doc parameter and its implications seems rather complicated but is actually very simple, it simply triggers a specific VLS command whose current Lisp buffer specific semantics are totally different from any vanilla semantics. This is usually only necessary when a Lisp implementation does not provide enough functionality to implement the vanilla semantics but still wants to have such a specific VLS command. Clisp for example prefers to prompt the user for a return/continue value when in a break loop rather than have Emacs prompt the user with a C-u prefix argument as the vanilla VLS command vls-return-frame specifies. The Clisp type specifics file then contains the following parameters to make this happen

 (m:replace-doc
  ((vls-return-frame
    "Return a value from the current stack frame and continue.")))
 (vls-return-frame "Return")

The first parameter m:replace-doc changes the vanilla command documentation and the second parameter vls-return-frame required by virtue of the first, changes the behavior of the vanilla command vls-return-frame for Clisp to just send the string "Return" to the current Lisp process.

Probe Specifics Parameters

The probe specifics parameters are used by VLS to get some necessary information from the current Lisp process. Each of these parameters should be an Elisp string that contains an expression that when sent to the current Lisp will return a value. In cases where there should be instance values substituted in the Elisp string there should be %s characters at that point in the s-expression.

Lisp Specific Parameter: p:bound-var-test Meaning: A predicate that should be true if a given variable is bound in the current Lisp process. There must be a %s where the name of the variable will occur in the s-expression.

Lisp Specific Parameter: p:current-package Meaning: For Lisps that have a symbol package system this should be an expression that will return the current Lisp process package name.

Lisp Specific Parameter: p:package-predicate Meaning: For Lisps that have a symbol package system this expression is a predicate that should be true if the a given package exists. There must be a %s where the package name should occur.

Variable Specifics Parameters

Variable specifics parameters are specific values that are needed by the VLS interface to the current Lisp process and buffer and can not be classified as commands, probes or internal mechanism. Or in other words everything else.

Lisp Specific Parameter: v:end-expression Meaning: A string of a character or characters that the specific Lisp process needs to indicate that all the data that is to be sent in fact has been sent. For example in most Common Lisps this is the newline character. Note that this works for any amount or kind of data sent to the Lisp process since embedded end expression characters in the data are eaten by the parsing of s-expressions.

Lisp Specific Parameter: v:eval-print-separator Meaning: After evaluating a Lisp expression in the current Lisp buffer the characters in this string will be inserted in the buffer before the return value is printed. This is mean to be something like a newline or empty string depending on how the specific Lisp process returns the return value string.

Lisp Specific Parameter: v:global-debug-variable-prefix Meaning: Used by VLS helper functions like vlsi-gvar-unique to automatically create a global variable name that is unique for all practical purposes. This prefix string will start the symbol name and other parts of the variable name will be computed based on the usage.

Lisp Specific Parameter: v:has-packages Meaning: If this parameter exits for the current Lisp and has a non-nil value then it indicates the the current Lisp has a symbol package system. This means that the current Lisp has more than one name-space for symbols, but further means that it has some functionality for dealing with packages like the in-package of Common Lisp. If some Lisp is invented that has a symbols package system with a different functionality VLS may have to be augmented to deal with that new functionality.

Lisp Specific Parameter: v:in-package-re Meaning: If the current Lisp has v:has-packages non-nil and it has a form that puts the current Lisp into a new symbol package then v:in-package-re should be an Elisp regular expression that allows Elisp search functions to use and successfully find such an expression in a buffer.

Lisp Specific Parameter: v:instrument-visual Meaning: A string that serves as a comment for the current Lisp and the nature of the comment indicates and delineates an instrument s-expression follows that was inserted in the users code. The characters %s must appear in the string where the instrument will be inserted.

For example this string for Common Lisp defaults to

"\n;; *Instrument* \n%s\n\n"

Note the newlines which also delineate the instrument s-expression from user code.

Lisp Specific Parameter: v:instruments Meaning: This is an Elisp variable where the instruments for the current lisp are stored, See section Creating Instruments. For example in Common Lisp the variable vls-cl-instruments. Having the value of this parameter be an Emacs variable rather than the instrument list itself gives the user a bit more flexibility in maintaining his own instruments.

Lisp Specifics Code

In composing Lisp specifics code, if the specific Lisp has a package system then strictly speaking one needs to make sure that all lisp code functions are of the fully qualified package form package:function. For example in Common Lisp specifying lisp:car instead of just car. The reason is that when sending code to the current Lisp process, the current package may not use the given package.

Considering that doing this is too pedantic VLS chooses not to do this in the given set of Lisp specifics parameters for the sake of making it easier to add specifics Lisp code. The risk of course is that if the symbols used are not in the current Lisp process package then then a VLS command may break with an undefined function. But this should be rare and seldom be a problem. If it does become a problem then a future version of VLS would probe the Lisp process to make sure that the current package is copacetic and if not put the process in a package that is.

Dealing with prompts

It is important to understand issues of Lisp prompts in any Lisp shell. Lisp prompts can be problematical to a Lisp shell if not handled properly. Not all such things that are thus problematical are strictly speaking Lisp prompts. A "proem" is a kind of introductory text and this document uses the term "proem" to refer to such Lisp prompts that are not really prompts. In a Lisp read-eval-print loop, more modern referred to as a "Lisp listener", there is a continuous loop where the Lisp process reads an s-expression from the user, evaluating it and then returning the value and printing it. It most modern Lisps an option is to have a prompt printed asking for the user input to be read. Some Lisps will also have a proem to introduce the printed return value, like for example printing "Value: " followed by the actual return value.

For prompts where there is white-space before and after the prompt there will never be a problem in VLS. There is almost always a white-space before a prompt since traditionally read-eval-print loops emit a newline character after the printing of each return value. If not VLS provides a specifics parameter v:eval-print-separator for this purpose.

If there is no white-space after the prompt the VLS command vls-eval-previous for example might include the prompt in the value to be evaluated. For example if you specified a prompt of "Enter:" and you typed "a" to evaluate the variable a VLS would interpret Enter:a as a whole legitimate symbol, as it should it most Lisps. The obvious cure in this example is to use a prompt like "Enter: " instead with a white-space character at the end.

For VLS, proems however are problematical regardless of white space. When VLS probes the current Lisp process for values, if a proem appears in the output stream along with the value VLS has no way of knowing if the proem is part of the output or not without some extra help. If there is a proem in a specific Lisp then the specifics files should specify the v:output-proem-regexp parameter.

VLS was designed to allow a free form scratch pad paradigm for operating the Lisp shell where there is no prompt or proem, much like the Elisp *scratch* buffer. We encourage the user to try this kind of paradigm and there is usually a way to set your prompts to nil or the empty string so that there are no prompts. It is a lot cleaner and it makes the Lisp shell buffer almost completely the same as a Lisp file buffer. Lisp read-eval-print loops do not need a prompt since there is always a return value printed as feedback to the user that it is ready for another input. There in one exception to this that the author knows of which is in Common Lisp if a function ends with a no argument values expression which means that the function will return no value. But in this case it is frequently used for making a nice display without an interfering output value, much like Common Lisp's pprint. VLS makes it easy to get information that is typically provided in a prompt string. For example in Lisps that have symbol package systems, it is easy in VLS to view the current Lisp package at any time. All this being said the encouraged free form paradigm applies mostly to Lisp files and the Lisp shell buffer at the top level listener. In other listeners however, like a stepper or break listener prompts with information like the break level are useful however.

Using Specifics Files

VLS provides a set of Lisp Type Specifics Files for many Lisp implementations and specifications. You can use these files if they serve your purposes, you can augment those files or you can completely create your own Specifics files using the given ones as examples.

Lets say for example that you want to augment the given Lisp Specifics and just change two Lisp Specifics parameters, one of for a Lisp specification of Common Lisp and another for a Lisp implementation Allegro. Here is an example of how to do this.

First create your own Specifics file in some directory $SOMEDIR for allegro in a file $SOMEDIR/allegro.el as follows

$VLSLIBDIR/types/allegro.el"

;; My Allegro specific stuff examples
;;; Change cl.el c:compile-file option only known to Allegro
((c:compile-file 
  (format "(compile-file \"%s\" :xref nil :verbose t)" arg))
;;; Change allegro.cl default of debug global variable prefix
 (v:global-debug-variable-prefix "/*"))

Then if you create a Lisp shell command

; Example Lisp shell command for illustration
(defun my-lisp-shell ()
  "My Lisp Shell"
  (interactive)
  (vls-shell '(my-allegro "lisp" "$SOMEDIR/allegro.el")))

and after executing my-lisp-shell the following will happen:

First $VLSLIBDIR/types/allegro.el will be interpreted by VLS. At this point everything would be as if you had just used the given $VLSLIBDIR/types/allegro.el in the above example Lisp shell command. Then the following parameters list would override the given Specifics parameters c:compile-file and c:compile-file with your versions of those parameters. And finally VLS would execute this my-allegro Lisp shell that will use these new parameters.


Go to the first, previous, next, last section, table of contents.