Mercurial > core / lisp/std/readtable.lisp
changeset 387: |
8252ee515756 |
parent: |
00d1c8afcdbb
|
child: |
d876b572b5b9 |
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Thu, 30 May 2024 18:31:53 -0400 |
permissions: |
-rw-r--r-- |
description: |
db and readtables |
1 ;;; std/readtable.lisp --- The Standard Readtable 3 ;; This readtable is accessible to systems which depend on the STD 6 ;;; Usage: (in-readtable :std) 9 (in-package :std/readtable) 11 (eval-when (:compile-toplevel :execute :load-toplevel) 12 (defun |#`-reader| (stream sub-char numarg) 13 (declare (ignore sub-char)) 14 (unless numarg (setq numarg 1)) 15 `(lambda ,(loop for i from 1 to numarg 18 (get-macro-character #\`) stream nil))) 20 (defun |#f-reader| (stream sub-char numarg) 21 (declare (ignore stream sub-char)) 22 (setq numarg (or numarg 3)) 24 (error "Bad value for #f: ~a" numarg)) 25 `(declare (optimize (speed ,numarg) 26 (safety ,(- 3 numarg))))) 28 ;; Nestable suggestion from Daniel Herring 29 (eval-when (:compile-toplevel :load-toplevel :execute) 30 (defun |#"-reader| (stream sub-char numarg) 31 (declare (ignore sub-char numarg)) 32 (let (chars (state 'normal) (depth 1)) 34 (let ((curr (read-char stream))) 35 (cond ((eq state 'normal) 36 (cond ((char= curr #\#) 38 (setq state 'read-sharp)) 40 (setq state 'read-quote)) 43 ((eq state 'read-sharp) 44 (cond ((char= curr #\") 50 (setq state 'normal)))) 51 ((eq state 'read-quote) 52 (cond ((char= curr #\#) 54 (if (zerop depth) (return)) 61 (setq state 'read-quote) 64 (setq state 'normal))))))))) 65 (coerce (nreverse chars) 'string)))) 67 ;; This version is from Martin Dirichs 68 (defun |#>-reader| (stream sub-char numarg) 69 (declare (ignore sub-char numarg)) 71 (do ((curr (read-char stream) 73 ((char= #\newline curr)) 75 (let ((pattern (nreverse chars)) 77 (labels ((match (pos chars) 80 (if (char= (nth pos pattern) (car chars)) 81 (match (1+ pos) (cdr chars)) 82 (match 0 (cdr (append (subseq pattern 0 pos) chars))))))) 85 ((= pos (length pattern))) 86 (setf curr (read-char stream) 87 pos (match pos (list curr))) 91 (nthcdr (length pattern) output)) 94 (defun segment-reader (stream ch n) 97 (do ((curr (read-char stream) 101 (cons (coerce (nreverse chars) 'string) 102 (segment-reader stream ch (- n 1)))))) 104 (defmacro! match-mode-ppcre-lambda-form (o!args o!mods) 106 (cl-ppcre:scan-to-strings 107 ,(if (zerop (length ,g!mods)) 109 (format nil "(?~a)~a" ,g!mods (car ,g!args))) 112 (defmacro! subst-mode-ppcre-lambda-form (o!args) 114 (cl-ppcre:regex-replace-all 119 (eval-when (:compile-toplevel :load-toplevel :execute) 120 (defun |#~-reader| (stream sub-char numarg) 121 (declare (ignore sub-char numarg)) 122 (let ((mode-char (read-char stream))) 124 ((char= mode-char #\m) 125 (match-mode-ppcre-lambda-form 126 (segment-reader stream 129 (coerce (loop for c = (read-char stream) 130 while (alpha-char-p c) 132 finally (unread-char c stream)) 134 ((char= mode-char #\s) 135 (subst-mode-ppcre-lambda-form 136 (segment-reader stream 139 (t (error "Unknown #~~ mode character")))))) 141 ;; #+cl-ppcre (set-dispatch-macro-character #\# #\~ #'|#~-reader|) 142 (eval-when (:compile-toplevel :load-toplevel :execute) 143 (defun lcurly-brace-reader (stream inchar) 144 (declare (ignore inchar)) 145 (let ((spec (read-delimited-list #\} stream t))) 146 (if (typep (car spec) '(integer 0)) 147 ;; Number of missing arguments 148 (let* ((n (pop spec)) 149 (extra-args (loop repeat n collect (gensym "A")))) 150 (if (eq (cadr spec) '_) 151 (let ((provided-vars (loop repeat (length (cddr spec)) 152 collect (gensym "P")))) 153 `(let ,(mapcar #'list provided-vars (cddr spec)) 154 (lambda ,extra-args (funcall (function ,(car spec)) 155 ,@extra-args ,@provided-vars)))) 156 (let ((provided-vars (loop repeat (length (cdr spec)) 157 collect (gensym "P")))) 158 `(let ,(mapcar #'list provided-vars (cdr spec)) 159 (lambda ,extra-args (funcall (function ,(car spec)) 160 ,@provided-vars ,@extra-args)))))) 161 (if (eq (cadr spec) '_) 162 `(the (values function &optional) (rcurry (function ,(car spec)) ,@(cddr spec))) 163 `(the (values function &optional) (curry (function ,(car spec)) ,@(cdr spec))))))) 165 (defun lsquare-brace-reader (stream inchar) 166 (declare (ignore inchar)) 167 (list 'the '(values function &optional) 168 (cons 'compose (read-delimited-list #\] stream t)))) 170 (defun langle-quotation-reader (stream inchar) 171 (declare (ignore inchar)) 172 (let ((contents (read-delimited-list #\» stream t)) 173 (args (gensym "langle-quotation-reader"))) 174 `(lambda (&rest ,args) 175 (,(car contents) ; Join function (or macro). 176 ,@(mapcar (lambda (fun) `(apply ,fun ,args)) (cdr contents)))))) 178 (defun lsingle-pointing-angle-quotation-mark-reader (stream inchar) 179 (declare (ignore inchar)) 180 (flet ((function-p (form) (functionp (ignore-errors (eval form))))) 181 (let ((contents (read-delimited-list #\› stream t)) 182 (arg (gensym "lsingle-pointing-angle-quotation-mark-reader"))) 184 (,(car contents) ; Case form. 185 ,@(case (car contents) ; If/when/unless guard. 187 `((funcall ,(cadr contents) ,arg))) 190 ,@(if (member (car contents) '(if when unless)) ; Clauses. 191 (mapcar (lambda (clause) 192 (if (function-p clause) 193 `(funcall ,clause ,arg) 196 (mapcar (lambda (clause) 197 `(,(if (function-p (car clause)) 198 `(funcall ,(car clause) ,arg) 200 ,(if (function-p (cadr clause)) 201 `(funcall ,(cadr clause) ,arg) 203 (cdr contents))))))))) 208 (:macro-char #\{ #'lcurly-brace-reader) 209 (:macro-char #\} (get-macro-character #\) )) 210 (:macro-char #\[ #'lsquare-brace-reader) 211 (:macro-char #\] (get-macro-character #\) )) 212 (:macro-char #\« #'langle-quotation-reader) 213 (:macro-char #\» (get-macro-character #\) )) 214 (:macro-char #\‹ #'lsingle-pointing-angle-quotation-mark-reader) 215 (:macro-char #\› (get-macro-character #\) )) 217 (:dispatch-macro-char #\# #\" #'|#"-reader|) 218 (:dispatch-macro-char #\# #\> #'|#>-reader|) 220 (:dispatch-macro-char #\# #\~ #'|#~-reader|) 222 (:dispatch-macro-char #\# #\` #'|#`-reader|) 223 (:dispatch-macro-char #\# #\f #'|#f-reader|))