|
191 | 191 | :cljs (new js/Error (str "Unsupported binding key: " (ffirst kwbs)))))
|
192 | 192 | (reduce process-entry [] bents)))))
|
193 | 193 |
|
194 |
| -(destructure* '[[[bind expr & mod-pairs] |
195 |
| - & [[_ next-expr] :as next-groups]]]) |
| 194 | +(destructure* '[[[bind expr & mod-pairs] & next-groups]]) |
196 | 195 |
|
197 | 196 | (def client {:name "Super Co."
|
198 | 197 | :location "Philadelphia"
|
|
236 | 235 | n/from-to
|
237 | 236 | (j/assoc! :insert " "))])})))))))
|
238 | 237 |
|
239 |
| -(fn [seq-exprs] |
240 |
| - (reduce (fn [groups [k v]] |
241 |
| - (if (keyword? k) |
242 |
| - (conj (pop groups) (conj (peek groups) [k v])) |
243 |
| - (conj groups [k v]))) |
244 |
| - [] (partition 2 seq-exprs))) |
245 |
| - |
246 | 238 | (defmacro for [seq-exprs body-expr]
|
247 | 239 | (let [to-groups (fn [seq-exprs]
|
248 | 240 | (reduce (fn [groups [k v]]
|
249 |
| - (if (keyword? k) |
250 |
| - (conj (pop groups) (conj (peek groups) [k v])) |
251 |
| - (conj groups [k v]))) |
252 |
| - [] (partition 2 seq-exprs))) |
| 241 | + (if (keyword? k) |
| 242 | + (conj (pop groups) (conj (peek groups) [k v])) |
| 243 | + (conj groups [k v]))) |
| 244 | + [] (partition 2 seq-exprs))) |
| 245 | + err (fn [& msg] (throw (IllegalArgumentException. ^String (apply str msg)))) |
253 | 246 | emit-bind (fn emit-bind [[[bind expr & mod-pairs]
|
254 | 247 | & [[_ next-expr] :as next-groups]]]
|
255 | 248 | (let [giter (gensym "iter__")
|
|
261 | 254 | (= k :when) `(if ~v
|
262 | 255 | ~(do-mod etc)
|
263 | 256 | (recur (rest ~gxs)))
|
| 257 | + (keyword? k) (err "Invalid 'for' keyword " k) |
264 | 258 | next-groups
|
265 | 259 | `(let [iterys# ~(emit-bind next-groups)
|
266 | 260 | fs# (seq (iterys# ~next-expr))]
|
|
287 | 281 | ~(do-cmod etc)
|
288 | 282 | (recur
|
289 | 283 | (unchecked-inc ~gi)))
|
290 |
| - |
| 284 | + (keyword? k) |
| 285 | + (err "Invalid 'for' keyword " k) |
291 | 286 | :else
|
292 | 287 | `(do (chunk-append ~gb ~body-expr)
|
293 | 288 | (recur (unchecked-inc ~gi)))))]
|
|
313 | 308 | `(let [iter# ~(emit-bind (to-groups seq-exprs))]
|
314 | 309 | (iter# ~(second seq-exprs)))))
|
315 | 310 |
|
316 |
| -(for [x [0 1 2 3 4 5] |
317 |
| - :let [y (* x 3)] |
318 |
| - :when (even? y)] |
319 |
| - y) |
320 |
| - |
321 |
| - |
322 |
| - |
323 |
| -(defn to-groups [seq-exprs] |
324 |
| - (reduce (fn [groups binding] |
325 |
| - (if (keyword? (first binding)) |
326 |
| - (conj (pop groups) |
327 |
| - (conj (peek groups) |
328 |
| - [(first binding) (last binding)])) |
329 |
| - (conj groups [(first binding) (last binding)]))) |
330 |
| - [] (partition 2 seq-exprs))) |
331 |
| - |
332 |
| -(let [[[[bind expr & mod-pairs] |
333 |
| - & [[_ next-expr] :as next-groups]]]] |
334 |
| - (to-groups '[x [1 2 3] |
335 |
| - y [1 2 3] |
336 |
| - :while (<= x y) |
337 |
| - z [1 2 3]])) |
338 |
| - |
339 |
| -(let [giter (gensym "iter__") |
340 |
| - gxs (gensym "s__") |
341 |
| - do-mod (fn do-mod [[[k v :as pair] & etc]])]) |
342 |
| - |
343 |
| -(defn do-mod [[pair & etc]] |
| 311 | +(declare do-mod) |
| 312 | +(declare do-mod*) |
| 313 | + |
| 314 | +(defn emit-bind [bindings body-expr] |
| 315 | + (let [giter (gensym) |
| 316 | + gxs (gensym)] |
| 317 | + (println "bindings:" bindings) |
| 318 | + (if (next bindings) |
| 319 | + `(defn ~giter [~gxs] |
| 320 | + (loop [~gxs ~gxs] |
| 321 | + (when-first [~(ffirst bindings) ~gxs] |
| 322 | + ~(do-mod* (subvec (first bindings) 2) body-expr bindings giter gxs)))) |
| 323 | + `(defn ~giter [~gxs] |
| 324 | + (loop [~gxs ~gxs] |
| 325 | + (when-let [~gxs (seq ~gxs)] |
| 326 | + (let [~(ffirst bindings) (first ~gxs)] |
| 327 | + ~(do-mod* (subvec (first bindings) 2) body-expr bindings giter gxs)))))))) |
| 328 | + |
| 329 | +(defn do-mod [domod body-expr bindings giter gxs] |
344 | 330 | (cond
|
345 |
| - (= k :let) `(let ~v ~(do-mod etc)) |
346 |
| - (= k :while) `(when ~v ~(do-mod etc)) |
347 |
| - (= k :when) `(if ~v |
348 |
| - ~(do-mod etc) |
349 |
| - (recur (rest ~gxs))) |
350 |
| - next-groups |
351 |
| - `(let [iterys# ~(emit-bind next-groups) |
352 |
| - fs# (seq (iterys# ~next-expr))] |
| 331 | + (= (ffirst domod) :let) `(let ~(second (first domod)) ~(do-mod (next domod) body-expr bindings giter gxs)) |
| 332 | + (= (ffirst domod) :while) `(when ~(second (first domod)) ~(do-mod (next domod) body-expr bindings giter gxs)) |
| 333 | + (= (ffirst domod) :when) `(if ~(second (first domod)) |
| 334 | + ~(do-mod (next domod) body-expr bindings giter gxs) |
| 335 | + (recur (rest ~gxs))) |
| 336 | + (keyword? (ffirst domod)) (str "Invalid 'for' keyword " (ffirst domod)) |
| 337 | + (next bindings) |
| 338 | + `(let [iterys# ~(emit-bind (next bindings) body-expr) |
| 339 | + fs# (seq (iterys# ~(second (first (next bindings)))))] |
353 | 340 | (if fs#
|
354 | 341 | (concat fs# (~giter (rest ~gxs)))
|
355 | 342 | (recur (rest ~gxs))))
|
356 | 343 | :else `(cons ~body-expr
|
357 | 344 | (~giter (rest ~gxs)))))
|
358 | 345 |
|
359 |
| -(defmacro for [seq-exprs body-expr] |
360 |
| - (let [emit-bind |
361 |
| - (fn emit-bind [[[bind expr & mod-pairs] |
362 |
| - & [[_ next-expr] :as next-groups]]] |
363 |
| - (let [giter (gensym "iter__") |
364 |
| - gxs (gensym "s__") |
365 |
| - do-mod (fn do-mod [[[k v :as pair] & etc]] |
366 |
| - (cond |
367 |
| - (= k :let) `(let ~v ~(do-mod etc)) |
368 |
| - (= k :while) `(when ~v ~(do-mod etc)) |
369 |
| - (= k :when) `(if ~v |
370 |
| - ~(do-mod etc) |
371 |
| - (recur (rest ~gxs))) |
372 |
| - next-groups |
373 |
| - `(let [iterys# ~(emit-bind next-groups) |
374 |
| - fs# (seq (iterys# ~next-expr))] |
375 |
| - (if fs# |
376 |
| - (concat fs# (~giter (rest ~gxs))) |
377 |
| - (recur (rest ~gxs)))) |
378 |
| - :else `(cons ~body-expr |
379 |
| - (~giter (rest ~gxs)))))] |
380 |
| - (if next-groups |
381 |
| - #_"not the inner-most loop" |
382 |
| - `(fn ~giter [~gxs] |
383 |
| - (lazy-seq |
384 |
| - (loop [~gxs ~gxs] |
385 |
| - (when-first [~bind ~gxs] |
386 |
| - ~(do-mod mod-pairs))))) |
387 |
| - #_"inner-most loop" |
388 |
| - (let [gi (gensym "i__") |
389 |
| - gb (gensym "b__") |
390 |
| - do-cmod (fn do-cmod [[[k v :as pair] & etc]] |
391 |
| - (cond |
392 |
| - (= k :let) `(let ~v ~(do-cmod etc)) |
393 |
| - (= k :while) `(when ~v ~(do-cmod etc)) |
394 |
| - (= k :when) `(if ~v |
395 |
| - ~(do-cmod etc) |
396 |
| - (recur |
397 |
| - (unchecked-inc ~gi))) |
398 |
| - |
399 |
| - :else |
400 |
| - `(do (chunk-append ~gb ~body-expr) |
401 |
| - (recur (unchecked-inc ~gi)))))] |
402 |
| - `(fn ~giter [~gxs] |
403 |
| - (lazy-seq |
404 |
| - (loop [~gxs ~gxs] |
405 |
| - (when-let [~gxs (seq ~gxs)] |
406 |
| - (if (chunked-seq? ~gxs) |
407 |
| - (let [c# (chunk-first ~gxs) |
408 |
| - size# (int (count c#)) |
409 |
| - ~gb (chunk-buffer size#)] |
410 |
| - (if (loop [~gi (int 0)] |
411 |
| - (if (< ~gi size#) |
412 |
| - (let [~bind (.nth c# ~gi)] |
413 |
| - ~(do-cmod mod-pairs)) |
414 |
| - true)) |
415 |
| - (chunk-cons |
416 |
| - (chunk ~gb) |
417 |
| - (~giter (chunk-rest ~gxs))) |
418 |
| - (chunk-cons (chunk ~gb) nil))) |
419 |
| - (let [~bind (first ~gxs)] |
420 |
| - ~(do-mod mod-pairs)))))))))))] |
421 |
| - `(let [iter# ~(emit-bind (to-groups seq-exprs))] |
422 |
| - (iter# ~(second seq-exprs))))) |
| 346 | +(defn do-mod* [domod body-expr bindings giter gxs] |
| 347 | + (if (next bindings) |
| 348 | + `(let [iterys# ~(emit-bind (next bindings) body-expr) |
| 349 | + fs# (seq (iterys# ~(second (first (next bindings)))))] |
| 350 | + (if fs# |
| 351 | + (concat fs# (~giter (rest ~gxs))) |
| 352 | + (recur (rest ~gxs)))) |
| 353 | + `(cons ~body-expr |
| 354 | + (~giter (rest ~gxs))))) |
423 | 355 |
|
424 |
| - (for [x [0 1 2 3 4 5] |
425 |
| - :let [y (* x 3)] |
426 |
| - :when (even? y)] |
427 |
| - y) |
| 356 | +(defmacro for* [seq-exprs body-expr] |
| 357 | + (let [to-groups (fn [seq-exprs] |
| 358 | + (reduce (fn [groups kv] |
| 359 | + (if (keyword? (first kv)) |
| 360 | + (conj (pop groups) (conj (peek groups) [(first kv) (last kv)])) |
| 361 | + (conj groups [(first kv) (last kv)]))) |
| 362 | + [] (partition 2 seq-exprs)))] |
| 363 | + `(let [iter# ~(emit-bind (to-groups seq-exprs) body-expr)] |
| 364 | + (iter# ~(second seq-exprs))))) |
| 365 | + |
| 366 | +(defmacro for* [seq-exprs body-expr] |
| 367 | + (let [to-groups (fn [seq-exprs] |
| 368 | + (reduce (fn [groups kv] |
| 369 | + (if (keyword? (first kv)) |
| 370 | + (conj (pop groups) (conj (peek groups) [(first kv) (last kv)])) |
| 371 | + (conj groups [(first kv) (last kv)]))) |
| 372 | + [] (partition 2 seq-exprs)))] |
| 373 | + `(let [iter# ~(emit-bind (to-groups seq-exprs) body-expr)] |
| 374 | + ~(second seq-exprs)))) |
| 375 | + |
| 376 | +(for* [x ['a 'b 'c] |
| 377 | + y [1 2 3]] |
| 378 | + [x y]) |
| 379 | + |
| 380 | +(for* [x [0 1 2 3 4 5] |
| 381 | + y [0 1 2 3 4 5] |
| 382 | + z [0 1 2 3 4 5] |
| 383 | + :let [y (* x 3)] |
| 384 | + :when (even? y)] |
| 385 | + y) |
428 | 386 |
|
429 |
| - (for [x [0 1 2] |
430 |
| - y [0 1 2]] |
431 |
| - [x y]) |
| 387 | +(for* [[x y] '([:a 1] [:b 2] [:c 0]) :when (= y 0)] x) |
432 | 388 |
|
433 |
| -(to-groups '[x [0 1 2] |
434 |
| - y [0 1 2]]) |
| 389 | +(for* [x (range 1 6) |
| 390 | + :let [y (* x x) |
| 391 | + z (* x x x)]] |
| 392 | + [x y z]) |
435 | 393 |
|
436 |
| - [[[0 0] [0 1]] |
437 |
| - [[0 2] [1 0]] |
438 |
| - [[1 1] [1 2]] |
439 |
| - [[2 0] [2 1]]] |
| 394 | +(for* [x [1 2 3] |
| 395 | + y [1 2 3] |
| 396 | + :while (<= x y) |
| 397 | + z [1 2 3] |
| 398 | + z1 [4 5 6] |
| 399 | + z2 [7 8 9]] |
| 400 | + [x y z]) |
0 commit comments