123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- %
- % SEQUENCE.RED - Useful functions on strings, vectors and lists
- %
- % Author: Martin Griss and Eric Benson
- % Symbolic Computation Group
- % Computer Science Dept.
- % University of Utah
- % Date: 10 September 1981
- % Copyright (c) 1981 University of Utah
- %
- % <PSL.KERNEL>SEQUENCE.RED.2, 25-Jan-83 16:11:28, Edit by PERDUE
- % Removed Make-String, leaving MkString.
- % STRINGS pkg defines Make-String (differently and Common LISP compatibly)
- % <PSL.INTERP>SEQUENCE.RED.2, 27-Feb-82 00:46:03, Edit by BENSON
- % Started adding more vector types
- % <PSL.INTERP>STRING-OPS.RED.11, 6-Jan-82 20:41:16, Edit by BENSON
- % Changed String and Vector into Nexprs
- on SysLisp;
- % Indexing operations
- syslsp procedure Indx(R1, R2); %. Element of sequence
- begin scalar Tmp1, Tmp2;
- if not PosIntP R2 then return IndexError(R2, 'Indx); % Subscript
- Tmp1 := Inf R1;
- Tmp2 := Tag R1;
- return case Tmp2 of
- Str, Bytes:
- if R2 > StrLen Tmp1 then
- RangeError(R1, R2, 'Indx)
- else StrByt(Tmp1, R2);
- Vect:
- if R2 > VecLen Tmp1 then
- RangeError(R1, R2, 'Indx)
- else VecItm(Tmp1, R2);
- Wrds:
- if R2 > WrdLen Tmp1 then
- RangeError(R1, R2, 'Indx)
- else WrdItm(Tmp1, R2);
- HalfWords:
- if R2 > HalfWordLen Tmp1 then
- RangeError(R1, R2, 'Indx)
- else HalfWordItm(Tmp1, R2);
- Pair:
- << Tmp2 := R2;
- while Tmp2 > 0 do
- << R1 := cdr R1;
- if atom R1 then RangeError(R1, R2, 'Indx);
- Tmp2 := Tmp2 - 1 >>;
- car R1 >>;
- default:
- NonSequenceError(R1, 'Indx);
- end;
- end;
- syslsp procedure SetIndx(R1, R2, R3); %. Store at index of sequence
- begin scalar Tmp1, Tmp2;
- if not PosIntP R2 then return IndexError(R2, 'SetIndx); % Subscript
- Tmp1 := Inf R1;
- Tmp2 := Tag R1;
- return case Tmp2 of
- Str, Bytes:
- if R2 > StrLen Tmp1 then
- RangeError(R1, R2, 'SetIndx)
- else
- << StrByt(Tmp1, R2) := R3;
- R3 >>;
- Vect:
- if R2 > VecLen Tmp1 then
- RangeError(R1, R2, 'SetIndx)
- else
- << VecItm(Tmp1, R2) := R3;
- R3 >>;
- Wrds:
- if R2 > WrdLen Tmp1 then
- RangeError(R1, R2, 'SetIndx)
- else
- << WrdItm(Tmp1, R2) := R3;
- R3 >>;
- HalfWords:
- if R2 > HalfWordLen Tmp1 then
- RangeError(R1, R2, 'SetIndx)
- else
- << HalfWordItm(Tmp1, R2) := R3;
- R3 >>;
- Pair:
- << Tmp2 := R2;
- while Tmp2 > 0 do
- << R1 := cdr R1;
- if atom R1 then RangeError(R1, R2, 'SetIndx);
- Tmp2 := Tmp2 - 1 >>;
- Rplaca(R1, R3);
- R3 >>;
- default:
- NonSequenceError(R1, 'SetIndx);
- end;
- end;
- % String and vector sub-part operations.
- syslsp procedure Sub(R1, R2, R3); %. Obsolete subsequence function
- SubSeq(R1, R2, R2 + R3 + 1);
- syslsp procedure SubSeq(R1, R2, R3); % R2 is lower bound, R3 upper
- begin scalar NewSize, OldSize, NewItem;
- if not PosIntP R2 then return IndexError(R2, 'SubSeq);
- if not PosIntP R3 then return IndexError(R3, 'SubSeq);
- NewSize := R3 - R2 - 1;
- if NewSize < -1 then return RangeError(R1, R3, 'SubSeq);
- return case Tag R1 of
- Str, Bytes:
- << OldSize := StrLen StrInf R1;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SubSeq)
- else
- << NewItem := GtSTR NewSize;
- R3 := StrInf R1;
- for I := 0 step 1 until NewSize do
- StrByt(NewItem, I) := StrByt(R3, R2 + I);
- case Tag R1 of
- Str:
- MkSTR NewItem;
- Bytes:
- MkBYTES NewItem;
- end >> >>;
- Vect:
- << OldSize := VecLen VecInf R1;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SubSeq)
- else
- << NewItem := GtVECT NewSize;
- R3 := VecInf R1;
- for I := 0 step 1 until NewSize do
- VecItm(NewItem, I) := VecItm(R3, R2 + I);
- MkVEC NewItem >> >>;
- Wrds:
- << OldSize := WrdLen WrdInf R1;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SubSeq)
- else
- << NewItem := GtWRDS NewSize;
- R3 := WrdInf R1;
- for I := 0 step 1 until NewSize do
- WrdItm(NewItem, I) := WrdItm(R3, R2 + I);
- MkWRDS NewItem >> >>;
- HalfWords:
- << OldSize := HalfWordLen HalfWordInf R1;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SubSeq)
- else
- << NewItem := GtHalfWords NewSize;
- R3 := HalfWordInf R1;
- for I := 0 step 1 until NewSize do
- HalfWordItm(NewItem, I) := HalfWordItm(R3, R2 + I);
- MkHalfWords NewItem >> >>;
- Pair:
- << for I := 1 step 1 until R2 do
- if PairP R1 then R1 := rest R1
- else RangeError(R1, R2, 'SubSeq);
- NewItem := NIL . NIL;
- for I := 0 step 1 until NewSize do
- if PairP R1 then
- << TConc(NewItem, first R1);
- R1 := rest R1 >>
- else RangeError(R1, R3, 'SubSeq);
- car NewItem >>;
- default:
- NonSequenceError(R1, 'SubSeq);
- end;
- end;
- syslsp procedure SetSub(R1, R2, R3, R4); %. Obsolete subsequence function
- SetSubSeq(R1, R2, R2 + R3 + 1, R4);
- syslsp procedure SetSubSeq(R1, R2, R3, R4); % R2 is lower bound, R3 upper
- begin scalar NewSize, OldSize, SubSize, NewItem;
- if not PosIntP R2 then return IndexError(R2, 'SetSubSeq);
- if not PosIntP R3 then return IndexError(R3, 'SetSubSeq);
- NewSize := R3 - R2 - 1;
- if NewSize < -1 then return RangeError(R1, R3, 'SetSubSeq);
- case Tag R1 of
- Str, Bytes:
- << if not StringP R4 and not BytesP R4 then return
- NonStringError(R4, 'SetSubSeq);
- OldSize := StrLen StrInf R1;
- NewItem := StrInf R4;
- SubSize := StrLen NewItem;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SetSubSeq)
- else if not (NewSize eq SubSize) then
- RangeError(R4, NewSize, 'SetSubSeq)
- else
- << R3 := StrInf R1;
- for I := 0 step 1 until NewSize do
- StrByt(R3, R2 + I) := StrByt(NewItem, I) >> >>;
- Vect:
- << if not VectorP R4 then return
- NonVectorError(R4, 'SetSubSeq);
- OldSize := VecLen VecInf R1;
- NewItem := VecInf R4;
- SubSize := VecLen NewItem;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SetSubSeq)
- else if not (NewSize eq SubSize) then
- RangeError(R4, NewSize, 'SetSubSeq)
- else
- << R3 := VecInf R1;
- for I := 0 step 1 until NewSize do
- VecItm(R3, R2 + I) := VecItm(NewItem, I) >> >>;
- Wrds:
- << if not WrdsP R4 then return
- NonVectorError(R4, 'SetSubSeq);
- OldSize := WrdLen WrdInf R1;
- NewItem := WrdInf R4;
- SubSize := WrdLen NewItem;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SetSubSeq)
- else if not (NewSize eq SubSize) then
- RangeError(R4, NewSize, 'SetSubSeq)
- else
- << R3 := WrdInf R1;
- for I := 0 step 1 until NewSize do
- WrdItm(R3, R2 + I) := WrdItm(NewItem, I) >> >>;
- HalfWords:
- << if not HalfWordsP R4 then return
- NonVectorError(R4, 'SetSubSeq);
- OldSize := HalfWordLen HalfWordInf R1;
- NewItem := HalfWordInf R4;
- SubSize := HalfWordLen NewItem;
- if R3 - 1 > OldSize then RangeError(R1, R3, 'SetSubSeq)
- else if not (NewSize eq SubSize) then
- RangeError(R4, NewSize, 'SetSubSeq)
- else
- << R3 := HalfWordInf R1;
- for I := 0 step 1 until NewSize do
- HalfWordItm(R3, R2 + I) := HalfWordItm(NewItem, I) >> >>;
- Pair:
- << if not PairP R4 and not null R4 then return
- NonPairError(R4, 'SetSubSeq);
- for I := 1 step 1 until R2 do
- if PairP R1 then R1 := rest R1
- else RangeError(R1, R2, 'SetSubSeq);
- NewItem := R4;
- for I := 0 step 1 until NewSize do
- if PairP R1 and PairP NewItem then
- << RPlaca(R1, first NewItem);
- R1 := rest R1;
- NewItem := rest NewItem >>
- else RangeError(R1, R3, 'SetSubSeq) >>;
- default:
- NonSequenceError(R1, 'SetSubSeq);
- end;
- return R4;
- end;
- syslsp procedure Concat(R1, R2); %. Concatenate 2 sequences
- begin scalar I1, I2, Tmp1, Tmp2, Tmp3;
- return case Tag R1 of
- STR, BYTES:
- << if not (StringP R2 or BytesP R2) then return
- NonStringError(R2, 'Concat);
- Tmp1 := StrInf R1;
- Tmp2 := StrInf R2;
- I1 := StrLen Tmp1;
- I2 := StrLen Tmp2;
- Tmp3 := GtSTR(I1 + I2 + 1); % R1 and R2 can move
- Tmp1 := StrInf R1;
- Tmp2 := StrInf R2;
- for I := 0 step 1 until I1 do
- StrByt(Tmp3, I) := StrByt(Tmp1, I);
- for I := 0 step 1 until I2 do
- StrByt(Tmp3, I1 + I + 1) := StrByt(Tmp2, I);
- if StringP R1 then MkSTR Tmp3 else MkBYTES Tmp3 >>;
- VECT:
- << if not VectorP R2 then return
- NonVectorError(R2, 'Concat);
- Tmp1 := VecInf R1;
- Tmp2 := VecInf R2;
- I1 := VecLen Tmp1;
- I2 := VecLen Tmp2;
- Tmp3 := GtVECT(I1 + I2 + 1); % R1 and R2 can move
- Tmp1 := VecInf R1;
- Tmp2 := VecInf R2;
- for I := 0 step 1 until I1 do
- VecItm(Tmp3, I) := VecItm(Tmp1, I);
- for I := 0 step 1 until I2 do
- VecItm(Tmp3, I1 + I + 1) := VecItm(Tmp2, I);
- MkVEC Tmp3 >>;
- WRDS:
- << if not WrdsP R2 then return
- NonVectorError(R2, 'Concat);
- Tmp1 := WrdInf R1;
- Tmp2 := WrdInf R2;
- I1 := WrdLen Tmp1;
- I2 := WrdLen Tmp2;
- Tmp3 := GtWrds(I1 + I2 + 1); % R1 and R2 can move
- Tmp1 := WrdInf R1;
- Tmp2 := WrdInf R2;
- for I := 0 step 1 until I1 do
- WrdItm(Tmp3, I) := WrdItm(Tmp1, I);
- for I := 0 step 1 until I2 do
- WrdItm(Tmp3, I1 + I + 1) := WrdItm(Tmp2, I);
- MkWRDS Tmp3 >>;
- HALFWORDS:
- << if not HalfWordsP R2 then return
- NonVectorError(R2, 'Concat);
- Tmp1 := HalfWordInf R1;
- Tmp2 := HalfWordInf R2;
- I1 := HalfWordLen Tmp1;
- I2 := HalfWordLen Tmp2;
- Tmp3 := GtHalfWords(I1 + I2 + 1); % R1 and R2 can move
- Tmp1 := HalfWordInf R1;
- Tmp2 := HalfWordInf R2;
- for I := 0 step 1 until I1 do
- HalfWordItm(Tmp3, I) := HalfWordItm(Tmp1, I);
- for I := 0 step 1 until I2 do
- HalfWordItm(Tmp3, I1 + I + 1) := HalfWordItm(Tmp2, I);
- MkHalfWords Tmp3 >>;
- PAIR, ID:
- if null R1 or PairP R1 then Append(R1, R2);
- default:
- NonSequenceError(R1, 'Concat);
- end;
- end;
- syslsp procedure Size S; %. Upper bound of sequence
- case Tag S of
- STR, BYTES, WRDS, VECT, HALFWORDS:
- GetLen Inf S;
- ID:
- -1;
- PAIR:
- begin scalar I;
- I := -1;
- while PairP S do
- << I := I + 1;
- S := cdr S >>;
- return I;
- end;
- default:
- NonSequenceError(S, 'Size);
- end;
- syslsp procedure MkString(L, C); %. Make str with upb L, all chars C
- begin scalar L1, S;
- if IntP L then L1 := IntInf L else return NonIntegerError(L, 'MkString);
- if L1 < -1 then return NonPositiveIntegerError(L, 'MkString);
- S := GtStr L1;
- for I := 0 step 1 until L1 do
- StrByt(S, I) := C;
- return MkSTR S;
- end;
- syslsp procedure Make!-Bytes(L, C); %. Make byte vector with upb L, all items C
- begin scalar L1, S;
- if IntP L then L1 := IntInf L else return NonIntegerError(L, 'Make!-Bytes);
- if L1 < -1 then return NonPositiveIntegerError(L, 'Make!-Bytes);
- S := GtStr L1;
- for I := 0 step 1 until L1 do
- StrByt(S, I) := C;
- return MkBytes S;
- end;
- syslsp procedure Make!-HalfWords(L, C); %. Make h vect with upb L, all items C
- begin scalar L1, S;
- if IntP L then L1 := IntInf L else
- return NonIntegerError(L, 'Make!-HalfWords);
- if L1 < -1 then return NonPositiveIntegerError(L, 'Make!-HalfWords);
- S := GtHalfWords L1;
- for I := 0 step 1 until L1 do
- HalfWordItm(S, I) := C;
- return MkHalfWords S;
- end;
- syslsp procedure Make!-Words(L, C); %. Make w vect with upb L, all items C
- begin scalar L1, S;
- if IntP L then L1 := IntInf L else return NonIntegerError(L, 'Make!-Words);
- if L1 < -1 then return NonPositiveIntegerError(L, 'Make!-Words);
- S := GtWrds L1;
- for I := 0 step 1 until L1 do
- WrdItm(S, I) := C;
- return MkWrds S;
- end;
- syslsp procedure Make!-Vector(L, C); %. Make vect with upb L, all items C
- begin scalar L1, S;
- if IntP L then L1 := IntInf L else return
- NonIntegerError(L, 'Make!-Vector);
- if L1 < -1 then return NonPositiveIntegerError(L, 'Make!-Vector);
- S := GtVECT L1;
- for I := 0 step 1 until L1 do
- VecItm(S, I) := C;
- return MkVEC S;
- end;
- off SysLisp;
- % Maybe we want to support efficient compilation of these, as with LIST,
- % by functions String2, String3, Vector2, Vector3, etc.
- nexpr procedure String U; %. Analogous to LIST, string constructor
- List2String U;
- nexpr procedure Vector U; %. Analogous to LIST, vector constructor
- List2Vector U;
- END;
|