changeset 357: | 7c1383c08493 |
author: | Richard Westhaver <ellis@rwest.io> |
date: | Tue, 21 May 2024 22:20:29 -0400 |
permissions: | -rw-r--r-- |
description: | port xsubseq, proc-parse. work on http and clap |
357
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
1 | ;;; std/macs/collecting.lisp --- Collecting Macros |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
2 | |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
3 | ;; ported from CL-UTILITIES |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
4 | |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
5 | ;;; Code: |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
6 | (in-package :std/macs) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
7 | |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
8 | ;; This should only be called inside of COLLECTING macros, but we |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
9 | ;; define it here to provide an informative error message and to make |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
10 | ;; it easier for SLIME (et al.) to get documentation for the COLLECT |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
11 | ;; function when it's used in the COLLECTING macro. |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
12 | (defun collect (thing) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
13 | "Collect THING in the context established by the COLLECTING macro" |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
14 | (error "Can't collect ~S outside the context of the COLLECTING macro" |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
15 | thing)) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
16 | |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
17 | (defmacro collecting (&body body) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
18 | "Collect things into a list forwards. Within the body of this macro, |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
19 | the COLLECT function will collect its argument into the list returned |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
20 | by COLLECTING." |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
21 | (with-gensyms (collector tail) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
22 | `(let (,collector ,tail) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
23 | (labels ((collect (thing) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
24 | (if ,collector |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
25 | (setf (cdr ,tail) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
26 | (setf ,tail (list thing))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
27 | (setf ,collector |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
28 | (setf ,tail (list thing)))))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
29 | ,@body) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
30 | ,collector))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
31 | |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
32 | (defmacro with-collectors ((&rest collectors) &body body) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
33 | "Collect some things into lists forwards. The names in COLLECTORS |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
34 | are defined as local functions which each collect into a separate |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
35 | list. Returns as many values as there are collectors, in the order |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
36 | they were given." |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
37 | (%with-collectors-check-collectors collectors) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
38 | (let ((gensyms-alist (%with-collectors-gensyms-alist collectors))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
39 | `(let ,(loop for collector in collectors |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
40 | for tail = (cdr (assoc collector gensyms-alist)) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
41 | nconc (list collector tail)) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
42 | (labels ,(loop for collector in collectors |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
43 | for tail = (cdr (assoc collector gensyms-alist)) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
44 | collect `(,collector (thing) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
45 | (if ,collector |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
46 | (setf (cdr ,tail) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
47 | (setf ,tail (list thing))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
48 | (setf ,collector |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
49 | (setf ,tail (list thing)))))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
50 | ,@body) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
51 | (values ,@collectors)))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
52 | |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
53 | (defun %with-collectors-check-collectors (collectors) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
54 | "Check that all of the COLLECTORS are symbols. If not, raise an error." |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
55 | (let ((bad-collector (find-if-not #'symbolp collectors))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
56 | (when bad-collector |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
57 | (error 'type-error |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
58 | :datum bad-collector |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
59 | :expected-type 'symbol)))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
60 | |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
61 | (defun %with-collectors-gensyms-alist (collectors) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
62 | "Return an alist mapping the symbols in COLLECTORS to gensyms" |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
63 | (mapcar #'cons collectors |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
64 | (mapcar (compose #'gensym |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
65 | #'(lambda (x) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
66 | (format nil "~A-TAIL-" x))) |
7c1383c08493
port xsubseq, proc-parse. work on http and clap
Richard Westhaver <ellis@rwest.io>
parents:
diff
changeset
|
67 | collectors))) |