Introduction
Introduction Statistics Contact Development Disclaimer Help
tcontrol-flow.lisp - clic - Clic is an command line interactive client for goph…
git clone git://bitreich.org/clic/ git://hg6vgqziawt5s4dj.onion/clic/
Log
Files
Refs
Tags
LICENSE
---
tcontrol-flow.lisp (5126B)
---
1 (in-package :alexandria)
2
3 (defun extract-function-name (spec)
4 "Useful for macros that want to mimic the functional interface for fun…
5 like #'eq and 'eq."
6 (if (and (consp spec)
7 (member (first spec) '(quote function)))
8 (second spec)
9 spec))
10
11 (defun generate-switch-body (whole object clauses test key &optional def…
12 (with-gensyms (value)
13 (setf test (extract-function-name test))
14 (setf key (extract-function-name key))
15 (when (and (consp default)
16 (member (first default) '(error cerror)))
17 (setf default `(,@default "No keys match in SWITCH. Testing agains…
18 ,value ',test)))
19 `(let ((,value (,key ,object)))
20 (cond ,@(mapcar (lambda (clause)
21 (if (member (first clause) '(t otherwise))
22 (progn
23 (when default
24 (error "Multiple default clauses or ille…
25 whole))
26 (setf default `(progn ,@(rest clause)))
27 '(()))
28 (destructuring-bind (key-form &body forms) c…
29 `((,test ,value ,key-form)
30 ,@forms))))
31 clauses)
32 (t ,default)))))
33
34 (defmacro switch (&whole whole (object &key (test 'eql) (key 'identity))
35 &body clauses)
36 "Evaluates first matching clause, returning its values, or evaluates a…
37 returns the values of T or OTHERWISE if no keys match."
38 (generate-switch-body whole object clauses test key))
39
40 (defmacro eswitch (&whole whole (object &key (test 'eql) (key 'identity))
41 &body clauses)
42 "Like SWITCH, but signals an error if no key matches."
43 (generate-switch-body whole object clauses test key '(error)))
44
45 (defmacro cswitch (&whole whole (object &key (test 'eql) (key 'identity))
46 &body clauses)
47 "Like SWITCH, but signals a continuable error if no key matches."
48 (generate-switch-body whole object clauses test key '(cerror "Return N…
49
50 (defmacro whichever (&rest possibilities &environment env)
51 "Evaluates exactly one of POSSIBILITIES, chosen at random."
52 (setf possibilities (mapcar (lambda (p) (macroexpand p env)) possibili…
53 (if (every (lambda (p) (constantp p)) possibilities)
54 `(svref (load-time-value (vector ,@possibilities)) (random ,(lengt…
55 (labels ((expand (possibilities position random-number)
56 (if (null (cdr possibilities))
57 (car possibilities)
58 (let* ((length (length possibilities))
59 (half (truncate length 2))
60 (second-half (nthcdr half possibilities))
61 (first-half (butlast possibilities (- length…
62 `(if (< ,random-number ,(+ position half))
63 ,(expand first-half position random-number)
64 ,(expand second-half (+ position half) rando…
65 (with-gensyms (random-number)
66 (let ((length (length possibilities)))
67 `(let ((,random-number (random ,length)))
68 ,(expand possibilities 0 random-number)))))))
69
70 (defmacro xor (&rest datums)
71 "Evaluates its arguments one at a time, from left to right. If more th…
72 argument evaluates to a true value no further DATUMS are evaluated, and …
73 returned as both primary and secondary value. If exactly one argument
74 evaluates to true, its value is returned as the primary value after all …
75 arguments have been evaluated, and T is returned as the secondary value.…
76 arguments evaluate to true NIL is retuned as primary, and T as secondary
77 value."
78 (with-gensyms (xor tmp true)
79 `(let (,tmp ,true)
80 (block ,xor
81 ,@(mapcar (lambda (datum)
82 `(if (setf ,tmp ,datum)
83 (if ,true
84 (return-from ,xor (values nil nil))
85 (setf ,true ,tmp))))
86 datums)
87 (return-from ,xor (values ,true t))))))
88
89 (defmacro nth-value-or (nth-value &body forms)
90 "Evaluates FORM arguments one at a time, until the NTH-VALUE returned …
91 of the forms is true. It then returns all the values returned by evaluat…
92 that form. If none of the forms return a true nth value, this form retur…
93 NIL."
94 (once-only (nth-value)
95 (with-gensyms (values)
96 `(let ((,values (multiple-value-list ,(first forms))))
97 (if (nth ,nth-value ,values)
98 (values-list ,values)
99 ,(if (rest forms)
100 `(nth-value-or ,nth-value ,@(rest forms))
101 nil))))))
102
103 (defmacro multiple-value-prog2 (first-form second-form &body forms)
104 "Evaluates FIRST-FORM, then SECOND-FORM, and then FORMS. Yields as its…
105 all the value returned by SECOND-FORM."
106 `(progn ,first-form (multiple-value-prog1 ,second-form ,@forms)))
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.