/src/tools/interpreter/liberty_interpreter_native_array_typed.e

http://github.com/tybor/Liberty · Specman e · 364 lines · 205 code · 23 blank · 136 comment · 11 complexity · 6c2e54e617304553572e052528bdc18a MD5 · raw file

  1. -- This file is part of Liberty Eiffel.
  2. --
  3. -- Liberty Eiffel is free software: you can redistribute it and/or modify
  4. -- it under the terms of the GNU General Public License as published by
  5. -- the Free Software Foundation, version 3 of the License.
  6. --
  7. -- Liberty Eiffel 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 General Public License for more details.
  11. --
  12. -- You should have received a copy of the GNU General Public License
  13. -- along with Liberty Eiffel. If not, see <http://www.gnu.org/licenses/>.
  14. --
  15. class LIBERTY_INTERPRETER_NATIVE_ARRAY_TYPED[E_]
  16. inherit
  17. LIBERTY_INTERPRETER_NATIVE_ARRAY
  18. creation {LIBERTY_INTERPRETER_NATIVE_ARRAY_CREATOR, LIBERTY_INTERPRETER_NATIVE_ARRAY_TYPED, LIBERTY_INTERPRETER}
  19. make, with_storage
  20. feature {ANY}
  21. copy (other: like Current) is
  22. do
  23. interpreter := other.interpreter
  24. accessor := other.accessor
  25. type := other.type
  26. item_type := other.item_type
  27. elements := other.elements
  28. end
  29. is_equal (other: LIBERTY_INTERPRETER_OBJECT): BOOLEAN is
  30. local
  31. o: like Current
  32. do
  33. if other.is_void then
  34. interpreter.fatal_error("Unexpected Void parameter", other.position)
  35. else
  36. o ::= other
  37. Result := elements = o.elements
  38. end
  39. end
  40. hash_code: INTEGER is
  41. do
  42. Result := elements.to_pointer.hash_code
  43. end
  44. item (index: INTEGER): LIBERTY_INTERPRETER_OBJECT is
  45. do
  46. Result := accessor.retrieve(elements.item(index))
  47. end
  48. put (o: LIBERTY_INTERPRETER_OBJECT; index: INTEGER) is
  49. do
  50. elements.put(accessor.store(o), index)
  51. end
  52. first: LIBERTY_INTERPRETER_OBJECT is
  53. do
  54. Result := accessor.retrieve(elements.first)
  55. end
  56. last: LIBERTY_INTERPRETER_OBJECT is
  57. do
  58. Result := accessor.retrieve(elements.last)
  59. end
  60. lower: INTEGER is
  61. do
  62. Result := elements.lower
  63. end
  64. upper: INTEGER is
  65. do
  66. Result := elements.upper
  67. end
  68. count: INTEGER is
  69. do
  70. Result := elements.count
  71. end
  72. is_empty: BOOLEAN is
  73. do
  74. Result := elements.is_empty
  75. end
  76. out_in_tagged_out_memory is
  77. local
  78. i: INTEGER
  79. do
  80. tagged_out_memory.extend('{')
  81. tagged_out_memory.append(type.full_name)
  82. tagged_out_memory.extend('[')
  83. from
  84. i := elements.lower
  85. until
  86. i > elements.upper
  87. loop
  88. if i > elements.lower then
  89. tagged_out_memory.append(once ", ")
  90. end
  91. elements.item(i).out_in_tagged_out_memory
  92. i := i + 1
  93. end
  94. tagged_out_memory.append(once "]}")
  95. end
  96. feature {LIBERTY_INTERPRETER_EXTERNAL_TYPE_ANY_BUILTINS} -- Standard builtings
  97. builtin_is_equal (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION): BOOLEAN is
  98. local
  99. i: INTEGER
  100. o: like Current
  101. do
  102. if type = other.type then
  103. o ::= other
  104. from
  105. Result := count = o.count
  106. i := lower
  107. until
  108. i > upper or else not Result
  109. loop
  110. Result := elements.item(i).is_equal(o.elements.item(i))
  111. i := i + 1
  112. end
  113. else
  114. interpreter.fatal_error("Type mismatch: expected " + type.full_name + ", but got " + other.type.full_name, a_position)
  115. end
  116. end
  117. builtin_standard_is_equal (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION): BOOLEAN is
  118. do
  119. Result := builtin_is_equal(other, a_position)
  120. end
  121. builtin_copy (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION) is
  122. local
  123. o: like Current
  124. do
  125. if type = other.type then
  126. o ::= other
  127. elements := o.elements
  128. else
  129. interpreter.fatal_error("Type mismatch: expected " + type.full_name + ", but got " + other.type.full_name, a_position)
  130. end
  131. end
  132. builtin_twin (a_position: LIBERTY_POSITION): like Current is
  133. do
  134. create Result.with_storage(interpreter, type, item_type, elements, elements.capacity, a_position)
  135. end
  136. builtin_standard_copy (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION) is
  137. do
  138. builtin_copy(other, a_position)
  139. end
  140. builtin_standard_twin (a_position: LIBERTY_POSITION): like Current is
  141. do
  142. create Result.with_storage(interpreter, type, item_type, elements, elements.capacity, a_position)
  143. end
  144. feature {LIBERTY_INTERPRETER_OBJECT}
  145. do_deep_twin (deep_twin_memory: DICTIONARY[LIBERTY_INTERPRETER_OBJECT, LIBERTY_INTERPRETER_OBJECT]; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  146. local
  147. i: INTEGER; elements_twin: like elements
  148. do
  149. Result := deep_twin_memory.reference_at(Current)
  150. if Result = Void then
  151. create elements_twin.make(elements.capacity)
  152. from
  153. i := elements.lower
  154. until
  155. i > elements.upper
  156. loop
  157. put(item(i).do_deep_twin(deep_twin_memory, a_position), i)
  158. i := i + 1
  159. end
  160. create {LIBERTY_INTERPRETER_NATIVE_ARRAY_TYPED[E_]} Result.with_storage(interpreter, type, item_type, elements_twin, elements.capacity, a_position)
  161. deep_twin_memory.put(Result, Current)
  162. end
  163. end
  164. do_deep_equal (object: LIBERTY_INTERPRETER_OBJECT; deep_equal_memory: SET[LIBERTY_INTERPRETER_OBJECT]; a_position: LIBERTY_POSITION): BOOLEAN is
  165. local
  166. i: INTEGER
  167. na: LIBERTY_INTERPRETER_NATIVE_ARRAY
  168. do
  169. if deep_equal_memory.fast_has(Current) then
  170. Result := True
  171. elseif object.type /= type then
  172. interpreter.fatal_error("Type mismatch: expected " + type.full_name + ", but got " + object.type.full_name, a_position)
  173. elseif na ?:= object then -- may be Void!
  174. na ::= object
  175. if na.item_type /= item_type then
  176. interpreter.fatal_error("Type mismatch: expected " + type.full_name + ", but got " + object.type.full_name, a_position)
  177. else
  178. Result := count = na.count
  179. from
  180. i := lower
  181. until
  182. not Result or else i > upper
  183. loop
  184. Result := item(i).do_deep_equal(na.item(i), deep_equal_memory, a_position)
  185. i := i + 1
  186. end
  187. end
  188. end
  189. deep_equal_memory.fast_add(Current)
  190. end
  191. feature {LIBERTY_INTERPRETER_OBJECT_PRINTER, LIBERTY_INTERPRETER_FEATURE_CALL}
  192. show_stack (o: OUTPUT_STREAM; indent: INTEGER) is
  193. local
  194. e: E_; i: INTEGER
  195. do
  196. o.put_character('{')
  197. o.put_string(type.full_name)
  198. o.put_character('<')
  199. o.put_character('<')
  200. o.put_new_line
  201. from
  202. i := lower
  203. until
  204. i > 16 or else i > upper
  205. loop
  206. e := elements.item(i)
  207. interpreter.object_printer.put_indent(o, indent + 1)
  208. interpreter.object_printer.print_object(o, accessor.retrieve(e), indent + 1)
  209. i := i + 1
  210. end
  211. if upper > 16 then
  212. interpreter.object_printer.put_indent(o, indent + 1)
  213. o.put_string(once "... (capacity=")
  214. o.put_integer(elements.capacity)
  215. o.put_character(')')
  216. o.put_new_line
  217. end
  218. interpreter.object_printer.put_indent(o, indent)
  219. o.put_character('>')
  220. o.put_character('>')
  221. o.put_character('}')
  222. o.put_new_line
  223. end
  224. feature {LIBERTY_INTERPRETER_EXTERNAL_TYPE_NATIVE_ARRAY_BUILTINS}
  225. builtin_element_sizeof: INTEGER is
  226. do
  227. not_yet_implemented
  228. end
  229. builtin_calloc (capacity: INTEGER; a_position: LIBERTY_POSITION): like Current is
  230. do
  231. create Result.make(interpreter, type, item_type, default_pointer, capacity, a_position)
  232. end
  233. builtin_slice_copy (at: INTEGER; src: like Current; src_min, src_max: INTEGER) is
  234. local
  235. i, j: INTEGER
  236. do
  237. from
  238. i := src_min
  239. j := at
  240. until
  241. i > src_max
  242. loop
  243. put(src.item(i), j)
  244. i := i + 1
  245. j := j + 1
  246. end
  247. end
  248. feature {}
  249. make (a_interpreter: like interpreter; a_type: like type; a_item_type: like item_type; a_storage: POINTER; a_capacity: INTEGER; a_position: like position) is
  250. require
  251. a_interpreter /= Void
  252. a_type /= Void
  253. a_item_type /= Void
  254. a_capacity >= 0
  255. a_position /= Void
  256. a_storage.is_not_null implies a_capacity > 0
  257. do
  258. interpreter := a_interpreter
  259. type := a_type
  260. item_type := a_item_type
  261. position := a_position
  262. if a_storage.is_null then
  263. create elements.make(a_capacity)
  264. else
  265. create elements.from_external(a_storage, a_capacity)
  266. end
  267. accessor ::= accessor_factory.accessor(a_interpreter, a_item_type, a_position)
  268. ensure
  269. interpreter = a_interpreter
  270. type = a_type
  271. item_type = a_item_type
  272. position = a_position
  273. end
  274. with_storage (a_interpreter: like interpreter; a_type: like type; a_item_type: like item_type; a_elements: TRAVERSABLE[E_]; a_capacity: INTEGER; a_position: like position) is
  275. require
  276. a_interpreter /= Void
  277. a_elements /= Void
  278. a_position /= Void
  279. a_capacity >= a_elements.count
  280. local
  281. i: INTEGER
  282. do
  283. interpreter := a_interpreter
  284. type := a_type
  285. item_type := a_item_type
  286. position := a_position
  287. create elements.make(a_capacity)
  288. from
  289. i := a_elements.lower
  290. until
  291. i > a_elements.upper
  292. loop
  293. elements.put(a_elements.item(i), i + elements.lower - a_elements.lower)
  294. i := i + 1
  295. end
  296. accessor ::= accessor_factory.accessor(a_interpreter, item_type, a_position)
  297. ensure
  298. interpreter = a_interpreter
  299. type = a_type
  300. item_type = a_item_type
  301. position = a_position
  302. end
  303. expanded_twin: like Current is
  304. do
  305. Result := twin
  306. end
  307. accessor_factory: LIBERTY_INTERPRETER_NATIVE_ARRAY_ACCESSOR_FACTORY is
  308. once
  309. create Result.make
  310. end
  311. feature {LIBERTY_INTERPRETER_NATIVE_ARRAY_TYPED}
  312. accessor: LIBERTY_INTERPRETER_NATIVE_ARRAY_ACCESSOR_TYPED[E_]
  313. feature {LIBERTY_INTERPRETER_NATIVE_ARRAY_TYPED, LIBERTY_INTERPRETER_OBJECT_PRINTER}
  314. elements: FAST_ARRAY[E_]
  315. feature {LIBERTY_INTERPRETER_TO_EXTERNAL}
  316. to_external: POINTER is
  317. do
  318. Result := elements.to_external
  319. end
  320. feature {LIBERTY_INTERPRETER_NATIVE_ARRAY_CREATOR}
  321. from_external (a_external: POINTER; a_capacity: INTEGER) is
  322. do
  323. elements.from_external(a_external, a_capacity)
  324. end
  325. invariant
  326. elements /= Void
  327. accessor /= Void
  328. end -- class LIBERTY_INTERPRETER_NATIVE_ARRAY_TYPED