/lib/dynvar.arc

http://github.com/alimoeeny/arc · Unknown · 37 lines · 32 code · 5 blank · 0 comment · 0 complexity · 3e22ad06feed16431b4cacb5eb8b6a03 MD5 · raw file

  1. (require "lib/util.arc")
  2. (require "lib/thread-cell.arc")
  3. (mac with* (parms . body)
  4. (let uparms (mapeach (var val) (pair parms)
  5. (list var val (uniq (+ "old-" var)) (uniq (+ "new-" var))))
  6. `(with ,(mappendeach (var val old new) uparms
  7. `(,old ,var ,new ,val))
  8. ; we should arguably use dynamic-wind here, but pg's method seems to be
  9. ; to just use protect instead and never use continuations as anything but
  10. ; escape procedures.
  11. (protect
  12. (fn ()
  13. ; update the variables
  14. (= ,@(mappendeach (var val old new) uparms
  15. `(,var ,new)))
  16. ,@body)
  17. (fn ()
  18. ; restore the variables
  19. (= ,@(mappendeach (var val old new) uparms
  20. `(,var ,old))))))))
  21. (mac let* (var val . body)
  22. `(with* (,var ,val) ,@body))
  23. (mac withs* (parms . body)
  24. (if no.parms `(do ,@body)
  25. (let (var val . rest) parms
  26. `(let* ,var ,val (withs* ,rest ,@body)))))
  27. ; Thread-local vars to use with the above
  28. (mac dynvar (name (o init-val))
  29. `(= ,name (thread-cell ,init-val)))
  30. (mac dynvars vars
  31. `(do ,@(mapeach var vars
  32. (if atom.var `(dynvar ,var) `(dynvar ,@var)))))