~dieggsy/srfi-143

64554ac4a4bafd43a90a382b081e160c609a67a0 — dieggsy 3 years ago a879029 0.3
Reorganize files, wrap wiki, add chicken/maintianership notes
9 files changed, 440 insertions(+), 501 deletions(-)

M Makefile
D README.org
D README.svnwiki
R srfi-143/carries.scm => carries.scm
R srfi-143/srfi-143-impl.scm => srfi-143-impl.scm
M srfi-143.egg
M srfi-143.scm
A srfi-143.svnwiki
D srfi-143/srfi-143.scm
M Makefile => Makefile +2 -6
@@ 1,4 1,3 @@
CSC			:= csc
CHICKEN_CLEAN		:= chicken-clean
CHICKEN_INSTALL		:= chicken-install
SALMONELLA		:= salmonella


@@ 14,16 13,13 @@ clean:
	rm -f $(SALMONELLA_LOG)

compile:
	$(CSC) $(SRFI)
	$(CHICKEN-INSTALL) -n

salmonella:
	$(SALMONELLA)

test:
	$(CHICKEN_INSTALL) -test

test_new_egg:
	$(TEST_NEW_EGG)
	$(CHICKEN_INSTALL) -n -test

view:
	$(SALMONELLA_LOG_VIEWER) $(SALMONELLA_LOG)

D README.org => README.org +0 -149
@@ 1,149 0,0 @@
* SRFI 143: Fixnums
** Abstract
This SRFI describes arithmetic procedures applicable to a limited range of exact integers only. These procedures are semantically similar to the corresponding generic-arithmetic procedures, but allow more efficient implementations.

