|
|
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 v
Length: 9963 (0x26eb)
Types: TextFile
Names: »vector.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/microcode/vector.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: VECTOR.C
*
* This file contains procedures for handling vectors and conversion
* back and forth to lists.
*/
#include "scheme.h"
#include "primitive.h"
\f
/*********************/
/* VECTORS <-> LISTS */
/*********************/
/* Subvector_To_List is a utility routine used by both
SUBVECTOR_TO_LIST and SYS_SUBVECTOR_TO_LIST. It copies the entries
in a vector (first argument) starting with the entry specified by
argument 2 and ending at the one specified by argument 3. The copy
includes the starting entry but does NOT include the ending entry.
Thus the entire vector is converted to a list by setting argument 2
to 0 and argument 3 to the length of the vector.
*/
Pointer Subvector_To_List()
{ Pointer *From, Result;
long Length, Start, End, Count, i;
Primitive_3_Args();
if (Type_Code(Arg2) != TC_FIXNUM) Primitive_Error(ERR_ARG_2_WRONG_TYPE);
if (Type_Code(Arg3) != TC_FIXNUM) Primitive_Error(ERR_ARG_3_WRONG_TYPE);
if (Type_Code(Vector_Ref(Arg1, VECTOR_TYPE)) != TC_MANIFEST_VECTOR)
Primitive_Error(ERR_ARG_1_WRONG_TYPE);
Length = Vector_Length(Arg1);
Start = Get_Integer(Arg2);
End = Get_Integer(Arg3);
if (End > Length) Primitive_Error(ERR_ARG_3_BAD_RANGE);
if (Start > End) Primitive_Error(ERR_ARG_3_BAD_RANGE);
if (Start == End) return NIL;
Primitive_GC_If_Needed(Free+2*(End-Start));
Result = Make_Pointer(TC_LIST, Free);
From = Nth_Vector_Loc(Arg1, Start+1);
Count = End-Start;
for (i=0; i < Count; i++)
{ *Free++ = Fetch(*From++);
*Free = Make_Pointer(TC_LIST, Free+1);
Free += 1;
}
Free[-1] = NIL;
return Result;
}
\f
/* Called by the primitives LIST_TO_VECTOR and SYS_LIST_TO_VECTOR.
This utility routine converts a list into a vector.
*/
Pointer L_To_V(Result_Type, List)
fast Pointer List;
{ Pointer *Orig_Free;
long Count;
Touch_In_Primitive(List, List);
Count = 0;
Orig_Free = Free++;
while (Type_Code(List) == TC_LIST)
{ Primitive_GC_If_Needed(Free);
Count += 1;
*Free++ = Vector_Ref(List, CONS_CAR);
Touch_In_Primitive(Vector_Ref(List, CONS_CDR), List);
}
if (List != NIL) Primitive_Error(ERR_ARG_1_WRONG_TYPE);
*Orig_Free = Make_Non_Pointer(TC_MANIFEST_VECTOR, Count);
return Make_Pointer(Result_Type, Orig_Free);
}
/* (LIST_TO_VECTOR LIST)
[Primitive number 0x7C]
Returns a vector made from the items in LIST.
*/
Built_In_Primitive(Prim_List_To_Vector, 1, "LIST->VECTOR")
{ Primitive_1_Arg();
return L_To_V(TC_VECTOR, Arg1);
}
\f
/* (SUBVECTOR_TO_LIST VECTOR FROM TO)
[Primitive number 0x7D]
Returns a list of the FROMth through TO-1st items in the vector.
Thus (SUBVECTOR_TO_LIST V 0 (VECTOR_LENGTH V)) returns a list of
all the items in V.
*/
Built_In_Primitive(Prim_Subvector_To_List, 3, "SUBVECTOR->LIST")
{ Primitive_3_Args();
Arg_1_Type(TC_VECTOR);
/* The work is done by Subvector_To_List, in PRIMSUBR.C */
return Subvector_To_List();
}
/* (VECTOR_CONS LENGTH CONTENTS)
[Primitive number 0x2C]
Create a new vector to hold LENGTH entries, all of which are
initialized to CONTENTS.
*/
Built_In_Primitive(Prim_Vector_Cons, 2, "VECTOR-CONS")
{ long Length, i;
Primitive_2_Args();
Arg_1_Type(TC_FIXNUM);
Length = Get_Integer(Arg1);
Primitive_GC_If_Needed(Free+Length+1);
*Free++ = Make_Non_Pointer(TC_MANIFEST_VECTOR, Length);
for (i=0; i < Length; i++) *Free++ = Arg2;
return Make_Pointer(TC_VECTOR, Free-(Length+1));
}
/* (VECTOR_REF VECTOR OFFSET)
[Primitive number 0x2E]
Return the OFFSETth entry in VECTOR. Entries are numbered from
0.
*/
Built_In_Primitive(Prim_Vector_Ref, 2, "VECTOR-REF")
{ long Offset;
Primitive_2_Args();
Arg_1_Type(TC_VECTOR);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2,
0, Vector_Length(Arg1)-1, ERR_ARG_2_BAD_RANGE);
return User_Vector_Ref(Arg1, Offset);
}
\f
/* (VECTOR_SET VECTOR OFFSET VALUE)
[Primitive number 0x30]
Store VALUE as the OFFSETth entry in VECTOR. Entries are
numbered from 0. Returns (bad style to rely on this) the
previous value of the entry.
*/
Built_In_Primitive(Prim_Vector_Set, 3, "VECTOR-SET!")
{ long Offset;
Primitive_3_Args();
Arg_1_Type(TC_VECTOR);
Arg_2_Type(TC_FIXNUM);
Range_Check(Offset, Arg2,
0, Vector_Length(Arg1)-1, ERR_ARG_2_BAD_RANGE);
Side_Effect_Impurify(Arg1, Arg3);
return Swap_Pointers(Nth_Vector_Loc(Arg1, Offset+1), Arg3);
}
/* (VECTOR_SIZE VECTOR)
[Primitive number 0x2D]
Returns the number of entries in VECTOR.
*/
Built_In_Primitive(Prim_Vector_Size, 1, "VECTOR-SIZE")
{ Primitive_1_Arg();
Arg_1_Type(TC_VECTOR);
return FIXNUM_0+Vector_Length(Arg1);
}
\f
/* (SYS_LIST_TO_VECTOR GC-LIST)
[Primitive number 0x97]
Same as LIST_TO_VECTOR except that the resulting vector has the
specified type code. This can be used, for example, to create
an environment from a list of values.
*/
Built_In_Primitive(Prim_Sys_List_To_Vector, 2, "SYSTEM-LIST->VECTOR")
{ long Type;
Primitive_2_Args();
Arg_1_Type(TC_FIXNUM);
Range_Check(Type, Arg1, 0, MAX_TYPE_CODE, ERR_ARG_1_BAD_RANGE);
if (GC_Type_Code(Type) == GC_Vector)
return L_To_V(Type, Arg2);
else
Primitive_Error(ERR_ARG_1_BAD_RANGE);
}
/* (SYS_SUBVECTOR_TO_LIST GC-VECTOR FROM TO)
[Primitive number 0x98]
Same as SUBVECTOR_TO_LIST, but accepts anything with a GC type
of VECTOR. Most useful for accessing values from environments.
*/
Built_In_Primitive(Prim_Sys_Subvector_To_List, 3,
"SYSTEM-SUBVECTOR->LIST")
{ Primitive_3_Args();
Touch_In_Primitive(Arg1, Arg1);
Arg_1_GC_Type(GC_Vector);
/* The work is done by Subvector_To_List, in PRIMSUBR.C */
return Subvector_To_List();
}
\f
/* (SYS_VECTOR OBJECT)
[Primitive number 0x99]
Returns #!TRUE if OBJECT is of GC type VECTOR. Otherwise
returns NIL.
*/
Built_In_Primitive(Prim_Sys_Vector, 1, "SYSTEM-VECTOR")
{ Primitive_1_Arg();
Touch_In_Primitive(Arg1, Arg1);
if (GC_Type_Vector(Arg1)) return TRUTH; else return NIL;
}
/* (SYS_VECTOR_REF GC-VECTOR OFFSET)
[Primitive number 0x9A]
Like VECTOR_REF, but for anything of GC type VECTOR (eg.
environments)
*/
Built_In_Primitive(Prim_Sys_Vector_Ref, 2, "SYSTEM-VECTOR-REF")
{ long Offset;
Primitive_2_Args();
Touch_In_Primitive(Arg1, Arg1);
Arg_1_GC_Type(GC_Vector);
Range_Check(Offset, Arg2, 0,
Vector_Length(Arg1)-1, ERR_ARG_2_BAD_RANGE);
return User_Vector_Ref(Arg1, Offset);
}
/* (SYS_VECTOR_SET GC-VECTOR OFFSET VALUE)
[Primitive number 0x9B]
Like VECTOR_SET, but for anything of GC type VECTOR (eg.
environments)
*/
Built_In_Primitive(Prim_Sys_Vec_Set, 3, "SYSTEM-VECTOR-SET!")
{ long Offset;
Primitive_3_Args();
Touch_In_Primitive(Arg1, Arg1);
Arg_1_GC_Type(GC_Vector);
Range_Check(Offset, Arg2, 0,
Vector_Length(Arg1)-1, ERR_ARG_2_BAD_RANGE);
Side_Effect_Impurify(Arg1, Arg3);
return Swap_Pointers(Nth_Vector_Loc(Arg1, Offset+1), Arg3);
}
\f
/* (SYS_VECTOR_SIZE GC-VECTOR)
[Primitive number 0xAE]
Like VECTOR_SIZE, but for anything of GC type VECTOR (eg.
environments)
*/
Built_In_Primitive(Prim_Sys_Vec_Size, 1, "SYSTEM-VECTOR-SIZE")
{ Primitive_1_Arg();
Touch_In_Primitive(Arg1, Arg1);
Arg_1_GC_Type(GC_Vector);
return FIXNUM_0+Vector_Length(Arg1);
}