SYMBOLIC PROCEDURE SIMPPART U;
BEGIN SCALAR EXPN;
EXPN := PREPSQ!* SIMP!* CAR U;
U := CDR U;
WHILE U DO
BEGIN SCALAR X,Y;
IF ATOM EXPN
THEN MSGPRI("Expression",EXPN,
"does not have part",CAR U,T)
ELSE IF NOT NUMBERP(X := REVAL CAR U)
THEN MSGPRI("Invalid argument",CAR U,"to part",NIL,T)
ELSE IF X=0
THEN RETURN <<EXPN := CAR EXPN; U := NIL>>
ELSE IF X<0 THEN <<X := -X; Y := REVERSE CDR EXPN>>
ELSE Y := CDR EXPN;
IF LENGTH Y<X
THEN MSGPRI("Expression",EXPN,
"does not have part",CAR U,T)
ELSE EXPN := NTH(Y,X);
U := CDR U
END;
RETURN SIMP EXPN
END;
PUT('PART,'SIMPFN,'SIMPPART);
SYMBOLIC PROCEDURE SIMPSETPART U;
%Simplifies a SETPART expression;
(LAMBDA X; SIMP SIMPSETP1(PREPSQ!* SIMP!* CAR U,REVERSE CDR X,CAR X))
REVERSE CDR U;
SYMBOLIC PROCEDURE SIMPSETP1(EXPN,PTLIST,REP);
IF NULL PTLIST THEN REP
ELSE IF ATOM EXPN
THEN MSGPRI("Expression",EXPN,
"does not have part",CAR PTLIST,T)
ELSE BEGIN SCALAR X;
IF NOT NUMBERP(X := REVAL CAR PTLIST)
THEN MSGPRI("Invalid argument",CAR PTLIST,"to part",NIL,T)
ELSE RETURN
IF X=0 THEN REP . CDR EXPN
ELSE IF X<0
THEN CAR EXPN .
REVERSE SSL(REVERSE CDR EXPN,
-X,CDR PTLIST,REP,EXPN . CAR PTLIST)
ELSE CAR EXPN . SSL(CDR EXPN,X,CDR PTLIST,
REP,EXPN . CAR PTLIST)
END;
SYMBOLIC PROCEDURE SSL(EXPN,INDX,PTLIST,REP,REST);
IF NULL EXPN
THEN MSGPRI("Expression",CAR REST,"does not have part",CDR REST)
ELSE IF INDX=1 THEN SIMPSETP1(CAR EXPN,PTLIST,REP) . CDR EXPN
ELSE CAR EXPN . SSL(CDR EXPN,INDX-1,PTLIST,REP,REST);
PUT('PART,'SETQFN,'SETPART!*);
PUT('SETPART!*,'SIMPFN,'SIMPSETPART);
SYMBOLIC PROCEDURE ARGLENGTH U;
BEGIN SCALAR X;
X := PREPSQ!* SIMP!* U;
RETURN IF ATOM X THEN -1 ELSE LENGTH CDR X
END;
FLAG('(ARGLENGTH),'OPFN);
END;