www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

7.8.3-dolist-dotimes.lisp (1740B)


      1 (defmacro my-dolist (spec &rest body)
      2   (let ((var (car spec))
      3         (listform (cadr spec))
      4         (resultform (caddr spec))
      5         (loopsym (make-symbol "loop"))
      6         (endsym (make-symbol "end"))
      7         (listsym (make-symbol "list")))
      8     `(let ((,var nil)
      9            (,listsym ,listform))
     10        (tagbody
     11         ,loopsym
     12           (setq ,var (car ,listsym))
     13           (when (endp ,listsym)
     14             (go ,endsym))
     15           (progn ,@body)
     16           (setq ,listsym (cdr ,listsym))
     17           (go ,loopsym)
     18         ,endsym)
     19        ,resultform)))
     20 
     21 ;; (let ((foo 42)) (my-dolist (a '(1 2 3) foo) (print a)))
     22 ;; => 1
     23 ;; => 2
     24 ;; => 3
     25 ;; => 42
     26 ;; (my-dolist (a '(1 2 3)) (print a))
     27 ;; => 1
     28 ;; => 2
     29 ;; => 3
     30 ;; => nil
     31 ;; (my-dolist (a '(1 2 3) a) (print a))
     32 ;; => 1
     33 ;; => 2
     34 ;; => 3
     35 ;; => nil
     36 ;; (my-dolist (a '()) (print a))
     37 ;; => nil
     38 
     39 (defmacro my-dotimes (spec &rest body)
     40   (let ((var (car spec))
     41         (countform (cadr spec))
     42         (resultform (caddr spec))
     43         (loopsym (make-symbol "loop"))
     44         (endsym (make-symbol "end"))
     45         (countersym (make-symbol "counter"))
     46         (maxsym (make-symbol "max")))
     47     `(let ((,var nil)
     48            (,maxsym ,countform)
     49            (,countersym 0))
     50        (tagbody
     51         ,loopsym
     52           (setq ,var ,countersym)
     53           (when (>= ,countersym ,maxsym)
     54             (go ,endsym))
     55           (progn ,@body)
     56           (setq ,countersym (+ ,countersym 1))
     57           (go ,loopsym)
     58         ,endsym
     59           (when (< 0 ,var) (setq ,var 0)))
     60        ,resultform)))
     61 
     62 ;; (my-dotimes (i 3) (print i))
     63 ;; => 0
     64 ;; => 1
     65 ;; => 2
     66 ;; => nil
     67 ;; (my-dotimes (i 3 i) (print i))
     68 ;; => 0
     69 ;; => 1
     70 ;; => 2
     71 ;; => 3
     72 ;; (my-dotimes (i -5 i) (print i))
     73 ;; => 0
     74 ;; (my-dotimes (i -5) (print i))
     75 ;; => nil