For more information see: [[https://srfi.schemers.org/srfi-143/][SRFI 143: Fixnums]]
** Rationale
It is common for Schemes that support arbitrarily large exact integers to have two different representations: one for smaller integers (in absolute value) and one for the rest. These are colloquially known as fixnums and bignums respectively. Because the maximum size of a fixnum is typically smaller than the size of a machine word, fixnums can be represented more compactly and operated on more efficiently than bignums.

Specific procedures for fixnum arithmetic are already supported by many Scheme systems. Standardizing fixnum arithmetic increases the portability of code that uses it. Standardizing the range of fixnums would make fixnum operations inefficient on some systems, which would defeat their purpose. Therefore, this SRFI specifies some of the semantics of fixnum operations, but makes the range of fixnums implementation-dependent.

This SRFI is a modest extension of the [[http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-12.html#node_sec_11.2][R6RS (rnrs arithmetic fixnum)]] library, with some procedures renamed for consistency with R7RS-small. New procedures include fxneg, fxabs, fxsquare, and fxsqrt.

Existing implementations employ different implementation strategies for fixnum procedures. Some implement the model specified by R6RS (overflows cause exceptions), some implement modular arithmetic (overflows "wrap around"), and others fail catastrophically. In programs that use fixnums instead of generic arithmetic, overflows are typically programming mistakes.
** Specification
Fixnums are an implementation-defined subset of the exact integers. Every implementation of this SRFI must define its fixnum range as a closed interval [-2^w-1, 2^w-1-1], where w is an integer greater than or equal to 24. Every mathematical integer within an implementation's fixnum range must correspond to an exact integer that is representable within the implementation. A fixnum is an exact integer whose value lies within this fixnum range.

Fixnum operations perform integer arithmetic on their fixnum arguments. If any argument is not a fixnum, or if the mathematical result is not representable as a fixnum, it is an error: this is known as the fixnum rule. In particular, this means that fixnum operations may return a mathematically incorrect fixnum in these situations without raising an error. Consequently, when this SRFI says things like "fx+ is semantically equivalent to +", the phrase "except for the effects of the fixnum rule" is to be understood.

This SRFI uses i, j, k as parameter names for fixnum arguments. Except as noted, the names of fixnum procedures begin with the letters fx. In most cases they correspond to an R7RS-small or [[https://srfi.schemers.org/srfi-151/srfi-151.html][SRFI 151]] operation on general integers.
*** Constants
**** fx-width
Bound to the value w that specifies the implementation-defined range. (R6RS fixnum-width is a procedure that always returns this value.)
**** fx-greatest
Bound to the value 2^w-1-1, the largest representable fixnum. (R6RS greatest-fixnum is a procedure that always returns this value.)
**** fx-least
Bound to the value -2^w-1, the smallest representable fixnum. (R6RS least-fixnum is a procedure that always returns this value.)
*** Predicates
**** (fixnum? obj)
Returns #t if obj is an exact integer within the fixnum range, and #f otherwise.
**** (fx=? i ...)
Semantically equivalent to =.
**** (fx<? i ...)
Semantically equivalent to <.
**** (fx>? i ...)
Semantically equivalent to >.
**** (fx<=? i ...)
Semantically equivalent to <=.
**** (fx>=? i ...)
Semantically equivalent to >=.
**** (fxzero? i)
Semantically equivalent to zero?.
**** (fxpositive? i)
Semantically equivalent to positive?.
**** (fxnegative? i)
Semantically equivalent to negative?.
**** (fxodd? i)
Semantically equivalent to odd?.
**** (fxeven? i)
Semantically equivalent to even?.
**** (fxmax i j ...)
Semantically equivalent to max.
**** (fxmin i j ...)
Semantically equivalent to min.
*** Basic arithmetic
**** (fx+ i j)
Semantically equivalent to +, but accepts exactly two arguments.
**** (fx- i j)
Semantically equivalent to -, but accepts exactly two arguments.
**** (fxneg i)
Semantically equivalent to -, but accepts exactly one argument.
**** (fx* i j)
Semantically equivalent to *, but accepts exactly two arguments.
**** (fxquotient i j)
Semantically equivalent to quotient.
**** (fxremainder i j)
Semantically equivalent to remainder.
**** (fxabs i)
Semantically equivalent to abs. In accordance with the fixnum rule, has undefined results when applied to fx-least.
**** (fxsquare i)
Semantically equivalent to square.
**** (fxsqrt i)
Semantically equivalent to exact-integer-sqrt (not sqrt).
*** Arithmetic with carry
**** (fx+/carry i j k)
Returns the two fixnum results of the following computation:

#+BEGIN_SRC scheme
(let*-values (((s) (+ i j k))
       ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))
#+END_SRC
**** (fx-/carry i j k)
Returns the two fixnum results of the following computation:

#+BEGIN_SRC scheme
(let*-values (((d) (- i j k))
       ((q r) (balanced/ d (expt 2 fx-width))))
  (values r q))
#+END_SRC
**** (fx*/carry i j k)
Returns the two fixnum results of the following computation:

#+BEGIN_SRC scheme
(let*-values (((s) (+ (* i j) k))
       ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))
#+END_SRC

The balanced/ procedure is available in [[https://srfi.schemers.org/srfi-141/srfi-141.html][SRFI 141]], and also in the R6RS base library under the name of div0-and-mod0.
*** Bitwise operations
The following procedures are the fixnum counterparts of certain bitwise operations from SRFI 151 and the R6RS (rnrs arithmetic fixnums) library. In case of disagreement, SRFI 151 is preferred. The prefixes bitwise- and integer- are dropped for brevity and compatibility.
**** (fxnot i)
Semantically equivalent to bitwise-not.
**** (fxand i ...)
Semantically equivalent to bitwise-and.
**** (fxior i ...)
Semantically equivalent to bitwise-ior.
**** (fxxor i ...)
Semantically equivalent to bitwise-xor.
**** (fxarithmetic-shift i count)
Semantically equivalent to arithmetic-shift, except that it is an error for the absolute value of count to exceed w-1.
**** (fxarithmetic-shift-left i count)
The same as fxarithmetic-shift except that a negative value of count is an error. This is provided for additional efficiency.
**** (fxarithmetic-shift-right i count)
The same as fxarithmetic-shift except that a non-negative value of count specifies the number of bits to shift right, and a negative value is an error. This is provided for additional efficiency.
**** (fxbit-count i)
Semantically equivalent to SRFI 151 bit-count.
**** (fxlength i)
Semantically equivalent to integer-length.
**** (fxif mask i j)
Semantically equivalent to bitwise-if. It can be implemented as (fxior (fxand mask i) (fxand (fxnot mask) j))).
**** (fxbit-set? index i)
Semantically equivalent to SRFI 151 bit-set?, except that it is an error for index to be larger than or equal to fx-width.
**** (fxcopy-bit index i boolean)
Semantically equivalent to SRFI 151 copy-bit, except that it is an error for index to be larger than or equal to fx-width.
**** (fxfirst-set-bit i)
Semantically equivalent to first-set-bit.
**** (fxbit-field i start end)
Semantically equivalent to bit-field.
**** (fxbit-field-rotate i count start end)
Semantically equivalent to SRFI 151 bit-field-rotate.
**** (fxbit-field-reverse i start end)
Semantically equivalent to bit-field-reverse.
** Acknowledgements
This SRFI would not be possible without the efforts of Olin Shivers, Audrey Jaffer, Taylor Campbell, and the R6RS editors.
** Author
 * John Cowan
 * Ported to Chicken 5 by Sergey Goldgaber
** Copyright
Copyright (C) John Cowan (2016). All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
** Version history
 * [[https://github.com/diamond-lizard/srfi-143/releases/tag/0.2][0.2]] - Fixed issues 2 and 3, and removed some unused files
 * [[https://github.com/diamond-lizard/srfi-143/releases/tag/0.1][0.1]] - Ported to Chicken Scheme 5

D README.svnwiki => README.svnwiki +0 -236
@@ 1,236 0,0 @@
== SRFI 143: Fixnums
=== Abstract
This SRFI describes arithmetic procedures applicable to a limited range of exact integers only. These procedures are semantically similar to the corresponding generic-arithmetic procedures, but allow more efficient implementations.

For more information see: [[https://srfi.schemers.org/srfi-141/|SRFI 143: Fixnums]]
=== Rationale
It is common for Schemes that support arbitrarily large exact integers to have two different representations: one for smaller integers (in absolute value) and one for the rest. These are colloquially known as fixnums and bignums respectively. Because the maximum size of a fixnum is typically smaller than the size of a machine word, fixnums can be represented more compactly and operated on more efficiently than bignums.

Specific procedures for fixnum arithmetic are already supported by many Scheme systems. Standardizing fixnum arithmetic increases the portability of code that uses it. Standardizing the range of fixnums would make fixnum operations inefficient on some systems, which would defeat their purpose. Therefore, this SRFI specifies some of the semantics of fixnum operations, but makes the range of fixnums implementation-dependent.

This SRFI is a modest extension of the [[http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-12.html#node_sec_11.2|R6RS (rnrs arithmetic fixnum)]] library, with some procedures renamed for consistency with R7RS-small. New procedures include {{fxneg}}, {{fxabs}}, {{fxsquare}}, and {{fxsqrt}}.

Existing implementations employ different implementation strategies for fixnum procedures. Some implement the model specified by R6RS (overflows cause exceptions), some implement modular arithmetic (overflows "wrap around"), and others fail catastrophically. In programs that use fixnums instead of generic arithmetic, overflows are typically programming mistakes.
=== Specification
Fixnums are an implementation-defined subset of the exact integers. Every implementation of this SRFI must define its fixnum range as a closed interval {{[-2^w-1, 2^w-1-1]}}, where {{w}} is an integer greater than or equal to 24. Every mathematical integer within an implementation's fixnum range must correspond to an exact integer that is representable within the implementation. A fixnum is an exact integer whose value lies within this fixnum range.

Fixnum operations perform integer arithmetic on their fixnum arguments. If any argument is not a fixnum, or if the mathematical result is not representable as a fixnum, it is an error: this is known as the fixnum rule. In particular, this means that fixnum operations may return a mathematically incorrect fixnum in these situations without raising an error. Consequently, when this SRFI says things like "fx+ is semantically equivalent to +", the phrase "except for the effects of the fixnum rule" is to be understood.

This SRFI uses {{i, j, k}} as parameter names for fixnum arguments. Except as noted, the names of fixnum procedures begin with the letters {{fx}}. In most cases they correspond to an R7RS-small or [[https://srfi.schemers.org/srfi-151/srfi-151.html|SRFI 151]] operation on general integers.
==== Constants

<constant>fx-width</constant>

Bound to the value {{w}} that specifies the implementation-defined range. (R6RS {{fixnum-width}} is a procedure that always returns this value.)

<constant>fx-greatest</constant>

Bound to the value {{2^w-1-1}}, the largest representable fixnum. (R6RS {{greatest-fixnum}} is a procedure that always returns this value.)

<constant>fx-least</constant>

Bound to the value {{-2^w-1}}, the smallest representable fixnum. (R6RS {{least-fixnum}} is a procedure that always returns this value.)
==== Predicates

<procedure>(fixnum? obj)</procedure>

Returns {{#t}} if obj is an exact integer within the fixnum range, and {{#f}} otherwise.

<procedure>(fx=? i ...)</procedure>

Semantically equivalent to {{=}}.

<procedure>(fx<? i ...)</procedure>

Semantically equivalent to {{<}}.

<procedure>(fx>? i ...)</procedure>

Semantically equivalent to {{>}}.

<procedure>(fx<=? i ...)</procedure>

Semantically equivalent to {{<=}}.

<procedure>(fx>=? i ...)</procedure>

Semantically equivalent to {{>=}}.

<procedure>(fxzero? i)</procedure>

Semantically equivalent to {{zero?}}.

<procedure>(fxpositive? i)</procedure>

Semantically equivalent to {{positive?}}.

<procedure>(fxnegative? i)</procedure>

Semantically equivalent to {{negative?}}.

<procedure>(fxodd? i)</procedure>

Semantically equivalent to {{odd?}}.

<procedure>(fxeven? i)</procedure>

Semantically equivalent to {{even?}}.

<procedure>(fxmax i j ...)</procedure>

Semantically equivalent to {{max}}.

<procedure>(fxmin i j ...)</procedure>

Semantically equivalent to {{min}}.
==== Basic arithmetic

<procedure>(fx+ i j)</procedure>

Semantically equivalent to {{+}}, but accepts exactly two arguments.

<procedure>(fx- i j)</procedure>

Semantically equivalent to {{-}}, but accepts exactly two arguments.

<procedure>(fxneg i)</procedure>

Semantically equivalent to {{-}}, but accepts exactly one argument.

<procedure>(fx* i j)</procedure>

Semantically equivalent to {{*}}, but accepts exactly two arguments.

<procedure>(fxquotient i j)</procedure>

Semantically equivalent to {{quotient}}.

<procedure>(fxremainder i j)</procedure>

Semantically equivalent to {{remainder}}.

<procedure>(fxabs i)</procedure>

Semantically equivalent to {{abs}}. In accordance with the fixnum rule, has undefined results when applied to {{fx-least}}.

<procedure>(fxsquare i)</procedure>

Semantically equivalent to {{square}}.

<procedure>(fxsqrt i)</procedure>

Semantically equivalent to {{exact-integer-sqrt}} (not {{sqrt}}).
==== Arithmetic with carry
<procedure>(fx+/carry i j k)</procedure>

Returns the two fixnum results of the following computation:

<enscript highlight="scheme">
(let*-values (((s) (+ i j k))
       ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))
</enscript>

<procedure>(fx-/carry i j k)</procedure>

Returns the two fixnum results of the following computation:

<enscript highlight="scheme">
(let*-values (((d) (- i j k))
       ((q r) (balanced/ d (expt 2 fx-width))))
  (values r q))
</enscript>

<procedure>(fx*/carry i j k)</procedure>

Returns the two fixnum results of the following computation:

<enscript highlight="scheme">
(let*-values (((s) (+ (* i j) k))
       ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))
</enscript>

The balanced/ procedure is available in [[https://srfi.schemers.org/srfi-141/srfi-141.html|SRFI 141]], and also in the R6RS base library under the name of div0-and-mod0.
==== Bitwise operations
The following procedures are the fixnum counterparts of certain bitwise operations from SRFI 151 and the R6RS (rnrs arithmetic fixnums) library. In case of disagreement, SRFI 151 is preferred. The prefixes bitwise- and integer- are dropped for brevity and compatibility.

<procedure>(fxnot i)</procedure>

Semantically equivalent to {{bitwise-not}}.

<procedure>(fxand i ...)</procedure>

Semantically equivalent to {{bitwise-and}}.

<procedure>(fxior i ...)</procedure>

Semantically equivalent to {{bitwise-ior}}.

<procedure>(fxxor i ...)</procedure>

Semantically equivalent to {{bitwise-xor}}.

<procedure>(fxarithmetic-shift i count)</procedure>

Semantically equivalent to {{arithmetic-shift}}, except that it is an error for the absolute value of count to exceed {{w-1}}.

<procedure>(fxarithmetic-shift-left i count)</procedure>

The same as {{fxarithmetic-shift}} except that a negative value of count is an error. This is provided for additional efficiency.

<procedure>(fxarithmetic-shift-right i count)</procedure>

The same as {{fxarithmetic-shift}} except that a non-negative value of count specifies the number of bits to shift right, and a negative value is an error. This is provided for additional efficiency.

<procedure>(fxbit-count i)</procedure>

Semantically equivalent to SRFI 151 {{bit-count}}.

<procedure>(fxlength i)</procedure>

Semantically equivalent to {{integer-length}}.

<procedure>(fxif mask i j)</procedure>

Semantically equivalent to {{bitwise-if}}. It can be implemented as {{(fxior (fxand mask i) (fxand (fxnot mask) j))}}).

<procedure>(fxbit-set? index i)</procedure>

Semantically equivalent to SRFI 151 {{bit-set?}}, except that it is an error for index to be larger than or equal to {{fx-width}}.

<procedure>(fxcopy-bit index i boolean)</procedure>

Semantically equivalent to SRFI 151 {{copy-bit}}, except that it is an error for index to be larger than or equal to {{fx-width}}.

<procedure>(fxfirst-set-bit i)</procedure>

Semantically equivalent to {{first-set-bit}}.

<procedure>(fxbit-field i start end)</procedure>

Semantically equivalent to {{bit-field}}.

<procedure>(fxbit-field-rotate {{i}} count start end)</procedure>

Semantically equivalent to SRFI 151 {{bit-field-rotate}}.

<procedure>(fxbit-field-reverse i start end)</procedure>

Semantically equivalent to {{bit-field-reverse}}.
=== Acknowledgements
This SRFI would not be possible without the efforts of Olin Shivers, Audrey Jaffer, Taylor Campbell, and the R6RS editors.
=== Author
* John Cowan
* Ported to Chicken 5 by Sergey Goldgaber
=== Copyright
Copyright (C) John Cowan (2016). All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=== Version history
* [[https://github.com/diamond-lizard/srfi-143/releases/tag/0.2|0.2]] - Fixed issues 2 and 3, and removed some unused files
* [[https://github.com/diamond-lizard/srfi-143/releases/tag/0.1|0.1]] - Ported to Chicken Scheme 5

R srfi-143/carries.scm => carries.scm +12 -12
@@ 10,17 10,17 @@

(define (fx+/carry i j k)
  (let*-values (((s) (+ i j k))
         ((q r) (balanced/ s exp-width)))
  (values r q)))
                ((q r) (balanced/ s exp-width)))
    (values r q)))

(define (fx-/carry i j k)
  (let*-values (((d) (- i j k))
         ((q r) (balanced/ d exp-width)))
                ((q r) (balanced/ d exp-width)))
    (values r q)))

(define (fx*/carry i j k)
  (let*-values (((s) (+ (* i j) k))
         ((q r) (balanced/ s exp-width)))
                ((q r) (balanced/ s exp-width)))
    (values r q)))

;;; Helper functions from SRFI 151


@@ 52,12 52,12 @@

(define (balanced/ x y)
  (call-with-values
   (lambda () (euclidean/ x y))
   (lambda (q r)
     (cond ((< r (abs (/ y 2)))
            (values q r))
           ((> y 0)
            (values (+ q 1) (- x (* (+ q 1) y))))
           (else
            (values (- q 1) (- x (* (- q 1) y))))))))
      (lambda () (euclidean/ x y))
    (lambda (q r)
      (cond ((< r (abs (/ y 2)))
             (values q r))
            ((> y 0)
             (values (+ q 1) (- x (* (+ q 1) y))))
            (else
             (values (- q 1) (- x (* (- q 1) y))))))))


R srfi-143/srfi-143-impl.scm => srfi-143-impl.scm +22 -23
@@ 4,28 4,28 @@

(define (fx=? i j . ks)
  (if (null? ks)
    (chicken:fx= i j)
    (and (chicken:fx= i j) (apply fx=? j ks))))
      (chicken:fx= i j)
      (and (chicken:fx= i j) (apply fx=? j ks))))

(define (fx<? i j . ks)
  (if (null? ks)
    (chicken:fx< i j)
    (and (chicken:fx< i j) (apply fx<? j ks))))
      (chicken:fx< i j)
      (and (chicken:fx< i j) (apply fx<? j ks))))

(define (fx>? i j . ks)
  (if (null? ks)
    (chicken:fx> i j)
    (and (chicken:fx> i j) (apply fx>? j ks))))
      (chicken:fx> i j)
      (and (chicken:fx> i j) (apply fx>? j ks))))

(define (fx<=? i j . ks)
  (if (null? ks)
    (chicken:fx<= i j)
    (and (chicken:fx<= i j) (apply fx<=? j ks))))
      (chicken:fx<= i j)
      (and (chicken:fx<= i j) (apply fx<=? j ks))))

(define (fx>=? i j . ks)
  (if (null? ks)
    (chicken:fx>= i j)
    (and (chicken:fx>= i j) (apply fx>=? j ks))))
      (chicken:fx>= i j)
      (and (chicken:fx>= i j) (apply fx>=? j ks))))

(define (fxzero? i) (chicken:fx= i 0))
(define (fxpositive? i) (chicken:fx> i 0))


@@ 33,13 33,13 @@

(define (fxmax i j . ks)
  (if (null? ks)
    (chicken:fxmax i j)
    (chicken:fxmax (chicken:fxmax i j) (apply fxmax j ks))))
      (chicken:fxmax i j)
      (chicken:fxmax (chicken:fxmax i j) (apply fxmax j ks))))

(define (fxmin i j . ks)
  (if (null? ks)
    (chicken:fxmin i j)
    (chicken:fxmin (chicken:fxmin i j) (apply fxmin j ks))))
      (chicken:fxmin i j)
      (chicken:fxmin (chicken:fxmin i j) (apply fxmin j ks))))

(define (fxabs i)
  (if (fxnegative? i) (fxneg i) i))


@@ 48,8 48,8 @@

(define (fxarithmetic-shift i count)
  (if (negative? count)
    (fxarithmetic-shift-right i (- count))
    (fxarithmetic-shift-left i count)))
      (fxarithmetic-shift-right i (- count))
      (fxarithmetic-shift-left i count)))

;;; Bitwise functions cloned from SRFI 151, fixnum version



@@ 58,7 58,7 @@

(define (fxif mask n0 n1)
  (fxior (fxand mask n0)
          (fxand (fxnot mask) n1)))
         (fxand (fxnot mask) n1)))

