|
45 | 45 | (defvar core:*read-hook*) |
46 | 46 | (defvar core:*read-preserving-whitespace-hook*) |
47 | 47 |
|
48 | | - |
49 | | -;;; to avoid that cl:*readtable* and eclector.readtable:*readtable* get out of sync |
50 | 48 | ;;; to avoid eclector.parse-result::*stack* being unbound, when *client* is bound to a parse-result-client |
51 | 49 | ;;; Not sure whether this a a fortunate design in eclector |
52 | 50 |
|
53 | 51 | (defclass clasp-non-cst-elector-client (clasp-cleavir::clasp-eclector-client-mixin) ()) |
54 | 52 | (defvar *clasp-normal-eclector-client* (make-instance 'clasp-non-cst-elector-client)) |
55 | 53 |
|
56 | | -;;; From eclector macro functions: |
57 | | -;;; So we need a way for readers for lists and vectors to explicitly |
58 | | -;;; allow for backquote and comma, whereas BY DEFAULT, they should not |
59 | | -;;; be allowed. We solve this by introducing two variables: |
60 | | -;;; *BACKQUOTE-ALLOWED-P* and *BACKQUOTE-IN-SUBFORMS-ALLOWED-P*. |
61 | | -;;; Initially the two are TRUE. Whenever READ is called, it binds the |
62 | | -;;; variable *BACKQUOTE-ALLOWED-P* to the value of |
63 | | -;;; *BACKQUOTE-IN-SUBFORMS-ALLOWED-P*, and it binds |
64 | | -;;; *BACKQUOTE-IN-SUBFORMS-ALLOWED-P* to FALSE. If no special action |
65 | | -;;; is taken, when READ is called recursively from a reader macro, |
66 | | -;;; the value of *BACKQUOTE-ALLOWED-P* will be FALSE. |
67 | | - |
68 | | -(defun read-with-readtable-synced (&optional |
69 | | - (input-stream *standard-input*) |
70 | | - (eof-error-p t) |
71 | | - (eof-value nil) |
72 | | - (recursive-p nil)) |
73 | | - (let ((eclector.readtable:*readtable* cl:*readtable*) |
74 | | - (eclector.reader:*client* *clasp-normal-eclector-client*) |
75 | | - #+(or)(eclector.reader::*backquote-in-subforms-allowed-p* t)) |
76 | | - (eclector.reader:read input-stream eof-error-p eof-value recursive-p))) |
| 54 | +(defmethod eclector.reader:state-value |
| 55 | + ((client clasp-non-cst-elector-client) (aspect (eql 'cl:*readtable*))) |
| 56 | + cl:*readtable*) |
77 | 57 |
|
78 | | -;;; to avoid cl:*readtable* and eclector.readtable:*readtable* get out of sync |
79 | | -(defun read-preserving-whitespace-with-readtable-synced (&optional |
80 | | - (input-stream *standard-input*) |
81 | | - (eof-error-p t) |
82 | | - (eof-value nil) |
83 | | - (recursive-p nil)) |
84 | | - (let ((eclector.readtable:*readtable* cl:*readtable*) |
85 | | - (eclector.reader:*client* *clasp-normal-eclector-client*) |
86 | | - #+(or)(eclector.reader::*backquote-in-subforms-allowed-p* t)) |
87 | | - (eclector.reader:read-preserving-whitespace input-stream eof-error-p eof-value recursive-p))) |
| 58 | +(defmethod eclector.reader:call-with-state-value |
| 59 | + ((client clasp-non-cst-elector-client) thunk (aspect (eql 'cl:*readtable*)) value) |
| 60 | + (let ((cl:*readtable* value)) |
| 61 | + (funcall thunk))) |
| 62 | + |
| 63 | +(defun read-with-eclector (&optional (input-stream *standard-input*) |
| 64 | + (eof-error-p t) |
| 65 | + (eof-value nil) |
| 66 | + (recursive-p nil)) |
| 67 | + (let ((eclector.reader:*client* *clasp-normal-eclector-client*)) |
| 68 | + (eclector.reader:read input-stream eof-error-p eof-value recursive-p))) |
88 | 69 |
|
89 | | -;;; need also sync in clasp-cleavir::cclasp-loop-read-and-compile-file-forms |
| 70 | +(defun read-preserving-whitespace-with-eclector |
| 71 | + (&optional (input-stream *standard-input*) |
| 72 | + (eof-error-p t) |
| 73 | + (eof-value nil) |
| 74 | + (recursive-p nil)) |
| 75 | + (let ((eclector.reader:*client* *clasp-normal-eclector-client*)) |
| 76 | + (eclector.reader:read-preserving-whitespace input-stream eof-error-p |
| 77 | + eof-value recursive-p))) |
90 | 78 |
|
91 | 79 | (defun cl:read-from-string (string |
92 | 80 | &optional (eof-error-p t) eof-value |
93 | 81 | &key (start 0) (end (length string)) |
94 | 82 | preserve-whitespace) |
95 | | - (let ((eclector.readtable:*readtable* cl:*readtable*) |
96 | | - (eclector.reader:*client* *clasp-normal-eclector-client*)) |
| 83 | + (let ((eclector.reader:*client* *clasp-normal-eclector-client*)) |
97 | 84 | (eclector.reader:read-from-string string eof-error-p eof-value |
98 | | - :start start :end end :preserve-whitespace preserve-whitespace))) |
| 85 | + :start start :end end |
| 86 | + :preserve-whitespace preserve-whitespace))) |
99 | 87 |
|
100 | 88 | ;;; Fixed in https://github.com/s-expressionists/Eclector/commit/19d2d903bb04e3e59ff0557051e134e8ee6195c7 |
101 | 89 | (defun cl:read-delimited-list (char &optional (input-stream *standard-input*) recursive-p) |
102 | | - (let ((eclector.readtable:*readtable* cl:*readtable*) |
103 | | - (eclector.reader:*client* *clasp-normal-eclector-client*)) |
| 90 | + (let ((eclector.reader:*client* *clasp-normal-eclector-client*)) |
104 | 91 | (eclector.reader:read-delimited-list char input-stream recursive-p))) |
105 | 92 |
|
106 | 93 | (defun core::set-eclector-reader-readmacros (readtable) |
107 | 94 | (eclector.reader::set-standard-macro-characters readtable) |
108 | 95 | (eclector.reader::set-standard-dispatch-macro-characters readtable) |
109 | | - (cl:set-dispatch-macro-character #\# #\a 'core:sharp-a-reader readtable) |
110 | 96 | (cl:set-dispatch-macro-character #\# #\A 'core:sharp-a-reader readtable) |
111 | | - (cl:set-dispatch-macro-character #\# #\I 'core::read-cxx-object readtable) |
112 | | - ;;; see issue https://github.com/s-expressionists/Eclector/issues/59 |
113 | | - ;;; sharpsign-single-quote/relaxed will be exported, but isn't yet |
114 | | - (cl:set-dispatch-macro-character #\# #\' (if (fboundp 'eclector.reader::sharpsign-single-quote/relaxed) |
115 | | - 'eclector.reader::sharpsign-single-quote/relaxed |
116 | | - 'eclector.reader::sharpsign-single-quote) |
117 | | - readtable)) |
| 97 | + (cl:set-dispatch-macro-character #\# #\I 'core::read-cxx-object readtable)) |
118 | 98 |
|
119 | 99 | (defun init-clasp-as-eclector-reader () |
120 | | - (setq eclector.readtable:*readtable* cl:*readtable*) |
121 | 100 | (core::set-eclector-reader-readmacros cl:*readtable*) |
122 | 101 | (core::set-eclector-reader-readmacros (symbol-value 'core:+standard-readtable+)) |
123 | 102 | ;;; also change read |
124 | | - (setq core:*read-hook* 'read-with-readtable-synced) |
125 | | - (setq core:*read-preserving-whitespace-hook* 'read-preserving-whitespace-with-readtable-synced) |
126 | 103 | ;;; read-from-string is overwritten above |
127 | | - ) |
128 | | - |
129 | | -(eclector.readtable::init-clasp-as-eclector-reader) |
130 | | - |
131 | | -(defun patch-object (client value-old seen-objects mapping) |
132 | | - (multiple-value-bind (value-new found-p) |
133 | | - (gethash value-old mapping) |
134 | | - (if found-p |
135 | | - value-new |
136 | | - (progn |
137 | | - (eclector.reader:fixup client value-old seen-objects mapping) |
138 | | - value-old)))) |
139 | | - |
140 | | -(defmethod eclector.reader:fixup (client (object core:cxx-object) seen-objects mapping) |
| 104 | + (setq core:*read-hook* 'read-with-eclector) |
| 105 | + (setq core:*read-preserving-whitespace-hook* 'read-preserving-whitespace-with-eclector)) |
| 106 | + |
| 107 | +(eclector.readtable::init-clasp-as-eclector-reader) |
| 108 | + |
| 109 | +(defun patch-object (client value-old seen-objects) |
| 110 | + (multiple-value-bind (state object*) |
| 111 | + (labeled-object-state client value-old) |
| 112 | + (case state |
| 113 | + ((nil) ; normal object |
| 114 | + (eclector.reader:fixup client value-old seen-objects) |
| 115 | + value-old) |
| 116 | + ((:final :final/circular) object*) ; fully resolved circular reference |
| 117 | + (otherwise value-old)))) ; unresolved reference - leave for later |
| 118 | + |
| 119 | +(defmethod eclector.reader:fixup (client (object core:cxx-object) seen-objects) |
141 | 120 | (let ((patcher (core:make-record-patcher (lambda (object) |
142 | | - (patch-object client object seen-objects mapping))))) |
| 121 | + (patch-object client object seen-objects))))) |
143 | 122 | (core:patch-object object patcher))) |
0 commit comments