Skip to content

Instantly share code, notes, and snippets.

@jneira
Created December 30, 2010 16:30
Show Gist options
  • Save jneira/759964 to your computer and use it in GitHub Desktop.
Save jneira/759964 to your computer and use it in GitHub Desktop.
;;1.45 Definir una macro MI-DO que tenga exactamente la misma funcionalidad que la macro DO,
;;pero que además de devolver el valor correspondiente cuando se cumpla la condición de finalización,
;;devuelva un segundo valor que indique el número de iteraciones que se han realizado. No se deben
;;utilizar las primitivas DO, DO*, DOLIST, DOTIMES.
(defmacro iterar (steps final &rest body)
`(labels ((main ,(mapcar #'car steps)
(if ,(car final) ,(cadr final)
(progn ,@body
(main ,@(apply #'append
(mapcar #'last steps)))))))
(main ,@(mapcar #'cadr steps))))
(macroexpand-1 '(do ((total x (1+ total))
(cont y (1- cont)))
((zerop cont) total) (print cont)))
;;(BLOCK NIL
;; (LET ((TOTAL X) (CONT Y))
;; (TAGBODY #:LOOP-3594 (IF (ZEROP CONT) (GO #:END-3595))
;; (PRINT CONT) (PSETQ TOTAL (1+ TOTAL) CONT (1- CONT))
;; (GO #:LOOP-3594) #:END-3595 (RETURN-FROM NIL (PROGN TOTAL)))))
(macroexpand-1 '(iterar ((total x (1+ total))
(cont y (1- cont)))
((zerop cont) total) (print cont)))
;; (LABELS ((MAIN (TOTAL CONT)
;; (IF (ZEROP CONT) TOTAL
;; (PROGN (PRINT CONT) (MAIN (1+ TOTAL) (1- CONT))))))
;; (MAIN X Y))
(defmacro iterar.con.contador (steps final &rest body)
(let ((c (gensym "counter")))
`(iterar ,(cons `(,c 0 (1+ ,c)) steps)
(,(car final) (values ,(cadr final) ,c))
,@body)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment