1995-10-13 23:34:21 -04:00
|
|
|
; Copyright (c) 1993, 1994 Richard Kelsey and Jonathan Rees. See file COPYING.
|
|
|
|
|
|
|
|
|
|
|
|
(define (concatenate-symbol . stuff)
|
|
|
|
(string->symbol
|
|
|
|
(apply string-append
|
|
|
|
(map (lambda (x)
|
|
|
|
(cond ((string? x) x)
|
|
|
|
((symbol? x) (symbol->string x))
|
|
|
|
((number? x) (number->string x))
|
|
|
|
(else
|
|
|
|
(error "cannot coerce ~S to a string" x))))
|
|
|
|
stuff))))
|
|
|
|
|
|
|
|
(define (error format-string . args)
|
|
|
|
((structure-ref signals error)
|
|
|
|
(apply format (cons #f (cons format-string args)))))
|
|
|
|
|
|
|
|
(define (breakpoint format-string . args)
|
|
|
|
((structure-ref debugging breakpoint)
|
|
|
|
(apply format (cons #f (cons format-string args)))))
|
|
|
|
|
|
|
|
; For macro expanders
|
|
|
|
|
|
|
|
(define (syntax-error message form)
|
|
|
|
(error "syntax error: ~A ~S" message form))
|
|
|
|
|
|
|
|
(define (atom? x)
|
|
|
|
(not (pair? x)))
|
|
|
|
|
|
|
|
(define (neq? x y)
|
|
|
|
(not (eq? x y)))
|
|
|
|
|
|
|
|
(define (n= x y)
|
|
|
|
(not (= x y)))
|
|
|
|
|
|
|
|
(define (identity x) x)
|
|
|
|
|
|
|
|
(define (no-op x) x) ; guaranteed not to be in-lined
|
|
|
|
|
|
|
|
(define (null-list? x)
|
|
|
|
(cond ((null? x) #t)
|
|
|
|
((pair? x) #f)
|
|
|
|
(error "null-list? got a non-list" x)))
|
|
|
|
|
|
|
|
(define (reverse! l)
|
|
|
|
(cond ((or (null? l)
|
|
|
|
(null? (cdr l)))
|
|
|
|
l)
|
|
|
|
(else
|
|
|
|
(let ((rest (cdr l)))
|
|
|
|
(set-cdr! l '())
|
|
|
|
(let loop ((l1 l) (l2 rest))
|
|
|
|
(cond ((null? l2)
|
|
|
|
l1)
|
|
|
|
(else
|
|
|
|
(let ((rest (cdr l2)))
|
|
|
|
(set-cdr! l2 l1)
|
|
|
|
(loop l2 rest)))))))))
|
|
|
|
|
|
|
|
(define (memq? x l)
|
|
|
|
(let loop ((l l))
|
|
|
|
(cond ((null? l) #f)
|
|
|
|
((eq? x (car l)) #t)
|
|
|
|
(else (loop (cdr l))))))
|
|
|
|
|
|
|
|
(define (first pred list)
|
|
|
|
(let loop ((list list))
|
|
|
|
(cond ((null? list)
|
|
|
|
#f)
|
|
|
|
((pred (car list))
|
|
|
|
(car list))
|
|
|
|
(else
|
|
|
|
(loop (cdr list))))))
|
|
|
|
|
|
|
|
(define any first) ; ANY? need not search in order, but it does anyway
|
|
|
|
|
|
|
|
(define (any? proc list)
|
|
|
|
(let loop ((list list))
|
|
|
|
(cond ((null? list)
|
|
|
|
#f)
|
|
|
|
((proc (car list))
|
|
|
|
#t)
|
|
|
|
(else
|
|
|
|
(loop (cdr list))))))
|
|
|
|
|
|
|
|
(define (every? pred list)
|
|
|
|
(let loop ((list list))
|
|
|
|
(cond ((null? list)
|
|
|
|
#t)
|
|
|
|
((pred (car list))
|
|
|
|
(loop (cdr list)))
|
|
|
|
(else
|
|
|
|
#f))))
|
|
|
|
|
|
|
|
(define (filter pred l)
|
|
|
|
(let loop ((l l) (r '()))
|
|
|
|
(cond ((null? l)
|
|
|
|
(reverse r))
|
|
|
|
((pred (car l))
|
|
|
|
(loop (cdr l) (cons (car l) r)))
|
|
|
|
(else
|
|
|
|
(loop (cdr l) r)))))
|
|
|
|
|
|
|
|
(define (filter! pred list)
|
|
|
|
(let filter! ((list list))
|
|
|
|
(cond ((null-list? list)
|
|
|
|
'())
|
|
|
|
((pred (car list))
|
|
|
|
(set-cdr! list (filter! (cdr list))) list)
|
|
|
|
(else
|
|
|
|
(filter! (cdr list))))))
|
|
|
|
|
|
|
|
(define (filter-map f l)
|
|
|
|
(let loop ((l l) (r '()))
|
|
|
|
(cond ((null? l)
|
|
|
|
(reverse r))
|
|
|
|
((f (car l))
|
|
|
|
=> (lambda (x)
|
|
|
|
(loop (cdr l) (cons x r))))
|
|
|
|
(else
|
|
|
|
(loop (cdr l) r)))))
|
|
|
|
|
|
|
|
(define (remove-duplicates list)
|
|
|
|
(do ((list list (cdr list))
|
|
|
|
(res '() (if (memq? (car list) res)
|
|
|
|
res
|
|
|
|
(cons (car list) res))))
|
|
|
|
((null-list? list)
|
|
|
|
res)))
|
|
|
|
|
|
|
|
(define (partition-list pred l)
|
|
|
|
(let loop ((l l) (yes '()) (no '()))
|
|
|
|
(cond ((null? l)
|
|
|
|
(values (reverse yes) (reverse no)))
|
|
|
|
((pred (car l))
|
|
|
|
(loop (cdr l) (cons (car l) yes) no))
|
|
|
|
(else
|
|
|
|
(loop (cdr l) yes (cons (car l) no))))))
|
|
|
|
|
|
|
|
(define (partition-list! pred l)
|
|
|
|
(let loop ((l l) (yes '()) (no '()))
|
|
|
|
(cond ((null? l)
|
|
|
|
(values (reverse! yes) (reverse! no)))
|
|
|
|
((pred (car l))
|
|
|
|
(let ((rest (cdr l)))
|
|
|
|
(set-cdr! l yes)
|
|
|
|
(loop rest l no)))
|
|
|
|
(else
|
|
|
|
(let ((rest (cdr l)))
|
|
|
|
(set-cdr! l no)
|
|
|
|
(loop rest yes l))))))
|
|
|
|
|
|
|
|
(define (delq! object list)
|
|
|
|
(let loop ((list list))
|
|
|
|
(cond ((null? list)
|
|
|
|
'())
|
|
|
|
((eq? object (car list))
|
|
|
|
(loop (cdr list)))
|
|
|
|
(else
|
|
|
|
(let loop ((next (cdr list)) (prev list))
|
|
|
|
(cond ((null? next)
|
|
|
|
list)
|
|
|
|
((eq? (car next) object)
|
|
|
|
(set-cdr! prev (cdr next))
|
|
|
|
(loop (cdr next) prev))
|
|
|
|
(else
|
|
|
|
(loop (cdr next) next))))))))
|
|
|
|
|
|
|
|
(define (delq thing list)
|
|
|
|
(delete (lambda (x) (eq? x thing)) list))
|
|
|
|
|
|
|
|
(define (append-reverse! l1 l2)
|
|
|
|
(let loop ((list l1) (res l2))
|
2001-03-10 22:47:00 -05:00
|
|
|
(if (pair? list)
|
|
|
|
(let ((next (cdr list)))
|
|
|
|
(set-cdr! list res)
|
|
|
|
(loop next list))
|
|
|
|
res)))
|
|
|
|
|
|
|
|
;; This DELETE shares the longest tail of L that has no deleted elements.
|
|
|
|
;; If we had multi-continuation calls, this could be made more efficient.
|
|
|
|
|
|
|
|
(define (delete pred l)
|
|
|
|
(call-with-values (lambda ()
|
|
|
|
;; (recur l) returns L with (pred x) values deleted.
|
|
|
|
;; It also returns a flag NO-DEL? if the returned value
|
|
|
|
;; is EQ? to L, i.e. if it didn't delete anything.
|
|
|
|
(let recur ((l l))
|
|
|
|
(if (pair? l)
|
|
|
|
(let ((x (car l))
|
|
|
|
(tl (cdr l)))
|
|
|
|
(if (pred x)
|
|
|
|
(call-with-values (lambda () (recur tl))
|
|
|
|
(lambda (ans no-del?)
|
|
|
|
(values ans #f))) ; Deleted X.
|
|
|
|
(call-with-values (lambda () (recur tl))
|
|
|
|
(lambda (ans no-del?)
|
|
|
|
(if no-del?
|
|
|
|
(values l #t)
|
|
|
|
(values (cons x ans) #f))))))
|
|
|
|
(values '() #t))))
|
|
|
|
(lambda (ans no-del?) ans)))
|