[climacs-cvs] CVS climacs

thenriksen thenriksen at common-lisp.net
Sun Apr 23 15:14:49 UTC 2006


Update of /project/climacs/cvsroot/climacs
In directory clnet:/tmp/cvs-serv19479

Modified Files:
	lisp-syntax.lisp 
Log Message:
Added `token-to-object' function that will convert parser tokens to
Lisp objects (for example, a `complete-list-form' to a list).

Fixed a comment and some indentation.


--- /project/climacs/cvsroot/climacs/lisp-syntax.lisp	2006/04/23 15:04:52	1.54
+++ /project/climacs/cvsroot/climacs/lisp-syntax.lisp	2006/04/23 15:14:49	1.55
@@ -380,7 +380,7 @@
 	(#\| (fo) (make-instance 'multiple-escape-start-lexeme))
 	(t (cond ((or (constituentp object)
 		      (eql object #\\))
-		  (lex-token syntax scan))
+                  (lex-token syntax scan))
 		 (t (fo) (make-instance 'error-lexeme))))))))
 
 (defmethod lex ((syntax lisp-syntax) (state lexer-list-state) scan)
@@ -1249,7 +1249,7 @@
                (return item))))
 
 (defun elt-form (list n)
-  "Returns the nth form in list."
+  "Returns the nth form in list or `nil'."
   (nth-form n list))
 
 (defun first-form (list)
@@ -1897,28 +1897,108 @@
 		(parse-token input readtable-case))))))
 |#
 
+(defun token-string (syntax token)
+  "Return the string that specifies `token' in the buffer of
+  `syntax'."
+  (coerce (buffer-sequence (buffer syntax)
+                           (start-offset token)
+                           (end-offset token))
+          'string))
+
 (defun parse-symbol (string &optional (package *package*))
   "Find the symbol named STRING.
-Return the symbol and a flag indicating whether the symbol was found."
+Return the symbol and a flag indicating whether the symbol was
+found in the package. Note that a symbol may be returned even if
+it was not found in a package."
   (multiple-value-bind (symbol-name package-name) (parse-token string)
     (let ((package (cond ((string= package-name "") +keyword-package+)
                          (package-name              (find-package package-name))
                          (t                         package))))
-      (if package
-          (find-symbol symbol-name package)
-          (values nil nil)))))
+      (or (and package
+               (find-symbol symbol-name package))
+          (values (make-symbol symbol-name) nil)))))
 
 (defun token-to-symbol (syntax token)
-  (let ((package (if (and (slot-boundp syntax 'package)
-                          (slot-value syntax 'package)
-			  (typep (slot-value syntax 'package) 'package))
-		     (slot-value syntax 'package)
-		     (find-package :common-lisp)))
-	(token-string (coerce (buffer-sequence (buffer syntax)
-					       (start-offset token)
-					       (end-offset token))
-			      'string)))
-    (parse-symbol token-string package)))
+  "Return the symbol `token' represents. If `token' represents
+anything else than a symbol, or it cannot be correctly converted
+to a symbol, return nil. If the symbol cannot be found in a
+package, an uninterned symbol will be returned."
+  (let ((result (token-to-object syntax token t)))
+    (when (symbolp result)
+      result)))
+
+;; FIXME? This generic function often errors on erroneous input. Since
+;; we are an editor, we might consider being a bit more lenient. Also,
+;; it will never intern symbols itself, but return NIL for uninterned
+;; symbols.
+(defgeneric token-to-object (syntax token &optional no-error)
+  (:documentation "Return the Lisp object `token' would evaluate
+  to if read. An attempt will be made to construct objects from
+  incomplete tokens. This function may signal an error if
+  `no-error' is nil and `token' cannot be converted to a Lisp
+  object. Otherwise, nil will be returned.")
+  (:method :around (syntax token &optional no-error)
+           ;; Ensure that every symbol that is READ will be looked up
+           ;; in the correct package.
+           (handler-case (let ((*package* (if (and (slot-boundp syntax 'package)
+                                                   (slot-value syntax 'package)
+                                                   (typep (slot-value syntax 'package) 'package))
+                                              (slot-value syntax 'package)
+                                              (find-package :common-lisp))))
+                           (call-next-method))
+             (t ()
+               (unless no-error
+                 (error "Cannot convert token to Lisp object: ~A" token)))))
+  (:method (syntax (token t) &optional no-error)
+    (declare (ignore no-error))
+    ;; We ignore `no-error' as it is truly a bug in Climacs if no
+    ;; handler method is specialized on this form.
+    (error "Cannot convert token to Lisp object: ~A"
+            token))
+  (:method (syntax (token incomplete-form-mixin) &optional no-error)
+    (unless no-error
+      (error "Cannot convert incomplete form to Lisp object: ~A"
+             token))))
+
+(defmethod token-to-object (syntax (token complete-token-lexeme) &optional no-error)
+  (declare (ignore no-error))
+  (parse-symbol (token-string syntax token)))
+
+(defmethod token-to-object (syntax (token number-lexeme) &optional no-error)
+  (declare (ignore no-error))
+  (let ((*read-base* (base syntax)))
+    (read-from-string (token-string syntax token))))
+
+(defmethod token-to-object (syntax (token list-form) &optional no-error)
+  (declare (ignore no-error))
+  (mapcar #'(lambda (form)
+              (token-to-object syntax form))
+          (remove-if-not #'(lambda (form)
+                             (typep form 'form))
+                         (children token))))
+
+(defmethod token-to-object (syntax (token simple-vector-form) &optional no-error)
+  (declare (ignore no-error))
+  (apply #'vector
+         (mapcar #'(lambda (form)
+                     (token-to-object syntax form))
+                 (remove-if-not #'(lambda (form)
+                                    (typep form 'form))
+                                (children token)))))
+
+(defmethod token-to-object (syntax (token incomplete-string-form) &optional no-error)
+  (declare (ignore no-error))
+  (read-from-string (concatenate 'string
+                                 (token-string syntax token)
+                                 "\"")))
+
+(defmethod token-to-object (syntax (token complete-string-form) &optional no-error)
+  (declare (ignore no-error))
+  (read-from-string (token-string syntax token)))
+
+(defmethod token-to-object (syntax (token quote-form) &optional no-error)
+  (list 'cl:quote
+        (token-to-object syntax (second (children token)) no-error)))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;




More information about the Climacs-cvs mailing list