[editor-hints-devel] Patch to support cmucl/unicode

Raymond Toy toy.raymond at gmail.com
Fri Jan 28 06:07:15 UTC 2011


The patch below adds support for cmucl/unicode.  This basically adds an
implementation of %make-readtable-iterator, updates %clear-readtable for
cmucl (like sbcl), a fix for %get-dispatch-macro-character, a fix for
%get-macro-character (like allegro).

With these changes (and a small change in named-readtables.lisp  that
has already been mentioned by Stas Boukarev last month. 

With these changes cmucl passes all 36 of the tests.

Oh, one thing.  I noticed that in %clear-readtable, the last sexp is
#+common-lisp.  CMUCL has the :common-lisp feature, so the table is set
twice.  Perhaps this is oversight and the reader conditional should be
#-(or allegro sbcl cmu)?

Ray

Change log:

 * Add implementation of %make-readtable-iterator for cmucl/unicode.
 * Implement %clear-readtable for cmucl.

 * Make %get-dispatch-macro-character return NIL where cmucl actually
   has #'lisp::dispatch-char-error.  It seems named-readtables wants
   this.
 * Update %get-macro-character for cmucl, which behaves like allegro
   here.


diff -u --recursive ./cruft.lisp
/Volumes/share2/src/sourceforge/matlisp/matlisp-cvs/lib-src/named-readtables-0.9/cruft.lisp
--- ./cruft.lisp    2009-10-10 04:19:32.000000000 -0400
+++
/Volumes/share2/src/sourceforge/matlisp/matlisp-cvs/lib-src/named-readtables-0.9/cruft.lisp   
2011-01-28 00:49:30.000000000 -0500
@@ -235,8 +235,55 @@
                                                      subch-fn))))))))
       #'grovel-macro-chars)))
 
+;; This really only needed for CMUCL with unicode support.  Without
+;; unicode, the default implementation is probably fast enough.
+#+(and cmu unicode)
+(defun %make-readtable-iterator (readtable)
+  (let ((char-macro-ht    (lisp::character-macro-hash-table readtable))
+        (dispatch-tables  (lisp::dispatch-tables readtable))
+        (char-code 0))
+    (with-hash-table-iterator (ht-iterator char-macro-ht)
+      (labels ((grovel-base-chars ()
+                 (if (>= char-code lisp::attribute-table-limit)
+                     (grovel-unicode-chars)
+             (let* ((char      (code-char (shiftf char-code (1+
char-code))))
+                ;; Need %get-macro-character here, not
+                ;; get-macro-character because we want NIL
+                ;; to be returned instead of
+                ;; #'lisp::read-token.
+                (reader-fn (%get-macro-character char readtable)))
+               (if reader-fn
+               (yield char reader-fn)
+               (grovel-base-chars)))))
+               (grovel-unicode-chars ()
+                 (multiple-value-bind (more? char reader-fn)
+             (ht-iterator)
+                   (if (not more?)
+                       (values nil nil nil nil nil)
+                       (yield char reader-fn))))
+               (yield (char reader-fn)
+                 (let ((disp-ht))
+                   (cond
+                     ((setq disp-ht (cdr (assoc char dispatch-tables)))
+                      (let ((disp-fn (get-macro-character char readtable))
+                (sub-char-alist))
+            (if (< (char-code char) lisp::attribute-table-limit)
+                (let ((disp (lisp::char-dispatch-table-table disp-ht)))
+                  (dotimes (k lisp::attribute-table-limit)
+                (let ((f (aref disp k)))
+                  (unless (eq f #'lisp::dispatch-char-error)
+                    (push (cons (code-char k) f)
+                      sub-char-alist)))))
+                (let ((disp-ht (lisp::char-dispatch-table-hash-table
disp-ht)))
+                  (maphash (lambda (k v)
+                     (push (cons k v) sub-char-alist))
+                       disp-ht)))
+                        (values t char disp-fn t sub-char-alist)))
+                     (t
+                      (values t char reader-fn nil nil))))))
+        #'grovel-base-chars))))
 
-#-(or sbcl clozure allegro)
+#-(or sbcl clozure allegro (and cmu unicode))
 (eval-when (:compile-toplevel)
   (let ((*print-pretty* t))
     (simple-style-warn
@@ -246,7 +293,7 @@
        On Unicode-aware implementations this may come with some
costs.~@:>"
      (package-name '#.*package*) (lisp-implementation-type))))
 
-#-(or sbcl clozure allegro)
+#-(or sbcl clozure allegro (and cmu unicode))
 (defun %make-readtable-iterator (readtable)
   (check-type readtable readtable)
   (let ((char-code 0))
@@ -325,6 +372,11 @@
     (do-readtable (char readtable)
       (set-syntax-from-char char #\A readtable))
     (setf (sb-impl::dispatch-tables readtable) nil))
+  #+:cmu
+  (prog1 readtable
+    (do-readtable (char readtable)
+      (set-syntax-from-char char #\A readtable))
+    (setf (lisp::dispatch-tables readtable) nil))
   #+ :allegro
   (prog1 readtable
     (do-readtable (char readtable)
@@ -343,17 +395,28 @@
   "Ensure ANSI behaviour for GET-DISPATCH-MACRO-CHARACTER."
   #+ :ccl         (ignore-errors
                     (get-dispatch-macro-character char subchar rt))
-  #+ :common-lisp (get-dispatch-macro-character char subchar rt))
+  #+cmu
+  (let ((f (get-dispatch-macro-character char subchar rt)))
+    ;; CMUCL returns #'lisp::dispatch-char-error, and named-readtables
+    ;; wants nil in those cases.
+    (unless (eq f #'lisp::dispatch-char-error)
+    f))
+  #-(or :ccl :cmu) (get-dispatch-macro-character char subchar rt))
 
 ;;; Allegro stores READ-TOKEN as reader macro function of each
-;;; constituent character.
+;;; constituent character.  CMUCL does the same.
 (define-cruft %get-macro-character (char rt)
   "Ensure ANSI behaviour for GET-MACRO-CHARACTER."
   #+ :allegro     (let ((fn (get-macro-character char rt)))
                     (cond ((not fn) nil)
                           ((function= fn #'excl::read-token) nil)
                           (t fn)))
-  #+ :common-lisp (get-macro-character char rt))
+  #+cmu
+  (let ((fn (get-macro-character char rt)))
+    (cond ((not fn) nil)
+      ((function= fn #'lisp::read-token) nil)
+      (t fn)))
+  #-(or :allegro cmu) (get-macro-character char rt))
 





More information about the editor-hints-devel mailing list