let-optionals.scm 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!r6rs
  2. ;;; let-optionals.sls --- Optional arguments
  3. ;; Copyright (c) 2001 Olin Shivers
  4. ;; This program is free software, you can redistribute it and/or
  5. ;; modify it under the terms of the new-style BSD license.
  6. ;; You should have received a copy of the BSD license along with this
  7. ;; program. If not, see <http://www.debian.org/misc/bsd.license>.
  8. ;;; Commentary:
  9. ;;; Code:
  10. ;;@ Optional arguments.
  11. (library (arguile lib private let-optionals)
  12. (export let-optionals*)
  13. (import (rnrs base)
  14. (rnrs lists))
  15. ;; The following code is taken from scsh, file scsh/let-opt.scm.
  16. ;;
  17. ;;@ Bind arguments from an argument rest-list to variables.
  18. ;;
  19. ;; Typical usage is like this:
  20. ;; @lisp
  21. ;; (define (foo arg1 arg2 . args)
  22. ;; (let-optionals* ((opt1 'default1) (opt2 'default2))
  23. ;; ...))
  24. ;; @end lisp
  25. (define-syntax let-optionals*
  26. (syntax-rules ()
  27. ((let-optionals* arg (opt-clause ...) body ...)
  28. (let ((rest arg))
  29. (%let-optionals* rest (opt-clause ...) body ...)))))
  30. (define-syntax %let-optionals*
  31. (syntax-rules ()
  32. ((%let-optionals* arg (((var ...) xparser) opt-clause ...) body ...)
  33. (call-with-values (lambda () (xparser arg))
  34. (lambda (rest var ...)
  35. (%let-optionals* rest (opt-clause ...) body ...))))
  36. ((%let-optionals* arg ((var default) opt-clause ...) body ...)
  37. (call-with-values (lambda () (if (null? arg) (values default '())
  38. (values (car arg) (cdr arg))))
  39. (lambda (var rest)
  40. (%let-optionals* rest (opt-clause ...) body ...))))
  41. ((%let-optionals* arg ((var default test) opt-clause ...) body ...)
  42. (call-with-values (lambda ()
  43. (if (null? arg) (values default '())
  44. (let ((var (car arg)))
  45. (if test (values var (cdr arg))
  46. (error "arg failed LET-OPT test" var)))))
  47. (lambda (var rest)
  48. (%let-optionals* rest (opt-clause ...) body ...))))
  49. ((%let-optionals* arg ((var default test supplied?) opt-clause ...) body ...)
  50. (call-with-values (lambda ()
  51. (if (null? arg) (values default #f '())
  52. (let ((var (car arg)))
  53. (if test (values var #t (cdr arg))
  54. (error "arg failed LET-OPT test" var)))))
  55. (lambda (var supplied? rest)
  56. (%let-optionals* rest (opt-clause ...) body ...))))
  57. ((%let-optionals* arg (rest) body ...)
  58. (let ((rest arg)) body ...))
  59. ((%let-optionals* arg () body ...)
  60. (if (null? arg) (let () body ...)
  61. (error "Too many arguments in let-opt" arg)))))
  62. )