|
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 b
Length: 9816 (0x2658) Types: TextFile Names: »bitops.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/microcode/bitops.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 /* File: BITOPS.C * * Additional bit string support */ /* This file extends C-SCHEME's bit string representation to represent infinite length bit strings; in this representation, virtual bits off the edge of the actual bit string are treated as zero or false. Logical operations can be performed on bit strings; one may take bitwise AND or OR of two bit strings. These procedures return new bit strings. All operations on bit strings are functional; they construct new bit strings rather than modifying existing bit strings. */ #include "scheme.h" #include "primitive.h" \f /*(BIT-STRING-CHECK bitstring index) Treats <bitstring> as an infinite bitstring and extracts the <index>th bit of it; this will be either TRUE or FALSE; if <index> is off the edge of the implemented bitstring, FALSE is returned. */ /* Assumes bits off the end of the bit string are zero. */ Define_Primitive(Prim_BSt_Check, 2, "BIT-STRING-CHECK") { long Word_No, Offset, Mask, *Data_Start; Primitive_2_Args(); Arg_1_Type(TC_BIT_STRING); Arg_2_Type(TC_FIXNUM); Offset=Get_Integer(Arg2); if (Offset > Vector_Ref(Arg1,NM_ENTRY_COUNT)) return NIL; else {Data_Start = (long *) Nth_Vector_Loc(Arg1,NM_DATA); Word_No = Offset/POINTER_LENGTH; Mask = 1 << Offset % POINTER_LENGTH; if ((Data_Start[Word_No] & Mask) != 0) return TRUTH; else return NIL; } } \f /*(BIT-STRING-AND bitstring1 bitstring2) Returns a new bitstring which is the logical bitwise AND of <bitstring1> and <bitstring2>. The length of this bitstrings actual representation is the shorter of the lengths of the two input bitstrings. */ Define_Primitive(Prim_BSt_And, 2, "BIT-STRING-AND") { fast Pointer short_string, long_string; long bit_count, new_vec_size, *bits1, *bits2, i; Primitive_2_Args(); Arg_1_Type(TC_BIT_STRING); Arg_2_Type(TC_BIT_STRING); if (Vector_Ref(Arg1,NM_ENTRY_COUNT) > Vector_Ref(Arg2,NM_ENTRY_COUNT)) {long_string=Arg1;short_string=Arg2;} else {long_string=Arg2; short_string=Arg1;} bit_count=Vector_Ref(short_string,NM_ENTRY_COUNT); new_vec_size=(bit_count+POINTER_LENGTH-1)/POINTER_LENGTH; Primitive_GC_If_Needed(Free+NM_HEADER_LENGTH+new_vec_size+1); Free[NM_VECTOR_HEADER]=Make_Non_Pointer(TC_MANIFEST_NM_VECTOR,new_vec_size+NM_HEADER_LENGTH-1); Free[NM_ENTRY_COUNT]=bit_count; Free=Free+NM_HEADER_LENGTH; bits1= (long *) Nth_Vector_Loc(long_string, NM_DATA); bits2= (long *) Nth_Vector_Loc(short_string, NM_DATA); for (i=0; i < new_vec_size; i++) *Free++ = bits1[i]&bits2[i]; return Make_Pointer(TC_BIT_STRING, Free-(new_vec_size+NM_HEADER_LENGTH)); } \f /*(BIT-STRING-OR bitstring1 bitstring2) Returns a new bitstring which is the logical bitwise OR of <bitstring1> and <bitstring2>. The length of this bitstrings actual representation is the shorter of the lengths of the two input bitstrings. */ Define_Primitive(Prim_BSt_Or, 2, "BIT-STRING-OR") { fast Pointer short_string, long_string; long bit_count, new_vec_size; long short_count, short_vec_size; long *bits1, *bits2, i; Primitive_2_Args(); Arg_1_Type(TC_BIT_STRING); Arg_2_Type(TC_BIT_STRING); if (Vector_Ref(Arg1,NM_ENTRY_COUNT) > Vector_Ref(Arg2,NM_ENTRY_COUNT)) {long_string=Arg1;short_string=Arg2;} else {long_string=Arg2; short_string=Arg1;} bit_count=Vector_Ref(long_string,NM_ENTRY_COUNT); new_vec_size=(bit_count+POINTER_LENGTH-1)/POINTER_LENGTH; short_count=Vector_Ref(short_string,NM_ENTRY_COUNT); short_vec_size=(short_count+POINTER_LENGTH-1)/POINTER_LENGTH; Primitive_GC_If_Needed(Free+NM_HEADER_LENGTH+new_vec_size+1); Free[NM_VECTOR_HEADER]=Make_Non_Pointer(TC_MANIFEST_NM_VECTOR,new_vec_size+NM_HEADER_LENGTH-1); Free[NM_ENTRY_COUNT]=bit_count; Free=Free+NM_HEADER_LENGTH; bits1= (long *) Nth_Vector_Loc(long_string, NM_DATA); bits2= (long *) Nth_Vector_Loc(short_string, NM_DATA); for (i=0; i < short_vec_size; i++) *Free++ = bits1[i]|bits2[i]; for (i=i; i < new_vec_size; i++) *Free++ = bits1[i]; return Make_Pointer(TC_BIT_STRING, Free-(new_vec_size+NM_HEADER_LENGTH)); } \f /*(SAME-BIT-STRING? string1 string2) Returns true if string1 and string2 are identical infinite bit strings (with infinite false extent). */ Define_Primitive(Prim_Compare_Bit_String,2,"SAME-BIT-STRING?") { Pointer long_string, short_string; long i, long_length, short_length, *long_data, *short_data; Primitive_3_Args(); Arg_1_Type(TC_BIT_STRING); Arg_2_Type(TC_BIT_STRING); if (Vector_Ref(Arg1,NM_ENTRY_COUNT) > Vector_Ref(Arg2,NM_ENTRY_COUNT)) {long_string=Arg1;short_string=Arg2;} else {long_string=Arg2; short_string=Arg1;} long_length=(Vector_Ref(long_string,NM_ENTRY_COUNT)+POINTER_LENGTH-1)/POINTER_LENGTH; short_length=(Vector_Ref(short_string,NM_ENTRY_COUNT)+POINTER_LENGTH-1)/POINTER_LENGTH; short_data= (long *) Nth_Vector_Loc(short_string, NM_DATA); long_data= (long *) Nth_Vector_Loc(long_string, NM_DATA); for (i=0; i < short_length; i++) if (long_data[i] != short_data[i]) return NIL; for (i=i; i < long_length; i++) if (long_data[i] != 0) return NIL; return TRUTH; } \f /*(BIT-STRING-MODIFY bitstring index value) Returns a bitstring which is a copy of <bitstring> with the <index>th element set to <value> (which must be boolean). */ Define_Primitive(Prim_BSt_Mod, 3, "BIT-STRING-MODIFY") { Boolean value_to_set; long Offset, Word_No, Mask, size, *Vector_Start, *Copy_Start; Pointer result; Primitive_3_Args(); Arg_1_Type(TC_BIT_STRING); Arg_2_Type(TC_FIXNUM); if (Arg3 == NIL) value_to_set=false; else value_to_set=true; Offset=Get_Integer(Arg2); Word_No = Offset/POINTER_LENGTH; Mask = 1 << Offset % POINTER_LENGTH; size = Vector_Ref(Arg1,NM_ENTRY_COUNT); if (Offset < size) {Vector_Start = (long *) Nth_Vector_Loc(Arg1,NM_DATA); if ((Vector_Start[Word_No] & Mask) != 0) if (value_to_set) return Arg1; else result=extend_bit_string(Arg1,size); else if (value_to_set) result=extend_bit_string(Arg1,size); else return Arg1; } else if (value_to_set) result=extend_bit_string(Arg1,Offset+1); else return Arg1; Copy_Start= (long *) Nth_Vector_Loc(result,NM_DATA); if (value_to_set) Copy_Start[Word_No] = Copy_Start[Word_No] | Mask; else Copy_Start[Word_No] = Copy_Start[Word_No] & ~Mask; return result; } \f /* Support for BIT-STRING-MODIFY */ #define EMPTY_POINTER ((Pointer) 0) extend_bit_string(string,to_size) Pointer string; long to_size; { long vec_size, i, copy_size; long zero_pointer, *copy_data; vec_size=(to_size+POINTER_LENGTH-1)/POINTER_LENGTH; Primitive_GC_If_Needed(Free+vec_size+NM_HEADER_LENGTH+1); Free[NM_VECTOR_HEADER]= Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, vec_size+NM_HEADER_LENGTH-1); Free[NM_ENTRY_COUNT]=to_size; copy_size= (Vector_Ref(string,NM_ENTRY_COUNT)+POINTER_LENGTH-1)/POINTER_LENGTH; copy_data= (long *) Nth_Vector_Loc(string, NM_DATA); zero_pointer= EMPTY_POINTER; Free=Free+NM_HEADER_LENGTH; for (i=0; ((i < vec_size) && (i < copy_size)); i++) *Free++=copy_data[i]; for (i=i; i < vec_size ; i++) *Free++= zero_pointer; return Make_Pointer(TC_BIT_STRING, Free-(vec_size+NM_HEADER_LENGTH)); }