Commit 48248b80 authored by Marco Antoniotti's avatar Marco Antoniotti 💬

Modified documentation strings.

parent bc69480c
......@@ -67,17 +67,35 @@
(define-condition unification-template-error (simple-error)
())
;;; Templates are introduced by the reader macro #T(...)
;;; template
;;; ========
(defclass template ()
((spec :accessor template-spec :type (or symbol cons) :initarg :spec))
(:default-initargs :spec nil))
(:default-initargs :spec nil)
(:documentation "The TEMPLATE Class.
The root of the hierarchy of template objects.")
)
(defgeneric template-p (x)
(:documentation "Returns T if the argument X is a TEMPLATE.
Arguments and Values:
X : any object
result : a BOOLEAN
")
(:method ((x template)) t)
(:method ((x t)) nil))
;;; type-template
;;; =============
(defclass type-template (template) ())
(defgeneric type-template-p (x)
......@@ -93,6 +111,8 @@
'null))))
;;; nil-template
;;; ============
(defclass nil-template (type-template) ()) ; This is the point where we break the type hierarchy.
......@@ -101,7 +121,14 @@
(:method ((x t)) nil))
(defclass expression-template (template) ())
;;; expression-template
;;; ===================
(defclass expression-template (template)
()
(:documentation "The EXPRESSION-TEMPLATE Class.
This class is the root of the 'expression template' sub-hierarchy."))
(defgeneric expression-template-p (x)
(:method ((x expression-template)) t)
......@@ -112,6 +139,9 @@
(format stream "#T~S" (template-spec template)))
;;; sequence-template
;;; =================
(defclass sequence-template (type-template) ())
(defgeneric sequence-template-p (x)
......@@ -119,6 +149,9 @@
(:method ((x t)) nil))
;;; list-template
;;; =============
(defclass list-template (sequence-template) ())
(defgeneric list-template-p (x)
......@@ -128,6 +161,9 @@
;;; 20121204 experimental
;;; plist-template
;;; ==============
(defclass plist-template (list-template) ())
(defgeneric plist-template-p (x)
......@@ -135,6 +171,9 @@
(:method ((x t)) nil))
;;; lambda-template
;;; ===============
(defclass lambda-template (list-template expression-template) ())
(defgeneric lambda-template-p (x)
......@@ -142,14 +181,115 @@
(:method ((x t)) nil))
;;; array-template
;;; ==============
(defclass array-template (type-template)
()
(:documentation "The ARRAY-TEMPLATE Class.
The instances of this class are objects that can be used to unify
against arrays.
The syntax of this particular template is the following:
<pre>
#T(array &lt;shape-template&gt;)
</pre>
<pre>
#T(&lt;CL array type specifier&gt; &lt;shape-template&gt;)
</pre>
<pre>
#T(array ([* | &lt;CL type specifier&gt;] [&lt;dimension spec&gt;]) &lt;shape-template&gt;)
</pre>
Where &lt;shape-template&gt; can be:
<pre>
&lt;shape-template&gt; ::= &lt;sequence-template&gt;
| &lt;destructuring template lambda list&gt;
| (&lt;shape-template&gt;)
</pre>
The ARRAY-TEMPLATE syntax denotes an ARRAY object. An ARRAY-TEMPLATE
must be unified against an ARRAY object. The elements of the array
must be unified against the &lt;shape-template&gt;. Each row of the
array is unified recursively against each element of the
&lt;shape-template&gt;.
Examples:
(defclass array-template (type-template) ())
cl-prompt> (setf e (unify #(0 1 42 3 4 5) #T(array (0 1 ?x 3 4 5))))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
42
cl-prompt> (setq e (unify #(0 1 42 3 4 5) #T(array (0 1 \"FOO\" 3 4 5))))
==> Error: UNIFICATION-FAILURE
cl-prompt> (setq e (unify #2A((0 1 42) (3 4 5)) #T(array ((0 1 ?x) (3 4 5)))))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
42
cl-prompt> (setq e (unify #2A((\"foo\" \"bar\" 42) (3 4 5)) #T(array ((_ _ ?x) (3 4 5)))))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
42
cl-prompt> (setq e (unify #2A((\"foo\" \"bar\" 42) (3 4 5)) #T(array (#T(vector _ &rest ?x) (3 4 5)))))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
#(\"bar\" 42)
Exceptional Situations:
Unifying an ARRAY-TEMPLATE against a non-ARRAY object results in an
UNIFICATION-FAILURE error being signaled.
Notes:
<h3>Syntax Note</h3>
The ARRAY-TEMPLATE syntax tries to be easy to use, at the cost of
being overloaded. There is no actual need to have the separate
forms <code>(<b>array</b> (fixnum) ...)</code> and
<code>((<b>array</b> fixnum) ...)</code>.
In a future release they may be conflated. For the time being
they are kept separate as it is unclear which would be better to
provide.
<h3>Elements Unification</h3>
It would be nice to have the possibility to unify against
<em>slices</em> of the array. Alas, this seems non trivial to get
right, and it is left as a future extension of the semantics of
<i>&lt;shape-template&gt;</i>.
<h3>ARRAY Structural Properties</h3>
For the time being, there is no way to \"unify\" against structural
properties of vectors like fill pointers and displacements.
")
)
(defgeneric array-template-p (x)
(:method ((x array-template)) t)
(:method ((x t)) nil))
;;; vector-template
;;; ===============
(defclass vector-template (sequence-template array-template) ())
(defgeneric vector-template-p (x)
......@@ -157,6 +297,9 @@
(:method ((x t)) nil))
;;; string-template
;;; ===============
(defclass string-template (vector-template) ())
(defgeneric string-template-p (x)
......@@ -164,6 +307,9 @@
(:method ((x t)) nil))
;;; symbol-template
;;; ===============
(defclass symbol-template (type-template) ())
(defgeneric symbol-template-p (x)
......@@ -171,6 +317,9 @@
(:method ((x t)) nil))
;;; number-template
;;; ===============
(defclass number-template (type-template)
())
......@@ -179,6 +328,8 @@
(:method ((x t)) nil))
;;; structure-object-template
;;; =========================
(defclass structure-object-template (type-template) ())
......@@ -187,6 +338,9 @@
(:method ((x t)) nil))
;;; standard-object-template
;;; ========================
(defclass standard-object-template (type-template) ())
(defgeneric standard-object-template-p (x)
......@@ -194,7 +348,11 @@
(:method ((x t)) nil))
;;; Expression Templates.
;;; Expression Templates
;;; ====================
;;; subseq-template
;;; ---------------
(defclass subseq-template (expression-template) ())
......@@ -203,14 +361,24 @@
(:method ((x t)) nil))
;;; element-template
;;; ----------------
(defclass element-template (expression-template)
()
(:documentation "The ELEMENT-TEMPLATE Class.
(defclass element-template (expression-template) ())
The instances of this class are those object that are used to unify
against a particular element of an ARRAY or a SEQUENCE."))
(defgeneric element-template-p (x)
(:method ((x element-template)) t)
(:method ((x t)) nil))
;;; elt-template
;;; ------------
(defclass elt-template (element-template) ())
(defgeneric elt-template-p (x)
......@@ -218,13 +386,89 @@
(:method ((x t)) nil))
(defclass aref-template (element-template) ())
;;; aref-template
;;; -------------
(defclass aref-template (element-template)
()
(:documentation "The AREF-TEMPLATE Class.
The instances of this class are those object that are used to unify
against a particular element of an ARRAY.
The syntax of these templates is the following:
<pre>
#T(<b>aref</b> (<i>index1</i> ... <i>indexN</i>) <i>item</i>)
</pre>
<pre>
#T(<b>aref</b> <i>index</i> <i>item</i>)
</pre>
The AREF-TEMPLATE syntax denotes the <i>item</i> at <i>index1</i> ...
<i>indexN</i> of an ARRAY. An AREF-TEMPLATE must be unified against a
ARRAY object. <i>item</i> is <em>unified</em> against the element
extracted from the sequence object at <i>index1</i> ... <i>indexN</i>
by the standard function AREF.
The second form is a shorthand.
<pre>
#T(<b>aref</b> <i>index</i> <i>item</i>) <==> #T(<b>aref</b> (<i>index</i>) <i>item</i>)
</pre>
Examples:
cl-prompt> (setf e (unify #(0 1 42 3 4 5) #T(aref 2 ?x)))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
42
cl-prompt> (setq e (unify #(0 1 42 3 4 5) #T(aref 42 ?x)))
==> Error: index 42 out of bounds.
cl-prompt> (setq e (unify 42 #T(aref 42 ?x)))
==> Error: UNIFICATION-FAILURE
cl-prompt> (setq e (unify \"This is a string!\" #T(aref 4 ?x)))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
#\\Space
cl-prompt> (setq e (unify #2A((1 0) (foo bar)) #T(aref (1 1) ?x)))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
BAR
cl-prompt> (setq e (unify #2A((1 0) (foo bar)) #T(aref (1 1) baz)))
==> Error: UNIFICATION-FAILURE
cl-prompt> (setq e (unify #2A((1 0) (foo ?x)) #T(aref (1 1) baz)))
#<ENVIRONMENT xxx>
cl-prompt> (find-variable-value '?x e)
BAZ
Exceptional Situations:
Unifying an AREF-TEMPLATE against a non-ARRAY object results in an
UNIFICATION-FAILURE error being signaled.")
)
(defgeneric aref-template-p (x)
(:method ((x aref-template)) t)
(:method ((x t)) nil))
;;; nth-template
;;; ------------
(defclass nth-template (element-template) ())
(defgeneric nth-template-p (x)
......@@ -232,6 +476,9 @@
(:method ((x t)) nil))
;;; nthcdr-template
;;; ---------------
(defclass nthcdr-template (element-template) ())
(defgeneric nthcdr-template-p (x)
......@@ -239,9 +486,29 @@
(:method ((x t)) nil))
(defgeneric make-template (kind spec))
;;; Template instantiation
;;; ======================
(defgeneric make-template (kind spec)
(:documentation "The 'template' factory.
Creates a TEMPLATE instance based on the values of KIND and SPEC.
Arguments and Values:
KIND : a T
SPEC : a T
result : a TEMPLATE
Exceptional Situations:
May signal an error if a particular combination of KIND and SPEC is either
not consistent or handled."))
;;; #T reader macro
;;; ---------------
;;;
;;; Setting up the reader macro.
;;; 20080711 MA:
......@@ -256,11 +523,12 @@
(cons (make-template (first spec) spec))
(t (make-template spec spec)))))
(defmethod make-load-form ((x template) &optional env)
(make-load-form-saving-slots x :environment env))
#||
#|
;;; Version with more 'macro-like' behavior. The previous version
;;; created an object at read-time, which may cause problems with
;;; MAKE-LOAD-FORMs, constant-ness etc etc.
......@@ -277,13 +545,13 @@
(cons `(make-template ',(first spec) ',spec))
(t `(make-template ',spec ',spec)))
))
||#
|#
(eval-when (:load-toplevel :execute)
(set-dispatch-macro-character #\# #\T '|sharp-T-reader|))
#|| Useless with the read time templates and MAKE-LOAD-FORM.
#| Useless with the read time templates and MAKE-LOAD-FORM.
(defun rewrite-template-spec (spec)
"Rewrites a template specification.
......@@ -302,8 +570,7 @@ The result is either the SPEC itself or an appropriate call to LIST."
)))
(t `',spec)))
||#
|#
(defmethod make-template ((kind null) (spec symbol))
......@@ -415,20 +682,47 @@ The result is either the SPEC itself or an appropriate call to LIST."
;;;
;;; Initialize the instance by checking a few constraints.
(defparameter *known-number-template-constants*
'(pi))
(defmethod initialize-instance :before ((nt number-template) &key spec &allow-other-keys)
(etypecase spec
(symbol (assert (variablep spec)))
(symbol (assert (or (member spec *known-number-template-constants*
:test #'eq)
(variablep spec)) ()
"~A is a symbol but not an unification variable." spec))
(number spec)
(cons (destructuring-bind (number-type-spec n)
spec
(assert (subtypep number-type-spec 'number))
(when (numberp n)
(unless (typep n number-type-spec)
(error 'unification-template-error
:format-control "Number type clash in NUMBER-TEMPLATE: ~S and ~S."
:format-arguments spec)))
))))
(etypecase n
(number
(unless (typep n number-type-spec)
(error 'unification-template-error
:format-control "Number type clash in NUMBER-TEMPLATE: ~S and ~S."
:format-arguments spec)))
(symbol (assert (or (member spec *known-number-template-constants*
:test #'eq)
(variablep n)) ()
"~A is a symbol but not an unification variable."
n))
)))))
(defmethod initialize-instance :after ((nt number-template) &key spec &allow-other-keys)
(when (consp spec)
(destructuring-bind (number-type-spec n)
spec
;; Let's constant fold a few known ones.
(case n
(pi (if (not (subtypep number-type-spec (type-of pi)))
(error 'unification-template-error
:format-control "Number type clash in NUMBER-TEMPLATE: ~S and ~S."
:format-arguments spec)
(setf (template-spec nt)
`(,number-type-spec ,pi))))))
))
(defun number-template-number (x)
......@@ -456,8 +750,6 @@ The result is either the SPEC itself or an appropriate call to LIST."
(find-class (first (template-spec x))))))
;;; Sequence Templates.
;;; Specification is
;;;
......@@ -507,7 +799,6 @@ The result is either the SPEC itself or an appropriate call to LIST."
;;; or
;;; (<array type specifier> <shape template>)
(defun array-template-shape-template (x)
(declare (type array-template x))
(assert (array-template-p x) (x) "Non array template ~S." x)
......@@ -541,7 +832,6 @@ The result is either the SPEC itself or an appropriate call to LIST."
'*)))
;;; Structure and Standard Object Templates.
(defun structure-object-template-class (x)
......@@ -565,7 +855,6 @@ The result is either the SPEC itself or an appropriate call to LIST."
;;;---------------------------------------------------------------------------
;;; Expression Templates.
;;; AREF Templates.
(defun aref-template-indexes (x)
......@@ -582,15 +871,15 @@ The result is either the SPEC itself or an appropriate call to LIST."
(third spec)))
;;;===========================================================================
;;; Template variables.
;;; Let's walk down a template.
;;; Note that there is an asymmetry here: I admit some containers to have
;;; variables inside, but I do not search instances of a class for variables.
;;; This is an asymmetry that would be way too hard to fix without more
;;; introspective power (which is available in the MOP, but not standard.)
;;; introspective power (which is available in the MOP, but not
;;; standard.) Let's not despair though: CLAST is on its way.
(defgeneric collect-template-vars (template))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment