|
|
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: 21855 (0x555f)
Types: TextFile
Names: »bitstr.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/microcode/bitstr.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: BITSTR.C
*
* Bit String support
*/
#include "scheme.h"
#include "primitive.h"
Built_In_Primitive(Prim_Equal_Bit_String, 2, "EQUAL-BIT-STRING?")
{ Primitive_2_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_BIT_STRING);
if (Arg1 == Arg2) return TRUTH;
else
{ if (Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT) ==
Fast_Vector_Ref(Arg2, NM_ENTRY_COUNT))
{ long *String1, *String2, i, Offset, Count, Mask;
Offset = Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT) % POINTER_LENGTH;
Count = (Get_Integer(Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)) +
POINTER_LENGTH-1)/POINTER_LENGTH-1;
String1 = (long *) Nth_Vector_Loc(Arg1, NM_DATA);
String2 = (long *) Nth_Vector_Loc(Arg2, NM_DATA);
for(i=0; i<Count; i++)
if(*String1++ != *String2++) return NIL;
Mask = (1 << Offset)-1;
if((*String1 & Mask) == (*String2 & Mask)) return TRUTH;
else return NIL;
}
else return NIL;
}
}
\f
/* (MAKE-FILLED-BIT-STRING size initialization)
[Primitive number 0xD2]
Returns a bit string of the specified size with all the bits
set to the specified initialization. The initialization must be
1 or 0.
*/
#define FULL_POINTER ((Pointer) -1)
#define EMPTY_POINTER ((Pointer) 0)
Built_In_Primitive(Prim_Make_Fld_Bit_String, 2, "MAKE-FILLED-BIT-STRING")
{ long Count, Fill_Word, Bit, i;
Primitive_2_Args();
Arg_1_Type(TC_FIXNUM);
Arg_2_Type(TC_FIXNUM);
Range_Check(Bit, Arg2, 0, 1, ERR_ARG_2_BAD_RANGE);
Count = (Get_Integer(Arg1)+POINTER_LENGTH-1)/POINTER_LENGTH;
/* Pointers needed */
Primitive_GC_If_Needed(Free+Count+1+NM_HEADER_LENGTH);
Free[NM_VECTOR_HEADER] =
Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, Count+NM_HEADER_LENGTH-1);
Free[NM_ENTRY_COUNT] = Get_Integer(Arg1);
if (Bit == 1) Fill_Word = FULL_POINTER;
else Fill_Word = EMPTY_POINTER;
Free += NM_HEADER_LENGTH;
for (i=0; i < Count; i++) *Free++ = Fill_Word;
return Make_Pointer(TC_BIT_STRING, Free-(Count+NM_HEADER_LENGTH));
}
\f
/*(MAKE-UNFILLED-BIT-STRING size)
[Primitive number 0xD1]
Returns an uninitialized bit string of the size given.
*/
Built_In_Primitive(Prim_Make_Unfilled_Bit_String, 1,
"MAKE-UNFILLED-BIT-STRING")
{ long Count, Bit, i;
Primitive_1_Arg();
Arg_1_Type(TC_FIXNUM);
Count = (Get_Integer(Arg1)+POINTER_LENGTH-1)/POINTER_LENGTH;
/* Pointers needed */
Primitive_GC_If_Needed(Free+Count+1+NM_HEADER_LENGTH);
Free[NM_VECTOR_HEADER] =
Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, Count+NM_HEADER_LENGTH-1);
Free[NM_ENTRY_COUNT] = Get_Integer(Arg1);
Free += Count+NM_HEADER_LENGTH;
return Make_Pointer(TC_BIT_STRING, Free-(Count+NM_HEADER_LENGTH));
}
\f
/*(INSERT-BIT-STRING bitstring1 index bitstring2)
[Primitive number 0xDA]
Creates a new bit string which is the append of
(BIT-SUBSTRING bitstring1 0 index)
bitstring2
(BIT-SUBSTRING bitstring1 index (BIT-STRING-SIZE bitstring1))
That is, it squeezes bitstring2 into bitstring1 starting at index.
*/
Built_In_Primitive(Prim_Ins_BStr, 3, "INSERT-BIT-STRING")
{ long Size_Needed, *Old_String, *New_String, *Orig_Free,
Offset, i, Longword_Offset, new_size;
Primitive_3_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_FIXNUM);
Arg_3_Type(TC_BIT_STRING);
Range_Check(Offset, Arg2, 0, Vector_Ref(Arg1, NM_ENTRY_COUNT),
ERR_ARG_2_BAD_RANGE);
new_size = Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT) +
Fast_Vector_Ref(Arg3, NM_ENTRY_COUNT);
Size_Needed =
(new_size+POINTER_LENGTH-1)/POINTER_LENGTH
+ NM_HEADER_LENGTH;
/* Pointers needed */
Primitive_GC_If_Needed(Free+Size_Needed);
Free[NM_ENTRY_COUNT] = new_size;
Free[NM_VECTOR_HEADER] =
Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, Size_Needed-1);
Offset %= POINTER_LENGTH;
Longword_Offset = Get_Integer(Arg2)/POINTER_LENGTH;
Old_String = (long *) Nth_Vector_Loc(Arg1, NM_DATA);
New_String = (long *) Nth_Vector_Loc(Arg3, NM_DATA);
Orig_Free = (long *) Free;
Free += NM_DATA;
for(i=0; i<Longword_Offset; i++) *Free++ = *Old_String++;
*Free = *Old_String;
Shift_Bit_String(New_String, &Free,0, &Offset,
Fast_Vector_Ref(Arg3, NM_ENTRY_COUNT));
Shift_Bit_String(Old_String, &Free,
Get_Integer(Arg2)%POINTER_LENGTH, &Offset,
Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-Get_Integer(Arg2));
Free++;
return Make_Pointer(TC_BIT_STRING,Orig_Free);
}
\f
/* (INSERT-BIT-STRING! bitstring1 index bitstring2)
[Primitive number 0xDB]
Like INSERT-STRING except this side effects bitstring1 to contain
the same bits as bitstring2, starting at index in bitstring1.
*/
Built_In_Primitive(Prim_Ins_BStr_Excl, 3, "INSERT-BIT-STRING!")
{ long Size_Needed, *Old_String, *New_String, *Orig_Free,
Offset, Longword_Offset;
Primitive_3_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_FIXNUM);
Arg_3_Type(TC_BIT_STRING);
Range_Check(Offset, Arg2, 0, Vector_Ref(Arg1, NM_ENTRY_COUNT-1),
ERR_ARG_2_BAD_RANGE);
if (Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT) <
(Fast_Vector_Ref(Arg3, NM_ENTRY_COUNT) + Get_Integer(Arg2)))
Primitive_Error(ERR_ARG_2_BAD_RANGE);
Offset %= POINTER_LENGTH;
Longword_Offset = Get_Integer(Arg2)/POINTER_LENGTH;
Old_String = (long *) Nth_Vector_Loc(Arg1, NM_DATA);
New_String = (long *) Nth_Vector_Loc(Arg3, NM_DATA);
Old_String += Longword_Offset;
Shift_Bit_String(New_String, &Old_String, 0, &Offset,
Fast_Vector_Ref(Arg3, NM_ENTRY_COUNT));
return Arg1;
}
\f
/*(READ-BITS address offset count)
[Primitive number 0xDF]
Returns a bit string of length count resulting from reading
memory starting at address plus the bit offset supplied. Address
is a FIXNUM (ADDRESS).
offset and Count are FIXNUMs.
*/
Built_In_Primitive(Prim_Read_Bits, 3, "READ-BITS")
{ long Count, *Source, Dest_Offset, Source_Offset;
Pointer *Orig_Free;
Primitive_3_Args();
Arg_1_Type(TC_ADDRESS);
Arg_2_Type(TC_FIXNUM);
Arg_3_Type(TC_FIXNUM);
Count = (Get_Integer(Arg3)+POINTER_LENGTH-1)/POINTER_LENGTH;
/* Pointers needed */
Primitive_GC_If_Needed(Free+Count+1+NM_HEADER_LENGTH);
Free[NM_VECTOR_HEADER] =
Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, Count+NM_HEADER_LENGTH-1);
Free[NM_ENTRY_COUNT] = Get_Integer(Arg3);
Orig_Free = Free;
Free += NM_HEADER_LENGTH;
Source = (long *) Get_Integer(Arg1);
Source_Offset = Get_Integer(Arg2);
Source += Source_Offset/POINTER_LENGTH;
Source_Offset %= POINTER_LENGTH;
Dest_Offset = 0;
Shift_Bit_String(Source, &Free, Source_Offset,
&Dest_Offset, Get_Integer(Arg3));
Free += 1;
return Make_Pointer(TC_BIT_STRING, Orig_Free);
}
\f
/* (BIT-STRING-REF bitstring index)
[Primitive number 0xD5]
Returns 1 or 0 coresponding to the bit addressed. Bits are indexed
from 0.
*/
Built_In_Primitive(Prim_BSt_Ref, 2, "BIT-STRING-REF")
{ long Word_No, Offset, Mask, *Data_Start;
Primitive_2_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
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 FIXNUM_0+1;
else return FIXNUM_0;
}
/* (BIT-STRING-SET! bitstring index value)
[Primitive number 0xD6]
Side effects the indexed bit in bitstring to be value. Value must
be 1 or 0. Bits are indexed from 0.
*/
Built_In_Primitive(Prim_BSt_Set, 3, "BIT-STRING-SET!")
{ long Value, Word_No, Offset, Mask, *Data_Start;
Primitive_3_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_FIXNUM);
Arg_3_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
Range_Check(Value, Arg3, 0, 1, ERR_ARG_3_BAD_RANGE);
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)
{ if (!Value) Data_Start[Word_No] &= ~Mask;
return FIXNUM_0+1;
}
else
{ if (Value) Data_Start[Word_No] |= Mask;
return FIXNUM_0;
}
}
\f
/* (BIT-STRING-SET-FALSE! bitstring index)
[Primitive number 0xD8]
Side effects the indexed bit in bitstring to be a logical FALSE.
Bits are indexed from 0.
*/
Built_In_Primitive(Prim_BSt_Set_False, 2, "BIT-STRING-SET-FALSE!")
{ long Value, Word_No, Offset, Mask, *Data_Start;
Primitive_2_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
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)
{ Data_Start[Word_No] &= ~Mask;
return FIXNUM_0+1;
}
return FIXNUM_0;
}
/*(BIT-STRING-SET-TRUE! bitstring index)
[Primitive number 0xD7]
Side effects the indexed bit in bitstring to be a logical TRUE.
Bits are indexed from 0.
*/
Built_In_Primitive(Prim_BSt_Set_True, 2, "BIT-STRING-SET-TRUE!")
{ long Value, Word_No, Offset, Mask, *Data_Start;
Primitive_2_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
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)
{ Data_Start[Word_No] |= Mask;
return FIXNUM_0;
}
return FIXNUM_0+1;
}
\f
/* (BIT-STRING-SIZE bitstring)
[Primitive number 0xD4]
Returns the number of bits in bitstring.
*/
Built_In_Primitive(Prim_BSt_Size, 1, "BIT-STRING-SIZE")
{ Primitive_1_Arg();
Arg_1_Type(TC_BIT_STRING);
return Make_Non_Pointer(TC_FIXNUM, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT));
}
/*(BIT-STRING? object)
[Primitive number 0xD3]
Returns #!TRUE if object is a bit string, otherwise #!FALSE.
*/
Built_In_Primitive(Prim_BSt_Qm, 1, "BIT-STRING?")
{ Primitive_1_Arg();
Touch_In_Primitive(Arg1, Arg1);
return (Type_Code(Arg1) == TC_BIT_STRING) ? TRUTH : NIL;
}
\f
/* (BIT-SUBSTRING bitstring low high)
[Primitive number 0xD9]
Returns a bit string whose bits consist of bits low through bit
high-1 of the given bitstring.
*/
Built_In_Primitive(Prim_Bit_Substring, 3, "BIT-SUBSTRING")
{ long Start, End, Offset, Count, i, Mask, Right_Shift, Dest_Offset,
*Orig_Free;
Pointer *Finger;
Primitive_3_Args();
Arg_1_Type(TC_BIT_STRING);
Arg_2_Type(TC_FIXNUM);
Arg_3_Type(TC_FIXNUM);
Range_Check(Start, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT),
ERR_ARG_2_BAD_RANGE);
Range_Check(End, Arg3, Start, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT),
ERR_ARG_3_BAD_RANGE);
Count = (End-Start+POINTER_LENGTH-1)/POINTER_LENGTH;
/* Number of Pointers needed */
Primitive_GC_If_Needed(Free+Count+NM_HEADER_LENGTH +1);
/* The + 1 in the GC macro is because we add one to free in the end */
Free[NM_VECTOR_HEADER] =
Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, Count+NM_HEADER_LENGTH-1);
Free[NM_ENTRY_COUNT] = End-Start;
Offset = Start % POINTER_LENGTH;
/* The bit index in first Pointer of substring */
Dest_Offset = 0;
Finger = Nth_Vector_Loc(Arg1, NM_DATA) + Start/POINTER_LENGTH;
/* C-pointer to the first Pointer of substring numbered from 0 */
Orig_Free = (long *) Free;
Free += NM_HEADER_LENGTH;
Shift_Bit_String(Finger,&Free,Offset,&Dest_Offset,End-Start);
Free++;
return Make_Pointer(TC_BIT_STRING, Orig_Free);
}
\f
/*(REVERSE-BIT-STRING bstring)
[primitive 0xDE]
Makes a new bitstring consisting of the bits in the bitstring
supplied in reverse order.
*/
Built_In_Primitive(Prim_Reverse_Bit_String, 1, "REVERSE-BIT-STRING")
{ long Count, Inner_Count, Remainder_Bits, Starting_Source_Mask,
*Orig_Free, Starting_Dest_Mask, *Source, *Dest, i, j;
fast long Source_Mask, Dest_Mask;
Primitive_1_Arg();
Arg_1_Type(TC_BIT_STRING);
Primitive_GC_If_Needed(Free + Fast_Vector_Ref(Arg1, NM_VECTOR_HEADER) + 1);
Free[NM_VECTOR_HEADER] = Fast_Vector_Ref(Arg1, NM_VECTOR_HEADER);
Free[NM_ENTRY_COUNT] = Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT);
Count = Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)/POINTER_LENGTH;
Remainder_Bits = Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT) % POINTER_LENGTH;
Dest = (long *) Free;
Dest += NM_DATA;
Source = (long *) Nth_Vector_Loc(Arg1, NM_DATA+Count);
if(Remainder_Bits > 0)
{ Starting_Source_Mask = (1 << (Remainder_Bits-1));
Source_Mask = Starting_Source_Mask;
Starting_Dest_Mask = (Starting_Source_Mask << 1);
}
else
{ Starting_Source_Mask = HIGH_BIT;
Source_Mask = Starting_Source_Mask;
Starting_Dest_Mask = 1;
}
/* Prim_Reverse_Bit_String continues on the next page */
\f
/* Prim_Reverse_Bit_String, continued */
*Dest = 0;
Dest_Mask = 1;
for(i=0; i<Remainder_Bits; i++)
{ if((*Source & Source_Mask) != 0)
*Dest |= Dest_Mask;
Dest_Mask = (Dest_Mask << 1);
Source_Mask = (Source_Mask >> 1);
}
Inner_Count = POINTER_LENGTH-Remainder_Bits-1;
for(i=0; i<Count; i++)
{ Source_Mask = HIGH_BIT;
Dest_Mask = Starting_Dest_Mask;
Source--;
if((*Source & Source_Mask) != 0) /* sign bit is copied on right-shift */
*Dest |= Dest_Mask;
Dest_Mask = (Dest_Mask << 1);
Source_Mask = (Source_Mask >> 1) & ~Source_Mask;
for(j=0; j<Inner_Count; j++)
{ if((*Source & Source_Mask) != 0)
*Dest |= Dest_Mask;
Dest_Mask = (Dest_Mask << 1);
Source_Mask = (Source_Mask >> 1);
}
*++Dest = 0;
Source_Mask = Starting_Source_Mask;
Dest_Mask = 1;
for(j=0; j<Remainder_Bits; j++)
{ if((*Source & Source_Mask) != 0)
*Dest |= Dest_Mask;
Dest_Mask = (Dest_Mask << 1);
Source_Mask = (Source_Mask >> 1);
}
}
Orig_Free = (long * ) Free;
Free += Get_Integer(Free[NM_VECTOR_HEADER]) + 1;
return Make_Pointer(TC_BIT_STRING, Orig_Free);
}
\f
/* (VECTOR-1B? OBJECT)
[Primitive number 0x9E]
Returns #!TRUE if OBJECT is a bit-vector as created by
VECTOR_1B_CONS.
*/
Built_In_Primitive(Prim_Vector_1b, 1, "VECTOR-1B")
{ Primitive_1_Arg();
Touch_In_Primitive(Arg1, Arg1);
return (Type_Code(Arg1) == TC_VECTOR_1B) ? TRUTH : NIL;
}
/* (VECTOR_1B_CONS LENGTH)
[Primitive number 0x9D]
Creates an uninitialized bit vector large enough to hold LENGTH
bits.
*/
Built_In_Primitive(Prim_Vector_1b_Cons, 1, "VECTOR-1B-CONS")
{ long Size_Needed;
Primitive_1_Arg();
Arg_1_Type(TC_FIXNUM);
Size_Needed = (Get_Integer(Arg1)+7)/8;
/* Bytes needed */
Size_Needed =
(Size_Needed*sizeof(char)) / sizeof(Pointer) +
1 + NM_HEADER_LENGTH;
/* Pointers needed */
Primitive_GC_If_Needed(Free+Size_Needed);
Free[NM_VECTOR_HEADER] =
Make_Non_Pointer(TC_MANIFEST_NM_VECTOR, Size_Needed-1);
Free[NM_ENTRY_COUNT] = Arg1;
Free += Size_Needed;
return Make_Pointer(TC_VECTOR_1B, Free-Size_Needed);
}
\f
/* (VECTOR_1B_REF BIT-VECTOR OFFSET)
[Primitive number 0x9F]
Return #!TRUE if the OFFSETth bit in BIT-VECTOR is set, or NIL
otherwise. Bits are numbered from 0.
*/
Built_In_Primitive(Prim_Vector_1b_Ref, 2, "VECTOR-1B-REF")
{ long Offset, Char_No, Mask;
char *Data_Start;
Primitive_2_Args();
Arg_1_Type(TC_VECTOR_1B);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
Char_No = Offset / 8;
Mask = 1 << (Offset % 8);
Data_Start = (char *) Nth_Vector_Loc(Arg1, NM_DATA);
if ((Data_Start[Char_No] & Mask) != 0)
return TRUTH;
else return NIL;
}
\f
/* (VECTOR_1B_SET BIT-VECTOR OFFSET VALUE)
[Primitive number 0xA0]
Sets the OFFSETth bit in BIT-VECTOR to VALUE, which must be
either #!TRUE or NIL. Returns (bad style to rely on this)
previous value. Bits are numbered from 0.
*/
Built_In_Primitive(Prim_Vec_1b_Set, 3, "VECTOR-1B-SET!")
{ long Offset, Char_No, Mask;
char *Data_Start;
Boolean Value;
Pointer Result;
Primitive_3_Args();
Arg_1_Type(TC_VECTOR_1B);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
if (Arg3 == NIL) Value = false;
else if (Arg3 == TRUTH) Value = true;
else Primitive_Error(ERR_ARG_3_WRONG_TYPE);
Char_No = Offset / 8;
Mask = 1 << (Offset % 8);
Data_Start = (char *) Nth_Vector_Loc(Arg1, NM_DATA);
if ((Data_Start[Char_No] & Mask) != 0)
Result = TRUTH;
else Result = NIL;
if (Value) Data_Start[Char_No] |= Mask;
else Data_Start[Char_No] &= ~Mask;
return Result;
}
/* (VECTOR_1B_SIZE BIT-VECTOR)
[Primitive number 0xAC]
Returns the number of bits in BIT-VECTOR.
*/
Built_In_Primitive(Prim_Vec_1b_Size, 1, "VECTOR-1B-SIZE")
{ Primitive_1_Arg();
Arg_1_Type(TC_VECTOR_1B);
return Make_Non_Pointer(TC_FIXNUM, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT));
}
\f
/* (VEC_1B_SET_FALSE VECTOR OFFSET)
[Primitive number 0xA1]
(VEC_1B_SET_FALSE V O) is the same as (VECTOR_1B_SET V O NIL)
*/
Built_In_Primitive(Prim_1b_Set_False, 2, "VECTOR-1B-SET-FALSE!")
{ long Offset, Char_No, Mask;
char *Data_Start;
Pointer Result;
Primitive_2_Args();
Arg_1_Type(TC_VECTOR_1B);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
Char_No = Offset / 8;
Mask = 1 << (Offset % 8);
Data_Start = (char *) Nth_Vector_Loc(Arg1, NM_DATA);
if ((Data_Start[Char_No] & Mask) != 0)
Result = TRUTH;
else Result = NIL;
Data_Start[Char_No] &= ~Mask;
return Result;
}
/* (VEC_1B_SET_TRUE
[Primitive number 0xA2]
(VEC_1B_SET_FALSE V O) is the same as (VECTOR_1B_SET V O #!TRUE)
*/
Built_In_Primitive(Prim_1b_Set_True, 2, "VECTOR-1B-SET-TRUE!")
{ long Offset, Char_No, Mask;
char *Data_Start;
Pointer Result;
Primitive_2_Args();
Arg_1_Type(TC_VECTOR_1B);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2, 0, Fast_Vector_Ref(Arg1, NM_ENTRY_COUNT)-1,
ERR_ARG_2_BAD_RANGE);
Char_No = Offset / 8;
Mask = 1 << (Offset % 8);
Data_Start = (char *) Nth_Vector_Loc(Arg1, NM_DATA);
if ((Data_Start[Char_No] & Mask) != 0)
Result = TRUTH;
else Result = NIL;
Data_Start[Char_No] |= Mask;
return Result;
}
\f
/*(WRITE-BITS! address offset bitstring)
[Primitive number 0xE0]
Starting at the address in memory supplied, and the bit offset,
OFFSET supplied, the bits in bitstring
are written over what was there. This is a low level mutator.
*/
Built_In_Primitive(Prim_Write_Bits, 3, "WRITE-BITS!")
{ long *Source, *Dest, Offset, Bits;
Primitive_3_Args();
Arg_1_Type(TC_ADDRESS);
Arg_2_Type(TC_FIXNUM);
Arg_3_Type(TC_BIT_STRING);
Source = (long *) Nth_Vector_Loc(Arg3, NM_DATA);
Dest = (long *) Get_Integer(Arg1);
Bits = Fast_Vector_Ref(Arg3, NM_ENTRY_COUNT);
Offset = Get_Integer(Arg2);
Dest += Offset/POINTER_LENGTH;
Offset %= POINTER_LENGTH;
Shift_Bit_String(Source, &Dest, 0, &Offset, Bits);
return TRUTH;
}