src/: Abolish the distinction between different kinds of initializers.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 5 Jan 2016 19:18:55 +0000 (19:18 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 29 May 2016 14:09:03 +0000 (15:09 +0100)
It made parsing difficult, both because the kind and value needed to be
carted about together, and just technically because of `scan-c-fragment'
interacts badly with token-level lookahead.

Against that, the formatting benefits are very slim, and more so when
one considers that there are ugly `#line' markers around the value
fragment.

So, the distinction is gone; there are no more `value-kind' slots or
arguments; and the `value-form' is now just plain `value'.

This is a fairly straightforward change (except for the radical
simplification of the `parse-initializer' function, which hardly needs
to exist any more), but somewhat far-reaching.

doc/SYMBOLS
doc/meta.tex
doc/syntax.tex
src/builtin.lisp
src/class-make-impl.lisp
src/class-make-proto.lisp
src/class-output.lisp
src/classes.lisp
src/module-parse.lisp
src/sod-module.5

index f165c35..58fdc74 100644 (file)
@@ -315,8 +315,7 @@ classes.lisp
   sod-initializer                               class
   sod-initializer-class                         generic
   sod-initializer-slot                          generic
-  sod-initializer-value-form                    generic
-  sod-initializer-value-kind                    generic
+  sod-initializer-value                         generic
   sod-instance-initializer                      class
   sod-message                                   class
   sod-message-class                             generic
@@ -1175,11 +1174,11 @@ make-method-entries
 sod-parser:make-scanner-stream
   sod-token-scanner
 make-sod-class-initializer
-  sod-class t t t t t
+  sod-class t t t t
 make-sod-initializer-using-slot
-  sod-class sod-slot t t t t t
+  sod-class sod-slot t t t t
 make-sod-instance-initializer
-  sod-class t t t t t
+  sod-class t t t t
 make-sod-message
   sod-class t t t
 make-sod-method
@@ -1313,7 +1312,6 @@ cl:slot-unbound
   t basic-effective-method (eql sod::basic-argument-names)
   t basic-effective-method (eql sod::functions)
   t basic-message (eql sod::argument-tail)
-  t basic-message (eql sod::no-varargs-tail)
   t delegating-direct-method (eql sod::function-type)
   t delegating-direct-method (eql sod::next-method-type)
   t sod-class (eql sod::%ilayout)
@@ -1369,9 +1367,7 @@ sod-initializer-class
   sod-initializer
 sod-initializer-slot
   sod-initializer
-sod-initializer-value-form
-  sod-initializer
-sod-initializer-value-kind
+sod-initializer-value
   sod-initializer
 sod-message-argument-tail
   basic-message
index 280a21c..a09ae21 100644 (file)
 
 \begin{describe*}
     {\dhead{cls}{sod-initializer ()
-       \&key :slot :location :class :value-kind :value-form}
+       \&key :slot :location :class :value}
      \dhead{cls}{sod-instance-initializer (sod-initializer)
-       \&key :slot :location :class :value-kind :value-form}
+       \&key :slot :location :class :value}
      \dhead{cls}{sod-class-initializer (sod-initializer)
-       \&key :slot :location :class :value-kind :value-form}}
+       \&key :slot :location :class :value}}
 \end{describe*}
 
 \begin{describe*}
     {\dhead{gf}{sod-initializer-slot @<init> @> @<slot>}
-     \dhead{gf}{sod-initializer-value-kind @<init> @> @<kind>}
-     \dhead{gf}{sod-initializer-value-form @<init> @> @<fragment>}}
+     \dhead{gf}{sod-initializer-value @<init> @> @<fragment>}}
 \end{describe*}
 
 \begin{describe*}
     {\dhead{gf}
-      {make-slot-instance-initializer \=@<class> @<nick> @<name>
-                                        @<value-kind> @<value-form> \+ \\
-                                        @<pset> \&optional @<floc> \-
+      {make-slot-instance-initializer
+          \=@<class> @<nick> @<name> @<value> @<pset> \&optional @<floc>
         \nlret @<init>}
      \dhead{gf}
-      {make-slot-class-initializer \=@<class> @<nick> @<name>
-                                     @<value-kind> @<value-form> \+ \\
-                                     @<pset> \&optional @<floc> \-
+      {make-slot-class-initializer
+          \=@<class> @<nick> @<name> @<value> @<pset> \&optional @<floc>
         \nlret @<init>}}
 \end{describe*}
 
 \begin{describe}{gf}
-    {make-sod-initializer-using-slot \=@<class> @<slot> @<init-class>
-                                       @<value-kind> @<value-form> \+ \\
-                                       @<pset> \&optional @<floc> \-
+    {make-sod-initializer-using-slot
+        \=@<class> @<slot> @<init-class> @<value> @<pset> \&optional @<floc>
       \nlret @<init>}
 \end{describe}
 
index 1090262..c23e58e 100644 (file)
@@ -664,7 +664,7 @@ class Example : Super {
 
 <slot-initializer> ::= <dotted-name> "=" <initializer>
 
-<initializer> :: "{" <c-fragment> "}" | <c-fragment>
+<initializer> :: <c-fragment>
 \end{grammar}
 
 An @<initializer-item> provides an initial value for one or more slots.  If
@@ -675,16 +675,6 @@ The first component of the @<dotted-name> must be the nickname of one of the
 class's superclasses (including itself); the second must be the name of a
 slot defined in that superclass.
 
-The initializer has one of two forms.
-\begin{itemize}
-\item A @<c-fragment> enclosed in braces denotes an aggregate initializer.
-  This is suitable for initializing structure, union or array slots.
-\item A @<c-fragment> \emph{not} beginning with an open brace is a `bare'
-  initializer, and continues until the next @`,' or @`;' which is not within
-  nested brackets.  Bare initializers are suitable for initializing scalar
-  slots, such as pointers or integers, and strings.
-\end{itemize}
-
 \subsubsection{Message items}
 \begin{grammar}
 <message-item> ::=
index ea72d66..e4b42de 100644 (file)
@@ -143,18 +143,10 @@ static void *~A__init(void *p)~%{~%" class)
                     (format stream "  {~%    ")
                     (pprint-c-type (sod-slot-type dslot) stream
                                    *sod-tmp-val*)
-                    (format stream " =")
-                    (ecase (sod-initializer-value-kind init)
-                      (:simple (write (sod-initializer-value-form init)
-                                      :stream stream
-                                      :pretty nil :escape nil)
-                               (format stream ";~%"))
-                      (:compound (format stream " {")
-                                 (write (sod-initializer-value-form init)
-                                        :stream stream
-                                        :pretty nil :escape nil)
-                                 (format stream "    };~%")))
-                    (format stream "    ~A.~A = ~A;~%  }~%"
+                    (format stream " = ~A;~%    ~
+                                      ~A.~A = ~A;~%  ~
+                                    }~%"
+                            (sod-initializer-value init)
                             isl (sod-slot-name dslot)
                             *sod-tmp-val*))))))))))
     (unless used
index 5b8baf0..d2f3093 100644 (file)
 ;;; Slot initializers.
 
 (defmethod make-sod-instance-initializer
-    ((class sod-class) nick name value-kind value-form pset
-     &optional location)
+    ((class sod-class) nick name value pset &optional location)
   (with-default-error-location (location)
     (let* ((slot (find-instance-slot-by-name class nick name))
-          (initializer (make-sod-initializer-using-slot
-                        class slot 'sod-instance-initializer
-                        value-kind value-form pset
-                        (file-location location))))
+          (initializer (and value
+                            (make-sod-initializer-using-slot
+                             class slot 'sod-instance-initializer
+                             value pset (file-location location)))))
       (with-slots (instance-initializers) class
+
        (setf instance-initializers
              (append instance-initializers (list initializer))))
       initializer)))
 
 (defmethod make-sod-class-initializer
-    ((class sod-class) nick name value-kind value-form pset
-     &optional location)
+    ((class sod-class) nick name value pset &optional location)
   (with-default-error-location (location)
     (let* ((slot (find-class-slot-by-name class nick name))
           (initializer (make-sod-initializer-using-slot
                         class slot 'sod-class-initializer
-                        value-kind value-form pset
-                        (file-location location))))
+                        value pset (file-location location))))
       (with-slots (class-initializers) class
        (setf class-initializers
              (append class-initializers (list initializer))))
       initializer)))
 
 (defmethod make-sod-initializer-using-slot
-    ((class sod-class) (slot sod-slot)
-     init-class value-kind value-form pset location)
+    ((class sod-class) (slot sod-slot) init-class value pset location)
   (make-instance (get-property pset :initializer-class :symbol init-class)
                 :class class
                 :slot slot
-                :value-kind value-kind
-                :value-form value-form
+                :value value
                 :location (file-location location)
                 :pset pset))
 
