part.red 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. SYMBOLIC PROCEDURE SIMPPART U;
  2. BEGIN SCALAR EXPN;
  3. EXPN := PREPSQ!* SIMP!* CAR U;
  4. U := CDR U;
  5. WHILE U DO
  6. BEGIN SCALAR X,Y;
  7. IF ATOM EXPN
  8. THEN MSGPRI("Expression",EXPN,
  9. "does not have part",CAR U,T)
  10. ELSE IF NOT NUMBERP(X := REVAL CAR U)
  11. THEN MSGPRI("Invalid argument",CAR U,"to part",NIL,T)
  12. ELSE IF X=0
  13. THEN RETURN <<EXPN := CAR EXPN; U := NIL>>
  14. ELSE IF X<0 THEN <<X := -X; Y := REVERSE CDR EXPN>>
  15. ELSE Y := CDR EXPN;
  16. IF LENGTH Y<X
  17. THEN MSGPRI("Expression",EXPN,
  18. "does not have part",CAR U,T)
  19. ELSE EXPN := NTH(Y,X);
  20. U := CDR U
  21. END;
  22. RETURN SIMP EXPN
  23. END;
  24. PUT('PART,'SIMPFN,'SIMPPART);
  25. SYMBOLIC PROCEDURE SIMPSETPART U;
  26. %Simplifies a SETPART expression;
  27. (LAMBDA X; SIMP SIMPSETP1(PREPSQ!* SIMP!* CAR U,REVERSE CDR X,CAR X))
  28. REVERSE CDR U;
  29. SYMBOLIC PROCEDURE SIMPSETP1(EXPN,PTLIST,REP);
  30. IF NULL PTLIST THEN REP
  31. ELSE IF ATOM EXPN
  32. THEN MSGPRI("Expression",EXPN,
  33. "does not have part",CAR PTLIST,T)
  34. ELSE BEGIN SCALAR X;
  35. IF NOT NUMBERP(X := REVAL CAR PTLIST)
  36. THEN MSGPRI("Invalid argument",CAR PTLIST,"to part",NIL,T)
  37. ELSE RETURN
  38. IF X=0 THEN REP . CDR EXPN
  39. ELSE IF X<0
  40. THEN CAR EXPN .
  41. REVERSE SSL(REVERSE CDR EXPN,
  42. -X,CDR PTLIST,REP,EXPN . CAR PTLIST)
  43. ELSE CAR EXPN . SSL(CDR EXPN,X,CDR PTLIST,
  44. REP,EXPN . CAR PTLIST)
  45. END;
  46. SYMBOLIC PROCEDURE SSL(EXPN,INDX,PTLIST,REP,REST);
  47. IF NULL EXPN
  48. THEN MSGPRI("Expression",CAR REST,"does not have part",CDR REST)
  49. ELSE IF INDX=1 THEN SIMPSETP1(CAR EXPN,PTLIST,REP) . CDR EXPN
  50. ELSE CAR EXPN . SSL(CDR EXPN,INDX-1,PTLIST,REP,REST);
  51. PUT('PART,'SETQFN,'SETPART!*);
  52. PUT('SETPART!*,'SIMPFN,'SIMPSETPART);
  53. SYMBOLIC PROCEDURE ARGLENGTH U;
  54. BEGIN SCALAR X;
  55. X := PREPSQ!* SIMP!* U;
  56. RETURN IF ATOM X THEN -1 ELSE LENGTH CDR X
  57. END;
  58. FLAG('(ARGLENGTH),'OPFN);
  59. END;