123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- ;;; fixnums.scm --- The R6RS fixnums arithmetic library
- ;; Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc.
- ;;
- ;; 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 arithmetic fixnums (6))
- (export fixnum?
-
- fixnum-width
- least-fixnum
- greatest-fixnum
- fx=?
- fx>?
- fx<?
- fx>=?
- fx<=?
- fxzero?
- fxpositive?
- fxnegative?
- fxodd?
- fxeven?
- fxmax
- fxmin
-
- fx+
- fx*
- fx-
- fxdiv-and-mod
- fxdiv
- fxmod
- fxdiv0-and-mod0
- fxdiv0
- fxmod0
- fx+/carry
- fx-/carry
- fx*/carry
- fxnot
- fxand
- fxior
- fxxor
- fxif
- fxbit-count
- fxlength
- fxfirst-bit-set
- fxbit-set?
- fxcopy-bit
- fxbit-field
- fxcopy-bit-field
- fxarithmetic-shift
- fxarithmetic-shift-left
- fxarithmetic-shift-right
- fxrotate-bit-field
- fxreverse-bit-field)
- (import (only (guile) ash
- cons*
- define-inlinable
- inexact->exact
- logand
- logbit?
- logcount
- logior
- lognot
- logxor
- most-positive-fixnum
- most-negative-fixnum
- object-address)
- (ice-9 optargs)
- (rnrs base (6))
- (rnrs control (6))
- (rnrs arithmetic bitwise (6))
- (rnrs conditions (6))
- (rnrs exceptions (6))
- (rnrs lists (6)))
- (define fixnum-width
- (let ((w (do ((i 0 (+ 1 i))
- (n 1 (* 2 n)))
- ((> n most-positive-fixnum)
- (+ 1 i)))))
- (lambda () w)))
- (define (greatest-fixnum) most-positive-fixnum)
- (define (least-fixnum) most-negative-fixnum)
- (define (fixnum? obj)
- (not (= 0 (logand 2 (object-address obj)))))
- (define-inlinable (inline-fixnum? obj)
- (not (= 0 (logand 2 (object-address obj)))))
- (define-syntax assert-fixnum
- (syntax-rules ()
- ((_ arg ...)
- (or (and (inline-fixnum? arg) ...)
- (raise (make-assertion-violation))))))
- (define (assert-fixnums args)
- (or (for-all inline-fixnum? args) (raise (make-assertion-violation))))
- (define-syntax define-fxop*
- (syntax-rules ()
- ((_ name op)
- (define name
- (case-lambda
- ((x y)
- (assert-fixnum x y)
- (op x y))
- (args
- (assert-fixnums args)
- (apply op args)))))))
- ;; All these predicates don't check their arguments for fixnum-ness,
- ;; as this doesn't seem to be strictly required by R6RS.
- (define fx=? =)
- (define fx>? >)
- (define fx<? <)
- (define fx>=? >=)
- (define fx<=? <=)
- (define fxzero? zero?)
- (define fxpositive? positive?)
- (define fxnegative? negative?)
- (define fxodd? odd?)
- (define fxeven? even?)
- (define-fxop* fxmax max)
- (define-fxop* fxmin min)
- (define (fx+ fx1 fx2)
- (assert-fixnum fx1 fx2)
- (let ((r (+ fx1 fx2)))
- (or (inline-fixnum? r)
- (raise (make-implementation-restriction-violation)))
- r))
- (define (fx* fx1 fx2)
- (assert-fixnum fx1 fx2)
- (let ((r (* fx1 fx2)))
- (or (inline-fixnum? r)
- (raise (make-implementation-restriction-violation)))
- r))
- (define* (fx- fx1 #:optional fx2)
- (assert-fixnum fx1)
- (if fx2
- (begin
- (assert-fixnum fx2)
- (let ((r (- fx1 fx2)))
- (or (inline-fixnum? r) (raise (make-assertion-violation)))
- r))
- (let ((r (- fx1)))
- (or (inline-fixnum? r) (raise (make-assertion-violation)))
- r)))
- (define (fxdiv fx1 fx2)
- (assert-fixnum fx1 fx2)
- (div fx1 fx2))
- (define (fxmod fx1 fx2)
- (assert-fixnum fx1 fx2)
- (mod fx1 fx2))
- (define (fxdiv-and-mod fx1 fx2)
- (assert-fixnum fx1 fx2)
- (div-and-mod fx1 fx2))
- (define (fxdiv0 fx1 fx2)
- (assert-fixnum fx1 fx2)
- (div0 fx1 fx2))
-
- (define (fxmod0 fx1 fx2)
- (assert-fixnum fx1 fx2)
- (mod0 fx1 fx2))
- (define (fxdiv0-and-mod0 fx1 fx2)
- (assert-fixnum fx1 fx2)
- (div0-and-mod0 fx1 fx2))
- (define (fx+/carry fx1 fx2 fx3)
- (assert-fixnum fx1 fx2 fx3)
- (let* ((s (+ fx1 fx2 fx3))
- (s0 (mod0 s (expt 2 (fixnum-width))))
- (s1 (div0 s (expt 2 (fixnum-width)))))
- (values s0 s1)))
- (define (fx-/carry fx1 fx2 fx3)
- (assert-fixnum fx1 fx2 fx3)
- (let* ((d (- fx1 fx2 fx3))
- (d0 (mod0 d (expt 2 (fixnum-width))))
- (d1 (div0 d (expt 2 (fixnum-width)))))
- (values d0 d1)))
- (define (fx*/carry fx1 fx2 fx3)
- (assert-fixnum fx1 fx2 fx3)
- (let* ((s (+ (* fx1 fx2) fx3))
- (s0 (mod0 s (expt 2 (fixnum-width))))
- (s1 (div0 s (expt 2 (fixnum-width)))))
- (values s0 s1)))
- (define (fxnot fx) (assert-fixnum fx) (lognot fx))
- (define-fxop* fxand logand)
- (define-fxop* fxior logior)
- (define-fxop* fxxor logxor)
- (define (fxif fx1 fx2 fx3)
- (assert-fixnum fx1 fx2 fx3)
- (bitwise-if fx1 fx2 fx3))
- (define (fxbit-count fx)
- (assert-fixnum fx)
- (if (negative? fx)
- (bitwise-not (logcount fx))
- (logcount fx)))
- (define (fxlength fx) (assert-fixnum fx) (bitwise-length fx))
- (define (fxfirst-bit-set fx) (assert-fixnum fx) (bitwise-first-bit-set fx))
- (define (fxbit-set? fx1 fx2) (assert-fixnum fx1 fx2) (logbit? fx2 fx1))
- (define (fxcopy-bit fx1 fx2 fx3)
- (assert-fixnum fx1 fx2 fx3)
- (bitwise-copy-bit fx1 fx2 fx3))
- (define (fxbit-field fx1 fx2 fx3)
- (assert-fixnum fx1 fx2 fx3)
- (bitwise-bit-field fx1 fx2 fx3))
- (define (fxcopy-bit-field fx1 fx2 fx3 fx4)
- (assert-fixnum fx1 fx2 fx3 fx4)
- (bitwise-copy-bit-field fx1 fx2 fx3 fx4))
- (define (fxarithmetic-shift fx1 fx2) (assert-fixnum fx1 fx2) (ash fx1 fx2))
- (define fxarithmetic-shift-left fxarithmetic-shift)
- (define (fxarithmetic-shift-right fx1 fx2)
- (assert-fixnum fx1 fx2) (ash fx1 (- fx2)))
- (define (fxrotate-bit-field fx1 fx2 fx3 fx4)
- (assert-fixnum fx1 fx2 fx3 fx4)
- (bitwise-rotate-bit-field fx1 fx2 fx3 fx4))
-
- (define (fxreverse-bit-field fx1 fx2 fx3)
- (assert-fixnum fx1 fx2 fx3)
- (bitwise-reverse-bit-field fx1 fx2 fx3))
- )
|