chiark / gitweb /
src/method-impl.lisp: Abolish the `emf-entry-tail' variable.
[sod] / src / module-parse.lisp
index df4ea277de7c0078f736a1927d548ad067300f2c..95220852b25ed6e7e07e8da35c8b23d4d49d9962 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
@@ -48,21 +48,28 @@ (define-pluggable-parser module typename (scanner pset)
 ;;; Fragments.
 
 (define-pluggable-parser module code (scanner pset)
-  ;; `code' id `:' id [constraints] `{' c-fragment `}'
+  ;; `code' id `:' item-name [constraints] `{' c-fragment `}'
   ;;
   ;; constrains ::= `[' constraint-list `]'
-  ;; constraint ::= id+
+  ;; constraint ::= item-name+
+  ;; item-name ::= id | `(' id+ `)'
   (declare (ignore pset))
   (with-parser-context (token-scanner-context :scanner scanner)
-    (flet ((kw ()
-            (parse (seq ((kw :id)) (intern (string-upcase kw) 'keyword)))))
+    (labels ((kw ()
+              (parse (seq ((kw :id))
+                       (intern (frob-identifier kw) 'keyword))))
+            (item ()
+              (parse (or (kw)
+                         (seq (#\( (names (list (:min 1) (kw))) #\))
+                           names)))))
       (parse (seq ("code"
                   (reason (kw))
                   #\:
-                  (name (kw))
+                  (name (item))
                   (constraints (? (seq (#\[
                                         (constraints (list (:min 1)
-                                                       (list (:min 1) (kw))
+                                                       (list (:min 1)
+                                                         (item))
                                                        #\,))
                                         #\])
                                     constraints)))
@@ -148,6 +155,29 @@ (define-pluggable-parser module file (scanner pset)
                                 (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)
@@ -167,6 +197,8 @@ (define-pluggable-parser module lisp (scanner pset)
 ;;;--------------------------------------------------------------------------
 ;;; Class declarations.
 
+(export 'class-item)
+
 (defun parse-class-body (scanner pset name supers)
   ;; class-body ::= `{' class-item* `}'
   ;;
@@ -197,9 +229,16 @@ (defun parse-class-body (scanner pset name supers)
               (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 ::=
@@ -335,13 +374,13 @@ (defun parse-class-body (scanner pset name supers)
                 ;; (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