changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/std/macs/collecting.lisp

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)))