(define (fxbit-set? index n)
  (bit->boolean n index))


@@ 79,10 79,10 @@
  (let ((mask (fxnot (fxarithmetic-shift -1 width))))
    (define zn (fxand mask (fxarithmetic-shift n (- start))))
    (fxior (fxarithmetic-shift
             (fxior (fxand mask (fxarithmetic-shift zn count))
                     (fxarithmetic-shift zn (- count width)))
             start)
            (fxand (fxnot (fxarithmetic-shift mask start)) n))))
            (fxior (fxand mask (fxarithmetic-shift zn count))
                   (fxarithmetic-shift zn (- count width)))
            start)
           (fxand (fxnot (fxarithmetic-shift mask start)) n))))

(define (fxreverse k n)
  (do ((m (if (negative? n) (fxnot n) n) (fxarithmetic-shift-right m 1))


@@ 95,5 95,4 @@
  (let ((mask (fxnot (fxarithmetic-shift-left -1 width))))
    (define zn (fxand mask (fxarithmetic-shift-right n start)))
    (fxior (fxarithmetic-shift-left (fxreverse width zn) start)
            (fxand (fxnot (fxarithmetic-shift-left mask start)) n))))
 
           (fxand (fxnot (fxarithmetic-shift-left mask start)) n))))

M srfi-143.egg => srfi-143.egg +4 -2
@@ 3,8 3,10 @@
((author "John Cowan")
 (maintainer "Sergey Goldgaber")
 (synopsis "SRFI 143: Fixnums")
 (version "0.1")
 (version "0.3")
 (category math)
 (test-dependencies test)
 (license "MIT")
 (components (extension srfi-143)))
 (components (extension srfi-143
                        (source-dependencies "srfi-143-impl.scm"
                                             "carries.scm"))))

