|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 7622 (0x1dc6)
Types: TextFile
Names: »fixnum.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/microcode/fixnum.c«
/* Hey EMACS, this is -*- C -*- code! */
/****************************************************************
* *
* Copyright (c) 1984 *
* Massachusetts Institute of Technology *
* *
* This material was developed by the Scheme project at the *
* Massachusetts Institute of Technology, Department of *
* Electrical Engineering and Computer Science. Permission to *
* copy this software, to redistribute it, and to use it for any *
* purpose is granted, subject to the following restrictions and *
* understandings. *
* *
* 1. Any copy made of this software must include this copyright *
* notice in full. *
* *
* 2. Users of this software agree to make their best efforts (a)*
* to return to the MIT Scheme project any improvements or *
* extensions that they make, so that these may be included in *
* future releases; and (b) to inform MIT of noteworthy uses of *
* this software. *
* *
* 3. All materials developed as a consequence of the use of *
* this software shall duly acknowledge such use, in accordance *
* with the usual standards of acknowledging credit in academic *
* research. *
* *
* 4. MIT has made no warrantee or representation that the *
* operation of this software will be error-free, and MIT is *
* under no obligation to provide any services, by way of *
* maintenance, update, or otherwise. *
* *
* 5. In conjunction with products arising from the use of this *
* material, there shall be no use of the name of the *
* Massachusetts Institute of Technology nor of any adaptation *
* thereof in any advertising, promotional, or sales literature *
* without prior written consent from MIT in each case. *
* *
****************************************************************/
\f
#include "scheme.h"
#include "primitive.h"
/* File: FIXNUM.C
*
* Support for fixed point arithmetic (24 bit). Mostly superceded
* by generic arithmetic.
*/
/***************************/
/* UNARY FIXNUM OPERATIONS */
/***************************/
/* These operations return NIL if their argument is not a fixnum.
Otherwise, they return the appropriate fixnum if the result is
expressible as a fixnum. If the result is out of range, they
return NIL.
*/
Built_In_Primitive(Prim_One_Plus_Fixnum, 1, "ONE-PLUS-FIXNUM")
{ fast long A, Result;
Primitive_1_Arg();
Arg_1_Type(TC_FIXNUM);
Sign_Extend(Arg1, A);
Result = A + 1;
if (Fixnum_Fits(Result)) return Make_Non_Pointer(TC_FIXNUM, Result);
else return NIL;
}
Built_In_Primitive(Prim_M_1_Plus_Fixnum, 1, "MINUS-ONE-PLUS-FIXNUM")
{ fast long A, Result;
Primitive_1_Arg();
Arg_1_Type(TC_FIXNUM);
Sign_Extend(Arg1, A);
Result = A - 1;
if (Fixnum_Fits(Result)) return Make_Non_Pointer(TC_FIXNUM, Result);
else return NIL;
}
\f
/****************************/
/* BINARY FIXNUM PREDICATES */
/****************************/
/* Binary fixnum predicates return NIL if their argument is not a
fixnum, 1 if the predicate is true, or 0 if the predicate is false.
*/
#define Binary_Predicate_Fixnum(Op) \
fast long A, B; \
Primitive_2_Args(); \
Arg_1_Type(TC_FIXNUM); \
Arg_2_Type(TC_FIXNUM); \
Sign_Extend(Arg1, A); Sign_Extend(Arg2, B); \
return FIXNUM_0+ ((A Op B) ? 1 : 0);
Built_In_Primitive(Prim_Equal_Fixnum, 2, "EQUAL-FIXNUM?")
{ Binary_Predicate_Fixnum(==);
}
Built_In_Primitive(Prim_Greater_Fixnum, 2, "LESS-FIXNUM?")
{ Binary_Predicate_Fixnum(>);
}
Built_In_Primitive(Prim_Less_Fixnum, 2, "GREATER-FIXNUM?")
{ Binary_Predicate_Fixnum(<);
}
\f
/****************************/
/* BINARY FIXNUM OPERATIONS */
/****************************/
/* All binary fixnum operations take two arguments and return NIL if
either is not a fixnum. If both arguments are fixnums and the
result fits as a fixnum, then the result is returned. If the
result will not fit as a fixnum, NIL is returned.
*/
#define Binary_Fixnum(Op) \
fast long A, B, Result; \
Primitive_2_Args(); \
Arg_1_Type(TC_FIXNUM); \
Arg_2_Type(TC_FIXNUM); \
Sign_Extend(Arg1, A); Sign_Extend(Arg2, B); \
Result = A Op B; \
if (Fixnum_Fits(Result)) \
return Make_Non_Pointer(TC_FIXNUM, Result); \
else return NIL; \
Built_In_Primitive(Prim_Minus_Fixnum, 2, "MINUS-FIXNUM")
{ Binary_Fixnum(-);
}
Built_In_Primitive(Prim_Plus_Fixnum, 2, "PLUS-FIXNUM")
{ Binary_Fixnum(+);
}
Built_In_Primitive(Prim_Multiply_Fixnum, 2, "MULTIPLY-FIXNUM")
{ /* Mul, which does the multiplication with overflow handling is
machine dependent. Therefore, it is in OS.C
*/
Primitive_2_Args();
Arg_1_Type(TC_FIXNUM);
Arg_2_Type(TC_FIXNUM);
return Mul(Arg1, Arg2);
}
\f
Built_In_Primitive(Prim_Divide_Fixnum, 2, "DIVIDE-FIXNUM")
{ fast long A, B, Quotient, Remainder;
/* Returns the CONS of quotient and remainder */
Primitive_2_Args();
Arg_1_Type(TC_FIXNUM);
Arg_2_Type(TC_FIXNUM);
Sign_Extend(Arg1, A); Sign_Extend(Arg2, B);
if (B==0) Primitive_Error(ERR_ARG_2_BAD_RANGE);
Primitive_GC_If_Needed(Free + 2);
Quotient = A/B;
Remainder = A%B;
if (Fixnum_Fits(Quotient))
{ Free[CONS_CAR] = Make_Non_Pointer(TC_FIXNUM, Quotient);
Free[CONS_CDR] = Make_Non_Pointer(TC_FIXNUM, Remainder);
Free += 2;
return Make_Pointer(TC_LIST, Free-2);
}
return NIL;
}
Built_In_Primitive(Prim_Gcd_Fixnum, 2, "GCD-FIXNUM")
{ fast long A, B, C;
/* Returns the Greatest Common Divisor */
Primitive_2_Args();
Arg_1_Type(TC_FIXNUM);
Arg_2_Type(TC_FIXNUM);
Sign_Extend(Arg1, A); Sign_Extend(Arg2, B);
while (B != 0)
{ C = A;
A = B;
B = C % B;
}
return Make_Non_Pointer(TC_FIXNUM, A);
}
\f
/* (NEGATIVE_FIXNUM NUMBER)
[Primitive number 0x7F]
Returns NIL if NUMBER isn't a fixnum. Returns 0 if NUMBER < 0, 1
if NUMBER >= 0.
*/
Built_In_Primitive(Prim_Negative_Fixnum, 1, "NEGATIVE-FIXNUM?")
{ long Value;
Primitive_1_Arg();
Arg_1_Type(TC_FIXNUM);
Sign_Extend(Arg1, Value);
return FIXNUM_0 + ((Value < 0) ? 1 : 0);
}
/* (POSITIVE_FIXNUM NUMBER)
[Primitive number 0x41]
Returns 1 if NUMBER is a positive fixnum, 0 for other fixnums,
or NIL.
*/
Built_In_Primitive(Prim_Positive_Fixnum, 1, "POSITIVE-FIXNUM?")
{ long Value;
Primitive_1_Arg();
Arg_1_Type(TC_FIXNUM);
Sign_Extend(Arg1, Value);
return FIXNUM_0 + ((Value > 0) ? 1 : 0);
}
/* (ZERO_FIXNUM NUMBER)
[Primitive number 0x46]
Returns NIL if NUMBER isn't a fixnum. Otherwise, returns 0 if
NUMBER is 0 or 1 if it is.
*/
Built_In_Primitive(Prim_Zero_Fixnum, 1, "ZERO-FIXNUM?")
{ Primitive_1_Arg();
Arg_1_Type(TC_FIXNUM);
return FIXNUM_0+((Get_Integer(Arg1) == 0) ? 1 : 0);
}