array.red 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. module array; % Array statement.
  2. % Author: Anthony C. Hearn.
  3. % Modifications by: Nancy Kirkwood.
  4. % These definitions are very careful about bounds checking. Appropriate
  5. % optimizations in a given system might really speed things up.
  6. fluid '(!*rlisp88);
  7. global '(erfg!*);
  8. symbolic procedure getel u;
  9. % Returns the value of the array element U.
  10. (if length n neq length cdr u
  11. then rerror(rlisp,21,"Incorrect array reference")
  12. else getel1(cadr get(car u,'avalue),cdr u,n))
  13. where n=get(car u,'dimension);
  14. symbolic procedure getel1(u,v,dims);
  15. if null v then u
  16. else if not fixp car v then typerr(car v,"array index")
  17. else if car v geq car dims or car v < 0
  18. then rerror(rlisp,21,"Array out of bounds")
  19. else getel1(getv(u,car v),cdr v,cdr dims);
  20. symbolic procedure setel(u,v);
  21. % Sets array element U to V and returns V.
  22. (if length n neq length cdr u
  23. then rerror(rlisp,22,"Incorrect array reference")
  24. else setel1(cadr get(car u,'avalue),cdr u,v,n))
  25. where n=get(car u,'dimension);
  26. symbolic procedure setel1(u,v,w,dims);
  27. if not fixp car v then typerr(car v,"array index")
  28. else if car v geq car dims or car v < 0
  29. then rerror(rlisp,23,"Array out of bounds")
  30. else if null cdr v then putv(u,car v,w)
  31. else setel1(getv(u,car v),cdr v,w,cdr dims);
  32. symbolic procedure dimension u; get(u,'dimension);
  33. comment further support for REDUCE arrays;
  34. symbolic procedure typechk(u,v);
  35. begin scalar x;
  36. if (x := gettype u) eq v or x eq 'parameter
  37. then lprim list(v,u,"redefined")
  38. else if x then typerr(list(x,u),v)
  39. end;
  40. symbolic procedure arrayfn(u,v);
  41. % U is the defining mode, V a list of lists, assumed syntactically
  42. % correct. ARRAYFN declares each element as an array unless a
  43. % semantic mismatch occurs.
  44. begin scalar y;
  45. for each x in v do
  46. <<typechk(car x,'array);
  47. y := add1lis for each z in cdr x collect lispeval z;
  48. if null erfg!*
  49. then <<put(car x,'rtype,'array);
  50. put(car x,'avalue,list('array,mkarray1(y,u)));
  51. put(car x,'dimension,y)>>>>
  52. end;
  53. flag('(arrayfn),'nochange);
  54. symbolic procedure add1lis u;
  55. if null u then nil else (car u+1) . add1lis cdr u;
  56. symbolic macro procedure mkarray u;
  57. if null !*rlisp88 then mkarray1(u,'algebraic) else
  58. list('mkar1,'list . cdr u);
  59. symbolic procedure mkarray1(u,v);
  60. % U is a list of positive integers representing array bounds, V
  61. % the defining mode. Value is an array structure.
  62. if null u then if v eq 'symbolic then nil else 0
  63. else begin integer n; scalar x;
  64. n := car u - 1;
  65. x := mkvect n;
  66. for i:=0:n do putv(x,i,mkarray1(cdr u,v));
  67. return x
  68. end;
  69. put('array,'stat,'rlis);
  70. flag ('(array arrayfn),'eval);
  71. symbolic procedure formarray(u,vars,mode);
  72. begin scalar x;
  73. x := cdr u;
  74. while x do <<if atom x then typerr(x,"Array List")
  75. else if atom car x or not idp caar x
  76. or not listp cdar x
  77. then typerr(car x,"Array declaration");
  78. x := cdr x>>;
  79. u := for each z in cdr u collect intargfn(z,vars,mode);
  80. %ARRAY arguments must be returned as quoted structures;
  81. return list('arrayfn,mkquote mode,'list . u)
  82. end;
  83. put('array,'formfn,'formarray);
  84. put('array,'rtypefn,'arraychk);
  85. symbolic procedure arraychk u;
  86. % If arraychk receives NIL, it means that array name is being used
  87. % as an identifier. We no longer permit this.
  88. if null u then 'array else nil;
  89. % nil;
  90. put('array,'evfn,'arrayeval);
  91. symbolic procedure arrayeval(u,v);
  92. % Eventually we'll support this properly.
  93. if not atom u then rerror(rlisp,24,"Array arithmetic not defined")
  94. else u;
  95. put('array,'lengthfn,'arraylength);
  96. symbolic procedure arraylength u; 'list . get(u,'dimension);
  97. endmodule;
  98. end;