|
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 - downloadIndex: ┃ T l ┃
Length: 9448 (0x24e8) Types: TextFile Names: »list.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/gnu-31mar87/scheme/microcode/list.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: LIST.C * * List creation and manipulation primitives. */ #include "scheme.h" #include "primitive.h" \f /* (CONS LEFT RIGHT) [Primitive number 0x20] Creates a pair with left component LEFT and right component RIGHT. */ Built_In_Primitive(Prim_Cons, 2, "CONS") { Primitive_2_Args(); Primitive_GC_If_Needed(Free+2); *Free++ = Arg1; *Free++ = Arg2; return Make_Pointer(TC_LIST, Free-2); } /* (CDR PAIR) [Primitive number 0x22] Returns the second element in the pair. By convention, (CAR NIL) is NIL. */ Built_In_Primitive(Prim_Cdr, 1, "CDR") { Primitive_1_Arg(); if (Arg1 == NIL) return NIL; Arg_1_Type(TC_LIST); return Vector_Ref(Arg1, CONS_CDR); } /* (CAR PAIR) [Primitive number 0x21] Returns the first element in the pair. By convention, (CAR NIL) is NIL. */ Built_In_Primitive(Prim_Car, 1, "CAR") { Primitive_1_Arg(); if (Arg1 == NIL) return NIL; Arg_1_Type(TC_LIST); return Vector_Ref(Arg1, CONS_CAR); } \f /* (GENERAL_CAR_CDR LIST DIRECTIONS) [Primitive number 0x27] DIRECTIONS encodes a string of CAR and CDR operations to be performed on LIST as follows: 1 = NOP 101 = CDAR 10 = CDR 110 = CADR 11 = CAR 111 = CAAR 100 = CDDR ... */ Built_In_Primitive(Prim_General_Car_Cdr, 2, "GENERAL-CAR-CDR") { fast long CAR_CDR_Pattern; Primitive_2_Args(); Arg_2_Type(TC_FIXNUM); CAR_CDR_Pattern = Get_Integer(Arg2); while (CAR_CDR_Pattern > 1) { Touch_In_Primitive(Arg1, Arg1); if (Arg1 == NIL) return NIL; if (Type_Code(Arg1) != TC_LIST) Primitive_Error(ERR_ARG_1_WRONG_TYPE); Arg1 = Vector_Ref(Arg1, ((CAR_CDR_Pattern & 1) == 0) ? CONS_CDR : CONS_CAR); CAR_CDR_Pattern >>= 1; } return Arg1; } \f /* (ASSQ ITEM A-LIST) Searches the association list A-LIST for ITEM, using EQ? for testing equality. Returns NIL if ITEM is not found, or the tail of the list whose CAAR is ITEM. */ Built_In_Primitive(Prim_Assq, 2, "ASSQ") { Pointer This_Assoc_Pair, Key; Primitive_2_Args(); Touch_In_Primitive(Arg1, Arg1); Touch_In_Primitive(Arg2, Arg2); while (Type_Code(Arg2) == TC_LIST) { Touch_In_Primitive(Vector_Ref(Arg2, CONS_CAR), This_Assoc_Pair); if (Type_Code(This_Assoc_Pair) != TC_LIST) Primitive_Error(ERR_ARG_2_WRONG_TYPE); Touch_In_Primitive(Vector_Ref(This_Assoc_Pair, CONS_CAR), Key); if (Key == Arg1) return This_Assoc_Pair; Touch_In_Primitive(Vector_Ref(Arg2, CONS_CDR), Arg2); } if (Arg2 != NIL) Primitive_Error(ERR_ARG_2_WRONG_TYPE); return NIL; } /* (LENGTH LIST) [Primitive number 0x5D] Returns the number of items in the list. By convention, (LENGTH NIL) is 0. LENGTH will loop forever if given a circular structure. */ Built_In_Primitive(Prim_Length, 1, "LENGTH") { fast long i; Primitive_1_Arg(); i = 0; Touch_In_Primitive(Arg1, Arg1); while (Type_Code(Arg1) == TC_LIST) { i += 1; Touch_In_Primitive(Vector_Ref(Arg1, CONS_CDR), Arg1); } if (Arg1 != NIL) Primitive_Error(ERR_ARG_1_WRONG_TYPE); return FIXNUM_0+i; } \f /* (MEMQ ITEM LIST) [Primitive number 0x1C] Searches LIST for ITEM, using EQ? as a test. Returns NIL if it is not found, or the [first] tail of LIST whose CAR is ITEM. */ Built_In_Primitive(Prim_Memq, 2, "MEMQ") { fast Pointer Key; Primitive_2_Args(); Touch_In_Primitive(Arg1, Arg1); Touch_In_Primitive(Arg2, Arg2); while (Type_Code(Arg2) == TC_LIST) { Touch_In_Primitive(Vector_Ref(Arg2, CONS_CAR), Key); if (Arg1 == Key) return Arg2; else Touch_In_Primitive(Vector_Ref(Arg2, CONS_CDR), Arg2); } if (Arg2 != NIL) Primitive_Error(ERR_ARG_2_WRONG_TYPE); return NIL; } /* (SET_CAR PAIR VALUE) [Primitive number 0x23] Stores VALUE in the CAR of PAIR. Returns (bad style to count on this) the previous CAR of PAIR. */ Built_In_Primitive(Prim_Set_Car, 2, "SET-CAR!") { Primitive_2_Args(); Arg_1_Type(TC_LIST); Side_Effect_Impurify(Arg1, Arg2); return Swap_Pointers(Nth_Vector_Loc(Arg1, CONS_CAR), Arg2); } /* (SET_CDR PAIR VALUE) [Primitive number 0x24] Stores VALUE in the CDR of PAIR. Returns (bad style to count on this) the previous CDR of PAIR. */ Built_In_Primitive(Prim_Set_Cdr, 2, "SET-CDR!") { Primitive_2_Args(); Arg_1_Type(TC_LIST); Side_Effect_Impurify(Arg1, Arg2); return Swap_Pointers(Nth_Vector_Loc(Arg1, CONS_CDR), Arg2); } \f /* (PAIR OBJECT) [Primitive number 0x7E] Returns #!TRUE if OBJECT has the type-code LIST (ie if it was created by CONS). Return NIL otherwise. */ Built_In_Primitive(Prim_Pair, 1, "PAIR?") { Primitive_1_Arg(); Touch_In_Primitive(Arg1, Arg1); if (Type_Code(Arg1) == TC_LIST) return TRUTH; else return NIL; } /* (SYS_PAIR OBJECT) [Primitive number 0x85] Returns #!TRUE if the garbage collector type of OBJECT is PAIR. */ Built_In_Primitive(Prim_Sys_Pair, 1, "SYSTEM-PAIR?") { Primitive_1_Arg(); Touch_In_Primitive(Arg1, Arg1); if (GC_Type_List(Arg1)) return TRUTH; else return NIL; } \f /* (SYS_PAIR_CAR GC-PAIR) [Primitive number 0x86] Same as CAR, but for anything of GC type PAIR. */ Built_In_Primitive(Prim_Sys_Pair_Car, 1, "SYSTEM-PAIR-CAR") { Primitive_1_Arg(); Arg_1_GC_Type(GC_Pair); return Vector_Ref(Arg1, CONS_CAR); } /* (SYS_PAIR_CDR GC-PAIR) [Primitive number 0x87] Same as CDR, but for anything of GC type PAIR. */ Built_In_Primitive(Prim_Sys_Pair_Cdr, 1, "SYSTEM-PAIR-CDR") { Primitive_1_Arg(); Arg_1_GC_Type(GC_Pair); return Vector_Ref(Arg1, CONS_CDR); } /* (SYS_PAIR_CONS TYPE-CODE OBJECT-1 OBJECT-2) [Primitive number 0x84] Like CONS, but returns an object with the specified type code (not limited to type code LIST). */ Built_In_Primitive(Prim_Sys_Pair_Cons, 3, "SYSTEM-CONS") { long Type; Primitive_3_Args(); Arg_1_Type(TC_FIXNUM); Range_Check(Type, Arg1, 0, MAX_SAFE_TYPE, ERR_ARG_1_BAD_RANGE); if (GC_Type_Code(Type) == GC_Pair) { Primitive_GC_If_Needed(Free + 2); *Free++ = Arg2; *Free++ = Arg3; return Make_Pointer(Type, Free-2); } else Primitive_Error(ERR_ARG_1_BAD_RANGE); } \f /* (SYS_SET_CAR GC-PAIR NEW_CAR) [Primitive number 0x88] Same as SET_CAR, but for anything of GC type PAIR. */ Built_In_Primitive(Prim_Sys_Set_Car, 2, "SYSTEM-PAIR-SET-CAR!") { Primitive_2_Args(); Arg_1_GC_Type(GC_Pair); Side_Effect_Impurify(Arg1, Arg2); return Swap_Pointers(Nth_Vector_Loc(Arg1, CONS_CAR), Arg2); } /* (SYS_SET_CDR GC-PAIR NEW_CDR) [Primitive number 0x89] Same as SET_CDR, but for anything of GC type PAIR. */ Built_In_Primitive(Prim_Sys_Set_Cdr, 2, "SYSTEM-PAIR-SET-CDR!") { Primitive_2_Args(); Arg_1_GC_Type(GC_Pair); Side_Effect_Impurify(Arg1, Arg2); return Swap_Pointers(Nth_Vector_Loc(Arg1, CONS_CDR), Arg2); }