2010-03-06 01:28:46 -05:00
|
|
|
|
;;; base.scm --- The R6RS base library
|
|
|
|
|
|
|
2019-09-12 21:50:51 +02:00
|
|
|
|
;; Copyright (C) 2010, 2011, 2019 Free Software Foundation, Inc.
|
2010-03-06 01:28:46 -05:00
|
|
|
|
;;
|
|
|
|
|
|
;; This library is free software; you can redistribute it and/or
|
|
|
|
|
|
;; modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
|
;; License as published by the Free Software Foundation; either
|
|
|
|
|
|
;; version 3 of the License, or (at your option) any later version.
|
|
|
|
|
|
;;
|
|
|
|
|
|
;; This library is distributed in the hope that it will be useful,
|
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
;; Lesser General Public License for more details.
|
|
|
|
|
|
;;
|
|
|
|
|
|
;; You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
;; License along with this library; if not, write to the Free Software
|
|
|
|
|
|
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(library (rnrs base (6))
|
|
|
|
|
|
(export boolean? symbol? char? vector? null? pair? number? string? procedure?
|
|
|
|
|
|
|
|
|
|
|
|
define define-syntax syntax-rules lambda let let* let-values
|
2010-08-06 11:52:27 +02:00
|
|
|
|
let*-values letrec letrec* begin
|
2010-03-06 01:28:46 -05:00
|
|
|
|
|
2019-09-12 21:50:51 +02:00
|
|
|
|
quote lambda if set! cond case else => _ ...
|
2010-03-06 01:28:46 -05:00
|
|
|
|
|
|
|
|
|
|
or and not
|
|
|
|
|
|
|
|
|
|
|
|
eqv? equal? eq?
|
|
|
|
|
|
|
|
|
|
|
|
+ - * / max min abs numerator denominator gcd lcm floor ceiling
|
|
|
|
|
|
truncate round rationalize real-part imag-part make-rectangular angle
|
|
|
|
|
|
div mod div-and-mod div0 mod0 div0-and-mod0
|
|
|
|
|
|
|
|
|
|
|
|
expt exact-integer-sqrt sqrt exp log sin cos tan asin acos atan
|
|
|
|
|
|
make-polar magnitude angle
|
|
|
|
|
|
|
|
|
|
|
|
complex? real? rational? integer? exact? inexact? real-valued?
|
Add exports for missing functions from `(rnrs base)'.
* module/rnrs.scm (boolean=?): New export.
Fix typo in export of`integer-valued?'.
* module/rnrs/base.scm: Add exports for `exact' and `inexact'.
(boolean=?, symbol=?, infinite?, finite?, exact-integer-sqrt,
integer-valued?, rational-valued?, real-valued?): New functions.
* test-suite/tests/r6rs-base.test (boolean=?, symbol=?, infinite?,
finite?, exact-integer-sqrt, integer-valued?, rational-valued?,
real-valued?): New test prefixes and tests.
2010-11-17 00:59:45 -05:00
|
|
|
|
rational-valued? integer-valued? zero? positive? negative? odd? even?
|
2010-03-06 01:28:46 -05:00
|
|
|
|
nan? finite? infinite?
|
|
|
|
|
|
|
|
|
|
|
|
exact inexact = < > <= >=
|
|
|
|
|
|
|
|
|
|
|
|
number->string string->number
|
|
|
|
|
|
|
Add exports for missing functions from `(rnrs base)'.
* module/rnrs.scm (boolean=?): New export.
Fix typo in export of`integer-valued?'.
* module/rnrs/base.scm: Add exports for `exact' and `inexact'.
(boolean=?, symbol=?, infinite?, finite?, exact-integer-sqrt,
integer-valued?, rational-valued?, real-valued?): New functions.
* test-suite/tests/r6rs-base.test (boolean=?, symbol=?, infinite?,
finite?, exact-integer-sqrt, integer-valued?, rational-valued?,
real-valued?): New test prefixes and tests.
2010-11-17 00:59:45 -05:00
|
|
|
|
boolean=?
|
|
|
|
|
|
|
2010-03-06 01:28:46 -05:00
|
|
|
|
cons car cdr caar cadr cdar cddr caaar caadr cadar cdaar caddr cdadr
|
|
|
|
|
|
cddar cdddr caaaar caaadr caadar cadaar cdaaar cddaar cdadar cdaadr
|
|
|
|
|
|
cadadr caaddr caddar cadddr cdaddr cddadr cdddar cddddr
|
|
|
|
|
|
|
|
|
|
|
|
list? list length append reverse list-tail list-ref map for-each
|
|
|
|
|
|
|
2010-03-20 08:36:17 -04:00
|
|
|
|
symbol->string string->symbol symbol=?
|
2010-03-06 01:28:46 -05:00
|
|
|
|
|
|
|
|
|
|
char->integer integer->char char=? char<? char>? char<=? char>=?
|
|
|
|
|
|
|
|
|
|
|
|
make-string string string-length string-ref string=? string<? string>?
|
|
|
|
|
|
string<=? string>=? substring string-append string->list list->string
|
|
|
|
|
|
string-for-each string-copy
|
|
|
|
|
|
|
|
|
|
|
|
vector? make-vector vector vector-length vector-ref vector-set!
|
|
|
|
|
|
vector->list list->vector vector-fill! vector-map vector-for-each
|
|
|
|
|
|
|
|
|
|
|
|
error assertion-violation assert
|
|
|
|
|
|
|
|
|
|
|
|
call-with-current-continuation call/cc call-with-values dynamic-wind
|
|
|
|
|
|
values apply
|
|
|
|
|
|
|
|
|
|
|
|
quasiquote unquote unquote-splicing
|
|
|
|
|
|
|
|
|
|
|
|
let-syntax letrec-syntax
|
|
|
|
|
|
|
|
|
|
|
|
syntax-rules identifier-syntax)
|
2012-11-22 09:45:12 +00:00
|
|
|
|
(import (rename (except (guile) error raise map string-for-each)
|
2011-04-06 01:53:38 +01:00
|
|
|
|
(log log-internal)
|
Add two new sets of fast quotient and remainder operators
* libguile/numbers.c (scm_euclidean_quo_and_rem, scm_euclidean_quotient,
scm_euclidean_remainder, scm_centered_quo_and_rem,
scm_centered_quotient, scm_centered_remainder): New extensible
procedures `euclidean/', `euclidean-quotient', `euclidean-remainder',
`centered/', `centered-quotient', `centered-remainder'.
* libguile/numbers.h: Add function prototypes.
* module/rnrs/base.scm: Remove incorrect stub implementations of `div',
`mod', `div-and-mod', `div0', `mod0', and `div0-and-mod0'. Instead do
renaming imports of `euclidean-quotient', `euclidean-remainder',
`euclidean/', `centered-quotient', `centered-remainder', and
`centered/', which are equivalent to the R6RS operators.
* module/rnrs/arithmetic/fixnums.scm (fxdiv, fxmod, fxdiv-and-mod,
fxdiv0, fxmod0, fxdiv0-and-mod0): Remove redundant checks for division
by zero and unnecessary complexity.
(fx+/carry): Remove unneeded calls to `inexact->exact'.
* module/rnrs/arithmetic/flonums.scm (fldiv, flmod, fldiv-and-mod,
fldiv0, flmod0, fldiv0-and-mod0): Remove redundant checks for division
by zero and unnecessary complexity. Remove unneeded calls to
`inexact->exact' and `exact->inexact'
* test-suite/tests/numbers.test: (test-eqv?): New internal predicate for
comparing numerical outputs with expected values.
Add extensive test code for `euclidean/', `euclidean-quotient',
`euclidean-remainder', `centered/', `centered-quotient',
`centered-remainder'.
* test-suite/tests/r6rs-arithmetic-fixnums.test: Fix some broken test
cases, and remove `unresolved' test markers for `fxdiv', `fxmod',
`fxdiv-and-mod', `fxdiv0', `fxmod0', and `fxdiv0-and-mod0'.
* test-suite/tests/r6rs-arithmetic-flonums.test: Remove `unresolved'
test markers for `fldiv', `flmod', `fldiv-and-mod', `fldiv0',
`flmod0', and `fldiv0-and-mod0'.
* doc/ref/api-data.texi (Arithmetic): Document `euclidean/',
`euclidean-quotient', `euclidean-remainder', `centered/',
`centered-quotient', and `centered-remainder'.
(Operations on Integer Values): Add cross-references to `euclidean/'
et al, from `quotient', `remainder', and `modulo'.
* doc/ref/r6rs.texi (rnrs base): Improve documentation for `div', `mod',
`div-and-mod', `div0', `mod0', and `div0-and-mod0'. Add
cross-references to `euclidean/' et al.
* NEWS: Add NEWS entry.
2011-01-30 08:48:28 -05:00
|
|
|
|
(euclidean-quotient div)
|
|
|
|
|
|
(euclidean-remainder mod)
|
|
|
|
|
|
(euclidean/ div-and-mod)
|
|
|
|
|
|
(centered-quotient div0)
|
|
|
|
|
|
(centered-remainder mod0)
|
|
|
|
|
|
(centered/ div0-and-mod0)
|
2011-01-26 09:34:02 -05:00
|
|
|
|
(inf? infinite?)
|
Add exports for missing functions from `(rnrs base)'.
* module/rnrs.scm (boolean=?): New export.
Fix typo in export of`integer-valued?'.
* module/rnrs/base.scm: Add exports for `exact' and `inexact'.
(boolean=?, symbol=?, infinite?, finite?, exact-integer-sqrt,
integer-valued?, rational-valued?, real-valued?): New functions.
* test-suite/tests/r6rs-base.test (boolean=?, symbol=?, infinite?,
finite?, exact-integer-sqrt, integer-valued?, rational-valued?,
real-valued?): New test prefixes and tests.
2010-11-17 00:59:45 -05:00
|
|
|
|
(exact->inexact inexact)
|
|
|
|
|
|
(inexact->exact exact))
|
|
|
|
|
|
(srfi srfi-11))
|
|
|
|
|
|
|
2012-11-22 09:45:12 +00:00
|
|
|
|
(define string-for-each
|
|
|
|
|
|
(case-lambda
|
|
|
|
|
|
((proc string)
|
|
|
|
|
|
(let ((end (string-length string)))
|
|
|
|
|
|
(let loop ((i 0))
|
|
|
|
|
|
(unless (= i end)
|
|
|
|
|
|
(proc (string-ref string i))
|
|
|
|
|
|
(loop (+ i 1))))))
|
|
|
|
|
|
((proc string1 string2)
|
|
|
|
|
|
(let ((end1 (string-length string1))
|
|
|
|
|
|
(end2 (string-length string2)))
|
|
|
|
|
|
(unless (= end1 end2)
|
|
|
|
|
|
(assertion-violation 'string-for-each
|
|
|
|
|
|
"string arguments must all have the same length"
|
|
|
|
|
|
string1 string2))
|
|
|
|
|
|
(let loop ((i 0))
|
|
|
|
|
|
(unless (= i end1)
|
|
|
|
|
|
(proc (string-ref string1 i)
|
|
|
|
|
|
(string-ref string2 i))
|
|
|
|
|
|
(loop (+ i 1))))))
|
|
|
|
|
|
((proc string . strings)
|
|
|
|
|
|
(let ((end (string-length string))
|
|
|
|
|
|
(ends (map string-length strings)))
|
|
|
|
|
|
(for-each (lambda (x)
|
|
|
|
|
|
(unless (= end x)
|
|
|
|
|
|
(apply assertion-violation
|
|
|
|
|
|
'string-for-each
|
|
|
|
|
|
"string arguments must all have the same length"
|
|
|
|
|
|
string strings)))
|
|
|
|
|
|
ends)
|
|
|
|
|
|
(let loop ((i 0))
|
|
|
|
|
|
(unless (= i end)
|
|
|
|
|
|
(apply proc
|
|
|
|
|
|
(string-ref string i)
|
|
|
|
|
|
(map (lambda (s) (string-ref s i)) strings))
|
|
|
|
|
|
(loop (+ i 1))))))))
|
|
|
|
|
|
|
2011-08-17 23:24:20 +02:00
|
|
|
|
(define map
|
|
|
|
|
|
(case-lambda
|
|
|
|
|
|
((f l)
|
|
|
|
|
|
(let map1 ((hare l) (tortoise l) (move? #f) (out '()))
|
|
|
|
|
|
(if (pair? hare)
|
|
|
|
|
|
(if move?
|
|
|
|
|
|
(if (eq? tortoise hare)
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map" "Circular list: ~S"
|
|
|
|
|
|
(list l) #f)
|
|
|
|
|
|
(map1 (cdr hare) (cdr tortoise) #f
|
|
|
|
|
|
(cons (f (car hare)) out)))
|
|
|
|
|
|
(map1 (cdr hare) tortoise #t
|
|
|
|
|
|
(cons (f (car hare)) out)))
|
|
|
|
|
|
(if (null? hare)
|
|
|
|
|
|
(reverse out)
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map" "Not a list: ~S"
|
|
|
|
|
|
(list l) #f)))))
|
|
|
|
|
|
|
|
|
|
|
|
((f l1 l2)
|
|
|
|
|
|
(let map2 ((h1 l1) (h2 l2) (t1 l1) (t2 l2) (move? #f) (out '()))
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((pair? h1)
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((not (pair? h2))
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map"
|
|
|
|
|
|
(if (list? h2)
|
|
|
|
|
|
"List of wrong length: ~S"
|
|
|
|
|
|
"Not a list: ~S")
|
|
|
|
|
|
(list l2) #f))
|
|
|
|
|
|
((not move?)
|
|
|
|
|
|
(map2 (cdr h1) (cdr h2) t1 t2 #t
|
|
|
|
|
|
(cons (f (car h1) (car h2)) out)))
|
|
|
|
|
|
((eq? t1 h1)
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map" "Circular list: ~S"
|
|
|
|
|
|
(list l1) #f))
|
|
|
|
|
|
((eq? t2 h2)
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map" "Circular list: ~S"
|
|
|
|
|
|
(list l2) #f))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(map2 (cdr h1) (cdr h2) (cdr t1) (cdr t2) #f
|
|
|
|
|
|
(cons (f (car h1) (car h2)) out)))))
|
|
|
|
|
|
|
|
|
|
|
|
((and (null? h1) (null? h2))
|
|
|
|
|
|
(reverse out))
|
|
|
|
|
|
|
|
|
|
|
|
((null? h1)
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map"
|
|
|
|
|
|
(if (list? h2)
|
|
|
|
|
|
"List of wrong length: ~S"
|
|
|
|
|
|
"Not a list: ~S")
|
|
|
|
|
|
(list l2) #f))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map"
|
|
|
|
|
|
"Not a list: ~S"
|
|
|
|
|
|
(list l1) #f)))))
|
|
|
|
|
|
|
|
|
|
|
|
((f l1 . rest)
|
|
|
|
|
|
(let ((len (length l1)))
|
|
|
|
|
|
(let mapn ((rest rest))
|
|
|
|
|
|
(or (null? rest)
|
|
|
|
|
|
(if (= (length (car rest)) len)
|
|
|
|
|
|
(mapn (cdr rest))
|
|
|
|
|
|
(scm-error 'wrong-type-arg "map" "List of wrong length: ~S"
|
|
|
|
|
|
(list (car rest)) #f)))))
|
|
|
|
|
|
(let mapn ((l1 l1) (rest rest) (out '()))
|
|
|
|
|
|
(if (null? l1)
|
|
|
|
|
|
(reverse out)
|
|
|
|
|
|
(mapn (cdr l1) (map cdr rest)
|
|
|
|
|
|
(cons (apply f (car l1) (map car rest)) out)))))))
|
|
|
|
|
|
|
2011-04-06 01:53:38 +01:00
|
|
|
|
(define log
|
|
|
|
|
|
(case-lambda
|
|
|
|
|
|
((n)
|
|
|
|
|
|
(log-internal n))
|
|
|
|
|
|
((n base)
|
|
|
|
|
|
(/ (log n)
|
|
|
|
|
|
(log base)))))
|
|
|
|
|
|
|
Add exports for missing functions from `(rnrs base)'.
* module/rnrs.scm (boolean=?): New export.
Fix typo in export of`integer-valued?'.
* module/rnrs/base.scm: Add exports for `exact' and `inexact'.
(boolean=?, symbol=?, infinite?, finite?, exact-integer-sqrt,
integer-valued?, rational-valued?, real-valued?): New functions.
* test-suite/tests/r6rs-base.test (boolean=?, symbol=?, infinite?,
finite?, exact-integer-sqrt, integer-valued?, rational-valued?,
real-valued?): New test prefixes and tests.
2010-11-17 00:59:45 -05:00
|
|
|
|
(define (boolean=? . bools)
|
|
|
|
|
|
(define (boolean=?-internal lst last)
|
|
|
|
|
|
(or (null? lst)
|
|
|
|
|
|
(let ((bool (car lst)))
|
|
|
|
|
|
(and (eqv? bool last) (boolean=?-internal (cdr lst) bool)))))
|
|
|
|
|
|
(or (null? bools)
|
|
|
|
|
|
(let ((bool (car bools)))
|
|
|
|
|
|
(and (boolean? bool) (boolean=?-internal (cdr bools) bool)))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (symbol=? . syms)
|
|
|
|
|
|
(define (symbol=?-internal lst last)
|
|
|
|
|
|
(or (null? lst)
|
|
|
|
|
|
(let ((sym (car lst)))
|
|
|
|
|
|
(and (eq? sym last) (symbol=?-internal (cdr lst) sym)))))
|
|
|
|
|
|
(or (null? syms)
|
|
|
|
|
|
(let ((sym (car syms)))
|
|
|
|
|
|
(and (symbol? sym) (symbol=?-internal (cdr syms) sym)))))
|
|
|
|
|
|
|
2011-01-28 23:42:01 -05:00
|
|
|
|
(define (real-valued? x)
|
|
|
|
|
|
(and (complex? x)
|
|
|
|
|
|
(zero? (imag-part x))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (rational-valued? x)
|
|
|
|
|
|
(and (real-valued? x)
|
|
|
|
|
|
(rational? (real-part x))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (integer-valued? x)
|
|
|
|
|
|
(and (rational-valued? x)
|
|
|
|
|
|
(= x (floor (real-part x)))))
|
2010-04-03 23:04:24 -04:00
|
|
|
|
|
2010-08-08 19:32:23 -04:00
|
|
|
|
(define (vector-for-each proc . vecs)
|
|
|
|
|
|
(apply for-each (cons proc (map vector->list vecs))))
|
|
|
|
|
|
(define (vector-map proc . vecs)
|
|
|
|
|
|
(list->vector (apply map (cons proc (map vector->list vecs)))))
|
|
|
|
|
|
|
2011-02-22 00:32:13 +01:00
|
|
|
|
(define-syntax define-proxy
|
|
|
|
|
|
(syntax-rules (@)
|
|
|
|
|
|
;; Define BINDING to point to (@ MODULE ORIGINAL). This hack is to
|
|
|
|
|
|
;; make sure MODULE is loaded lazily, at run-time, when BINDING is
|
|
|
|
|
|
;; encountered, rather than being loaded while compiling and
|
|
|
|
|
|
;; loading (rnrs base).
|
|
|
|
|
|
;; This avoids circular dependencies among modules and makes
|
|
|
|
|
|
;; (rnrs base) more lightweight.
|
|
|
|
|
|
((_ binding (@ module original))
|
|
|
|
|
|
(define-syntax binding
|
|
|
|
|
|
(identifier-syntax
|
|
|
|
|
|
(module-ref (resolve-interface 'module) 'original))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-proxy raise
|
|
|
|
|
|
(@ (rnrs exceptions) raise))
|
|
|
|
|
|
|
|
|
|
|
|
(define-proxy condition
|
2010-08-28 10:16:30 -07:00
|
|
|
|
(@ (rnrs conditions) condition))
|
2011-02-22 00:32:13 +01:00
|
|
|
|
(define-proxy make-error
|
2010-11-25 23:03:12 +01:00
|
|
|
|
(@ (rnrs conditions) make-error))
|
2011-02-22 00:32:13 +01:00
|
|
|
|
(define-proxy make-assertion-violation
|
2010-08-28 10:16:30 -07:00
|
|
|
|
(@ (rnrs conditions) make-assertion-violation))
|
2011-02-22 00:32:13 +01:00
|
|
|
|
(define-proxy make-who-condition
|
2010-08-28 10:16:30 -07:00
|
|
|
|
(@ (rnrs conditions) make-who-condition))
|
2011-02-22 00:32:13 +01:00
|
|
|
|
(define-proxy make-message-condition
|
2010-08-28 10:16:30 -07:00
|
|
|
|
(@ (rnrs conditions) make-message-condition))
|
2011-02-22 00:32:13 +01:00
|
|
|
|
(define-proxy make-irritants-condition
|
2010-08-28 10:16:30 -07:00
|
|
|
|
(@ (rnrs conditions) make-irritants-condition))
|
2010-11-25 23:03:12 +01:00
|
|
|
|
|
|
|
|
|
|
(define (error who message . irritants)
|
|
|
|
|
|
(raise (apply condition
|
|
|
|
|
|
(append (list (make-error))
|
|
|
|
|
|
(if who (list (make-who-condition who)) '())
|
|
|
|
|
|
(list (make-message-condition message)
|
|
|
|
|
|
(make-irritants-condition irritants))))))
|
2010-08-28 10:16:30 -07:00
|
|
|
|
|
|
|
|
|
|
(define (assertion-violation who message . irritants)
|
2010-11-25 23:03:12 +01:00
|
|
|
|
(raise (apply condition
|
|
|
|
|
|
(append (list (make-assertion-violation))
|
|
|
|
|
|
(if who (list (make-who-condition who)) '())
|
|
|
|
|
|
(list (make-message-condition message)
|
|
|
|
|
|
(make-irritants-condition irritants))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-syntax assert
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((_ expression)
|
2011-04-06 13:51:44 +01:00
|
|
|
|
(or expression
|
2010-11-25 23:03:12 +01:00
|
|
|
|
(raise (condition
|
|
|
|
|
|
(make-assertion-violation)
|
|
|
|
|
|
(make-message-condition
|
|
|
|
|
|
(format #f "assertion failed: ~s" 'expression))))))))
|
2010-08-28 10:16:30 -07:00
|
|
|
|
|
2010-04-03 23:04:24 -04:00
|
|
|
|
)
|