array.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /* Declarations for the array type.
  2. This file is part of khipu.
  3. khipu 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 <https://www.gnu.org/licenses/>. */
  13. #ifndef __KP_ARRAY__
  14. #define __KP_ARRAY__ 1
  15. #include "interp.hpp"
  16. #include "initop.hpp"
  17. KP_DECLS_BEGIN
  18. struct alignas (object) array : public varobj
  19. {
  20. static const uint32_t nonref_flag = 1u << 15;
  21. static const int code = typecode::ARRAY;
  22. uint32_t len;
  23. object *data;
  24. static array* alloc_raw (uint32_t nelems);
  25. // Needed by the raw_acc interface.
  26. uint32_t& len_ref ()
  27. {
  28. return (this->len);
  29. }
  30. object* data_ptr ()
  31. {
  32. return (this->data);
  33. }
  34. void local_init (object *data = nullptr, uint32_t len = 0)
  35. {
  36. this->data = data;
  37. this->len = len;
  38. }
  39. struct iterator
  40. {
  41. valref value;
  42. object *curr;
  43. object *last;
  44. inline iterator (interpreter *interp, object ax, uint32_t i = 0);
  45. iterator (interpreter *interp, const iterator& right) :
  46. value (interp, *right.value), curr (right.curr), last (right.curr)
  47. {
  48. }
  49. bool valid () const
  50. {
  51. return (this->curr < this->last);
  52. }
  53. object operator* () const
  54. {
  55. return (*this->value);
  56. }
  57. iterator& operator++ ()
  58. {
  59. ++this->curr;
  60. if (this->valid ())
  61. *this->value = *this->curr;
  62. return (*this);
  63. }
  64. iterator operator++ (int)
  65. {
  66. iterator ret { interpreter::self (), *this };
  67. ++*this;
  68. return (ret);
  69. }
  70. };
  71. };
  72. inline array* as_array (object obj)
  73. {
  74. return ((array *)unmask (obj));
  75. }
  76. #ifdef KP_ARCH_WIDE
  77. inline constexpr bool array_p (object obj)
  78. {
  79. return (itype (obj) == typecode::ARRAY);
  80. }
  81. #else
  82. inline bool array_p (object obj)
  83. {
  84. return (varobj_p (obj) && as_varobj(obj)->vo_type == typecode::ARRAY);
  85. }
  86. #endif
  87. template <typename T>
  88. inline object& xaref (object obj, T idx)
  89. {
  90. return (as_array(obj)->data[idx]);
  91. }
  92. inline uint32_t
  93. len_a (object obj)
  94. {
  95. return (as_array(obj)->len);
  96. }
  97. array::iterator::iterator (interpreter *interp, object ax, uint32_t i) :
  98. value (interp, UNBOUND), curr (&xaref(ax, i)), last (&xaref(ax, len_a (ax)))
  99. {
  100. if (len_a (ax))
  101. *this->value = *this->curr;
  102. }
  103. // Allocate an array of length NELEM, filling it with FILL.
  104. KP_EXPORT result<object> alloc_array (interpreter *interp, uint32_t nelem,
  105. object fill = UNBOUND);
  106. // Add 2 arrays.
  107. KP_EXPORT result<object> add_aa (interpreter *interp, object a1, object a2);
  108. // Concatenate ARGC arrays from ARGV.
  109. KP_EXPORT result<object> concat_a (interpreter *interp,
  110. object *argv, int argc);
  111. // Multiply an array by an integer.
  112. KP_EXPORT result<object> mul_ia (interpreter *interp,
  113. object ival, object array);
  114. // Index an array.
  115. KP_EXPORT result<object> get_a (interpreter *interp,
  116. object array, object idx, object dfl);
  117. // Destructively set an object inside an array.
  118. KP_EXPORT result<object> nput_a (interpreter *interp,
  119. object array, object idx, object val);
  120. // Compute the hashcode of an array.
  121. KP_EXPORT result<uint32_t> hash_a (interpreter *interp, object obj);
  122. // Get the subsequence of an array.
  123. KP_EXPORT result<object> subseq_a (interpreter *interp,
  124. object array, object i1, object i2);
  125. // Copy an array.
  126. KP_EXPORT result<object> copy_a (interpreter *interp, object obj, bool deep);
  127. // Reverse an array.
  128. KP_EXPORT result<object> reverse_a (interpreter *interp, object obj);
  129. // Destructively reverse an array.
  130. KP_EXPORT result<object> nreverse_a (interpreter *interp, object obj);
  131. // Destructively sort an array.
  132. KP_EXPORT result<object> nsort_a (interpreter *interp,
  133. object obj, comparator& c);
  134. // Test for array equality.
  135. KP_EXPORT result<bool> eq_aa (interpreter *interp, object a1, object a2);
  136. // Compare 2 arrays.
  137. KP_EXPORT result<int> cmp_aa (interpreter *interp, object a1, object a2);
  138. // Iterator interface for an array.
  139. KP_EXPORT result<object> iter_a (interpreter *interp,
  140. object obj, object token, bool adv);
  141. // Mutate an object inside the array
  142. KP_EXPORT result<object> nzap_a (interpreter *interp, object obj, object key,
  143. uint32_t flags, object fn,
  144. object *argv, int argc);
  145. // Return the last element of an array.
  146. KP_EXPORT result<object> last_a (interpreter *interp, object obj);
  147. // Find an element in an array.
  148. KP_EXPORT result<object> find_a (interpreter *interp, object obj,
  149. object key, object start,
  150. object end, object test);
  151. // Write an array to a stream.
  152. KP_EXPORT result<int64_t> write_a (interpreter *interp,
  153. stream *strm, object obj, io_info& info);
  154. // Serialize an array in a stream.
  155. KP_EXPORT result<int64_t> pack_a (interpreter *interp,
  156. stream *strm, object obj, pack_info& info);
  157. // Deserialize an array from a stream.
  158. KP_EXPORT result<object> unpack_a (interpreter *interp,
  159. stream *strm, pack_info& info, bool save);
  160. // Init OP for arrays.
  161. KP_EXPORT init_op init_array;
  162. KP_DECLS_END
  163. #endif