src/class-make-impl.lisp: Don't store `nil' in the `metaclass' slot.
[sod] / src / module-parse.lisp
index df4ea27..a42c31f 100644 (file)
@@ -7,7 +7,7 @@
 
 ;;;----- Licensing notice ---------------------------------------------------
 ;;;
-;;; This file is part of the Sensble Object Design, an object system for C.
+;;; This file is part of the Sensible Object Design, an object system for C.
 ;;;
 ;;; SOD is free software; you can redistribute it and/or modify
 ;;; it under the terms of the GNU General Public License as published by
                                 (cerror* "Error loading Lisp file ~S: ~A"
                                          path error)))))))))))
 
+;;; Setting properties.
+
+(define-pluggable-parser module set (scanner pset)
+  ;; `set' property-list `;'
+  (with-parser-context (token-scanner-context :scanner scanner)
+    (parse (and "set"
+               (lisp (let ((module-pset (module-pset *module*)))
+                       (when pset
+                         (pset-map (lambda (prop)
+                                     (add-property module-pset
+                                                   (p-name prop)
+                                                   (p-value prop)
+                                                   :type (p-type prop)
+                                                   :location (p-location prop))
+                                     (setf (p-seenp prop) t))
+                                   pset))
+                       (parse (skip-many (:min 0)
+                                (error (:ignore-unconsumed t)
+                                  (parse-property scanner module-pset)
+                                  (skip-until (:keep-end t) #\, #\;))
+                                #\,))))
+               #\;))))
+
 ;;; Lisp escape.
 
 (define-pluggable-parser module lisp (scanner pset)
 ;;;--------------------------------------------------------------------------
 ;;; Class declarations.
 
+(export 'class-item)
+
 (defun parse-class-body (scanner pset name supers)
   ;; class-body ::= `{' class-item* `}'
   ;;
               (parse-message-item (sub-pset type name)
                 ;; message-item ::=
                 ;;     declspec+ declarator -!- (method-body | `;')
-                (make-sod-message class name type sub-pset scanner)
-                (parse (or #\; (parse-method-item sub-pset
-                                                  type nick name))))
+                ;;
+                ;; Don't allow a method-body here if the message takes a
+                ;; varargs list, because we don't have a name for the
+                ;; `va_list' parameter.
+                (let ((message (make-sod-message class name type
+                                                 sub-pset scanner)))
+                  (if (varargs-message-p message)
+                      (parse #\;)
+                      (parse (or #\; (parse-method-item sub-pset
+                                                        type nick name))))))
 
               (parse-method-item (sub-pset type sub-nick name)
                 ;; method-item ::=
                 ;; (which might be dotted).  So we parse that here and
                 ;; dispatch based on what we find.
                 (parse (or (plug class-item scanner class sub-pset)
-                           ;(peek
+                           (peek
                             (seq ((ds (parse-c-type scanner))
                                   (dc (parse-maybe-dotted-declarator ds))
                                   (nil (class-item-dispatch sub-pset
                                                             ds
                                                             (car dc)
-                                                            (cdr dc)))));)
+                                                            (cdr dc))))))
                            (and "class"
                                 (parse-initializer-item
                                  sub-pset