home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mitsch75.zip
/
scheme-7_5_17-src.zip
/
scheme-7.5.17
/
src
/
microcode
/
intprm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-02
|
8KB
|
235 lines
/* -*-C-*-
$Id: intprm.c,v 1.9 1999/01/02 06:11:34 cph Exp $
Copyright (c) 1989-1999 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Generic Integer Primitives */
#include "scheme.h"
#include "prims.h"
#include "zones.h"
#define INTEGER_TEST(test) \
{ \
PRIMITIVE_HEADER (1); \
Set_Time_Zone (Zone_Math); \
CHECK_ARG (1, INTEGER_P); \
PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (test (ARG_REF (1)))); \
}
DEFINE_PRIMITIVE ("INTEGER-ZERO?", Prim_integer_zero_p, 1, 1, 0)
INTEGER_TEST (integer_zero_p)
DEFINE_PRIMITIVE ("INTEGER-NEGATIVE?", Prim_integer_negative_p, 1, 1, 0)
INTEGER_TEST (integer_negative_p)
DEFINE_PRIMITIVE ("INTEGER-POSITIVE?", Prim_integer_positive_p, 1, 1, 0)
INTEGER_TEST (integer_positive_p)
#define INTEGER_COMPARISON(comparison) \
{ \
PRIMITIVE_HEADER (2); \
Set_Time_Zone (Zone_Math); \
CHECK_ARG (1, INTEGER_P); \
CHECK_ARG (2, INTEGER_P); \
PRIMITIVE_RETURN \
(BOOLEAN_TO_OBJECT (comparison ((ARG_REF (1)), (ARG_REF (2))))); \
}
DEFINE_PRIMITIVE ("INTEGER-EQUAL?", Prim_integer_equal_p, 2, 2, 0)
INTEGER_COMPARISON (integer_equal_p)
DEFINE_PRIMITIVE ("INTEGER-LESS?", Prim_integer_less_p, 2, 2, 0)
INTEGER_COMPARISON (integer_less_p)
DEFINE_PRIMITIVE ("INTEGER-GREATER?", Prim_integer_greater_p, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
Set_Time_Zone (Zone_Math);
CHECK_ARG (1, INTEGER_P);
CHECK_ARG (2, INTEGER_P);
PRIMITIVE_RETURN
(BOOLEAN_TO_OBJECT (integer_less_p ((ARG_REF (2)), (ARG_REF (1)))));
}
#define INTEGER_BINARY_OPERATION(operator) \
{ \
PRIMITIVE_HEADER (2); \
Set_Time_Zone (Zone_Math); \
CHECK_ARG (1, INTEGER_P); \
CHECK_ARG (2, INTEGER_P); \
PRIMITIVE_RETURN (operator ((ARG_REF (1)), (ARG_REF (2)))); \
}
DEFINE_PRIMITIVE ("INTEGER-ADD", Prim_integer_add, 2, 2, 0)
INTEGER_BINARY_OPERATION (integer_add)
DEFINE_PRIMITIVE ("INTEGER-SUBTRACT", Prim_integer_subtract, 2, 2, 0)
INTEGER_BINARY_OPERATION (integer_subtract)
DEFINE_PRIMITIVE ("INTEGER-MULTIPLY", Prim_integer_multiply, 2, 2, 0)
INTEGER_BINARY_OPERATION (integer_multiply)
#define INTEGER_UNARY_OPERATION(operator) \
{ \
PRIMITIVE_HEADER (1); \
Set_Time_Zone (Zone_Math); \
CHECK_ARG (1, INTEGER_P); \
PRIMITIVE_RETURN (operator (ARG_REF (1))); \
}
DEFINE_PRIMITIVE ("INTEGER-NEGATE", Prim_integer_negate, 1, 1, 0)
INTEGER_UNARY_OPERATION (integer_negate)
DEFINE_PRIMITIVE ("INTEGER-ADD-1", Prim_integer_add_1, 1, 1, 0)
INTEGER_UNARY_OPERATION (integer_add_1)
DEFINE_PRIMITIVE ("INTEGER-SUBTRACT-1", Prim_integer_subtract_1, 1, 1, 0)
INTEGER_UNARY_OPERATION (integer_subtract_1)
DEFINE_PRIMITIVE ("INTEGER-LENGTH-IN-BITS", Prim_integer_length_in_bits, 1, 1, 0)
INTEGER_UNARY_OPERATION (integer_length_in_bits)
DEFINE_PRIMITIVE ("INTEGER-DIVIDE", Prim_integer_divide, 2, 2, 0)
{
SCHEME_OBJECT quotient;
SCHEME_OBJECT remainder;
PRIMITIVE_HEADER (2);
Set_Time_Zone (Zone_Math);
CHECK_ARG (1, INTEGER_P);
CHECK_ARG (2, INTEGER_P);
if (integer_divide ((ARG_REF (1)), (ARG_REF (2)), ("ient), (&remainder)))
error_bad_range_arg (2);
PRIMITIVE_RETURN (cons (quotient, remainder));
}
#define INTEGER_QR(operator) \
{ \
SCHEME_OBJECT result; \
PRIMITIVE_HEADER (2); \
Set_Time_Zone (Zone_Math); \
CHECK_ARG (1, INTEGER_P); \
CHECK_ARG (2, INTEGER_P); \
result = (operator ((ARG_REF (1)), (ARG_REF (2)))); \
if (result == SHARP_F) \
error_bad_range_arg (2); \
PRIMITIVE_RETURN (result); \
}
DEFINE_PRIMITIVE ("INTEGER-QUOTIENT", Prim_integer_quotient, 2, 2, 0)
INTEGER_QR (integer_quotient)
DEFINE_PRIMITIVE ("INTEGER-REMAINDER", Prim_integer_remainder, 2, 2, 0)
INTEGER_QR (integer_remainder)
DEFINE_PRIMITIVE ("INTEGER?", Prim_integer_p, 1, 1, 0)
{
PRIMITIVE_HEADER (1);
{
fast SCHEME_OBJECT integer = (ARG_REF (1));
PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (INTEGER_P (integer)));
}
}
DEFINE_PRIMITIVE ("INTEGER->FLONUM", Prim_integer_to_flonum, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
Set_Time_Zone (Zone_Math);
CHECK_ARG (1, INTEGER_P);
{
fast SCHEME_OBJECT integer = (ARG_REF (1));
fast long control = (arg_index_integer (2, 4));
if (FIXNUM_P (integer))
{
long X = (FIXNUM_TO_LONG (integer));
double Y = ((double) X);
if (((long) Y) == X)
PRIMITIVE_RETURN (FIXNUM_TO_FLONUM (integer));
if ((control & 2) != 0)
error_bad_range_arg (1);
PRIMITIVE_RETURN (SHARP_F);
}
if (bignum_fits_in_word_p
(integer,
(((control & 1) != 0) ? DBL_MANT_DIG : DBL_MAX_EXP),
0))
PRIMITIVE_RETURN (BIGNUM_TO_FLONUM (integer));
if ((control & 2) != 0)
error_bad_range_arg (1);
PRIMITIVE_RETURN (SHARP_F);
}
}
DEFINE_PRIMITIVE ("INTEGER-SHIFT-LEFT", Prim_integer_shift_left, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
Set_Time_Zone (Zone_Math);
CHECK_ARG (1, INTEGER_P);
{
SCHEME_OBJECT n = (ARG_REF (1));
if (integer_negative_p (n))
error_bad_range_arg (1);
PRIMITIVE_RETURN (integer_shift_left (n, (arg_ulong_integer (2))));
}
}
static unsigned int
DEFUN (list_to_integer_producer, (context), PTR context)
{
SCHEME_OBJECT * digits = context;
unsigned int digit = (UNSIGNED_FIXNUM_TO_LONG (PAIR_CAR (*digits)));
(*digits) = (PAIR_CDR (*digits));
return (digit);
}
DEFINE_PRIMITIVE ("LIST->INTEGER", Prim_list_to_integer, 3, 3,
"(list radix negative?)\n\
LIST is a non-null list of digits in RADIX, most-significant first.\n\
Converts the list to an integer. NEGATIVE? specifies the sign.")
{
PRIMITIVE_HEADER (3);
Set_Time_Zone (Zone_Math);
CHECK_ARG (1, PAIR_P);
{
SCHEME_OBJECT digits = (ARG_REF (1));
unsigned long radix = (arg_ulong_integer (2));
unsigned int n_digits;
if ((radix < 2)
|| (radix >= ((unsigned long) (bignum_max_digit_stream_radix ()))))
error_bad_range_arg (2);
{
SCHEME_OBJECT scan = digits;
n_digits = 0;
while (1)
{
SCHEME_OBJECT digit = (PAIR_CAR (scan));
if (!UNSIGNED_FIXNUM_P (digit))
error_wrong_type_arg (1);
if (((unsigned long) (UNSIGNED_FIXNUM_TO_LONG (digit))) >= radix)
error_bad_range_arg (1);
n_digits += 1;
scan = (PAIR_CDR (scan));
if (scan == EMPTY_LIST)
break;
if (!PAIR_P (scan))
error_wrong_type_arg (1);
}
}
PRIMITIVE_RETURN
(bignum_to_integer
(digit_stream_to_bignum (n_digits,
list_to_integer_producer,
(&digits),
radix,
(OBJECT_TO_BOOLEAN (ARG_REF (3))))));
}
}