M srfi-143.scm => srfi-143.scm +64 -4
@@ 1,6 1,66 @@
(import scheme)
(import (chicken platform))
;;;; Chicken module for SRFI 143

(register-feature! 'srfi-143)
(module srfi-143 ()

(include "srfi-143/srfi-143.scm")
  (import scheme)
  (import (chicken module))
  (import (rename (chicken base) (exact-integer-sqrt fxsqrt)))

  (export fx-width fx-greatest fx-least)
  (export fixnum? fx=? fx<? fx>? fx<=? fx>=?
          fxzero? fxpositive? fxnegative?
          fxodd? fxeven? fxmax fxmin)
  (export fx+ fx- fxneg fx* fxquotient fxremainder
          fxabs fxsquare fxsqrt)
  (export fx+/carry fx-/carry fx*/carry)
  (export fxnot fxand fxior fxxor fxarithmetic-shift
          fxarithmetic-shift-left fxarithmetic-shift-right
          fxbit-count fxlength fxif fxbit-set? fxcopy-bit
          fxfirst-set-bit fxbit-field
          fxbit-field-rotate fxbit-field-reverse)

  (import (only (chicken bitwise) bit->boolean))
  (import (rename (only (chicken fixnum)
                        fxmax fxmin fx= fx< fx> fx<= fx>= fx/ fxlen fxrem
                        fxshl fxshr fixnum-bits
                        most-positive-fixnum most-negative-fixnum)
                  (fxmax chicken:fxmax)
                  (fxmin chicken:fxmin)
                  (fx= chicken:fx=)
                  (fx< chicken:fx<)
                  (fx> chicken:fx>)
                  (fx<= chicken:fx<=)
                  (fx>= chicken:fx>=)
                  (fx/ fxquotient)
                  (fxlen fxlength)
                  (fxrem fxremainder)
                  (fxshl fxarithmetic-shift-left)
                  (fxshr fxarithmetic-shift-right)
                  (fixnum-bits fx-width)
                  (most-positive-fixnum fx-greatest)
                  (most-negative-fixnum fx-least)))
  (import (only (chicken base) fixnum?))
  (import (only (chicken fixnum) fx+ fx- fx* fxneg fxand fxior fxxor
                fxnot fxodd? fxeven?))
  (import (only (chicken platform) register-feature!))

  (register-feature! 'srfi-143)

  ;; Core functions not available in Chicken
  (define fxbit-count
    (letrec ((logcnt (lambda (n tot)
                       (if (fxzero? n)
                           tot
                           (logcnt (fxquotient n 16)
                                   (fx+ (vector-ref
                                         '#(0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4)
                                         (fxremainder n 16))
                                        tot))))))
      (lambda (n)
        (cond ((fxnegative? n) (logcnt (fxnot n) 0))
              ((fxpositive? n) (logcnt n 0))
              (else 0)))))


  (include "carries.scm")
  (include "srfi-143-impl.scm"))

A srfi-143.svnwiki => srfi-143.svnwiki +336 -0
@@ 0,0 1,336 @@
== SRFI 143: Fixnums

=== Abstract

This SRFI describes arithmetic procedures applicable to a limited range of
exact integers only. These procedures are semantically similar to the
corresponding generic-arithmetic procedures, but allow more efficient
implementations.

For more information see: [[https://srfi.schemers.org/srfi-141/|SRFI 143:
Fixnums]]

=== Rationale

It is common for Schemes that support arbitrarily large exact integers to have
two different representations: one for smaller integers (in absolute value) and
one for the rest. These are colloquially known as fixnums and bignums
respectively. Because the maximum size of a fixnum is typically smaller than
the size of a machine word, fixnums can be represented more compactly and
operated on more efficiently than bignums.

Specific procedures for fixnum arithmetic are already supported by many Scheme
systems. Standardizing fixnum arithmetic increases the portability of code that
uses it. Standardizing the range of fixnums would make fixnum operations
inefficient on some systems, which would defeat their purpose. Therefore, this
SRFI specifies some of the semantics of fixnum operations, but makes the range
of fixnums implementation-dependent.

This SRFI is a modest extension of the
[[http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-12.html#node_sec_11.2|R6RS
(rnrs arithmetic fixnum)]] library, with some procedures renamed for
consistency with R7RS-small. New procedures include {{fxneg}}, {{fxabs}},
{{fxsquare}}, and {{fxsqrt}}.

Existing implementations employ different implementation strategies for fixnum
procedures. Some implement the model specified by R6RS (overflows cause
exceptions), some implement modular arithmetic (overflows "wrap around"), and
others fail catastrophically. In programs that use fixnums instead of generic
arithmetic, overflows are typically programming mistakes.

In CHICKEN, this SRFI uses the built-in
[[https://wiki.call-cc.org/man/5/Module%20(chicken%20fixnum)|(chicken fixnum]]
module, in which overflows "wrap around".

=== Specification

Fixnums are an implementation-defined subset of the exact integers. Every
implementation of this SRFI must define its fixnum range as a closed interval
{{[-2^w-1, 2^w-1-1]}}, where {{w}} is an integer greater than or equal to 24.
Every mathematical integer within an implementation's fixnum range must
correspond to an exact integer that is representable within the implementation.
A fixnum is an exact integer whose value lies within this fixnum range.

Fixnum operations perform integer arithmetic on their fixnum arguments. If any
argument is not a fixnum, or if the mathematical result is not representable as
a fixnum, it is an error: this is known as the fixnum rule. In particular, this
means that fixnum operations may return a mathematically incorrect fixnum in
these situations without raising an error. Consequently, when this SRFI says
things like "fx+ is semantically equivalent to +", the phrase "except for the
effects of the fixnum rule" is to be understood.

This SRFI uses {{i, j, k}} as parameter names for fixnum arguments. Except as
noted, the names of fixnum procedures begin with the letters {{fx}}. In most
cases they correspond to an R7RS-small or
[[https://srfi.schemers.org/srfi-151/srfi-151.html|SRFI 151]] operation on
general integers.

==== Constants

<constant>fx-width</constant>

Bound to the value {{w}} that specifies the implementation-defined range. (R6RS
{{fixnum-width}} is a procedure that always returns this value.)

<constant>fx-greatest</constant>

Bound to the value {{2^w-1-1}}, the largest representable fixnum. (R6RS
{{greatest-fixnum}} is a procedure that always returns this value.)

<constant>fx-least</constant>

Bound to the value {{-2^w-1}}, the smallest representable fixnum. (R6RS
{{least-fixnum}} is a procedure that always returns this value.)

==== Predicates

<procedure>(fixnum? obj)</procedure>

Returns {{#t}} if obj is an exact integer within the fixnum range, and {{#f}}
otherwise.

<procedure>(fx=? i ...)</procedure>

Semantically equivalent to {{=}}.

<procedure>(fx<? i ...)</procedure>

Semantically equivalent to {{<}}.

<procedure>(fx>? i ...)</procedure>

Semantically equivalent to {{>}}.

<procedure>(fx<=? i ...)</procedure>

Semantically equivalent to {{<=}}.

<procedure>(fx>=? i ...)</procedure>

Semantically equivalent to {{>=}}.

<procedure>(fxzero? i)</procedure>

Semantically equivalent to {{zero?}}.

<procedure>(fxpositive? i)</procedure>

Semantically equivalent to {{positive?}}.

<procedure>(fxnegative? i)</procedure>

Semantically equivalent to {{negative?}}.

<procedure>(fxodd? i)</procedure>

Semantically equivalent to {{odd?}}.

<procedure>(fxeven? i)</procedure>

Semantically equivalent to {{even?}}.

<procedure>(fxmax i j ...)</procedure>

Semantically equivalent to {{max}}.

<procedure>(fxmin i j ...)</procedure>

Semantically equivalent to {{min}}.

==== Basic arithmetic

<procedure>(fx+ i j)</procedure>

Semantically equivalent to {{+}}, but accepts exactly two arguments.

<procedure>(fx- i j)</procedure>

Semantically equivalent to {{-}}, but accepts exactly two arguments.

<procedure>(fxneg i)</procedure>

Semantically equivalent to {{-}}, but accepts exactly one argument.

<procedure>(fx* i j)</procedure>

Semantically equivalent to {{*}}, but accepts exactly two arguments.

<procedure>(fxquotient i j)</procedure>

Semantically equivalent to {{quotient}}.

<procedure>(fxremainder i j)</procedure>

Semantically equivalent to {{remainder}}.

<procedure>(fxabs i)</procedure>

Semantically equivalent to {{abs}}. In accordance with the fixnum rule, has
undefined results when applied to {{fx-least}}.

<procedure>(fxsquare i)</procedure>

Semantically equivalent to {{square}}.

<procedure>(fxsqrt i)</procedure>

Semantically equivalent to {{exact-integer-sqrt}} (not {{sqrt}}).

==== Arithmetic with carry

<procedure>(fx+/carry i j k)</procedure>

Returns the two fixnum results of the following computation:

<enscript highlight="scheme">
(let*-values (((s) (+ i j k))
       ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))
</enscript>

<procedure>(fx-/carry i j k)</procedure>

Returns the two fixnum results of the following computation:

<enscript highlight="scheme">
(let*-values (((d) (- i j k))
       ((q r) (balanced/ d (expt 2 fx-width))))
  (values r q))
</enscript>

<procedure>(fx*/carry i j k)</procedure>

Returns the two fixnum results of the following computation:

<enscript highlight="scheme">
(let*-values (((s) (+ (* i j) k))
       ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))
</enscript>

The balanced/ procedure is available in
[[https://srfi.schemers.org/srfi-141/srfi-141.html|SRFI 141]], and also in the
R6RS base library under the name of div0-and-mod0.

==== Bitwise operations

The following procedures are the fixnum counterparts of certain bitwise
operations from SRFI 151 and the R6RS (rnrs arithmetic fixnums) library. In
case of disagreement, SRFI 151 is preferred. The prefixes bitwise- and integer-
are dropped for brevity and compatibility.

<procedure>(fxnot i)</procedure>

Semantically equivalent to {{bitwise-not}}.

<procedure>(fxand i ...)</procedure>

Semantically equivalent to {{bitwise-and}}.

<procedure>(fxior i ...)</procedure>

Semantically equivalent to {{bitwise-ior}}.

<procedure>(fxxor i ...)</procedure>

Semantically equivalent to {{bitwise-xor}}.

<procedure>(fxarithmetic-shift i count)</procedure>

Semantically equivalent to {{arithmetic-shift}}, except that it is an error for
the absolute value of count to exceed {{w-1}}.

<procedure>(fxarithmetic-shift-left i count)</procedure>

The same as {{fxarithmetic-shift}} except that a negative value of count is an
error. This is provided for additional efficiency.

<procedure>(fxarithmetic-shift-right i count)</procedure>

The same as {{fxarithmetic-shift}} except that a non-negative value of count
specifies the number of bits to shift right, and a negative value is an error.
This is provided for additional efficiency.

<procedure>(fxbit-count i)</procedure>

Semantically equivalent to SRFI 151 {{bit-count}}.

<procedure>(fxlength i)</procedure>

Semantically equivalent to {{integer-length}}.

<procedure>(fxif mask i j)</procedure>

Semantically equivalent to {{bitwise-if}}. It can be implemented as {{(fxior
(fxand mask i) (fxand (fxnot mask) j))}}).

<procedure>(fxbit-set? index i)</procedure>

Semantically equivalent to SRFI 151 {{bit-set?}}, except that it is an error
for index to be larger than or equal to {{fx-width}}.

<procedure>(fxcopy-bit index i boolean)</procedure>

Semantically equivalent to SRFI 151 {{copy-bit}}, except that it is an error
for index to be larger than or equal to {{fx-width}}.

<procedure>(fxfirst-set-bit i)</procedure>

Semantically equivalent to {{first-set-bit}}.

<procedure>(fxbit-field i start end)</procedure>

Semantically equivalent to {{bit-field}}.

<procedure>(fxbit-field-rotate {{i}} count start end)</procedure>

Semantically equivalent to SRFI 151 {{bit-field-rotate}}.

<procedure>(fxbit-field-reverse i start end)</procedure>

Semantically equivalent to {{bit-field-reverse}}.

=== Acknowledgements

This SRFI would not be possible without the efforts of Olin Shivers, Audrey
Jaffer, Taylor Campbell, and the R6RS editors.

=== Author

* John Cowan
* Ported to Chicken 5 by Sergey Goldgaber

=== Maintainer

[[https://wiki.call-cc.org/users/diego-mundo|Diego A. Mundo]]

=== Repository

[[https://code.dieggsy.com/srfi-143]]

=== Copyright

 Copyright (C) John Cowan (2016). All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
 the Software without restriction, including without limitation the rights to
 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 of the Software, and to permit persons to whom the Software is furnished to do
 so, subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.

=== Version history

* 0.2 - Fixed issues 2 and 3, and removed some unused files
* 0.1 - Ported to Chicken Scheme 5

D srfi-143/srfi-143.scm => srfi-143/srfi-143.scm +0 -69
@@ 1,69 0,0 @@
;;;; Chicken module for SRFI 143

(module srfi-143 ()

  (import scheme)
  (import (chicken module))
  (import (rename (chicken base) (exact-integer-sqrt fxsqrt)))

  (export fx-width fx-greatest fx-least)
  (export fixnum? fx=? fx<? fx>? fx<=? fx>=?
          fxzero? fxpositive? fxnegative?
          fxodd? fxeven? fxmax fxmin)
  (export fx+ fx- fxneg fx* fxquotient fxremainder
          fxabs fxsquare fxsqrt)
  (export fx+/carry fx-/carry fx*/carry)
  (export fxnot fxand fxior fxxor fxarithmetic-shift
          fxarithmetic-shift-left fxarithmetic-shift-right
          fxbit-count fxlength fxif fxbit-set? fxcopy-bit
          fxfirst-set-bit fxbit-field
          fxbit-field-rotate fxbit-field-reverse)

  (import (only (chicken bitwise) bit->boolean))
  (import (rename (only (chicken fixnum)
                        fxmax fxmin fx= fx< fx> fx<= fx>= fx/ fxlen fxrem
                        fxshl fxshr fixnum-bits
                        most-positive-fixnum most-negative-fixnum)
		  (fxmax chicken:fxmax)
		  (fxmin chicken:fxmin)
		  (fx= chicken:fx=)
		  (fx< chicken:fx<)
		  (fx> chicken:fx>)
		  (fx<= chicken:fx<=)
		  (fx>= chicken:fx>=)
		  (fx/ fxquotient)
                  (fxlen fxlength)
		  (fxrem fxremainder)
                  (fxshl fxarithmetic-shift-left)
                  (fxshr fxarithmetic-shift-right)
		  (fixnum-bits fx-width)
		  (most-positive-fixnum fx-greatest)
		  (most-negative-fixnum fx-least)))
  (import (only (chicken base) fixnum?))
  (import (only (chicken fixnum) fx+ fx- fx* fxneg fxand fxior fxxor
                        fxnot fxodd? fxeven?))

  ;; Core functions not available in Chicken

  (define (logical:ash-4 x)
    (if (negative? x)
        (+ -1 (quotient (+ 1 x) 16))
        (quotient x 16)))

  (define fxbit-count
    (letrec ((logcnt (lambda (n tot)
                       (if (fxzero? n)
                           tot
                           (logcnt (fxquotient n 16)
                                   (fx+ (vector-ref
                                       '#(0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4)
                                       (fxremainder n 16))
                                      tot))))))
      (lambda (n)
        (cond ((fxnegative? n) (logcnt (fxnot n) 0))
              ((fxpositive? n) (logcnt n 0))
              (else 0)))))

  (include "srfi-143/carries.scm")
  (include "srfi-143/srfi-143-impl.scm")
)