X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/a888e3acc123993fa6fca9338f291b306aa131e2..b07535d86a625c99240d8fdc46d589f5cc03a29c:/src/module-parse.lisp?ds=sidebyside diff --git a/src/module-parse.lisp b/src/module-parse.lisp index 2866c08..15a7d8f 100644 --- a/src/module-parse.lisp +++ b/src/module-parse.lisp @@ -199,6 +199,34 @@ (export 'class-item) +(define-pluggable-parser class-item initfrags (scanner class pset) + ;; raw-class-item ::= frag-keyword `{' c-fragment `}' + ;; frag-keyword ::= `init' | `teardown' + (with-parser-context (token-scanner-context :scanner scanner) + (parse (seq ((make (or (seq ("init") #'make-sod-class-initfrag) + (seq ("teardown") #'make-sod-class-tearfrag))) + (frag (parse-delimited-fragment scanner #\{ #\}))) + (funcall make class frag pset scanner))))) + +(define-pluggable-parser class-item initargs (scanner class pset) + ;; initarg-item ::= `initarg' declspec+ init-declarator-list + ;; init-declarator ::= declarator [`=' initializer] + (with-parser-context (token-scanner-context :scanner scanner) + (parse (seq ("initarg" + (base-type (parse-c-type scanner)) + (nil (skip-many (:min 1) + (seq ((declarator (parse-declarator scanner + base-type)) + (init (? (parse-delimited-fragment + scanner #\= (list #\; #\,) + :keep-end t)))) + (make-sod-user-initarg class + (cdr declarator) + (car declarator) + pset init scanner)) + #\,)) + #\;))))) + (defun parse-class-body (scanner pset name supers) ;; class-body ::= `{' class-item* `}' ;; @@ -286,19 +314,22 @@ sub-pset scanner)))) #\;))) - (parse-initializer-item (sub-pset constructor) + (parse-initializer-item (sub-pset must-init-p constructor) ;; initializer-item ::= ;; [`class'] -!- slot-initializer-list `;' ;; - ;; slot-initializer ::= id `.' id initializer - (parse (and (skip-many () - (seq ((name-a :id) #\. (name-b :id) - (init (parse-initializer))) - (funcall constructor class - name-a name-b init - sub-pset scanner)) - #\,) - #\;))) + ;; slot-initializer ::= id `.' id [initializer] + (let ((parse-init (if must-init-p + #'parse-initializer + (parser () (? (parse-initializer)))))) + (parse (and (skip-many () + (seq ((name-a :id) #\. (name-b :id) + (init (funcall parse-init))) + (funcall constructor class + name-a name-b init + sub-pset scanner)) + #\,) + #\;)))) (class-item-dispatch (sub-pset base-type type name) ;; Logically part of `parse-raw-class-item', but the @@ -329,6 +360,7 @@ ;; | method-item ;; | slot-item ;; | initializer-item + ;; | initfrag-item ;; ;; Most of the above begin with declspecs and a declarator ;; (which might be dotted). So we parse that here and @@ -337,16 +369,17 @@ (peek (seq ((ds (parse-c-type scanner)) (dc (parse-maybe-dotted-declarator ds)) + (nil (commit)) (nil (class-item-dispatch sub-pset ds (car dc) (cdr dc)))))) (and "class" (parse-initializer-item - sub-pset + sub-pset t #'make-sod-class-initializer)) (parse-initializer-item - sub-pset + sub-pset nil #'make-sod-instance-initializer))))) (parse (seq (#\{