index a974f0e..b10c298 100644 (file)
@@ -77,7 +77,7 @@
 
 (export 'make-sod-instance-initializer)
 (defgeneric make-sod-instance-initializer
-    (class nick name value-kind value-form pset &optional location)
+    (class nick name value pset &optional location)
   (:documentation
    "Construct and attach an instance slot initializer, to CLASS.
 
@@ -90,7 +90,7 @@
 
 (export 'make-sod-class-initializer)
 (defgeneric make-sod-class-initializer
-    (class nick name value-kind value-form pset &optional location)
+    (class nick name value pset &optional location)
   (:documentation
    "Construct and attach a class slot initializer, to CLASS.
 
 
 (export 'make-sod-initializer-using-slot)
 (defgeneric make-sod-initializer-using-slot
-    (class slot init-class value-kind value-form pset location)
+    (class slot init-class value pset location)
   (:documentation
    "Common construction protocol for slot initializers.
 
index abe5132..a59bda0 100644 (file)
@@ -675,13 +675,9 @@ const struct ~A ~A__classobj = {~%"
   (:method ((slot effective-slot) (instance sod-class) stream)
     (let ((init (find-class-initializer slot instance))
          (direct-slot (effective-slot-direct-slot slot)))
-      (ecase (sod-initializer-value-kind init)
-       (:simple (format stream "        /* ~15@A = */ ~A,~%"
-                        (sod-slot-name direct-slot)
-                        (sod-initializer-value-form init)))
-       (:compound (format stream "        /* ~15@A = */ ~@<{ ~;~A~; },~:>~%"
-                          (sod-slot-name direct-slot)
-                          (sod-initializer-value-form init)))))))
+      (format stream "        /* ~15@A = */ ~A,~%"
+             (sod-slot-name direct-slot)
+             (sod-initializer-value init)))))
 
 (defmethod hook-output progn
     ((slot sod-class-effective-slot) (reason (eql 'class)) sequencer)
index d403d10..1a3a925 100644 (file)
                           (sod-slot-name slot)))))
 
 (export '(sod-initializer sod-initializer-slot sod-initializer-class
-         sod-initializer-value-kind sod-initializer-value-form))
+         sod-initializer-value))
 (defclass sod-initializer ()
   ((slot :initarg :slot :type sod-slot :reader sod-initializer-slot)
    (location :initarg :location :initform (file-location nil)
             :type file-location :reader file-location)
    (%class :initarg :class :type sod-class :reader sod-initializer-class)
-   (value-kind :initarg :value-kind :type keyword
-              :reader sod-initializer-value-kind)
-   (value-form :initarg :value-form :type c-fragment
-              :reader sod-initializer-value-form))
+   (value :initarg :value :type c-fragment :reader sod-initializer-value))
   (:documentation
    "Provides an initial value for a slot.
 
      * The LOCATION states the position in the user's source file where the
        initializer was found.  This gets used in error messages.  (Depending
        on the source layout style, this might differ from the location in the
-       VALUE-FORM C fragment.)
+       VALUE C fragment.)
 
      * The CLASS states which class defined this initializer.  For instance
        slot initializers (`sod-instance-initializer'), this will be the same
        initializers (`sod-class-initializer'), this will be an instance of
        the SLOT's class, or an instance of one of its descendants.
 
-     * The VALUE-KIND states what manner of initializer we have.  It can be
-       either `:single', indicating a standalone expression, or `:compound',
-       indicating a compound initializer which must be surrounded by braces
-       on output.
-
-     * The VALUE-FORM gives the text of the initializer, as a C fragment.
+     * The VALUE gives the text of the initializer, as a C fragment.
 
    Typically you'll see instances of subclasses of this class in the wild
    rather than instances of this class directly.  See `sod-class-initializer'
    and `sod-instance-initializer'."))
 
 (defmethod print-object ((initializer sod-initializer) stream)
-  (with-slots (slot value-kind value-form) initializer
+  (with-slots (slot value) initializer
     (if *print-escape*
        (print-unreadable-object (initializer stream :type t)
-         (format stream "~A = ~A" slot value-form))
-       (format stream "~:[{~A}~;~A~]" (eq value-kind :single) value-form))))
+         (format stream "~A = ~A" slot value))
+       (format stream "~A" value))))
 
 (export 'sod-class-initializer)
 (defclass sod-class-initializer (sod-initializer)
 
    A class slot initializer provides an initial value for a slot in the class
    object (i.e., one of the slots defined by the class's metaclass).  Its
-   VALUE-FORM must have the syntax of an initializer, and its consituent
+   VALUE must have the syntax of an initializer, and its consituent
    expressions must be constant expressions.
 
    See `sod-initializer' for more details."))
    "Provides an initial value for a slot in all instances.
 
    An instance slot initializer provides an initial value for a slot in
-   instances of the class.  Its VALUE-FORM must have the syntax of an
-   initializer.  Furthermore, if the slot has aggregate type, then you'd
-   better be sure that your compiler supports compound literals (6.5.2.5)
-   because that's what the initializer gets turned into.
+   instances of the class.  Its VALUE must have the syntax of an initializer.
+   Furthermore, if the slot has aggregate type, then you'd better be sure
+   that your compiler supports compound literals (6.5.2.5) because that's
+   what the initializer gets turned into.
 
    See `sod-initializer' for more details."))
 
index a458922..2866c08 100644 (file)
                                           body sub-pset scanner))))
 
               (parse-initializer ()
-                ;; initializer ::= `=' c-fragment | `=' `{' c-fragment `}'
+                ;; initializer ::= `=' c-fragment
                 ;;
-                ;; Return (VALUE-KIND . VALUE-FORM), ready for passing to a
-                ;; `sod-initializer' constructor.
-
-                ;; This is kind of tricky because we have to juggle both
-                ;; layers of the parsing machinery.  The character scanner
-                ;; will already have consumed the lookahead token (which, if
-                ;; we're going to do anything, is `=').
-                (let ((char-scanner (token-scanner-char-scanner scanner)))
-
-                  ;; First, skip the character-scanner past any whitespace.
-                  ;; We don't record this consumption, which is a bit
-                  ;; naughty, but nobody will actually mind.
-                  (loop
-                    (when (or (scanner-at-eof-p char-scanner)
-                              (not (whitespace-char-p
-                                    (scanner-current-char char-scanner))))
-                      (return))
-                    (scanner-step char-scanner))
-
-                  ;; Now maybe read an initializer.
-                  (cond ((not (eql (token-type scanner) #\=))
-                         ;; It's not an `=' after all.  There's no
-                         ;; initializer.
-                         (values '(#\=) nil nil))
-
-                        ((and (not (scanner-at-eof-p char-scanner))
-                              (char= (scanner-current-char char-scanner)
-                                     #\{))
-                         ;; There's a brace after the `=', so we should
-                         ;; consume the `=' here, and read a compound
-                         ;; initializer enclosed in braces.
-                         (parse (seq (#\= (frag (parse-delimited-fragment
-                                                 scanner #\{ #\})))
-                                  (cons :compound frag))))
-
-                        (t
-                         ;; No brace, so read from the `=' up to, but not
-                         ;; including, the trailing `,' or `;' delimiter.
-                         (parse (seq ((frag (parse-delimited-fragment
-                                             scanner #\= '(#\; #\,)
-                                             :keep-end t)))
-                                  (cons :simple frag)))))))
+                ;; Return a VALUE, ready for passing to a `sod-initializer'
+                ;; constructor.
+                (parse-delimited-fragment scanner #\= (list #\, #\;)
+                                          :keep-end t))
 
               (parse-slot-item (sub-pset base-type type name)
                 ;; slot-item ::=
                                              sub-pset scanner)
                               (when init
                                 (make-sod-instance-initializer
-                                 class nick name (car init) (cdr init)
-                                 sub-pset scanner)))
+                                 class nick name init sub-pset scanner)))
                             (skip-many ()
                               (seq (#\,
                                     (ds (parse-declarator scanner
                                                sub-pset scanner)
                                 (when init
                                   (make-sod-instance-initializer
-                                   class nick (cdr ds)
-                                   (car init) (cdr init)
+                                   class nick (cdr ds) init
                                    sub-pset scanner))))
                             #\;)))
 
                               (seq ((name-a :id) #\. (name-b :id)
                                     (init (parse-initializer)))
                                 (funcall constructor class
-                                         name-a name-b
-                                         (car init) (cdr init)
+                                         name-a name-b init
                                          sub-pset scanner))
                               #\,)
                             #\;)))
index 2ffe671..bdb13e5 100644 (file)
@@ -573,10 +573,6 @@ class-definition
 .br
 .I initializer
 ::=
-.B {
-.I c-fragment
-.B }
-|
 .I c-fragment
 .br
 .I message-item