chiark / gitweb /
src/module-parse.lisp (read-module): Use requested pathname for location.
[sod] / src / module-parse.lisp
index 83cc0add4590593e6fc18709989d0eb669ee2add..f90f360ae61f2dfcecaaf87fadadfedc7cd2ac5b 100644 (file)
@@ -31,11 +31,11 @@ (in-package #:sod)
 ;;; Type names.
 
 (define-pluggable-parser module typename (scanner pset)
-  ;; `typename' id ( `,' id )* `;'
+  ;; `typename' list[id] `;'
   (declare (ignore pset))
   (with-parser-context (token-scanner-context :scanner scanner)
     (parse (and "typename"
-               (skip-many (:min 1)
+               (skip-many ()
                  (seq ((id :id))
                    (if (gethash id *module-type-map*)
                        (cerror* "Type `~A' already defined" id)
@@ -50,7 +50,7 @@ (define-pluggable-parser module typename (scanner pset)
 (define-pluggable-parser module code (scanner pset)
   ;; `code' id `:' item-name [constraints] `{' c-fragment `}'
   ;;
-  ;; constrains ::= `[' constraint-list `]'
+  ;; constraints ::= `[' list[constraint] `]'
   ;; constraint ::= item-name+
   ;; item-name ::= id | `(' id+ `)'
   (declare (ignore pset))
@@ -103,16 +103,22 @@   (define-module (pathname :location location :truename truename)
       (let* ((*readtable* (copy-readtable))
             (*package* (find-package '#:sod-user))
             (char-scanner (make-instance 'charbuf-scanner
-                                         :stream f-stream))
+                                         :stream f-stream
+                                         :filename (namestring pathname)))
             (scanner (make-instance 'sod-token-scanner
                                     :char-scanner char-scanner)))
        (with-default-error-location (scanner)
          (with-parser-context (token-scanner-context :scanner scanner)
-           (parse (skip-many ()
-                    (seq ((pset (parse-property-set scanner))
-                          (nil (error ()
-                                 (plug module scanner pset))))
-                      (check-unused-properties pset))))))))))
+           (multiple-value-bind (result winp consumedp)
+               (parse (skip-many ()
+                         (seq ((pset (parse-property-set scanner))
+                               (nil (error ()
+                                        (plug module scanner pset)
+                                      (skip-until (:keep-end nil)
+                                        #\; #\}))))
+                           (check-unused-properties pset))))
+             (declare (ignore consumedp))
+             (unless winp (syntax-error scanner result)))))))))
 
 (define-pluggable-parser module test (scanner pset)
   ;; `demo' string `;'
@@ -159,23 +165,23 @@ (define-pluggable-parser module file (scanner pset)
 ;;; Setting properties.
 
 (define-pluggable-parser module set (scanner pset)
-  ;; `set' property-list `;'
+  ;; `set' list[property] `;'
   (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))
+                                     (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) #\, #\;))
+                                    (parse-property scanner module-pset)
+                                  (skip-until () #\, #\;))
                                 #\,))))
                #\;))))
 
@@ -210,7 +216,7 @@ (define-pluggable-parser class-item initfrags (scanner class pset)
             (funcall make class frag pset scanner)))))
 
 (define-pluggable-parser class-item initargs (scanner class pset)
-  ;; initarg-item ::= `initarg' declspec+ init-declarator-list
+  ;; initarg-item ::= `initarg' declspec+ list[init-declarator]
   ;; init-declarator ::= declarator [`=' initializer]
   (with-parser-context (token-scanner-context :scanner scanner)
     (parse (seq ("initarg"
@@ -234,7 +240,13 @@ (defun parse-class-body (scanner pset name supers)
   ;; class-item ::= property-set raw-class-item
   (with-parser-context (token-scanner-context :scanner scanner)
     (make-class-type name)
-    (let* ((class (make-sod-class name (mapcar #'find-sod-class supers)
+    (let* ((duff nil)
+          (class (make-sod-class name
+                                 (restart-case
+                                     (mapcar #'find-sod-class supers)
+                                   (continue ()
+                                     (setf duff t)
+                                     (list (find-sod-class "SodObject"))))
                                  pset scanner))
           (nick (sod-class-nickname class)))
 
@@ -292,10 +304,9 @@ (defun parse-class-body (scanner pset name supers)
               (parse-slot-item (sub-pset base-type type name)
                 ;; slot-item ::=
                 ;;     declspec+ declarator -!- [initializer]
-                ;;             [`,' init-declarator-list] `;'
+                ;;             [`,' list[init-declarator]] `;'
                 ;;
-                ;; init-declarator-list ::=
-                ;;     declarator [initializer] [`,' init-declarator-list]
+                ;; init-declarator ::= declarator [initializer]
                 (parse (and (seq ((init (? (parse-initializer))))
                               (make-sod-slot class name type
                                              sub-pset scanner)
@@ -317,11 +328,10 @@ (defun parse-class-body (scanner pset name supers)
 
               (parse-initializer-item (sub-pset must-init-p constructor)
                 ;; initializer-item ::=
-                ;;     [`class'] -!- slot-initializer-list `;'
+                ;;     [`class'] -!- list[slot-initializer] `;'
                 ;;
                 ;; slot-initializer ::= id `.' id [initializer]
-                (let ((parse-init (if must-init-p
-                                      #'parse-initializer
+                (let ((parse-init (if must-init-p #'parse-initializer
                                       (parser () (? (parse-initializer))))))
                   (parse (and (skip-many ()
                                 (seq ((name-a :id) #\. (name-b :id)
@@ -344,9 +354,8 @@ (defun parse-class-body (scanner pset name supers)
                 ;; definition; otherwise it might be a message or slot.
                 (cond ((not (typep type 'c-function-type))
                        (when (consp name)
-                         (cerror*-with-location
-                          scanner
-                          "Method declarations must have function type.")
+                         (cerror*
+                          "Method declarations must have function type")
                          (setf name (cdr name)))
                        (parse-slot-item sub-pset base-type type name))
                       ((consp name)
@@ -376,11 +385,9 @@ (defun parse-class-body (scanner pset name supers)
                                                             (car dc)
                                                             (cdr dc))))))
                            (and "class"
-                                (parse-initializer-item
-                                 sub-pset t
+                                (parse-initializer-item sub-pset t
                                  #'make-sod-class-initializer))
-                           (parse-initializer-item
-                            sub-pset nil
+                           (parse-initializer-item sub-pset nil
                             #'make-sod-instance-initializer)))))
 
        (parse (seq (#\{
@@ -389,19 +396,21 @@ (defun parse-class-body (scanner pset name supers)
                                  (nil (parse-raw-class-item sub-pset)))
                              (check-unused-properties sub-pset))))
                     (nil (error () #\})))
-                (finalize-sod-class class)
-                (add-to-module *module* class)))))))
+                (unless (finalize-sod-class class)
+                  (setf duff t))
+                (unless duff
+                  (add-to-module *module* class))))))))
 
 (define-pluggable-parser module class (scanner pset)
-  ;; `class' id [`:' id-list] class-body
+  ;; `class' id `:' list[id] class-body
   ;; `class' id `;'
   (with-parser-context (token-scanner-context :scanner scanner)
     (parse (seq ("class"
                 (name :id)
                 (nil (or (seq (#\;)
                            (make-class-type name))
-                         (seq ((supers (? (seq (#\: (ids (list () :id #\,)))
-                                            ids)))
+                         (seq ((supers (seq (#\: (ids (list () :id #\,)))
+                                         ids))
                                (nil (parse-class-body
                                      scanner
                                      pset name supers)))))))))))