123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- %
- % OBLIST.RED - Intern, RemOb and friends
- %
- % Author: Eric Benson
- % Symbolic Computation Group
- % Computer Science Dept.
- % University of Utah
- % Date: 27 August 1981
- % Copyright (c) 1981 University of Utah
- %
- % <PSL.INTERP>OBLIST.RED.9, 15-Sep-82 09:35:25, Edit by BENSON
- % InternP accepts a string as well as a symbol
- % CopyString and CopyStringToFrom are found in COPIERS.RED
- CompileTime flag('(AddToObList LookupOrAddToObList InObList
- InitNewID GenSym1),
- 'InternalFunction);
- on SysLisp;
- internal WConst DeletedSlotValue = -1,
- EmptySlotValue = 0;
- CompileTime <<
- syslsp smacro procedure DeletedSlot U;
- ObArray U eq DeletedSlotValue;
- syslsp smacro procedure EmptySlot U;
- ObArray U eq EmptySlotValue;
- syslsp smacro procedure NextSlot H;
- if H eq MaxObArray then 0 else H + 1;
- % StringEqual found in EQUAL.RED
- syslsp smacro procedure EqualObArrayEntry(ObArrayIndex, S);
- StringEqual(SymNam ObArray ObArrayIndex, S);
- >>;
- syslsp procedure AddToObList U;
- %
- % U is an ID, which is added to the oblist if an ID with the same
- % print name is not already there. The interned ID is returned.
- %
- begin scalar V, W, X, Y;
- W := IDInf U;
- U := StrInf SymNam W;
- Y := StrLen U;
- if Y < 0 then return StdError '"The null string cannot be interned";
- if Y eq 0 then return MkID StrByt(U, 0);
- return if OccupiedSlot(V := InObList U) then MkID ObArray V
- else
- << ObArray V := W;
- X := GtConstSTR Y;
- CopyStringToFrom(X, U);
- SymNam W := MkSTR X;
- MkID W >>;
- end;
- syslsp procedure LookupOrAddToObList U;
- %
- % U is a String, which IS copied if it is not found on the ObList
- % The interned ID with U as print name is returned
- %
- begin scalar V, W, X, Y;
- U := StrInf U;
- Y := StrLen U;
- if Y < 0 then return StdError '"The null string cannot be interned";
- if Y eq 0 then return MkID StrByt(U, 0);
- return if OccupiedSlot(V := InObList U) then MkID ObArray V
- else
- << W := GtID(); % allocate a new ID
- ObArray V := W; % plant it in the Oblist
- X := GtConstSTR Y; % allocate a string from uncollected
- CopyStringToFrom(X, StrInf U); % space
- InitNewID(W, MkSTR X) >>;
- end;
- syslsp procedure NewID S; %. Allocate un-interned ID with print name S
- InitNewID(GtID(), S); % Doesn't copy S
- syslsp procedure InitNewID(U, V); % Initialize cells of an ID to defaults
- << SymNam U := V;
- U := MkID U;
- MakeUnBound U;
- SetProp(U, NIL);
- MakeFUnBound U;
- U >>;
- syslsp procedure HashFunction S; % Compute hash function of string
- begin scalar Len, HashVal; % Fold together a bunch of bits
- S := StrInf S;
- HashVal := 0; % from the first BitsPerWord - 8
- Len := StrLen S; % chars of the string
- if Len > BitsPerWord - 8 then Len := BitsPerWord - 8;
- for I := 0 step 1 until Len do
- HashVal := LXOR(HashVal, LSH(StrByt(S, I), (BitsPerWord - 8) - I));
- return MOD(HashVal, MaxObArray);
- end;
- syslsp procedure InObList U; % U is a string. Returns an ObArray pointer
- begin scalar H, DSlot, WalkObArray;
- H := HashFunction U;
- WalkObArray := H;
- DSlot := -1;
- Loop:
- if EmptySlot WalkObArray then return
- if DSlot neq -1 then
- DSlot
- else
- WalkObArray
- else if DeletedSlot WalkObArray and DSlot eq -1 then
- DSlot := WalkObArray
- else if EqualObArrayEntry(WalkObArray, U) then return
- WalkObArray;
- WalkObArray := NextSlot WalkObArray;
- if WalkObArray eq H then FatalError "Oblist overflow";
- goto Loop;
- end;
- syslsp procedure Intern U; %. Add U to ObList
- %
- % U is a string or uninterned ID
- %
- if IDP U then
- AddToObList U
- else if StringP U then
- LookupOrAddToObList U
- else
- TypeError(U, 'Intern, '"ID or string");
- syslsp procedure RemOb U; %. REMove id from OBlist
- begin scalar V;
- if not IDP U then return
- NonIDError(U, 'RemOb);
- V := IDInf U;
- if V < 128 then return
- TypeError(U, 'RemOb, '"non-char");
- V := SymNam V;
- return
- << if OccupiedSlot(V := InObList V) then
- ObArray V := DeletedSlotValue;
- U >>
- end;
- % Changed to allow a string as well as a symbol, EB, 15 September 1982
- syslsp procedure InternP U; %. Is U an interned ID?
- if IDP U then
- << U := IDInf U;
- U < 128 or U eq ObArray InObList SymNam U >>
- else if StringP U then
- StrLen StrInf U eq 0 or OccupiedSlot InObList U
- else NIL;
- internal WString GenSymPName = "G0000";
- syslsp procedure GenSym(); %. GENerate unique, uninterned SYMbol
- << GenSym1 4;
- NewID CopyString GenSymPName >>;
- syslsp procedure GenSym1 N; % Auxiliary function for GenSym
- begin scalar Ch;
- return if N > 0 then
- if (Ch := StrByt(GenSymPName, N)) < char !9 then
- StrByt(GenSymPName, N) := Ch + 1
- else
- << StrByt(GenSymPName, N) := char !0;
- GenSym1(N - 1) >>
- else % start over
- << StrByt(GenSymPName, 0) := StrByt(GenSymPName, 0) + 1;
- GenSym1 4 >>;
- end;
- syslsp procedure InternGenSym(); %. GENerate unique, interned SYMbol
- << GenSym1 4;
- Intern MkSTR GenSymPName >>;
- syslsp procedure MapObl F; %. Apply F to every interned ID
- << for I := 0 step 1 until 127 do Apply(F, list MkID I);
- for I := 0 step 1 until MaxObArray do
- if OccupiedSlot I then Apply(F, list MkID ObArray I) >>;
- % These functions provide support for multiple oblists
- % Cf PACKAGE.RED for their use
- internal WVar LastObArrayPtr;
- syslsp procedure GlobalLookup S; % Lookup string S in global oblist
- if not StringP S then NonStringError(S, 'GlobalLookup)
- else if OccupiedSlot(LastObArrayPtr := InObList S) then
- MkID ObArray LastObArrayPtr
- else '0;
- syslsp procedure GlobalInstall S; % Add new ID with PName S to oblist
- begin scalar Ind, PN;
- Ind := GlobalLookup S;
- return if Ind neq '0 then Ind
- else
- << Ind := GtID();
- ObArray LastObArrayPtr := Ind;
- PN := GtConstSTR StrLen StrInf S; % allocate a string from uncollected
- CopyStringToFrom(PN, StrInf S); % space
- InitNewID(Ind, MkSTR PN) >>;
- end;
- syslsp procedure GlobalRemove S; % Remove ID with PName S from oblist
- begin scalar Ind;
- Ind := GlobalLookup S;
- return if Ind eq '0 then '0
- else
- << Ind := ObArray LastObArrayPtr;
- ObArray LastObArrayPtr := DeletedSlotValue;
- MkID Ind >>;
- end;
- syslsp procedure InitObList();
- begin scalar Tmp;
- if_system(MC68000, << % 68000 systems don't clear memory statically
- for I := 0 step 1 until MaxObArray do
- ObArray I := EmptySlotValue >>);
- Tmp := NextSymbol - 1;
- for I := 128 step 1 until Tmp do
- ObArray InObList SymNam I := I;
- end;
- off SysLisp;
- StartupTime InitObList();
- END;
|