doc/concepts.tex: Fix subclass/superclass confusion.
[sod] / src / pset-parse.lisp
index 0bc4680..a2199b6 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
@@ -73,7 +73,7 @@
       "Parse and evaluate a simple expression.
 
    The result is a pair (TYPE . VALUE).  Currently, type types are `:id',
-   `:int', `:string', and `:char'.  If an error prevented a sane value from
+   `:int', `:string', `:char', `:fragment', `:type'.  If an error prevented a sane value from
    being produced, the type `:invalid' is returned.
 
    The syntax of expressions is rather limited at the moment, but more may be
@@ -82,7 +82,8 @@
    expression: term | expression `+' term | expression `-' term
    term: factor | term `*' factor | term `/' factor
    factor: primary | `+' factor | `-' factor
-   primary: int | id | string | `(' expression `)' | `?' lisp-expression
+   primary: int | id | string | `(' expression `)' | `{' fragment `}'
+     | `<' declspec+ declarator[empty] `>' | `?' lisp-expression
 
    Only operators for dealing with integers are provided."
       (with-parser-context (token-scanner-context :scanner scanner)
                            (let* ((stream (make-scanner-stream scanner))
                                   (sexp (read stream t)))
                              (scanner-step scanner)
-                             (values (cons (property-type sexp) sexp)
-                                     t t)))
+                             (multiple-value-bind (type value)
+                                 (restart-case (decode-property (eval sexp))
+                                   (continue () (values :invalid nil)))
+                               (values (cons type value) t t))))
+                          (#\{
+                           (values (cons :fragment
+                                         (parse-delimited-fragment scanner
+                                                                   #\{ #\}))
+                                         t t))
+                          (#\<
+                           (parse (seq (#\<
+                                        (ds (parse-c-type scanner))
+                                        (dc (parse-declarator
+                                             scanner ds
+                                             :kernel (lambda ()
+                                                       (values nil t nil))
+                                             :abstractp t))
+                                        #\>)
+                                    (values (cons :type (car dc))
+                                            t t))))
                           (t
-                           (values (list :int :id :char :string #\?)
+                           (values (list :int :id :char :string #\? #\{ #\<)
                                    nil nil)))))
                 (or (seq (#\+) add)
                     (seq (#\-) sub)
 ;;;--------------------------------------------------------------------------
 ;;; Parsing property sets.
 
+(export 'parse-property)
 (defun parse-property (scanner pset)
   "Parse a single property using the SCANNER; add it to the PSET."
   ;; property ::= id `=' expression
 (export 'parse-property-set)
 (defun parse-property-set (scanner)
   "Parse an optional property set from the SCANNER and return it."
-  ;; property-set ::= `[' property-list `]'
+  ;; property-set ::= [`[' property-list `]']
   (with-parser-context (token-scanner-context :scanner scanner)
-    (parse (seq (#\[
-                (pset (many (pset (make-property-set) pset)
-                        (parse-property scanner pset)
-                        #\,))
-                #\])
-            pset))))
+    (parse (? (seq (#\[
+                   (pset (many (pset (make-property-set) pset)
+                           (error ()
+                             (parse-property scanner pset)
+                             (skip-until () #\, #\]))
+                           #\,))
+                   #\])
+               pset)))))
 
 ;;;----- That's all, folks --------------------------------------------------