chiark / gitweb /
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 f165c3520ce14b0a276d02a956028a82ba1ca239..58fdc748f130df4ec3d6b114e2e603c0b77e96e0 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 280a21c35f57e308aac653864f0acb135ab2867f..a09ae21155a1abb2c32e28fe303a8dcdf324413f 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 1090262710f7400e3f7ea24249ea9b2321f1112e..c23e58efc6272ef61e98a68f12b7727d2569cf64 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 ea72d662999a5244e315feac9aae815848727848..e4b42de7665ce27bf9d64e637af15b0699b4470c 100644 (file)
@@ -143,18 +143,10 @@ (define-class-slot "init" (class stream)
                     (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 5b8baf0a0e5ec0cdf19548758dd763b1871ec9c6..d2f3093c7e853e63f14c22963f8891dcb09bc769 100644 (file)
@@ -89,41 +89,37 @@ (defmethod shared-initialize :after ((slot sod-slot) slot-names &key pset)
 ;;; 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 a974f0e2ac5087114047dc613330e6459d06db62..b10c29817324e4d7dc4ceb216fbe47ecf888919c 100644 (file)
@@ -77,7 +77,7 @@ (defgeneric make-sod-slot (class name type pset &optional location)
 
 (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 @@ (defgeneric make-sod-instance-initializer
 
 (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.
 
@@ -103,7 +103,7 @@ (defgeneric make-sod-class-initializer
 
 (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 abe5132a16b3f7e14c60053975f028a41fc02632..a59bda0956a8fbd2f7bd1adbc97ec5bad0f9457c 100644 (file)
@@ -675,13 +675,9 @@ (defgeneric output-class-initializer (slot instance stream)
   (: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 d403d109e60fdbe131a4428b983ecb15b804c237..1a3a9258605cab70426ab112e9194d3865c788d9 100644 (file)
@@ -254,16 +254,13 @@ (defmethod print-object ((slot sod-slot) stream)
                           (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.
 
@@ -274,7 +271,7 @@ (defclass sod-initializer ()
      * 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
@@ -282,23 +279,18 @@ (defclass sod-initializer ()
        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)
@@ -308,7 +300,7 @@ (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."))
@@ -320,10 +312,10 @@ (defclass sod-instance-initializer (sod-initializer)
    "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 a45892216da5c362beb0b2493576078e30f7ac16..2866c08aa4288359619820380394ef723e2a9b93 100644 (file)
@@ -253,50 +253,12 @@ (defun parse-class-body (scanner pset name supers)
                                           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 ::=
@@ -310,8 +272,7 @@ (defun parse-class-body (scanner pset name supers)
                                              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
@@ -321,8 +282,7 @@ (defun parse-class-body (scanner pset name supers)
                                                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))))
                             #\;)))
 
@@ -335,8 +295,7 @@ (defun parse-class-body (scanner pset name supers)
                               (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 2ffe67145cc101cfcf1bfd5efe94c49b8f25651b..bdb13e5ee52302c635f6542b202a1590c920bbe5 100644 (file)
@@ -573,10 +573,6 @@ class-definition
 .br
 .I initializer
 ::=
-.B {
-.I c-fragment
-.B }
-|
 .I c-fragment
 .br
 .I message-item