12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- #!r6rs
- ;;; let-optionals.sls --- Optional arguments
- ;; Copyright (c) 2001 Olin Shivers
- ;; This program is free software, you can redistribute it and/or
- ;; modify it under the terms of the new-style BSD license.
- ;; You should have received a copy of the BSD license along with this
- ;; program. If not, see <http://www.debian.org/misc/bsd.license>.
- ;;; Commentary:
- ;;; Code:
- ;;@ Optional arguments.
- (library (arguile lib private let-optionals)
- (export let-optionals*)
- (import (rnrs base)
- (rnrs lists))
- ;; The following code is taken from scsh, file scsh/let-opt.scm.
- ;;
- ;;@ Bind arguments from an argument rest-list to variables.
- ;;
- ;; Typical usage is like this:
- ;; @lisp
- ;; (define (foo arg1 arg2 . args)
- ;; (let-optionals* ((opt1 'default1) (opt2 'default2))
- ;; ...))
- ;; @end lisp
- (define-syntax let-optionals*
- (syntax-rules ()
- ((let-optionals* arg (opt-clause ...) body ...)
- (let ((rest arg))
- (%let-optionals* rest (opt-clause ...) body ...)))))
- (define-syntax %let-optionals*
- (syntax-rules ()
- ((%let-optionals* arg (((var ...) xparser) opt-clause ...) body ...)
- (call-with-values (lambda () (xparser arg))
- (lambda (rest var ...)
- (%let-optionals* rest (opt-clause ...) body ...))))
-
- ((%let-optionals* arg ((var default) opt-clause ...) body ...)
- (call-with-values (lambda () (if (null? arg) (values default '())
- (values (car arg) (cdr arg))))
- (lambda (var rest)
- (%let-optionals* rest (opt-clause ...) body ...))))
- ((%let-optionals* arg ((var default test) opt-clause ...) body ...)
- (call-with-values (lambda ()
- (if (null? arg) (values default '())
- (let ((var (car arg)))
- (if test (values var (cdr arg))
- (error "arg failed LET-OPT test" var)))))
- (lambda (var rest)
- (%let-optionals* rest (opt-clause ...) body ...))))
- ((%let-optionals* arg ((var default test supplied?) opt-clause ...) body ...)
- (call-with-values (lambda ()
- (if (null? arg) (values default #f '())
- (let ((var (car arg)))
- (if test (values var #t (cdr arg))
- (error "arg failed LET-OPT test" var)))))
- (lambda (var supplied? rest)
- (%let-optionals* rest (opt-clause ...) body ...))))
- ((%let-optionals* arg (rest) body ...)
- (let ((rest arg)) body ...))
- ((%let-optionals* arg () body ...)
- (if (null? arg) (let () body ...)
- (error "Too many arguments in let-opt" arg)))))
- )
|