Very ragged work-in-progress.
[sod] / pset.lisp
index f1c1172..67a77fc 100644 (file)
--- a/pset.lisp
+++ b/pset.lisp
 
 (defun property-type (value)
   "Guess the right property type to use for VALUE."
-  (etypecase value
+  (typecase value
     (symbol :symbol)
     (integer :integer)
     (string :string)
-    (c-fragment :frag)))
+    (character :char)
+    (c-fragment :frag)
+    (t :other)))
 
 (defstruct (property
             (:conc-name p-)
@@ -87,7 +89,6 @@
    processed; don't put colons in package names if you want to use them from
    SOD property sets."
 
-  (declare (optimize debug))
   (let* ((length (length string))
         (colon (position #\: string)))
     (multiple-value-bind (start internalp)
    "Convert VALUE, a property of type TYPE, to be of type WANTED.")
 
   ;; If TYPE matches WANTED, we'll assume that VALUE already has the right
-  ;; form.
-  (:method :around (value type wanted)
-    (if (eq type wanted)
-       value
-       (call-next-method)))
-
-  ;; If nothing else matched, then I guess we'll have to say it didn't work.
+  ;; form.  Otherwise, if nothing else matched, then I guess we'll have to
+  ;; say it didn't work.
   (:method (value type wanted)
     (if (eql type wanted)
        value
        (error "Incorrect type: expected ~A but found ~A" wanted type)))
 
+  ;; If the caller asks for type T then give him the raw thing.
+  (:method (value type (wanted (eql t)))
+    value)
+
   ;; Keywords.
   (:method ((value symbol) (type (eql :symbol)) (wanted (eql :keyword)))
     value)
    the value and its file location.  In the latter case, mark the property as
    having been used.
 
-   The value returned depends on the TYPE argument provided.  If you pass T
-   (meaning any type) then you get back the entire PROPERTY object.
-   Otherwise the value is coerced to the right kind of thing (where possible)
-   and returned."
+   The value returned depends on the TYPE argument provided.  If you pass NIL
+   then you get back the entire PROPERTY object.  If you pass T, then you get
+   whatever was left in the property set, uninterpreted.  Otherwise the value
+   is coerced to the right kind of thing (where possible) and returned."
 
   (let ((prop (find name pset :key #'p-key)))
     (with-default-error-location ((and prop (p-location prop)))
   (dolist (prop pset)
     (unless (p-seenp prop)
       (cerror*-with-location (p-location prop) "Unknown property `~A'"
-                            (p-name prop)))))a
+                            (p-name prop)))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Property set parsing.
 (defun parse-expression (lexer)
   "Parse an expression from the LEXER.
 
-   The return values are the expression's VALUE and TYPE; currently the
-   types are :ID, :INTEGER and :STRING.  If an error prevented a sane value
+   The return values are the expression's VALUE and TYPE; currently the types
+   are :ID, :INTEGER, :STRING, and :CHAR.  If an error prevented a sane value
    being produced, the TYPE :INVALID is returned.
 
    Expression syntax is rather limited at the moment:
 
               ;; Aha.  A primary.  Push it onto the stack, and see if
               ;; there's an infix operator.
-              ((:integer :id :string)
+              ((:integer :id :string :char)
                (push (cons (token-type lexer)
                            (token-value lexer))
                      valstack)