-
Notifications
You must be signed in to change notification settings - Fork 1
/
assignment.lisp
171 lines (126 loc) · 4.45 KB
/
assignment.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
(in-package :arc-compat.internal)
(in-readtable :common-lisp)
; [code] [Foundation] [Destructive] set symbol expr
(defmacro set (&rest args)
"set is used to set a variable to an expression."
(cl:let ((args (if (oddp (length args))
(append args (list t))
args)))
`(cl:setf ,@args)))
;>(set x 10)
;10
;[code] [Foundation] [Destructive] scar list expr -> ac.lisp
;[code] [Foundation] [Destructive] scdr list exp -> ac.lisp
;[code] [Macro] [Destructive] = [place expr] ... [place]
(defmacro = (&rest args &environment env)
"Sets each place to the associated expression. If the last place
has no associated expression, it is set to nil."
(cl:let ((args (if (oddp (length args))
(append args (list t))
args)))
(if (null-lexenv-p env)
`(eval-when (:compile-toplevel :load-toplevel :execute)
(cl:setf (symbol-value ',(elt args 0))
,(elt args 1)))
`(cl:setf ,@args))))
;>(= x 1)
;1
;>(= x 2 y 4)
;4
;;(w/table t1 (= (t1 "a") 42) (write-table t1))
;[code] [Macro] [Destructive] wipe [place ...]
;
(mac wipe (&rest args)
"Sets the places to nil. Typically, the places are simple
variables."
`(do ,@(mapcar (fn (a) `(= ,a nil))
args)))
;(do (wipe a b c) (list a b c))
;(nil nil nil)
;[code] [Macro] [Destructive] assert [place ...]
(mac assert (&rest args)
"Sets the places to t. Note that this is unrelated to asserting
that a condition holds."
`(do ,@(mapcar (fn (a) `(= ,a t))
args)))
;>(do (assert a b c) (list a b c))
;(t t t)
;[code] [Macro] [Destructive] swap place1 place2
;The contents of the two places are swapped. The new contents of place2 are returned.
;>(with (x 'a y '(1 2))
; (swap x y)
; (prn "x:" x)
; y)
;x:(1 2)
;[code] [Macro] [Destructive] rotate [place1 place2 ...]
(defalias rotate cl:rotatef
"Assigns place2 to place1, assigns place3 to place2, and so on,
assigning place1 to the last place.")
#|(let ((s "abc"))
(rotate (aref s 0)
(aref s 1)
(aref s 2))
s)|#
;>(let s "abc" (rotate (s 0) (s 1) (s 2)) s)
;"bca"
;[code] [Macro] [Destructive] ++ place [i]
(defalias ++ cl:incf
"Increments the value at place by i. The default increment is 1.")
;>(let ((x '(10 20)))
; (++ (car x))
; (++ (cadr x) 5)
; x)
;(11 25)
;[code] [Macro] [Destructive] -- place [i]
(defalias -- cl:decf
"Decrements the value at place by i. The default decrement is 1.")
;>(let ((x '(10 20))) (-- (car x)) (-- (cadr x) 5) x)
;(9 15)
;[code] [Macro] [Destructive] zap op place [args ...]
"Gets the value at the place, evaluates (op value args...), and stores the result in the place."
(mac zap (op place &rest args)
`(setf ,place (apply ,op ,place (list ,@args))))
#|(mac zap (op place . args)
(with (gop (uniq)
gargs (map (fn (_) (declare (ignore _)) (uniq)) args)
mix (afn seqs
(if (some no seqs)
nil
(+ (map car seqs)
(apply self (map cdr seqs))))))
(let (binds val setter) (setforms place)
`(atwiths ,(+ binds (list gop op) (mix gargs args))
(,setter (,gop ,val ,@gargs))))))|#
;(let ((x '(0 10 20))) (zap #'* (cadr x) 5 8 9 10) x)
;>(let x '(0 10 20) (zap * (x 1) 5) x)
;(0 50 20)
;[code] [Macro] [Destructive] push elt place
;Pushes an element at the beginning of the list referenced by place. The list is modified and returned.
;>(let x '(1 2 3) (push 'a x) x)
;(a 1 2 3)
;[code] [Macro] [Destructive] pushnew elt place [test]
;Pushes elt before the place if it is not present in the list. The equality test can be specified; iso is used by default.
;>(let x '(1 2 3) (pushnew 'a x) x)
;(a 1 2 3)
;>(let x '(1 2 3) (pushnew 2 x) x)
;(1 2 3)
;[code] [Macro] [Destructive] pop place
;The first element is removed from place and returned. If the value at the place is nil, then nil is returned.
;>(let x '(1 2 3)
; (prn "Popped:" (pop x))
; x)
;Popped:1
;(2 3)
;[code] [Macro] [Destructive] pull test place
(defmacro pull (test place)
"Remove elements satisfying test from the list starting at place."
(multiple-value-bind (vars forms var set access)
(get-setf-expansion place)
`(let* (,@(mapcar #'cl:list vars forms)
(,(car var) (delete-if ,test ,access)))
,set)))
;(let ((x '((1 100 2 50 3) foo)))
; (pull (fn (x)(< x 10)) (car x))
; x)
;>(let x '(1 100 2 50 3) (pull [< _ 10] x) x)
;(100 50)