Vector.ob07 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. (*
  2. Copyright 2016 Anton Krotov
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. *)
  14. MODULE Vector;
  15. IMPORT sys := SYSTEM, K := KOSAPI;
  16. TYPE
  17. DESC_VECTOR = RECORD
  18. data : INTEGER;
  19. count : INTEGER;
  20. size : INTEGER
  21. END;
  22. VECTOR* = POINTER TO DESC_VECTOR;
  23. ANYREC* = RECORD END;
  24. ANYPTR* = POINTER TO ANYREC;
  25. DESTRUCTOR* = PROCEDURE (VAR ptr: ANYPTR);
  26. PROCEDURE count* (vector: VECTOR): INTEGER;
  27. BEGIN
  28. ASSERT(vector # NIL)
  29. RETURN vector.count
  30. END count;
  31. PROCEDURE push* (vector: VECTOR; value: ANYPTR);
  32. BEGIN
  33. ASSERT(vector # NIL);
  34. IF vector.count = vector.size THEN
  35. vector.data := K.realloc(vector.data, (vector.size + 1024) * 4);
  36. ASSERT(vector.data # 0);
  37. vector.size := vector.size + 1024
  38. END;
  39. sys.PUT(vector.data + vector.count * 4, value);
  40. INC(vector.count)
  41. END push;
  42. PROCEDURE get* (vector: VECTOR; idx: INTEGER): ANYPTR;
  43. VAR res: ANYPTR;
  44. BEGIN
  45. ASSERT(vector # NIL);
  46. ASSERT( (0 <= idx) & (idx < vector.count) );
  47. sys.GET(vector.data + idx * 4, res)
  48. RETURN res
  49. END get;
  50. PROCEDURE put* (vector: VECTOR; idx: INTEGER; value: ANYPTR);
  51. BEGIN
  52. ASSERT(vector # NIL);
  53. ASSERT( (0 <= idx) & (idx < vector.count) );
  54. sys.PUT(vector.data + idx * 4, value)
  55. END put;
  56. PROCEDURE create* (size: INTEGER): VECTOR;
  57. VAR vector: VECTOR;
  58. BEGIN
  59. NEW(vector);
  60. IF vector # NIL THEN
  61. vector.data := K.malloc(4 * size);
  62. IF vector.data # 0 THEN
  63. vector.size := size;
  64. vector.count := 0
  65. ELSE
  66. DISPOSE(vector)
  67. END
  68. END
  69. RETURN vector
  70. END create;
  71. PROCEDURE def_destructor (VAR any: ANYPTR);
  72. BEGIN
  73. DISPOSE(any)
  74. END def_destructor;
  75. PROCEDURE destroy* (VAR vector: VECTOR; destructor: DESTRUCTOR);
  76. VAR i: INTEGER;
  77. any: ANYPTR;
  78. BEGIN
  79. ASSERT(vector # NIL);
  80. IF destructor = NIL THEN
  81. destructor := def_destructor
  82. END;
  83. FOR i := 0 TO vector.count - 1 DO
  84. any := get(vector, i);
  85. destructor(any)
  86. END;
  87. vector.data := K.free(vector.data);
  88. DISPOSE(vector)
  89. END destroy;
  90. END Vector.