All Manuals > LispWorks® User Guide and Reference Manual > 35 The DSPEC Package

define-form-parser Macro

Summary

Establishes a parser for top level forms with the given definer.

Package

dspec

Signature

define-form-parser definer-and-options &optional parameters &body body => parser

definer-and-options ::= definer | (definer {option}*)

option ::= (:parser parser-function) | (:alias alias) | (:anonymous anonymous)

parameters ::= nil | ({param}* [&rest param-getter])

Arguments
body
The body of a parser function.
definer
A symbol naming a definer of functions, macros, variables and so on.
parser-function
A symbol.
alias
A symbol naming a definer of functions, macros, variables and so on.
anonymous
A boolean.
param
A symbol.
param-getter
A symbol.
Values
parser
A form parser function.
Description

The macro define-form-parser defines a form parser function for forms beginning with definer.

When a symbol definer has an associated form parser function, this function is used by the source location commands such as Expression > Find Source in the LispWorks IDE. Having identified the file where the definition was recorded, LispWorks parses the top level forms in the file looking for the one which matches the definition spec. When found, this match is displayed.

If parameters and body are omitted, then the form parser is expected to be defined by a different define-form-parser form. In this case, you can either supply the :alias option, which makes the form parser for definer be the same as the form parser for alias, or you can supply the :parser option to name another form parser function.

If parameters and body are supplied, then define-form-parser defines a global function named parser-function that executes the forms in body and is expected to return the dspec of the form being parsed. If the :parser option is omitted then parser-function defaults to a symbol in the current package whose symbol name is the symbol name of definer with "-FORM-PARSER" appended. While executing body, definer is bound to the car of the actual form being parsed. In simple cases, this is just definer itself, but if definer is used in the :alias option of another form parser then definer will be bound to the car of that form instead. In addition, each param are bound to subsequent subforms of the form being parsed. If &rest param-getter is supplied, then it is bound to a function of no arguments that returns two values: the next subform of the form being parsed if there is one and a boolean to indicate if a subform was found.

If definer is the name of a defining macro (for example defvar), then body is expected to return a dspec for that macro or nil if this is not possible.

Alternatively, definer can be a macro that acts like an implicit progn. Such macros (for example, eval-when) are used in a source file to wrap other definitions in the file, but do not have a name themselves. For these macros, body should return a list (progn n) where n is the index of the first subform that contains a definition. For example for eval-when, the form parser would return (progn 2).

If anonymous is non-nil then definer is not associated with the form parser. This is useful in conjunction with parameters and body for defining generic form parsers that can be used in other define-form-parser forms.

LispWorks contains pre-defined form parser functions for the Common Lisp definers defun, defmethod, defgeneric, defvar, defparameter, defconstant, defstruct, defclass, defmacro and deftype and for LispWorks definers such as fli:define-foreign-type and define-form-parser itself.

Examples

Define a parser for def-foo forms which have a single name as the second element in the form:

(dspec:define-form-parser def-foo (name)
  `(,def-foo ,name))

Define a parser for def-other-foo forms which are like def-foo forms:

(dspec:define-form-parser 
    (def-other-foo (:parser def-foo-form-parser)))

Define a parser for def-bar forms whose name is made from the second element of the form and any subsequent keywords:

(dspec:define-form-parser def-bar (name &rest details)
  `(,def-bar (,name
              ,@(loop for detail = (funcall details)
                      while (keywordp detail)
                      collect detail))))

Define a parser for forms which have another name as the second element in the form:

(dspec:define-form-parser (two-names
                           (:anonymous t)) (name1 name2)
  `(,two-names ,name1 ,name2))

Define a new way to define CLOS methods, and tell the dspec system to treat them the same. Note the use of define-dspec-alias to inform the dspec system that my-defmethod is another way of naming defmethod dspecs:

(defmacro my-defmethod (name args &body body)
  `(defmethod ,name ,args 
     ,@body))
 
(dspec:define-dspec-alias my-defmethod 
    (name &rest args)
  `(defmethod ,name ,@args))
 
(my-defmethod foo ((x number)) 
  42)
 
(dspec:define-form-parser 
    (my-defmethod 
        (:parser 
         #.(dspec:get-form-parser 'defmethod))))

A simpler way to write the last form is:

(dspec:define-form-parser
    (my-defmethod
        (:alias defmethod)))
See also

get-form-parser
parse-form-dspec


LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:33