unif.c 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957
  1. /* Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
  2. * 2006, 2011, 2012 Free Software Foundation, Inc.
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. /*
  19. This file has code for arrays in lots of variants (double, integer,
  20. unsigned etc. ). It suffers from hugely repetitive code because
  21. there is similar (but different) code for every variant included. (urg.)
  22. --hwn
  23. */
  24. #ifdef HAVE_CONFIG_H
  25. # include <config.h>
  26. #endif
  27. #include <stdio.h>
  28. #include <errno.h>
  29. #include <string.h>
  30. #include "libguile/_scm.h"
  31. #include "libguile/__scm.h"
  32. #include "libguile/eq.h"
  33. #include "libguile/chars.h"
  34. #include "libguile/eval.h"
  35. #include "libguile/fports.h"
  36. #include "libguile/smob.h"
  37. #include "libguile/feature.h"
  38. #include "libguile/root.h"
  39. #include "libguile/strings.h"
  40. #include "libguile/srfi-13.h"
  41. #include "libguile/srfi-4.h"
  42. #include "libguile/vectors.h"
  43. #include "libguile/list.h"
  44. #include "libguile/deprecation.h"
  45. #include "libguile/dynwind.h"
  46. #include "libguile/validate.h"
  47. #include "libguile/unif.h"
  48. #include "libguile/ramap.h"
  49. #include "libguile/print.h"
  50. #include "libguile/read.h"
  51. #ifdef HAVE_UNISTD_H
  52. #include <unistd.h>
  53. #endif
  54. #ifdef HAVE_IO_H
  55. #include <io.h>
  56. #endif
  57. /* The set of uniform scm_vector types is:
  58. * Vector of: Called: Replaced by:
  59. * unsigned char string
  60. * char byvect s8 or u8, depending on signedness of 'char'
  61. * boolean bvect
  62. * signed long ivect s32
  63. * unsigned long uvect u32
  64. * float fvect f32
  65. * double dvect d32
  66. * complex double cvect c64
  67. * short svect s16
  68. * long long llvect s64
  69. */
  70. scm_t_bits scm_i_tc16_array;
  71. scm_t_bits scm_i_tc16_enclosed_array;
  72. #define SCM_SET_ARRAY_CONTIGUOUS_FLAG(x) \
  73. (SCM_SET_CELL_WORD_0 ((x), SCM_CELL_WORD_0 (x) | SCM_I_ARRAY_FLAG_CONTIGUOUS))
  74. #define SCM_CLR_ARRAY_CONTIGUOUS_FLAG(x) \
  75. (SCM_SET_CELL_WORD_0 ((x), SCM_CELL_WORD_0 (x) & ~SCM_I_ARRAY_FLAG_CONTIGUOUS))
  76. typedef SCM creator_proc (SCM len, SCM fill);
  77. struct {
  78. char *type_name;
  79. SCM type;
  80. creator_proc *creator;
  81. } type_creator_table[] = {
  82. { "a", SCM_UNSPECIFIED, scm_make_string },
  83. { "b", SCM_UNSPECIFIED, scm_make_bitvector },
  84. { "u8", SCM_UNSPECIFIED, scm_make_u8vector },
  85. { "s8", SCM_UNSPECIFIED, scm_make_s8vector },
  86. { "u16", SCM_UNSPECIFIED, scm_make_u16vector },
  87. { "s16", SCM_UNSPECIFIED, scm_make_s16vector },
  88. { "u32", SCM_UNSPECIFIED, scm_make_u32vector },
  89. { "s32", SCM_UNSPECIFIED, scm_make_s32vector },
  90. { "u64", SCM_UNSPECIFIED, scm_make_u64vector },
  91. { "s64", SCM_UNSPECIFIED, scm_make_s64vector },
  92. { "f32", SCM_UNSPECIFIED, scm_make_f32vector },
  93. { "f64", SCM_UNSPECIFIED, scm_make_f64vector },
  94. { "c32", SCM_UNSPECIFIED, scm_make_c32vector },
  95. { "c64", SCM_UNSPECIFIED, scm_make_c64vector },
  96. { NULL }
  97. };
  98. static void
  99. init_type_creator_table ()
  100. {
  101. int i;
  102. for (i = 0; type_creator_table[i].type_name; i++)
  103. {
  104. SCM sym = scm_from_locale_symbol (type_creator_table[i].type_name);
  105. type_creator_table[i].type = scm_permanent_object (sym);
  106. }
  107. }
  108. static creator_proc *
  109. type_to_creator (SCM type)
  110. {
  111. int i;
  112. if (scm_is_eq (type, SCM_BOOL_T))
  113. return scm_make_vector;
  114. for (i = 0; type_creator_table[i].type_name; i++)
  115. if (scm_is_eq (type, type_creator_table[i].type))
  116. return type_creator_table[i].creator;
  117. scm_misc_error (NULL, "unknown array type: ~a", scm_list_1 (type));
  118. }
  119. static SCM
  120. make_typed_vector (SCM type, size_t len)
  121. {
  122. creator_proc *creator = type_to_creator (type);
  123. return creator (scm_from_size_t (len), SCM_UNDEFINED);
  124. }
  125. #if SCM_ENABLE_DEPRECATED
  126. SCM_SYMBOL (scm_sym_s, "s");
  127. SCM_SYMBOL (scm_sym_l, "l");
  128. static int
  129. singp (SCM obj)
  130. {
  131. if (!SCM_REALP (obj))
  132. return 0;
  133. else
  134. {
  135. double x = SCM_REAL_VALUE (obj);
  136. float fx = x;
  137. return (- SCM_FLTMAX < x) && (x < SCM_FLTMAX) && (fx == x);
  138. }
  139. }
  140. SCM_API int scm_i_inump (SCM obj);
  141. SCM_API scm_t_signed_bits scm_i_inum (SCM obj);
  142. static SCM
  143. prototype_to_type (SCM proto)
  144. {
  145. const char *type_name;
  146. if (scm_is_eq (proto, SCM_BOOL_T))
  147. type_name = "b";
  148. else if (scm_is_eq (proto, SCM_MAKE_CHAR (0)))
  149. type_name = "s8";
  150. else if (SCM_CHARP (proto))
  151. type_name = "a";
  152. else if (scm_i_inump (proto))
  153. {
  154. if (scm_i_inum (proto) > 0)
  155. type_name = "u32";
  156. else
  157. type_name = "s32";
  158. }
  159. else if (scm_is_eq (proto, scm_sym_s))
  160. type_name = "s16";
  161. else if (scm_is_eq (proto, scm_sym_l))
  162. type_name = "s64";
  163. else if (SCM_REALP (proto)
  164. || scm_is_true (scm_eqv_p (proto,
  165. scm_divide (scm_from_int (1),
  166. scm_from_int (3)))))
  167. {
  168. if (singp (proto))
  169. type_name = "f32";
  170. else
  171. type_name = "f64";
  172. }
  173. else if (SCM_COMPLEXP (proto))
  174. type_name = "c64";
  175. else if (scm_is_null (proto))
  176. type_name = NULL;
  177. else
  178. type_name = NULL;
  179. if (type_name)
  180. return scm_from_locale_symbol (type_name);
  181. else
  182. return SCM_BOOL_T;
  183. }
  184. static SCM
  185. scm_i_get_old_prototype (SCM uvec)
  186. {
  187. if (scm_is_bitvector (uvec))
  188. return SCM_BOOL_T;
  189. else if (scm_is_string (uvec))
  190. return SCM_MAKE_CHAR ('a');
  191. else if (scm_is_true (scm_s8vector_p (uvec)))
  192. return SCM_MAKE_CHAR ('\0');
  193. else if (scm_is_true (scm_s16vector_p (uvec)))
  194. return scm_sym_s;
  195. else if (scm_is_true (scm_u32vector_p (uvec)))
  196. return scm_from_int (1);
  197. else if (scm_is_true (scm_s32vector_p (uvec)))
  198. return scm_from_int (-1);
  199. else if (scm_is_true (scm_s64vector_p (uvec)))
  200. return scm_sym_l;
  201. else if (scm_is_true (scm_f32vector_p (uvec)))
  202. return scm_from_double (1.0);
  203. else if (scm_is_true (scm_f64vector_p (uvec)))
  204. return scm_divide (scm_from_int (1), scm_from_int (3));
  205. else if (scm_is_true (scm_c64vector_p (uvec)))
  206. return scm_c_make_rectangular (0, 1);
  207. else if (scm_is_vector (uvec))
  208. return SCM_EOL;
  209. else
  210. scm_misc_error (NULL, "~a has no prototype", scm_list_1 (uvec));
  211. }
  212. SCM
  213. scm_make_uve (long k, SCM prot)
  214. #define FUNC_NAME "scm_make_uve"
  215. {
  216. scm_c_issue_deprecation_warning
  217. ("`scm_make_uve' is deprecated, see the manual for alternatives.");
  218. return make_typed_vector (prototype_to_type (prot), k);
  219. }
  220. #undef FUNC_NAME
  221. #endif
  222. int
  223. scm_is_array (SCM obj)
  224. {
  225. return (SCM_I_ENCLOSED_ARRAYP (obj)
  226. || SCM_I_ARRAYP (obj)
  227. || scm_is_generalized_vector (obj));
  228. }
  229. int
  230. scm_is_typed_array (SCM obj, SCM type)
  231. {
  232. if (SCM_I_ENCLOSED_ARRAYP (obj))
  233. {
  234. /* Enclosed arrays are arrays but are not of any type.
  235. */
  236. return 0;
  237. }
  238. /* Get storage vector.
  239. */
  240. if (SCM_I_ARRAYP (obj))
  241. obj = SCM_I_ARRAY_V (obj);
  242. /* It must be a generalized vector (which includes vectors, strings, etc).
  243. */
  244. if (!scm_is_generalized_vector (obj))
  245. return 0;
  246. return scm_is_eq (type, scm_i_generalized_vector_type (obj));
  247. }
  248. static SCM
  249. enclosed_ref (scm_t_array_handle *h, ssize_t pos)
  250. {
  251. return scm_i_cvref (SCM_I_ARRAY_V (h->array), pos + h->base, 1);
  252. }
  253. static SCM
  254. vector_ref (scm_t_array_handle *h, ssize_t pos)
  255. {
  256. return ((const SCM *)h->elements)[pos];
  257. }
  258. static SCM
  259. string_ref (scm_t_array_handle *h, ssize_t pos)
  260. {
  261. pos += h->base;
  262. if (SCM_I_ARRAYP (h->array))
  263. return scm_c_string_ref (SCM_I_ARRAY_V (h->array), pos);
  264. else
  265. return scm_c_string_ref (h->array, pos);
  266. }
  267. static SCM
  268. bitvector_ref (scm_t_array_handle *h, ssize_t pos)
  269. {
  270. pos += scm_array_handle_bit_elements_offset (h);
  271. return
  272. scm_from_bool (((scm_t_uint32 *)h->elements)[pos/32] & (1l << (pos % 32)));
  273. }
  274. static SCM
  275. memoize_ref (scm_t_array_handle *h, ssize_t pos)
  276. {
  277. SCM v = h->array;
  278. if (SCM_I_ENCLOSED_ARRAYP (v))
  279. {
  280. h->ref = enclosed_ref;
  281. return enclosed_ref (h, pos);
  282. }
  283. if (SCM_I_ARRAYP (v))
  284. v = SCM_I_ARRAY_V (v);
  285. if (scm_is_vector (v))
  286. {
  287. h->elements = scm_array_handle_elements (h);
  288. h->ref = vector_ref;
  289. }
  290. else if (scm_is_uniform_vector (v))
  291. {
  292. h->elements = scm_array_handle_uniform_elements (h);
  293. h->ref = scm_i_uniform_vector_ref_proc (v);
  294. }
  295. else if (scm_is_string (v))
  296. {
  297. h->ref = string_ref;
  298. }
  299. else if (scm_is_bitvector (v))
  300. {
  301. h->elements = scm_array_handle_bit_elements (h);
  302. h->ref = bitvector_ref;
  303. }
  304. else
  305. scm_misc_error (NULL, "unknown array type: ~a", scm_list_1 (h->array));
  306. return h->ref (h, pos);
  307. }
  308. static void
  309. enclosed_set (scm_t_array_handle *h, ssize_t pos, SCM val)
  310. {
  311. scm_wrong_type_arg_msg (NULL, 0, h->array, "non-enclosed array");
  312. }
  313. static void
  314. vector_set (scm_t_array_handle *h, ssize_t pos, SCM val)
  315. {
  316. ((SCM *)h->writable_elements)[pos] = val;
  317. }
  318. static void
  319. string_set (scm_t_array_handle *h, ssize_t pos, SCM val)
  320. {
  321. pos += h->base;
  322. if (SCM_I_ARRAYP (h->array))
  323. scm_c_string_set_x (SCM_I_ARRAY_V (h->array), pos, val);
  324. else
  325. scm_c_string_set_x (h->array, pos, val);
  326. }
  327. static void
  328. bitvector_set (scm_t_array_handle *h, ssize_t pos, SCM val)
  329. {
  330. scm_t_uint32 mask;
  331. pos += scm_array_handle_bit_elements_offset (h);
  332. mask = 1l << (pos % 32);
  333. if (scm_to_bool (val))
  334. ((scm_t_uint32 *)h->writable_elements)[pos/32] |= mask;
  335. else
  336. ((scm_t_uint32 *)h->writable_elements)[pos/32] &= ~mask;
  337. }
  338. static void
  339. memoize_set (scm_t_array_handle *h, ssize_t pos, SCM val)
  340. {
  341. SCM v = h->array;
  342. if (SCM_I_ENCLOSED_ARRAYP (v))
  343. {
  344. h->set = enclosed_set;
  345. enclosed_set (h, pos, val);
  346. return;
  347. }
  348. if (SCM_I_ARRAYP (v))
  349. v = SCM_I_ARRAY_V (v);
  350. if (scm_is_vector (v))
  351. {
  352. h->writable_elements = scm_array_handle_writable_elements (h);
  353. h->set = vector_set;
  354. }
  355. else if (scm_is_uniform_vector (v))
  356. {
  357. h->writable_elements = scm_array_handle_uniform_writable_elements (h);
  358. h->set = scm_i_uniform_vector_set_proc (v);
  359. }
  360. else if (scm_is_string (v))
  361. {
  362. h->set = string_set;
  363. }
  364. else if (scm_is_bitvector (v))
  365. {
  366. h->writable_elements = scm_array_handle_bit_writable_elements (h);
  367. h->set = bitvector_set;
  368. }
  369. else
  370. scm_misc_error (NULL, "unknown array type: ~a", scm_list_1 (h->array));
  371. h->set (h, pos, val);
  372. }
  373. void
  374. scm_array_get_handle (SCM array, scm_t_array_handle *h)
  375. {
  376. h->array = array;
  377. h->ref = memoize_ref;
  378. h->set = memoize_set;
  379. if (SCM_I_ARRAYP (array) || SCM_I_ENCLOSED_ARRAYP (array))
  380. {
  381. h->dims = SCM_I_ARRAY_DIMS (array);
  382. h->base = SCM_I_ARRAY_BASE (array);
  383. }
  384. else if (scm_is_generalized_vector (array))
  385. {
  386. h->dim0.lbnd = 0;
  387. h->dim0.ubnd = scm_c_generalized_vector_length (array) - 1;
  388. h->dim0.inc = 1;
  389. h->dims = &h->dim0;
  390. h->base = 0;
  391. }
  392. else
  393. scm_wrong_type_arg_msg (NULL, 0, array, "array");
  394. }
  395. void
  396. scm_array_handle_release (scm_t_array_handle *h)
  397. {
  398. /* Nothing to do here until arrays need to be reserved for real.
  399. */
  400. }
  401. size_t
  402. scm_array_handle_rank (scm_t_array_handle *h)
  403. {
  404. if (SCM_I_ARRAYP (h->array) || SCM_I_ENCLOSED_ARRAYP (h->array))
  405. return SCM_I_ARRAY_NDIM (h->array);
  406. else
  407. return 1;
  408. }
  409. scm_t_array_dim *
  410. scm_array_handle_dims (scm_t_array_handle *h)
  411. {
  412. return h->dims;
  413. }
  414. const SCM *
  415. scm_array_handle_elements (scm_t_array_handle *h)
  416. {
  417. SCM vec = h->array;
  418. if (SCM_I_ARRAYP (vec))
  419. vec = SCM_I_ARRAY_V (vec);
  420. if (SCM_I_IS_VECTOR (vec))
  421. return SCM_I_VECTOR_ELTS (vec) + h->base;
  422. scm_wrong_type_arg_msg (NULL, 0, h->array, "non-uniform array");
  423. }
  424. SCM *
  425. scm_array_handle_writable_elements (scm_t_array_handle *h)
  426. {
  427. SCM vec = h->array;
  428. if (SCM_I_ARRAYP (vec))
  429. vec = SCM_I_ARRAY_V (vec);
  430. if (SCM_I_IS_VECTOR (vec))
  431. return SCM_I_VECTOR_WELTS (vec) + h->base;
  432. scm_wrong_type_arg_msg (NULL, 0, h->array, "non-uniform array");
  433. }
  434. #if SCM_ENABLE_DEPRECATED
  435. SCM_DEFINE (scm_array_p, "array?", 1, 1, 0,
  436. (SCM obj, SCM prot),
  437. "Return @code{#t} if the @var{obj} is an array, and @code{#f} if\n"
  438. "not.")
  439. #define FUNC_NAME s_scm_array_p
  440. {
  441. if (!SCM_UNBNDP (prot))
  442. {
  443. scm_c_issue_deprecation_warning
  444. ("Using prototypes with `array?' is deprecated."
  445. " Use `typed-array?' instead.");
  446. return scm_typed_array_p (obj, prototype_to_type (prot));
  447. }
  448. else
  449. return scm_from_bool (scm_is_array (obj));
  450. }
  451. #undef FUNC_NAME
  452. #else /* !SCM_ENABLE_DEPRECATED */
  453. /* We keep the old 2-argument C prototype for a while although the old
  454. PROT argument is always ignored now. C code should probably use
  455. scm_is_array or scm_is_typed_array anyway.
  456. */
  457. static SCM scm_i_array_p (SCM obj);
  458. SCM_DEFINE (scm_i_array_p, "array?", 1, 0, 0,
  459. (SCM obj),
  460. "Return @code{#t} if the @var{obj} is an array, and @code{#f} if\n"
  461. "not.")
  462. #define FUNC_NAME s_scm_i_array_p
  463. {
  464. return scm_from_bool (scm_is_array (obj));
  465. }
  466. #undef FUNC_NAME
  467. SCM
  468. scm_array_p (SCM obj, SCM prot)
  469. {
  470. return scm_from_bool (scm_is_array (obj));
  471. }
  472. #endif /* !SCM_ENABLE_DEPRECATED */
  473. SCM_DEFINE (scm_typed_array_p, "typed-array?", 2, 0, 0,
  474. (SCM obj, SCM type),
  475. "Return @code{#t} if the @var{obj} is an array of type\n"
  476. "@var{type}, and @code{#f} if not.")
  477. #define FUNC_NAME s_scm_typed_array_p
  478. {
  479. return scm_from_bool (scm_is_typed_array (obj, type));
  480. }
  481. #undef FUNC_NAME
  482. size_t
  483. scm_c_array_rank (SCM array)
  484. {
  485. scm_t_array_handle handle;
  486. size_t res;
  487. scm_array_get_handle (array, &handle);
  488. res = scm_array_handle_rank (&handle);
  489. scm_array_handle_release (&handle);
  490. return res;
  491. }
  492. SCM_DEFINE (scm_array_rank, "array-rank", 1, 0, 0,
  493. (SCM array),
  494. "Return the number of dimensions of the array @var{array.}\n")
  495. #define FUNC_NAME s_scm_array_rank
  496. {
  497. return scm_from_size_t (scm_c_array_rank (array));
  498. }
  499. #undef FUNC_NAME
  500. SCM_DEFINE (scm_array_dimensions, "array-dimensions", 1, 0, 0,
  501. (SCM ra),
  502. "@code{array-dimensions} is similar to @code{array-shape} but replaces\n"
  503. "elements with a @code{0} minimum with one greater than the maximum. So:\n"
  504. "@lisp\n"
  505. "(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5)\n"
  506. "@end lisp")
  507. #define FUNC_NAME s_scm_array_dimensions
  508. {
  509. scm_t_array_handle handle;
  510. scm_t_array_dim *s;
  511. SCM res = SCM_EOL;
  512. size_t k;
  513. scm_array_get_handle (ra, &handle);
  514. s = scm_array_handle_dims (&handle);
  515. k = scm_array_handle_rank (&handle);
  516. while (k--)
  517. res = scm_cons (s[k].lbnd
  518. ? scm_cons2 (scm_from_ssize_t (s[k].lbnd),
  519. scm_from_ssize_t (s[k].ubnd),
  520. SCM_EOL)
  521. : scm_from_ssize_t (1 + s[k].ubnd),
  522. res);
  523. scm_array_handle_release (&handle);
  524. return res;
  525. }
  526. #undef FUNC_NAME
  527. SCM_DEFINE (scm_shared_array_root, "shared-array-root", 1, 0, 0,
  528. (SCM ra),
  529. "Return the root vector of a shared array.")
  530. #define FUNC_NAME s_scm_shared_array_root
  531. {
  532. if (SCM_I_ARRAYP (ra) || SCM_I_ENCLOSED_ARRAYP (ra))
  533. return SCM_I_ARRAY_V (ra);
  534. else if (scm_is_generalized_vector (ra))
  535. return ra;
  536. scm_wrong_type_arg_msg (NULL, 0, ra, "array");
  537. }
  538. #undef FUNC_NAME
  539. SCM_DEFINE (scm_shared_array_offset, "shared-array-offset", 1, 0, 0,
  540. (SCM ra),
  541. "Return the root vector index of the first element in the array.")
  542. #define FUNC_NAME s_scm_shared_array_offset
  543. {
  544. scm_t_array_handle handle;
  545. SCM res;
  546. scm_array_get_handle (ra, &handle);
  547. res = scm_from_size_t (handle.base);
  548. scm_array_handle_release (&handle);
  549. return res;
  550. }
  551. #undef FUNC_NAME
  552. SCM_DEFINE (scm_shared_array_increments, "shared-array-increments", 1, 0, 0,
  553. (SCM ra),
  554. "For each dimension, return the distance between elements in the root vector.")
  555. #define FUNC_NAME s_scm_shared_array_increments
  556. {
  557. scm_t_array_handle handle;
  558. SCM res = SCM_EOL;
  559. size_t k;
  560. scm_t_array_dim *s;
  561. scm_array_get_handle (ra, &handle);
  562. k = scm_array_handle_rank (&handle);
  563. s = scm_array_handle_dims (&handle);
  564. while (k--)
  565. res = scm_cons (scm_from_ssize_t (s[k].inc), res);
  566. scm_array_handle_release (&handle);
  567. return res;
  568. }
  569. #undef FUNC_NAME
  570. ssize_t
  571. scm_array_handle_pos (scm_t_array_handle *h, SCM indices)
  572. {
  573. scm_t_array_dim *s = scm_array_handle_dims (h);
  574. ssize_t pos = 0, i;
  575. size_t k = scm_array_handle_rank (h);
  576. while (k > 0 && scm_is_pair (indices))
  577. {
  578. i = scm_to_signed_integer (SCM_CAR (indices), s->lbnd, s->ubnd);
  579. pos += (i - s->lbnd) * s->inc;
  580. k--;
  581. s++;
  582. indices = SCM_CDR (indices);
  583. }
  584. if (k > 0 || !scm_is_null (indices))
  585. scm_misc_error (NULL, "wrong number of indices, expecting ~a",
  586. scm_list_1 (scm_from_size_t (scm_array_handle_rank (h))));
  587. return pos;
  588. }
  589. SCM
  590. scm_i_make_ra (int ndim, int enclosed)
  591. {
  592. scm_t_bits tag = enclosed? scm_i_tc16_enclosed_array : scm_i_tc16_array;
  593. SCM ra;
  594. SCM_NEWSMOB(ra, ((scm_t_bits) ndim << 17) + tag,
  595. scm_gc_malloc ((sizeof (scm_i_t_array) +
  596. ndim * sizeof (scm_t_array_dim)),
  597. "array"));
  598. SCM_I_ARRAY_V (ra) = SCM_BOOL_F;
  599. return ra;
  600. }
  601. static char s_bad_spec[] = "Bad scm_array dimension";
  602. /* Increments will still need to be set. */
  603. static SCM
  604. scm_i_shap2ra (SCM args)
  605. {
  606. scm_t_array_dim *s;
  607. SCM ra, spec, sp;
  608. int ndim = scm_ilength (args);
  609. if (ndim < 0)
  610. scm_misc_error (NULL, s_bad_spec, SCM_EOL);
  611. ra = scm_i_make_ra (ndim, 0);
  612. SCM_I_ARRAY_BASE (ra) = 0;
  613. s = SCM_I_ARRAY_DIMS (ra);
  614. for (; !scm_is_null (args); s++, args = SCM_CDR (args))
  615. {
  616. spec = SCM_CAR (args);
  617. if (scm_is_integer (spec))
  618. {
  619. if (scm_to_long (spec) < 0)
  620. scm_misc_error (NULL, s_bad_spec, SCM_EOL);
  621. s->lbnd = 0;
  622. s->ubnd = scm_to_long (spec) - 1;
  623. s->inc = 1;
  624. }
  625. else
  626. {
  627. if (!scm_is_pair (spec) || !scm_is_integer (SCM_CAR (spec)))
  628. scm_misc_error (NULL, s_bad_spec, SCM_EOL);
  629. s->lbnd = scm_to_long (SCM_CAR (spec));
  630. sp = SCM_CDR (spec);
  631. if (!scm_is_pair (sp)
  632. || !scm_is_integer (SCM_CAR (sp))
  633. || !scm_is_null (SCM_CDR (sp)))
  634. scm_misc_error (NULL, s_bad_spec, SCM_EOL);
  635. s->ubnd = scm_to_long (SCM_CAR (sp));
  636. s->inc = 1;
  637. }
  638. }
  639. return ra;
  640. }
  641. SCM_DEFINE (scm_make_typed_array, "make-typed-array", 2, 0, 1,
  642. (SCM type, SCM fill, SCM bounds),
  643. "Create and return an array of type @var{type}.")
  644. #define FUNC_NAME s_scm_make_typed_array
  645. {
  646. size_t k, rlen = 1;
  647. scm_t_array_dim *s;
  648. creator_proc *creator;
  649. SCM ra;
  650. creator = type_to_creator (type);
  651. ra = scm_i_shap2ra (bounds);
  652. SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra);
  653. s = SCM_I_ARRAY_DIMS (ra);
  654. k = SCM_I_ARRAY_NDIM (ra);
  655. while (k--)
  656. {
  657. s[k].inc = rlen;
  658. SCM_ASSERT_RANGE (1, bounds, s[k].lbnd <= s[k].ubnd + 1);
  659. rlen = (s[k].ubnd - s[k].lbnd + 1) * s[k].inc;
  660. }
  661. if (scm_is_eq (fill, SCM_UNSPECIFIED))
  662. fill = SCM_UNDEFINED;
  663. SCM_I_ARRAY_V (ra) = creator (scm_from_size_t (rlen), fill);
  664. if (1 == SCM_I_ARRAY_NDIM (ra) && 0 == SCM_I_ARRAY_BASE (ra))
  665. if (s->ubnd < s->lbnd || (0 == s->lbnd && 1 == s->inc))
  666. return SCM_I_ARRAY_V (ra);
  667. return ra;
  668. }
  669. #undef FUNC_NAME
  670. SCM_DEFINE (scm_make_array, "make-array", 1, 0, 1,
  671. (SCM fill, SCM bounds),
  672. "Create and return an array.")
  673. #define FUNC_NAME s_scm_make_array
  674. {
  675. return scm_make_typed_array (SCM_BOOL_T, fill, bounds);
  676. }
  677. #undef FUNC_NAME
  678. #if SCM_ENABLE_DEPRECATED
  679. SCM_DEFINE (scm_dimensions_to_uniform_array, "dimensions->uniform-array", 2, 1, 0,
  680. (SCM dims, SCM prot, SCM fill),
  681. "@deffnx {Scheme Procedure} make-uniform-vector length prototype [fill]\n"
  682. "Create and return a uniform array or vector of type\n"
  683. "corresponding to @var{prototype} with dimensions @var{dims} or\n"
  684. "length @var{length}. If @var{fill} is supplied, it's used to\n"
  685. "fill the array, otherwise @var{prototype} is used.")
  686. #define FUNC_NAME s_scm_dimensions_to_uniform_array
  687. {
  688. scm_c_issue_deprecation_warning
  689. ("`dimensions->uniform-array' is deprecated. "
  690. "Use `make-typed-array' instead.");
  691. if (scm_is_integer (dims))
  692. dims = scm_list_1 (dims);
  693. if (SCM_UNBNDP (fill))
  694. {
  695. /* Using #\nul as the prototype yields a s8 array, but numeric
  696. arrays can't store characters, so we have to special case this.
  697. */
  698. if (scm_is_eq (prot, SCM_MAKE_CHAR (0)))
  699. fill = scm_from_int (0);
  700. else
  701. fill = prot;
  702. }
  703. return scm_make_typed_array (prototype_to_type (prot), fill, dims);
  704. }
  705. #undef FUNC_NAME
  706. #endif
  707. static void
  708. scm_i_ra_set_contp (SCM ra)
  709. {
  710. size_t k = SCM_I_ARRAY_NDIM (ra);
  711. if (k)
  712. {
  713. long inc = SCM_I_ARRAY_DIMS (ra)[k - 1].inc;
  714. while (k--)
  715. {
  716. if (inc != SCM_I_ARRAY_DIMS (ra)[k].inc)
  717. {
  718. SCM_CLR_ARRAY_CONTIGUOUS_FLAG (ra);
  719. return;
  720. }
  721. inc *= (SCM_I_ARRAY_DIMS (ra)[k].ubnd
  722. - SCM_I_ARRAY_DIMS (ra)[k].lbnd + 1);
  723. }
  724. }
  725. SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra);
  726. }
  727. SCM_DEFINE (scm_make_shared_array, "make-shared-array", 2, 0, 1,
  728. (SCM oldra, SCM mapfunc, SCM dims),
  729. "@code{make-shared-array} can be used to create shared subarrays of other\n"
  730. "arrays. The @var{mapper} is a function that translates coordinates in\n"
  731. "the new array into coordinates in the old array. A @var{mapper} must be\n"
  732. "linear, and its range must stay within the bounds of the old array, but\n"
  733. "it can be otherwise arbitrary. A simple example:\n"
  734. "@lisp\n"
  735. "(define fred (make-array #f 8 8))\n"
  736. "(define freds-diagonal\n"
  737. " (make-shared-array fred (lambda (i) (list i i)) 8))\n"
  738. "(array-set! freds-diagonal 'foo 3)\n"
  739. "(array-ref fred 3 3) @result{} foo\n"
  740. "(define freds-center\n"
  741. " (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))\n"
  742. "(array-ref freds-center 0 0) @result{} foo\n"
  743. "@end lisp")
  744. #define FUNC_NAME s_scm_make_shared_array
  745. {
  746. scm_t_array_handle old_handle;
  747. SCM ra;
  748. SCM inds, indptr;
  749. SCM imap;
  750. size_t k;
  751. ssize_t i;
  752. long old_base, old_min, new_min, old_max, new_max;
  753. scm_t_array_dim *s;
  754. SCM_VALIDATE_REST_ARGUMENT (dims);
  755. SCM_VALIDATE_PROC (2, mapfunc);
  756. ra = scm_i_shap2ra (dims);
  757. scm_array_get_handle (oldra, &old_handle);
  758. if (SCM_I_ARRAYP (oldra))
  759. {
  760. SCM_I_ARRAY_V (ra) = SCM_I_ARRAY_V (oldra);
  761. old_base = old_min = old_max = SCM_I_ARRAY_BASE (oldra);
  762. s = scm_array_handle_dims (&old_handle);
  763. k = scm_array_handle_rank (&old_handle);
  764. while (k--)
  765. {
  766. if (s[k].inc > 0)
  767. old_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
  768. else
  769. old_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
  770. }
  771. }
  772. else
  773. {
  774. SCM_I_ARRAY_V (ra) = oldra;
  775. old_base = old_min = 0;
  776. old_max = scm_c_generalized_vector_length (oldra) - 1;
  777. }
  778. inds = SCM_EOL;
  779. s = SCM_I_ARRAY_DIMS (ra);
  780. for (k = 0; k < SCM_I_ARRAY_NDIM (ra); k++)
  781. {
  782. inds = scm_cons (scm_from_long (s[k].lbnd), inds);
  783. if (s[k].ubnd < s[k].lbnd)
  784. {
  785. if (1 == SCM_I_ARRAY_NDIM (ra))
  786. ra = make_typed_vector (scm_array_type (ra), 0);
  787. else
  788. SCM_I_ARRAY_V (ra) = make_typed_vector (scm_array_type (ra), 0);
  789. scm_array_handle_release (&old_handle);
  790. return ra;
  791. }
  792. }
  793. imap = scm_apply_0 (mapfunc, scm_reverse (inds));
  794. i = scm_array_handle_pos (&old_handle, imap);
  795. SCM_I_ARRAY_BASE (ra) = new_min = new_max = i + old_base;
  796. indptr = inds;
  797. k = SCM_I_ARRAY_NDIM (ra);
  798. while (k--)
  799. {
  800. if (s[k].ubnd > s[k].lbnd)
  801. {
  802. SCM_SETCAR (indptr, scm_sum (SCM_CAR (indptr), scm_from_int (1)));
  803. imap = scm_apply_0 (mapfunc, scm_reverse (inds));
  804. s[k].inc = scm_array_handle_pos (&old_handle, imap) - i;
  805. i += s[k].inc;
  806. if (s[k].inc > 0)
  807. new_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
  808. else
  809. new_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
  810. }
  811. else
  812. s[k].inc = new_max - new_min + 1; /* contiguous by default */
  813. indptr = SCM_CDR (indptr);
  814. }
  815. scm_array_handle_release (&old_handle);
  816. if (old_min > new_min || old_max < new_max)
  817. SCM_MISC_ERROR ("mapping out of range", SCM_EOL);
  818. if (1 == SCM_I_ARRAY_NDIM (ra) && 0 == SCM_I_ARRAY_BASE (ra))
  819. {
  820. SCM v = SCM_I_ARRAY_V (ra);
  821. size_t length = scm_c_generalized_vector_length (v);
  822. if (1 == s->inc && 0 == s->lbnd && length == 1 + s->ubnd)
  823. return v;
  824. if (s->ubnd < s->lbnd)
  825. return make_typed_vector (scm_array_type (ra), 0);
  826. }
  827. scm_i_ra_set_contp (ra);
  828. return ra;
  829. }
  830. #undef FUNC_NAME
  831. /* args are RA . DIMS */
  832. SCM_DEFINE (scm_transpose_array, "transpose-array", 1, 0, 1,
  833. (SCM ra, SCM args),
  834. "Return an array sharing contents with @var{array}, but with\n"
  835. "dimensions arranged in a different order. There must be one\n"
  836. "@var{dim} argument for each dimension of @var{array}.\n"
  837. "@var{dim0}, @var{dim1}, @dots{} should be integers between 0\n"
  838. "and the rank of the array to be returned. Each integer in that\n"
  839. "range must appear at least once in the argument list.\n"
  840. "\n"
  841. "The values of @var{dim0}, @var{dim1}, @dots{} correspond to\n"
  842. "dimensions in the array to be returned, their positions in the\n"
  843. "argument list to dimensions of @var{array}. Several @var{dim}s\n"
  844. "may have the same value, in which case the returned array will\n"
  845. "have smaller rank than @var{array}.\n"
  846. "\n"
  847. "@lisp\n"
  848. "(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))\n"
  849. "(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)\n"
  850. "(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}\n"
  851. " #2((a 4) (b 5) (c 6))\n"
  852. "@end lisp")
  853. #define FUNC_NAME s_scm_transpose_array
  854. {
  855. SCM res, vargs;
  856. scm_t_array_dim *s, *r;
  857. int ndim, i, k;
  858. SCM_VALIDATE_REST_ARGUMENT (args);
  859. SCM_ASSERT (SCM_NIMP (ra), ra, SCM_ARG1, FUNC_NAME);
  860. if (scm_is_generalized_vector (ra))
  861. {
  862. /* Make sure that we are called with a single zero as
  863. arguments.
  864. */
  865. if (scm_is_null (args) || !scm_is_null (SCM_CDR (args)))
  866. SCM_WRONG_NUM_ARGS ();
  867. SCM_VALIDATE_INT_COPY (SCM_ARG2, SCM_CAR (args), i);
  868. SCM_ASSERT_RANGE (SCM_ARG2, SCM_CAR (args), i == 0);
  869. return ra;
  870. }
  871. if (SCM_I_ARRAYP (ra) || SCM_I_ENCLOSED_ARRAYP (ra))
  872. {
  873. vargs = scm_vector (args);
  874. if (SCM_SIMPLE_VECTOR_LENGTH (vargs) != SCM_I_ARRAY_NDIM (ra))
  875. SCM_WRONG_NUM_ARGS ();
  876. ndim = 0;
  877. for (k = 0; k < SCM_I_ARRAY_NDIM (ra); k++)
  878. {
  879. i = scm_to_signed_integer (SCM_SIMPLE_VECTOR_REF (vargs, k),
  880. 0, SCM_I_ARRAY_NDIM(ra));
  881. if (ndim < i)
  882. ndim = i;
  883. }
  884. ndim++;
  885. res = scm_i_make_ra (ndim, 0);
  886. SCM_I_ARRAY_V (res) = SCM_I_ARRAY_V (ra);
  887. SCM_I_ARRAY_BASE (res) = SCM_I_ARRAY_BASE (ra);
  888. for (k = ndim; k--;)
  889. {
  890. SCM_I_ARRAY_DIMS (res)[k].lbnd = 0;
  891. SCM_I_ARRAY_DIMS (res)[k].ubnd = -1;
  892. }
  893. for (k = SCM_I_ARRAY_NDIM (ra); k--;)
  894. {
  895. i = scm_to_int (SCM_SIMPLE_VECTOR_REF (vargs, k));
  896. s = &(SCM_I_ARRAY_DIMS (ra)[k]);
  897. r = &(SCM_I_ARRAY_DIMS (res)[i]);
  898. if (r->ubnd < r->lbnd)
  899. {
  900. r->lbnd = s->lbnd;
  901. r->ubnd = s->ubnd;
  902. r->inc = s->inc;
  903. ndim--;
  904. }
  905. else
  906. {
  907. if (r->ubnd > s->ubnd)
  908. r->ubnd = s->ubnd;
  909. if (r->lbnd < s->lbnd)
  910. {
  911. SCM_I_ARRAY_BASE (res) += (s->lbnd - r->lbnd) * r->inc;
  912. r->lbnd = s->lbnd;
  913. }
  914. r->inc += s->inc;
  915. }
  916. }
  917. if (ndim > 0)
  918. SCM_MISC_ERROR ("bad argument list", SCM_EOL);
  919. scm_i_ra_set_contp (res);
  920. return res;
  921. }
  922. scm_wrong_type_arg_msg (NULL, 0, ra, "array");
  923. }
  924. #undef FUNC_NAME
  925. /* args are RA . AXES */
  926. SCM_DEFINE (scm_enclose_array, "enclose-array", 1, 0, 1,
  927. (SCM ra, SCM axes),
  928. "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than\n"
  929. "the rank of @var{array}. @var{enclose-array} returns an array\n"
  930. "resembling an array of shared arrays. The dimensions of each shared\n"
  931. "array are the same as the @var{dim}th dimensions of the original array,\n"
  932. "the dimensions of the outer array are the same as those of the original\n"
  933. "array that did not match a @var{dim}.\n\n"
  934. "An enclosed array is not a general Scheme array. Its elements may not\n"
  935. "be set using @code{array-set!}. Two references to the same element of\n"
  936. "an enclosed array will be @code{equal?} but will not in general be\n"
  937. "@code{eq?}. The value returned by @var{array-prototype} when given an\n"
  938. "enclosed array is unspecified.\n\n"
  939. "examples:\n"
  940. "@lisp\n"
  941. "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}\n"
  942. " #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>\n\n"
  943. "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}\n"
  944. " #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>\n"
  945. "@end lisp")
  946. #define FUNC_NAME s_scm_enclose_array
  947. {
  948. SCM axv, res, ra_inr;
  949. const char *c_axv;
  950. scm_t_array_dim vdim, *s = &vdim;
  951. int ndim, j, k, ninr, noutr;
  952. SCM_VALIDATE_REST_ARGUMENT (axes);
  953. if (scm_is_null (axes))
  954. axes = scm_cons ((SCM_I_ARRAYP (ra) ? scm_from_size_t (SCM_I_ARRAY_NDIM (ra) - 1) : SCM_INUM0), SCM_EOL);
  955. ninr = scm_ilength (axes);
  956. if (ninr < 0)
  957. SCM_WRONG_NUM_ARGS ();
  958. ra_inr = scm_i_make_ra (ninr, 0);
  959. if (scm_is_generalized_vector (ra))
  960. {
  961. s->lbnd = 0;
  962. s->ubnd = scm_c_generalized_vector_length (ra) - 1;
  963. s->inc = 1;
  964. SCM_I_ARRAY_V (ra_inr) = ra;
  965. SCM_I_ARRAY_BASE (ra_inr) = 0;
  966. ndim = 1;
  967. }
  968. else if (SCM_I_ARRAYP (ra))
  969. {
  970. s = SCM_I_ARRAY_DIMS (ra);
  971. SCM_I_ARRAY_V (ra_inr) = SCM_I_ARRAY_V (ra);
  972. SCM_I_ARRAY_BASE (ra_inr) = SCM_I_ARRAY_BASE (ra);
  973. ndim = SCM_I_ARRAY_NDIM (ra);
  974. }
  975. else
  976. scm_wrong_type_arg_msg (NULL, 0, ra, "array");
  977. noutr = ndim - ninr;
  978. if (noutr < 0)
  979. SCM_WRONG_NUM_ARGS ();
  980. axv = scm_make_string (scm_from_int (ndim), SCM_MAKE_CHAR (0));
  981. res = scm_i_make_ra (noutr, 1);
  982. SCM_I_ARRAY_BASE (res) = SCM_I_ARRAY_BASE (ra_inr);
  983. SCM_I_ARRAY_V (res) = ra_inr;
  984. for (k = 0; k < ninr; k++, axes = SCM_CDR (axes))
  985. {
  986. if (!scm_is_integer (SCM_CAR (axes)))
  987. SCM_MISC_ERROR ("bad axis", SCM_EOL);
  988. j = scm_to_int (SCM_CAR (axes));
  989. SCM_I_ARRAY_DIMS (ra_inr)[k].lbnd = s[j].lbnd;
  990. SCM_I_ARRAY_DIMS (ra_inr)[k].ubnd = s[j].ubnd;
  991. SCM_I_ARRAY_DIMS (ra_inr)[k].inc = s[j].inc;
  992. scm_c_string_set_x (axv, j, SCM_MAKE_CHAR (1));
  993. }
  994. c_axv = scm_i_string_chars (axv);
  995. for (j = 0, k = 0; k < noutr; k++, j++)
  996. {
  997. while (c_axv[j])
  998. j++;
  999. SCM_I_ARRAY_DIMS (res)[k].lbnd = s[j].lbnd;
  1000. SCM_I_ARRAY_DIMS (res)[k].ubnd = s[j].ubnd;
  1001. SCM_I_ARRAY_DIMS (res)[k].inc = s[j].inc;
  1002. }
  1003. scm_remember_upto_here_1 (axv);
  1004. scm_i_ra_set_contp (ra_inr);
  1005. scm_i_ra_set_contp (res);
  1006. return res;
  1007. }
  1008. #undef FUNC_NAME
  1009. SCM_DEFINE (scm_array_in_bounds_p, "array-in-bounds?", 1, 0, 1,
  1010. (SCM v, SCM args),
  1011. "Return @code{#t} if its arguments would be acceptable to\n"
  1012. "@code{array-ref}.")
  1013. #define FUNC_NAME s_scm_array_in_bounds_p
  1014. {
  1015. SCM res = SCM_BOOL_T;
  1016. SCM_VALIDATE_REST_ARGUMENT (args);
  1017. if (SCM_I_ARRAYP (v) || SCM_I_ENCLOSED_ARRAYP (v))
  1018. {
  1019. size_t k, ndim = SCM_I_ARRAY_NDIM (v);
  1020. scm_t_array_dim *s = SCM_I_ARRAY_DIMS (v);
  1021. for (k = 0; k < ndim; k++)
  1022. {
  1023. long ind;
  1024. if (!scm_is_pair (args))
  1025. SCM_WRONG_NUM_ARGS ();
  1026. ind = scm_to_long (SCM_CAR (args));
  1027. args = SCM_CDR (args);
  1028. if (ind < s[k].lbnd || ind > s[k].ubnd)
  1029. {
  1030. res = SCM_BOOL_F;
  1031. /* We do not stop the checking after finding a violation
  1032. since we want to validate the type-correctness and
  1033. number of arguments in any case.
  1034. */
  1035. }
  1036. }
  1037. }
  1038. else if (scm_is_generalized_vector (v))
  1039. {
  1040. /* Since real arrays have been covered above, all generalized
  1041. vectors are guaranteed to be zero-origin here.
  1042. */
  1043. long ind;
  1044. if (!scm_is_pair (args))
  1045. SCM_WRONG_NUM_ARGS ();
  1046. ind = scm_to_long (SCM_CAR (args));
  1047. args = SCM_CDR (args);
  1048. res = scm_from_bool (ind >= 0
  1049. && ind < scm_c_generalized_vector_length (v));
  1050. }
  1051. else
  1052. scm_wrong_type_arg_msg (NULL, 0, v, "array");
  1053. if (!scm_is_null (args))
  1054. SCM_WRONG_NUM_ARGS ();
  1055. return res;
  1056. }
  1057. #undef FUNC_NAME
  1058. SCM
  1059. scm_i_cvref (SCM v, size_t pos, int enclosed)
  1060. {
  1061. if (enclosed)
  1062. {
  1063. int k = SCM_I_ARRAY_NDIM (v);
  1064. SCM res = scm_i_make_ra (k, 0);
  1065. SCM_I_ARRAY_V (res) = SCM_I_ARRAY_V (v);
  1066. SCM_I_ARRAY_BASE (res) = pos;
  1067. while (k--)
  1068. {
  1069. SCM_I_ARRAY_DIMS (res)[k].ubnd = SCM_I_ARRAY_DIMS (v)[k].ubnd;
  1070. SCM_I_ARRAY_DIMS (res)[k].lbnd = SCM_I_ARRAY_DIMS (v)[k].lbnd;
  1071. SCM_I_ARRAY_DIMS (res)[k].inc = SCM_I_ARRAY_DIMS (v)[k].inc;
  1072. }
  1073. return res;
  1074. }
  1075. else
  1076. return scm_c_generalized_vector_ref (v, pos);
  1077. }
  1078. SCM_DEFINE (scm_array_ref, "array-ref", 1, 0, 1,
  1079. (SCM v, SCM args),
  1080. "Return the element at the @code{(index1, index2)} element in\n"
  1081. "@var{array}.")
  1082. #define FUNC_NAME s_scm_array_ref
  1083. {
  1084. scm_t_array_handle handle;
  1085. SCM res;
  1086. scm_array_get_handle (v, &handle);
  1087. res = scm_array_handle_ref (&handle, scm_array_handle_pos (&handle, args));
  1088. scm_array_handle_release (&handle);
  1089. return res;
  1090. }
  1091. #undef FUNC_NAME
  1092. SCM_DEFINE (scm_array_set_x, "array-set!", 2, 0, 1,
  1093. (SCM v, SCM obj, SCM args),
  1094. "Set the element at the @code{(index1, index2)} element in @var{array} to\n"
  1095. "@var{new-value}. The value returned by array-set! is unspecified.")
  1096. #define FUNC_NAME s_scm_array_set_x
  1097. {
  1098. scm_t_array_handle handle;
  1099. scm_array_get_handle (v, &handle);
  1100. scm_array_handle_set (&handle, scm_array_handle_pos (&handle, args), obj);
  1101. scm_array_handle_release (&handle);
  1102. return SCM_UNSPECIFIED;
  1103. }
  1104. #undef FUNC_NAME
  1105. /* attempts to unroll an array into a one-dimensional array.
  1106. returns the unrolled array or #f if it can't be done. */
  1107. /* if strict is not SCM_UNDEFINED, return #f if returned array
  1108. wouldn't have contiguous elements. */
  1109. SCM_DEFINE (scm_array_contents, "array-contents", 1, 1, 0,
  1110. (SCM ra, SCM strict),
  1111. "If @var{array} may be @dfn{unrolled} into a one dimensional shared array\n"
  1112. "without changing their order (last subscript changing fastest), then\n"
  1113. "@code{array-contents} returns that shared array, otherwise it returns\n"
  1114. "@code{#f}. All arrays made by @var{make-array} and\n"
  1115. "@var{make-uniform-array} may be unrolled, some arrays made by\n"
  1116. "@var{make-shared-array} may not be.\n\n"
  1117. "If the optional argument @var{strict} is provided, a shared array will\n"
  1118. "be returned only if its elements are stored internally contiguous in\n"
  1119. "memory.")
  1120. #define FUNC_NAME s_scm_array_contents
  1121. {
  1122. SCM sra;
  1123. if (scm_is_generalized_vector (ra))
  1124. return ra;
  1125. if (SCM_I_ARRAYP (ra))
  1126. {
  1127. size_t k, ndim = SCM_I_ARRAY_NDIM (ra), len = 1;
  1128. if (!SCM_I_ARRAYP (ra) || !SCM_I_ARRAY_CONTP (ra))
  1129. return SCM_BOOL_F;
  1130. for (k = 0; k < ndim; k++)
  1131. len *= SCM_I_ARRAY_DIMS (ra)[k].ubnd - SCM_I_ARRAY_DIMS (ra)[k].lbnd + 1;
  1132. if (!SCM_UNBNDP (strict))
  1133. {
  1134. if (ndim && (1 != SCM_I_ARRAY_DIMS (ra)[ndim - 1].inc))
  1135. return SCM_BOOL_F;
  1136. if (scm_is_bitvector (SCM_I_ARRAY_V (ra)))
  1137. {
  1138. if (len != scm_c_bitvector_length (SCM_I_ARRAY_V (ra)) ||
  1139. SCM_I_ARRAY_BASE (ra) % SCM_LONG_BIT ||
  1140. len % SCM_LONG_BIT)
  1141. return SCM_BOOL_F;
  1142. }
  1143. }
  1144. {
  1145. SCM v = SCM_I_ARRAY_V (ra);
  1146. size_t length = scm_c_generalized_vector_length (v);
  1147. if ((len == length) && 0 == SCM_I_ARRAY_BASE (ra) && SCM_I_ARRAY_DIMS (ra)->inc)
  1148. return v;
  1149. }
  1150. sra = scm_i_make_ra (1, 0);
  1151. SCM_I_ARRAY_DIMS (sra)->lbnd = 0;
  1152. SCM_I_ARRAY_DIMS (sra)->ubnd = len - 1;
  1153. SCM_I_ARRAY_V (sra) = SCM_I_ARRAY_V (ra);
  1154. SCM_I_ARRAY_BASE (sra) = SCM_I_ARRAY_BASE (ra);
  1155. SCM_I_ARRAY_DIMS (sra)->inc = (ndim ? SCM_I_ARRAY_DIMS (ra)[ndim - 1].inc : 1);
  1156. return sra;
  1157. }
  1158. else if (SCM_I_ENCLOSED_ARRAYP (ra))
  1159. scm_wrong_type_arg_msg (NULL, 0, ra, "non-enclosed array");
  1160. else
  1161. scm_wrong_type_arg_msg (NULL, 0, ra, "array");
  1162. }
  1163. #undef FUNC_NAME
  1164. SCM
  1165. scm_ra2contig (SCM ra, int copy)
  1166. {
  1167. SCM ret;
  1168. long inc = 1;
  1169. size_t k, len = 1;
  1170. for (k = SCM_I_ARRAY_NDIM (ra); k--;)
  1171. len *= SCM_I_ARRAY_DIMS (ra)[k].ubnd - SCM_I_ARRAY_DIMS (ra)[k].lbnd + 1;
  1172. k = SCM_I_ARRAY_NDIM (ra);
  1173. if (SCM_I_ARRAY_CONTP (ra) && ((0 == k) || (1 == SCM_I_ARRAY_DIMS (ra)[k - 1].inc)))
  1174. {
  1175. if (!scm_is_bitvector (SCM_I_ARRAY_V (ra)))
  1176. return ra;
  1177. if ((len == scm_c_bitvector_length (SCM_I_ARRAY_V (ra)) &&
  1178. 0 == SCM_I_ARRAY_BASE (ra) % SCM_LONG_BIT &&
  1179. 0 == len % SCM_LONG_BIT))
  1180. return ra;
  1181. }
  1182. ret = scm_i_make_ra (k, 0);
  1183. SCM_I_ARRAY_BASE (ret) = 0;
  1184. while (k--)
  1185. {
  1186. SCM_I_ARRAY_DIMS (ret)[k].lbnd = SCM_I_ARRAY_DIMS (ra)[k].lbnd;
  1187. SCM_I_ARRAY_DIMS (ret)[k].ubnd = SCM_I_ARRAY_DIMS (ra)[k].ubnd;
  1188. SCM_I_ARRAY_DIMS (ret)[k].inc = inc;
  1189. inc *= SCM_I_ARRAY_DIMS (ra)[k].ubnd - SCM_I_ARRAY_DIMS (ra)[k].lbnd + 1;
  1190. }
  1191. SCM_I_ARRAY_V (ret) = make_typed_vector (scm_array_type (ra), inc);
  1192. if (copy)
  1193. scm_array_copy_x (ra, ret);
  1194. return ret;
  1195. }
  1196. SCM_DEFINE (scm_uniform_array_read_x, "uniform-array-read!", 1, 3, 0,
  1197. (SCM ura, SCM port_or_fd, SCM start, SCM end),
  1198. "@deffnx {Scheme Procedure} uniform-vector-read! uve [port-or-fdes] [start] [end]\n"
  1199. "Attempt to read all elements of @var{ura}, in lexicographic order, as\n"
  1200. "binary objects from @var{port-or-fdes}.\n"
  1201. "If an end of file is encountered,\n"
  1202. "the objects up to that point are put into @var{ura}\n"
  1203. "(starting at the beginning) and the remainder of the array is\n"
  1204. "unchanged.\n\n"
  1205. "The optional arguments @var{start} and @var{end} allow\n"
  1206. "a specified region of a vector (or linearized array) to be read,\n"
  1207. "leaving the remainder of the vector unchanged.\n\n"
  1208. "@code{uniform-array-read!} returns the number of objects read.\n"
  1209. "@var{port-or-fdes} may be omitted, in which case it defaults to the value\n"
  1210. "returned by @code{(current-input-port)}.")
  1211. #define FUNC_NAME s_scm_uniform_array_read_x
  1212. {
  1213. if (SCM_UNBNDP (port_or_fd))
  1214. port_or_fd = scm_current_input_port ();
  1215. if (scm_is_uniform_vector (ura))
  1216. {
  1217. return scm_uniform_vector_read_x (ura, port_or_fd, start, end);
  1218. }
  1219. else if (SCM_I_ARRAYP (ura))
  1220. {
  1221. size_t base, vlen, cstart, cend;
  1222. SCM cra, ans;
  1223. cra = scm_ra2contig (ura, 0);
  1224. base = SCM_I_ARRAY_BASE (cra);
  1225. vlen = SCM_I_ARRAY_DIMS (cra)->inc *
  1226. (SCM_I_ARRAY_DIMS (cra)->ubnd - SCM_I_ARRAY_DIMS (cra)->lbnd + 1);
  1227. cstart = 0;
  1228. cend = vlen;
  1229. if (!SCM_UNBNDP (start))
  1230. {
  1231. cstart = scm_to_unsigned_integer (start, 0, vlen);
  1232. if (!SCM_UNBNDP (end))
  1233. cend = scm_to_unsigned_integer (end, cstart, vlen);
  1234. }
  1235. ans = scm_uniform_vector_read_x (SCM_I_ARRAY_V (cra), port_or_fd,
  1236. scm_from_size_t (base + cstart),
  1237. scm_from_size_t (base + cend));
  1238. if (!scm_is_eq (cra, ura))
  1239. scm_array_copy_x (cra, ura);
  1240. return ans;
  1241. }
  1242. else if (SCM_I_ENCLOSED_ARRAYP (ura))
  1243. scm_wrong_type_arg_msg (NULL, 0, ura, "non-enclosed array");
  1244. else
  1245. scm_wrong_type_arg_msg (NULL, 0, ura, "array");
  1246. }
  1247. #undef FUNC_NAME
  1248. SCM_DEFINE (scm_uniform_array_write, "uniform-array-write", 1, 3, 0,
  1249. (SCM ura, SCM port_or_fd, SCM start, SCM end),
  1250. "Writes all elements of @var{ura} as binary objects to\n"
  1251. "@var{port-or-fdes}.\n\n"
  1252. "The optional arguments @var{start}\n"
  1253. "and @var{end} allow\n"
  1254. "a specified region of a vector (or linearized array) to be written.\n\n"
  1255. "The number of objects actually written is returned.\n"
  1256. "@var{port-or-fdes} may be\n"
  1257. "omitted, in which case it defaults to the value returned by\n"
  1258. "@code{(current-output-port)}.")
  1259. #define FUNC_NAME s_scm_uniform_array_write
  1260. {
  1261. if (SCM_UNBNDP (port_or_fd))
  1262. port_or_fd = scm_current_output_port ();
  1263. if (scm_is_uniform_vector (ura))
  1264. {
  1265. return scm_uniform_vector_write (ura, port_or_fd, start, end);
  1266. }
  1267. else if (SCM_I_ARRAYP (ura))
  1268. {
  1269. size_t base, vlen, cstart, cend;
  1270. SCM cra, ans;
  1271. cra = scm_ra2contig (ura, 1);
  1272. base = SCM_I_ARRAY_BASE (cra);
  1273. vlen = SCM_I_ARRAY_DIMS (cra)->inc *
  1274. (SCM_I_ARRAY_DIMS (cra)->ubnd - SCM_I_ARRAY_DIMS (cra)->lbnd + 1);
  1275. cstart = 0;
  1276. cend = vlen;
  1277. if (!SCM_UNBNDP (start))
  1278. {
  1279. cstart = scm_to_unsigned_integer (start, 0, vlen);
  1280. if (!SCM_UNBNDP (end))
  1281. cend = scm_to_unsigned_integer (end, cstart, vlen);
  1282. }
  1283. ans = scm_uniform_vector_write (SCM_I_ARRAY_V (cra), port_or_fd,
  1284. scm_from_size_t (base + cstart),
  1285. scm_from_size_t (base + cend));
  1286. return ans;
  1287. }
  1288. else if (SCM_I_ENCLOSED_ARRAYP (ura))
  1289. scm_wrong_type_arg_msg (NULL, 0, ura, "non-enclosed array");
  1290. else
  1291. scm_wrong_type_arg_msg (NULL, 0, ura, "array");
  1292. }
  1293. #undef FUNC_NAME
  1294. /** Bit vectors */
  1295. static scm_t_bits scm_tc16_bitvector;
  1296. #define IS_BITVECTOR(obj) SCM_SMOB_PREDICATE(scm_tc16_bitvector,(obj))
  1297. #define BITVECTOR_BITS(obj) ((scm_t_uint32 *)SCM_SMOB_DATA(obj))
  1298. #define BITVECTOR_LENGTH(obj) ((size_t)SCM_SMOB_DATA_2(obj))
  1299. static size_t
  1300. bitvector_free (SCM vec)
  1301. {
  1302. scm_gc_free (BITVECTOR_BITS (vec),
  1303. sizeof (scm_t_uint32) * ((BITVECTOR_LENGTH (vec)+31)/32),
  1304. "bitvector");
  1305. return 0;
  1306. }
  1307. static int
  1308. bitvector_print (SCM vec, SCM port, scm_print_state *pstate)
  1309. {
  1310. size_t bit_len = BITVECTOR_LENGTH (vec);
  1311. size_t word_len = (bit_len+31)/32;
  1312. scm_t_uint32 *bits = BITVECTOR_BITS (vec);
  1313. size_t i, j;
  1314. scm_puts ("#*", port);
  1315. for (i = 0; i < word_len; i++, bit_len -= 32)
  1316. {
  1317. scm_t_uint32 mask = 1;
  1318. for (j = 0; j < 32 && j < bit_len; j++, mask <<= 1)
  1319. scm_putc ((bits[i] & mask)? '1' : '0', port);
  1320. }
  1321. return 1;
  1322. }
  1323. static SCM
  1324. bitvector_equalp (SCM vec1, SCM vec2)
  1325. {
  1326. size_t bit_len = BITVECTOR_LENGTH (vec1);
  1327. size_t word_len = (bit_len + 31) / 32;
  1328. scm_t_uint32 last_mask = ((scm_t_uint32)-1) >> (32*word_len - bit_len);
  1329. scm_t_uint32 *bits1 = BITVECTOR_BITS (vec1);
  1330. scm_t_uint32 *bits2 = BITVECTOR_BITS (vec2);
  1331. /* compare lengths */
  1332. if (BITVECTOR_LENGTH (vec2) != bit_len)
  1333. return SCM_BOOL_F;
  1334. /* avoid underflow in word_len-1 below. */
  1335. if (bit_len == 0)
  1336. return SCM_BOOL_T;
  1337. /* compare full words */
  1338. if (memcmp (bits1, bits2, sizeof (scm_t_uint32) * (word_len-1)))
  1339. return SCM_BOOL_F;
  1340. /* compare partial last words */
  1341. if ((bits1[word_len-1] & last_mask) != (bits2[word_len-1] & last_mask))
  1342. return SCM_BOOL_F;
  1343. return SCM_BOOL_T;
  1344. }
  1345. int
  1346. scm_is_bitvector (SCM vec)
  1347. {
  1348. return IS_BITVECTOR (vec);
  1349. }
  1350. SCM_DEFINE (scm_bitvector_p, "bitvector?", 1, 0, 0,
  1351. (SCM obj),
  1352. "Return @code{#t} when @var{obj} is a bitvector, else\n"
  1353. "return @code{#f}.")
  1354. #define FUNC_NAME s_scm_bitvector_p
  1355. {
  1356. return scm_from_bool (scm_is_bitvector (obj));
  1357. }
  1358. #undef FUNC_NAME
  1359. SCM
  1360. scm_c_make_bitvector (size_t len, SCM fill)
  1361. {
  1362. size_t word_len = (len + 31) / 32;
  1363. scm_t_uint32 *bits;
  1364. SCM res;
  1365. bits = scm_gc_malloc (sizeof (scm_t_uint32) * word_len,
  1366. "bitvector");
  1367. SCM_NEWSMOB2 (res, scm_tc16_bitvector, bits, len);
  1368. if (!SCM_UNBNDP (fill))
  1369. scm_bitvector_fill_x (res, fill);
  1370. return res;
  1371. }
  1372. SCM_DEFINE (scm_make_bitvector, "make-bitvector", 1, 1, 0,
  1373. (SCM len, SCM fill),
  1374. "Create a new bitvector of length @var{len} and\n"
  1375. "optionally initialize all elements to @var{fill}.")
  1376. #define FUNC_NAME s_scm_make_bitvector
  1377. {
  1378. return scm_c_make_bitvector (scm_to_size_t (len), fill);
  1379. }
  1380. #undef FUNC_NAME
  1381. SCM_DEFINE (scm_bitvector, "bitvector", 0, 0, 1,
  1382. (SCM bits),
  1383. "Create a new bitvector with the arguments as elements.")
  1384. #define FUNC_NAME s_scm_bitvector
  1385. {
  1386. return scm_list_to_bitvector (bits);
  1387. }
  1388. #undef FUNC_NAME
  1389. size_t
  1390. scm_c_bitvector_length (SCM vec)
  1391. {
  1392. scm_assert_smob_type (scm_tc16_bitvector, vec);
  1393. return BITVECTOR_LENGTH (vec);
  1394. }
  1395. SCM_DEFINE (scm_bitvector_length, "bitvector-length", 1, 0, 0,
  1396. (SCM vec),
  1397. "Return the length of the bitvector @var{vec}.")
  1398. #define FUNC_NAME s_scm_bitvector_length
  1399. {
  1400. return scm_from_size_t (scm_c_bitvector_length (vec));
  1401. }
  1402. #undef FUNC_NAME
  1403. const scm_t_uint32 *
  1404. scm_array_handle_bit_elements (scm_t_array_handle *h)
  1405. {
  1406. return scm_array_handle_bit_writable_elements (h);
  1407. }
  1408. scm_t_uint32 *
  1409. scm_array_handle_bit_writable_elements (scm_t_array_handle *h)
  1410. {
  1411. SCM vec = h->array;
  1412. if (SCM_I_ARRAYP (vec))
  1413. vec = SCM_I_ARRAY_V (vec);
  1414. if (IS_BITVECTOR (vec))
  1415. return BITVECTOR_BITS (vec) + h->base/32;
  1416. scm_wrong_type_arg_msg (NULL, 0, h->array, "bit array");
  1417. }
  1418. size_t
  1419. scm_array_handle_bit_elements_offset (scm_t_array_handle *h)
  1420. {
  1421. return h->base % 32;
  1422. }
  1423. const scm_t_uint32 *
  1424. scm_bitvector_elements (SCM vec,
  1425. scm_t_array_handle *h,
  1426. size_t *offp,
  1427. size_t *lenp,
  1428. ssize_t *incp)
  1429. {
  1430. return scm_bitvector_writable_elements (vec, h, offp, lenp, incp);
  1431. }
  1432. scm_t_uint32 *
  1433. scm_bitvector_writable_elements (SCM vec,
  1434. scm_t_array_handle *h,
  1435. size_t *offp,
  1436. size_t *lenp,
  1437. ssize_t *incp)
  1438. {
  1439. scm_generalized_vector_get_handle (vec, h);
  1440. if (offp)
  1441. {
  1442. scm_t_array_dim *dim = scm_array_handle_dims (h);
  1443. *offp = scm_array_handle_bit_elements_offset (h);
  1444. *lenp = dim->ubnd - dim->lbnd + 1;
  1445. *incp = dim->inc;
  1446. }
  1447. return scm_array_handle_bit_writable_elements (h);
  1448. }
  1449. SCM
  1450. scm_c_bitvector_ref (SCM vec, size_t idx)
  1451. {
  1452. scm_t_array_handle handle;
  1453. const scm_t_uint32 *bits;
  1454. if (IS_BITVECTOR (vec))
  1455. {
  1456. if (idx >= BITVECTOR_LENGTH (vec))
  1457. scm_out_of_range (NULL, scm_from_size_t (idx));
  1458. bits = BITVECTOR_BITS(vec);
  1459. return scm_from_bool (bits[idx/32] & (1L << (idx%32)));
  1460. }
  1461. else
  1462. {
  1463. SCM res;
  1464. size_t len, off;
  1465. ssize_t inc;
  1466. bits = scm_bitvector_elements (vec, &handle, &off, &len, &inc);
  1467. if (idx >= len)
  1468. scm_out_of_range (NULL, scm_from_size_t (idx));
  1469. idx = idx*inc + off;
  1470. res = scm_from_bool (bits[idx/32] & (1L << (idx%32)));
  1471. scm_array_handle_release (&handle);
  1472. return res;
  1473. }
  1474. }
  1475. SCM_DEFINE (scm_bitvector_ref, "bitvector-ref", 2, 0, 0,
  1476. (SCM vec, SCM idx),
  1477. "Return the element at index @var{idx} of the bitvector\n"
  1478. "@var{vec}.")
  1479. #define FUNC_NAME s_scm_bitvector_ref
  1480. {
  1481. return scm_c_bitvector_ref (vec, scm_to_size_t (idx));
  1482. }
  1483. #undef FUNC_NAME
  1484. void
  1485. scm_c_bitvector_set_x (SCM vec, size_t idx, SCM val)
  1486. {
  1487. scm_t_array_handle handle;
  1488. scm_t_uint32 *bits, mask;
  1489. if (IS_BITVECTOR (vec))
  1490. {
  1491. if (idx >= BITVECTOR_LENGTH (vec))
  1492. scm_out_of_range (NULL, scm_from_size_t (idx));
  1493. bits = BITVECTOR_BITS(vec);
  1494. }
  1495. else
  1496. {
  1497. size_t len, off;
  1498. ssize_t inc;
  1499. bits = scm_bitvector_writable_elements (vec, &handle, &off, &len, &inc);
  1500. if (idx >= len)
  1501. scm_out_of_range (NULL, scm_from_size_t (idx));
  1502. idx = idx*inc + off;
  1503. }
  1504. mask = 1L << (idx%32);
  1505. if (scm_is_true (val))
  1506. bits[idx/32] |= mask;
  1507. else
  1508. bits[idx/32] &= ~mask;
  1509. if (!IS_BITVECTOR (vec))
  1510. scm_array_handle_release (&handle);
  1511. }
  1512. SCM_DEFINE (scm_bitvector_set_x, "bitvector-set!", 3, 0, 0,
  1513. (SCM vec, SCM idx, SCM val),
  1514. "Set the element at index @var{idx} of the bitvector\n"
  1515. "@var{vec} when @var{val} is true, else clear it.")
  1516. #define FUNC_NAME s_scm_bitvector_set_x
  1517. {
  1518. scm_c_bitvector_set_x (vec, scm_to_size_t (idx), val);
  1519. return SCM_UNSPECIFIED;
  1520. }
  1521. #undef FUNC_NAME
  1522. SCM_DEFINE (scm_bitvector_fill_x, "bitvector-fill!", 2, 0, 0,
  1523. (SCM vec, SCM val),
  1524. "Set all elements of the bitvector\n"
  1525. "@var{vec} when @var{val} is true, else clear them.")
  1526. #define FUNC_NAME s_scm_bitvector_fill_x
  1527. {
  1528. scm_t_array_handle handle;
  1529. size_t off, len;
  1530. ssize_t inc;
  1531. scm_t_uint32 *bits;
  1532. bits = scm_bitvector_writable_elements (vec, &handle,
  1533. &off, &len, &inc);
  1534. if (off == 0 && inc == 1 && len > 0)
  1535. {
  1536. /* the usual case
  1537. */
  1538. size_t word_len = (len + 31) / 32;
  1539. scm_t_uint32 last_mask = ((scm_t_uint32)-1) >> (32*word_len - len);
  1540. if (scm_is_true (val))
  1541. {
  1542. memset (bits, 0xFF, sizeof(scm_t_uint32)*(word_len-1));
  1543. bits[word_len-1] |= last_mask;
  1544. }
  1545. else
  1546. {
  1547. memset (bits, 0x00, sizeof(scm_t_uint32)*(word_len-1));
  1548. bits[word_len-1] &= ~last_mask;
  1549. }
  1550. }
  1551. else
  1552. {
  1553. size_t i;
  1554. for (i = 0; i < len; i++)
  1555. scm_array_handle_set (&handle, i*inc, val);
  1556. }
  1557. scm_array_handle_release (&handle);
  1558. return SCM_UNSPECIFIED;
  1559. }
  1560. #undef FUNC_NAME
  1561. SCM_DEFINE (scm_list_to_bitvector, "list->bitvector", 1, 0, 0,
  1562. (SCM list),
  1563. "Return a new bitvector initialized with the elements\n"
  1564. "of @var{list}.")
  1565. #define FUNC_NAME s_scm_list_to_bitvector
  1566. {
  1567. size_t bit_len = scm_to_size_t (scm_length (list));
  1568. SCM vec = scm_c_make_bitvector (bit_len, SCM_UNDEFINED);
  1569. size_t word_len = (bit_len+31)/32;
  1570. scm_t_array_handle handle;
  1571. scm_t_uint32 *bits = scm_bitvector_writable_elements (vec, &handle,
  1572. NULL, NULL, NULL);
  1573. size_t i, j;
  1574. for (i = 0; i < word_len && scm_is_pair (list); i++, bit_len -= 32)
  1575. {
  1576. scm_t_uint32 mask = 1;
  1577. bits[i] = 0;
  1578. for (j = 0; j < 32 && j < bit_len;
  1579. j++, mask <<= 1, list = SCM_CDR (list))
  1580. if (scm_is_true (SCM_CAR (list)))
  1581. bits[i] |= mask;
  1582. }
  1583. scm_array_handle_release (&handle);
  1584. return vec;
  1585. }
  1586. #undef FUNC_NAME
  1587. SCM_DEFINE (scm_bitvector_to_list, "bitvector->list", 1, 0, 0,
  1588. (SCM vec),
  1589. "Return a new list initialized with the elements\n"
  1590. "of the bitvector @var{vec}.")
  1591. #define FUNC_NAME s_scm_bitvector_to_list
  1592. {
  1593. scm_t_array_handle handle;
  1594. size_t off, len;
  1595. ssize_t inc;
  1596. scm_t_uint32 *bits;
  1597. SCM res = SCM_EOL;
  1598. bits = scm_bitvector_writable_elements (vec, &handle,
  1599. &off, &len, &inc);
  1600. if (off == 0 && inc == 1)
  1601. {
  1602. /* the usual case
  1603. */
  1604. size_t word_len = (len + 31) / 32;
  1605. size_t i, j;
  1606. for (i = 0; i < word_len; i++, len -= 32)
  1607. {
  1608. scm_t_uint32 mask = 1;
  1609. for (j = 0; j < 32 && j < len; j++, mask <<= 1)
  1610. res = scm_cons ((bits[i] & mask)? SCM_BOOL_T : SCM_BOOL_F, res);
  1611. }
  1612. }
  1613. else
  1614. {
  1615. size_t i;
  1616. for (i = 0; i < len; i++)
  1617. res = scm_cons (scm_array_handle_ref (&handle, i*inc), res);
  1618. }
  1619. scm_array_handle_release (&handle);
  1620. return scm_reverse_x (res, SCM_EOL);
  1621. }
  1622. #undef FUNC_NAME
  1623. /* From mmix-arith.w by Knuth.
  1624. Here's a fun way to count the number of bits in a tetrabyte.
  1625. [This classical trick is called the ``Gillies--Miller method for
  1626. sideways addition'' in {\sl The Preparation of Programs for an
  1627. Electronic Digital Computer\/} by Wilkes, Wheeler, and Gill, second
  1628. edition (Reading, Mass.:\ Addison--Wesley, 1957), 191--193. Some of
  1629. the tricks used here were suggested by Balbir Singh, Peter
  1630. Rossmanith, and Stefan Schwoon.]
  1631. */
  1632. static size_t
  1633. count_ones (scm_t_uint32 x)
  1634. {
  1635. x=x-((x>>1)&0x55555555);
  1636. x=(x&0x33333333)+((x>>2)&0x33333333);
  1637. x=(x+(x>>4))&0x0f0f0f0f;
  1638. x=x+(x>>8);
  1639. return (x+(x>>16)) & 0xff;
  1640. }
  1641. SCM_DEFINE (scm_bit_count, "bit-count", 2, 0, 0,
  1642. (SCM b, SCM bitvector),
  1643. "Return the number of occurrences of the boolean @var{b} in\n"
  1644. "@var{bitvector}.")
  1645. #define FUNC_NAME s_scm_bit_count
  1646. {
  1647. scm_t_array_handle handle;
  1648. size_t off, len;
  1649. ssize_t inc;
  1650. scm_t_uint32 *bits;
  1651. int bit = scm_to_bool (b);
  1652. size_t count = 0;
  1653. bits = scm_bitvector_writable_elements (bitvector, &handle,
  1654. &off, &len, &inc);
  1655. if (off == 0 && inc == 1 && len > 0)
  1656. {
  1657. /* the usual case
  1658. */
  1659. size_t word_len = (len + 31) / 32;
  1660. scm_t_uint32 last_mask = ((scm_t_uint32)-1) >> (32*word_len - len);
  1661. size_t i;
  1662. for (i = 0; i < word_len-1; i++)
  1663. count += count_ones (bits[i]);
  1664. count += count_ones (bits[i] & last_mask);
  1665. }
  1666. else
  1667. {
  1668. size_t i;
  1669. for (i = 0; i < len; i++)
  1670. if (scm_is_true (scm_array_handle_ref (&handle, i*inc)))
  1671. count++;
  1672. }
  1673. scm_array_handle_release (&handle);
  1674. return scm_from_size_t (bit? count : len-count);
  1675. }
  1676. #undef FUNC_NAME
  1677. /* returns 32 for x == 0.
  1678. */
  1679. static size_t
  1680. find_first_one (scm_t_uint32 x)
  1681. {
  1682. size_t pos = 0;
  1683. /* do a binary search in x. */
  1684. if ((x & 0xFFFF) == 0)
  1685. x >>= 16, pos += 16;
  1686. if ((x & 0xFF) == 0)
  1687. x >>= 8, pos += 8;
  1688. if ((x & 0xF) == 0)
  1689. x >>= 4, pos += 4;
  1690. if ((x & 0x3) == 0)
  1691. x >>= 2, pos += 2;
  1692. if ((x & 0x1) == 0)
  1693. pos += 1;
  1694. return pos;
  1695. }
  1696. SCM_DEFINE (scm_bit_position, "bit-position", 3, 0, 0,
  1697. (SCM item, SCM v, SCM k),
  1698. "Return the index of the first occurrance of @var{item} in bit\n"
  1699. "vector @var{v}, starting from @var{k}. If there is no\n"
  1700. "@var{item} entry between @var{k} and the end of\n"
  1701. "@var{bitvector}, then return @code{#f}. For example,\n"
  1702. "\n"
  1703. "@example\n"
  1704. "(bit-position #t #*000101 0) @result{} 3\n"
  1705. "(bit-position #f #*0001111 3) @result{} #f\n"
  1706. "@end example")
  1707. #define FUNC_NAME s_scm_bit_position
  1708. {
  1709. scm_t_array_handle handle;
  1710. size_t off, len, first_bit;
  1711. ssize_t inc;
  1712. const scm_t_uint32 *bits;
  1713. int bit = scm_to_bool (item);
  1714. SCM res = SCM_BOOL_F;
  1715. bits = scm_bitvector_elements (v, &handle, &off, &len, &inc);
  1716. first_bit = scm_to_unsigned_integer (k, 0, len);
  1717. if (off == 0 && inc == 1 && len > 0)
  1718. {
  1719. size_t i, word_len = (len + 31) / 32;
  1720. scm_t_uint32 last_mask = ((scm_t_uint32)-1) >> (32*word_len - len);
  1721. size_t first_word = first_bit / 32;
  1722. scm_t_uint32 first_mask =
  1723. ((scm_t_uint32)-1) << (first_bit - 32*first_word);
  1724. scm_t_uint32 w;
  1725. for (i = first_word; i < word_len; i++)
  1726. {
  1727. w = (bit? bits[i] : ~bits[i]);
  1728. if (i == first_word)
  1729. w &= first_mask;
  1730. if (i == word_len-1)
  1731. w &= last_mask;
  1732. if (w)
  1733. {
  1734. res = scm_from_size_t (32*i + find_first_one (w));
  1735. break;
  1736. }
  1737. }
  1738. }
  1739. else
  1740. {
  1741. size_t i;
  1742. for (i = first_bit; i < len; i++)
  1743. {
  1744. SCM elt = scm_array_handle_ref (&handle, i*inc);
  1745. if ((bit && scm_is_true (elt)) || (!bit && scm_is_false (elt)))
  1746. {
  1747. res = scm_from_size_t (i);
  1748. break;
  1749. }
  1750. }
  1751. }
  1752. scm_array_handle_release (&handle);
  1753. return res;
  1754. }
  1755. #undef FUNC_NAME
  1756. SCM_DEFINE (scm_bit_set_star_x, "bit-set*!", 3, 0, 0,
  1757. (SCM v, SCM kv, SCM obj),
  1758. "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
  1759. "selecting the entries to change. The return value is\n"
  1760. "unspecified.\n"
  1761. "\n"
  1762. "If @var{kv} is a bit vector, then those entries where it has\n"
  1763. "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
  1764. "@var{kv} and @var{v} must be the same length. When @var{obj}\n"
  1765. "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
  1766. "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
  1767. "\n"
  1768. "@example\n"
  1769. "(define bv #*01000010)\n"
  1770. "(bit-set*! bv #*10010001 #t)\n"
  1771. "bv\n"
  1772. "@result{} #*11010011\n"
  1773. "@end example\n"
  1774. "\n"
  1775. "If @var{kv} is a u32vector, then its elements are\n"
  1776. "indices into @var{v} which are set to @var{obj}.\n"
  1777. "\n"
  1778. "@example\n"
  1779. "(define bv #*01000010)\n"
  1780. "(bit-set*! bv #u32(5 2 7) #t)\n"
  1781. "bv\n"
  1782. "@result{} #*01100111\n"
  1783. "@end example")
  1784. #define FUNC_NAME s_scm_bit_set_star_x
  1785. {
  1786. scm_t_array_handle v_handle;
  1787. size_t v_off, v_len;
  1788. ssize_t v_inc;
  1789. scm_t_uint32 *v_bits;
  1790. int bit;
  1791. /* Validate that OBJ is a boolean so this is done even if we don't
  1792. need BIT.
  1793. */
  1794. bit = scm_to_bool (obj);
  1795. v_bits = scm_bitvector_writable_elements (v, &v_handle,
  1796. &v_off, &v_len, &v_inc);
  1797. if (scm_is_bitvector (kv))
  1798. {
  1799. scm_t_array_handle kv_handle;
  1800. size_t kv_off, kv_len;
  1801. ssize_t kv_inc;
  1802. const scm_t_uint32 *kv_bits;
  1803. kv_bits = scm_bitvector_elements (v, &kv_handle,
  1804. &kv_off, &kv_len, &kv_inc);
  1805. if (v_len != kv_len)
  1806. scm_misc_error (NULL,
  1807. "bit vectors must have equal length",
  1808. SCM_EOL);
  1809. if (v_off == 0 && v_inc == 1 && kv_off == 0 && kv_inc == 1 && kv_len > 0)
  1810. {
  1811. size_t word_len = (kv_len + 31) / 32;
  1812. scm_t_uint32 last_mask = ((scm_t_uint32)-1) >> (32*word_len - kv_len);
  1813. size_t i;
  1814. if (bit == 0)
  1815. {
  1816. for (i = 0; i < word_len-1; i++)
  1817. v_bits[i] &= ~kv_bits[i];
  1818. v_bits[i] &= ~(kv_bits[i] & last_mask);
  1819. }
  1820. else
  1821. {
  1822. for (i = 0; i < word_len-1; i++)
  1823. v_bits[i] |= kv_bits[i];
  1824. v_bits[i] |= kv_bits[i] & last_mask;
  1825. }
  1826. }
  1827. else
  1828. {
  1829. size_t i;
  1830. for (i = 0; i < kv_len; i++)
  1831. if (scm_is_true (scm_array_handle_ref (&kv_handle, i*kv_inc)))
  1832. scm_array_handle_set (&v_handle, i*v_inc, obj);
  1833. }
  1834. scm_array_handle_release (&kv_handle);
  1835. }
  1836. else if (scm_is_true (scm_u32vector_p (kv)))
  1837. {
  1838. scm_t_array_handle kv_handle;
  1839. size_t i, kv_len;
  1840. ssize_t kv_inc;
  1841. const scm_t_uint32 *kv_elts;
  1842. kv_elts = scm_u32vector_elements (kv, &kv_handle, &kv_len, &kv_inc);
  1843. for (i = 0; i < kv_len; i++, kv_elts += kv_inc)
  1844. scm_array_handle_set (&v_handle, (*kv_elts)*v_inc, obj);
  1845. scm_array_handle_release (&kv_handle);
  1846. }
  1847. else
  1848. scm_wrong_type_arg_msg (NULL, 0, kv, "bitvector or u32vector");
  1849. scm_array_handle_release (&v_handle);
  1850. return SCM_UNSPECIFIED;
  1851. }
  1852. #undef FUNC_NAME
  1853. SCM_DEFINE (scm_bit_count_star, "bit-count*", 3, 0, 0,
  1854. (SCM v, SCM kv, SCM obj),
  1855. "Return a count of how many entries in bit vector @var{v} are\n"
  1856. "equal to @var{obj}, with @var{kv} selecting the entries to\n"
  1857. "consider.\n"
  1858. "\n"
  1859. "If @var{kv} is a bit vector, then those entries where it has\n"
  1860. "@code{#t} are the ones in @var{v} which are considered.\n"
  1861. "@var{kv} and @var{v} must be the same length.\n"
  1862. "\n"
  1863. "If @var{kv} is a u32vector, then it contains\n"
  1864. "the indexes in @var{v} to consider.\n"
  1865. "\n"
  1866. "For example,\n"
  1867. "\n"
  1868. "@example\n"
  1869. "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
  1870. "(bit-count* #*01110111 #u32(7 0 4) #f) @result{} 2\n"
  1871. "@end example")
  1872. #define FUNC_NAME s_scm_bit_count_star
  1873. {
  1874. scm_t_array_handle v_handle;
  1875. size_t v_off, v_len;
  1876. ssize_t v_inc;
  1877. const scm_t_uint32 *v_bits;
  1878. size_t count = 0;
  1879. int bit;
  1880. /* Validate that OBJ is a boolean so this is done even if we don't
  1881. need BIT.
  1882. */
  1883. bit = scm_to_bool (obj);
  1884. v_bits = scm_bitvector_elements (v, &v_handle,
  1885. &v_off, &v_len, &v_inc);
  1886. if (scm_is_bitvector (kv))
  1887. {
  1888. scm_t_array_handle kv_handle;
  1889. size_t kv_off, kv_len;
  1890. ssize_t kv_inc;
  1891. const scm_t_uint32 *kv_bits;
  1892. kv_bits = scm_bitvector_elements (v, &kv_handle,
  1893. &kv_off, &kv_len, &kv_inc);
  1894. if (v_len != kv_len)
  1895. scm_misc_error (NULL,
  1896. "bit vectors must have equal length",
  1897. SCM_EOL);
  1898. if (v_off == 0 && v_inc == 1 && kv_off == 0 && kv_inc == 1 && kv_len > 0)
  1899. {
  1900. size_t i, word_len = (kv_len + 31) / 32;
  1901. scm_t_uint32 last_mask = ((scm_t_uint32)-1) >> (32*word_len - kv_len);
  1902. scm_t_uint32 xor_mask = bit? 0 : ((scm_t_uint32)-1);
  1903. for (i = 0; i < word_len-1; i++)
  1904. count += count_ones ((v_bits[i]^xor_mask) & kv_bits[i]);
  1905. count += count_ones ((v_bits[i]^xor_mask) & kv_bits[i] & last_mask);
  1906. }
  1907. else
  1908. {
  1909. size_t i;
  1910. for (i = 0; i < kv_len; i++)
  1911. if (scm_is_true (scm_array_handle_ref (&kv_handle, i)))
  1912. {
  1913. SCM elt = scm_array_handle_ref (&v_handle, i*v_inc);
  1914. if ((bit && scm_is_true (elt)) || (!bit && scm_is_false (elt)))
  1915. count++;
  1916. }
  1917. }
  1918. scm_array_handle_release (&kv_handle);
  1919. }
  1920. else if (scm_is_true (scm_u32vector_p (kv)))
  1921. {
  1922. scm_t_array_handle kv_handle;
  1923. size_t i, kv_len;
  1924. ssize_t kv_inc;
  1925. const scm_t_uint32 *kv_elts;
  1926. kv_elts = scm_u32vector_elements (kv, &kv_handle, &kv_len, &kv_inc);
  1927. for (i = 0; i < kv_len; i++, kv_elts += kv_inc)
  1928. {
  1929. SCM elt = scm_array_handle_ref (&v_handle, (*kv_elts)*v_inc);
  1930. if ((bit && scm_is_true (elt)) || (!bit && scm_is_false (elt)))
  1931. count++;
  1932. }
  1933. scm_array_handle_release (&kv_handle);
  1934. }
  1935. else
  1936. scm_wrong_type_arg_msg (NULL, 0, kv, "bitvector or u32vector");
  1937. scm_array_handle_release (&v_handle);
  1938. return scm_from_size_t (count);
  1939. }
  1940. #undef FUNC_NAME
  1941. SCM_DEFINE (scm_bit_invert_x, "bit-invert!", 1, 0, 0,
  1942. (SCM v),
  1943. "Modify the bit vector @var{v} by replacing each element with\n"
  1944. "its negation.")
  1945. #define FUNC_NAME s_scm_bit_invert_x
  1946. {
  1947. scm_t_array_handle handle;
  1948. size_t off, len;
  1949. ssize_t inc;
  1950. scm_t_uint32 *bits;
  1951. bits = scm_bitvector_writable_elements (v, &handle, &off, &len, &inc);
  1952. if (off == 0 && inc == 1 && len > 0)
  1953. {
  1954. size_t word_len = (len + 31) / 32;
  1955. scm_t_uint32 last_mask = ((scm_t_uint32)-1) >> (32*word_len - len);
  1956. size_t i;
  1957. for (i = 0; i < word_len-1; i++)
  1958. bits[i] = ~bits[i];
  1959. bits[i] = bits[i] ^ last_mask;
  1960. }
  1961. else
  1962. {
  1963. size_t i;
  1964. for (i = 0; i < len; i++)
  1965. scm_array_handle_set (&handle, i*inc,
  1966. scm_not (scm_array_handle_ref (&handle, i*inc)));
  1967. }
  1968. scm_array_handle_release (&handle);
  1969. return SCM_UNSPECIFIED;
  1970. }
  1971. #undef FUNC_NAME
  1972. SCM
  1973. scm_istr2bve (SCM str)
  1974. {
  1975. scm_t_array_handle handle;
  1976. size_t len = scm_i_string_length (str);
  1977. SCM vec = scm_c_make_bitvector (len, SCM_UNDEFINED);
  1978. SCM res = vec;
  1979. scm_t_uint32 mask;
  1980. size_t k, j;
  1981. const char *c_str;
  1982. scm_t_uint32 *data;
  1983. data = scm_bitvector_writable_elements (vec, &handle, NULL, NULL, NULL);
  1984. c_str = scm_i_string_chars (str);
  1985. for (k = 0; k < (len + 31) / 32; k++)
  1986. {
  1987. data[k] = 0L;
  1988. j = len - k * 32;
  1989. if (j > 32)
  1990. j = 32;
  1991. for (mask = 1L; j--; mask <<= 1)
  1992. switch (*c_str++)
  1993. {
  1994. case '0':
  1995. break;
  1996. case '1':
  1997. data[k] |= mask;
  1998. break;
  1999. default:
  2000. res = SCM_BOOL_F;
  2001. goto exit;
  2002. }
  2003. }
  2004. exit:
  2005. scm_array_handle_release (&handle);
  2006. scm_remember_upto_here_1 (str);
  2007. return res;
  2008. }
  2009. static SCM
  2010. ra2l (SCM ra, unsigned long base, unsigned long k)
  2011. {
  2012. SCM res = SCM_EOL;
  2013. long inc;
  2014. size_t i;
  2015. int enclosed = SCM_I_ENCLOSED_ARRAYP (ra);
  2016. if (k == SCM_I_ARRAY_NDIM (ra))
  2017. return scm_i_cvref (SCM_I_ARRAY_V (ra), base, enclosed);
  2018. inc = SCM_I_ARRAY_DIMS (ra)[k].inc;
  2019. if (SCM_I_ARRAY_DIMS (ra)[k].ubnd < SCM_I_ARRAY_DIMS (ra)[k].lbnd)
  2020. return SCM_EOL;
  2021. i = base + (1 + SCM_I_ARRAY_DIMS (ra)[k].ubnd - SCM_I_ARRAY_DIMS (ra)[k].lbnd) * inc;
  2022. do
  2023. {
  2024. i -= inc;
  2025. res = scm_cons (ra2l (ra, i, k + 1), res);
  2026. }
  2027. while (i != base);
  2028. return res;
  2029. }
  2030. SCM_DEFINE (scm_array_to_list, "array->list", 1, 0, 0,
  2031. (SCM v),
  2032. "Return a list consisting of all the elements, in order, of\n"
  2033. "@var{array}.")
  2034. #define FUNC_NAME s_scm_array_to_list
  2035. {
  2036. if (scm_is_generalized_vector (v))
  2037. return scm_generalized_vector_to_list (v);
  2038. else if (SCM_I_ARRAYP (v) || SCM_I_ENCLOSED_ARRAYP (v))
  2039. return ra2l (v, SCM_I_ARRAY_BASE (v), 0);
  2040. scm_wrong_type_arg_msg (NULL, 0, v, "array");
  2041. }
  2042. #undef FUNC_NAME
  2043. static void l2ra (SCM lst, scm_t_array_handle *handle, ssize_t pos, size_t k);
  2044. SCM_DEFINE (scm_list_to_typed_array, "list->typed-array", 3, 0, 0,
  2045. (SCM type, SCM shape, SCM lst),
  2046. "Return an array of the type @var{type}\n"
  2047. "with elements the same as those of @var{lst}.\n"
  2048. "\n"
  2049. "The argument @var{shape} determines the number of dimensions\n"
  2050. "of the array and their shape. It is either an exact integer,\n"
  2051. "giving the\n"
  2052. "number of dimensions directly, or a list whose length\n"
  2053. "specifies the number of dimensions and each element specified\n"
  2054. "the lower and optionally the upper bound of the corresponding\n"
  2055. "dimension.\n"
  2056. "When the element is list of two elements, these elements\n"
  2057. "give the lower and upper bounds. When it is an exact\n"
  2058. "integer, it gives only the lower bound.")
  2059. #define FUNC_NAME s_scm_list_to_typed_array
  2060. {
  2061. SCM row;
  2062. SCM ra;
  2063. scm_t_array_handle handle;
  2064. row = lst;
  2065. if (scm_is_integer (shape))
  2066. {
  2067. size_t k = scm_to_size_t (shape);
  2068. shape = SCM_EOL;
  2069. while (k-- > 0)
  2070. {
  2071. shape = scm_cons (scm_length (row), shape);
  2072. if (k > 0 && !scm_is_null (row))
  2073. row = scm_car (row);
  2074. }
  2075. }
  2076. else
  2077. {
  2078. SCM shape_spec = shape;
  2079. shape = SCM_EOL;
  2080. while (1)
  2081. {
  2082. SCM spec = scm_car (shape_spec);
  2083. if (scm_is_pair (spec))
  2084. shape = scm_cons (spec, shape);
  2085. else
  2086. shape = scm_cons (scm_list_2 (spec,
  2087. scm_sum (scm_sum (spec,
  2088. scm_length (row)),
  2089. scm_from_int (-1))),
  2090. shape);
  2091. shape_spec = scm_cdr (shape_spec);
  2092. if (scm_is_pair (shape_spec))
  2093. {
  2094. if (!scm_is_null (row))
  2095. row = scm_car (row);
  2096. }
  2097. else
  2098. break;
  2099. }
  2100. }
  2101. ra = scm_make_typed_array (type, SCM_UNSPECIFIED,
  2102. scm_reverse_x (shape, SCM_EOL));
  2103. scm_array_get_handle (ra, &handle);
  2104. l2ra (lst, &handle, 0, 0);
  2105. scm_array_handle_release (&handle);
  2106. return ra;
  2107. }
  2108. #undef FUNC_NAME
  2109. SCM_DEFINE (scm_list_to_array, "list->array", 2, 0, 0,
  2110. (SCM ndim, SCM lst),
  2111. "Return an array with elements the same as those of @var{lst}.")
  2112. #define FUNC_NAME s_scm_list_to_array
  2113. {
  2114. return scm_list_to_typed_array (SCM_BOOL_T, ndim, lst);
  2115. }
  2116. #undef FUNC_NAME
  2117. static void
  2118. l2ra (SCM lst, scm_t_array_handle *handle, ssize_t pos, size_t k)
  2119. {
  2120. if (k == scm_array_handle_rank (handle))
  2121. scm_array_handle_set (handle, pos, lst);
  2122. else
  2123. {
  2124. scm_t_array_dim *dim = scm_array_handle_dims (handle) + k;
  2125. ssize_t inc = dim->inc;
  2126. size_t len = 1 + dim->ubnd - dim->lbnd, n;
  2127. char *errmsg = NULL;
  2128. n = len;
  2129. while (n > 0 && scm_is_pair (lst))
  2130. {
  2131. l2ra (SCM_CAR (lst), handle, pos, k + 1);
  2132. pos += inc;
  2133. lst = SCM_CDR (lst);
  2134. n -= 1;
  2135. }
  2136. if (n != 0)
  2137. errmsg = "too few elements for array dimension ~a, need ~a";
  2138. if (!scm_is_null (lst))
  2139. errmsg = "too many elements for array dimension ~a, want ~a";
  2140. if (errmsg)
  2141. scm_misc_error (NULL, errmsg, scm_list_2 (scm_from_ulong (k),
  2142. scm_from_size_t (len)));
  2143. }
  2144. }
  2145. #if SCM_ENABLE_DEPRECATED
  2146. SCM_DEFINE (scm_list_to_uniform_array, "list->uniform-array", 3, 0, 0,
  2147. (SCM ndim, SCM prot, SCM lst),
  2148. "Return a uniform array of the type indicated by prototype\n"
  2149. "@var{prot} with elements the same as those of @var{lst}.\n"
  2150. "Elements must be of the appropriate type, no coercions are\n"
  2151. "done.\n"
  2152. "\n"
  2153. "The argument @var{ndim} determines the number of dimensions\n"
  2154. "of the array. It is either an exact integer, giving the\n"
  2155. "number directly, or a list of exact integers, whose length\n"
  2156. "specifies the number of dimensions and each element is the\n"
  2157. "lower index bound of its dimension.")
  2158. #define FUNC_NAME s_scm_list_to_uniform_array
  2159. {
  2160. return scm_list_to_typed_array (prototype_to_type (prot), ndim, lst);
  2161. }
  2162. #undef FUNC_NAME
  2163. #endif
  2164. /* Print dimension DIM of ARRAY.
  2165. */
  2166. static int
  2167. scm_i_print_array_dimension (SCM array, int dim, int base, int enclosed,
  2168. SCM port, scm_print_state *pstate)
  2169. {
  2170. scm_t_array_dim *dim_spec = SCM_I_ARRAY_DIMS (array) + dim;
  2171. long idx;
  2172. scm_putc ('(', port);
  2173. for (idx = dim_spec->lbnd; idx <= dim_spec->ubnd; idx++)
  2174. {
  2175. if (dim < SCM_I_ARRAY_NDIM(array)-1)
  2176. scm_i_print_array_dimension (array, dim+1, base, enclosed,
  2177. port, pstate);
  2178. else
  2179. scm_iprin1 (scm_i_cvref (SCM_I_ARRAY_V (array), base, enclosed),
  2180. port, pstate);
  2181. if (idx < dim_spec->ubnd)
  2182. scm_putc (' ', port);
  2183. base += dim_spec->inc;
  2184. }
  2185. scm_putc (')', port);
  2186. return 1;
  2187. }
  2188. /* Print an array. (Only for strict arrays, not for generalized vectors.)
  2189. */
  2190. static int
  2191. scm_i_print_array (SCM array, SCM port, scm_print_state *pstate)
  2192. {
  2193. long ndim = SCM_I_ARRAY_NDIM (array);
  2194. scm_t_array_dim *dim_specs = SCM_I_ARRAY_DIMS (array);
  2195. SCM v = SCM_I_ARRAY_V (array);
  2196. unsigned long base = SCM_I_ARRAY_BASE (array);
  2197. long i;
  2198. int print_lbnds = 0, zero_size = 0, print_lens = 0;
  2199. scm_putc ('#', port);
  2200. if (ndim != 1 || dim_specs[0].lbnd != 0)
  2201. scm_intprint (ndim, 10, port);
  2202. if (scm_is_uniform_vector (v))
  2203. scm_puts (scm_i_uniform_vector_tag (v), port);
  2204. else if (scm_is_bitvector (v))
  2205. scm_puts ("b", port);
  2206. else if (scm_is_string (v))
  2207. scm_puts ("a", port);
  2208. else if (!scm_is_vector (v))
  2209. scm_puts ("?", port);
  2210. for (i = 0; i < ndim; i++)
  2211. {
  2212. if (dim_specs[i].lbnd != 0)
  2213. print_lbnds = 1;
  2214. if (dim_specs[i].ubnd - dim_specs[i].lbnd + 1 == 0)
  2215. zero_size = 1;
  2216. else if (zero_size)
  2217. print_lens = 1;
  2218. }
  2219. if (print_lbnds || print_lens)
  2220. for (i = 0; i < ndim; i++)
  2221. {
  2222. if (print_lbnds)
  2223. {
  2224. scm_putc ('@', port);
  2225. scm_intprint (dim_specs[i].lbnd, 10, port);
  2226. }
  2227. if (print_lens)
  2228. {
  2229. scm_putc (':', port);
  2230. scm_intprint (dim_specs[i].ubnd - dim_specs[i].lbnd + 1,
  2231. 10, port);
  2232. }
  2233. }
  2234. if (ndim == 0)
  2235. {
  2236. /* Rank zero arrays, which are really just scalars, are printed
  2237. specially. The consequent way would be to print them as
  2238. #0 OBJ
  2239. where OBJ is the printed representation of the scalar, but we
  2240. print them instead as
  2241. #0(OBJ)
  2242. to make them look less strange.
  2243. Just printing them as
  2244. OBJ
  2245. would be correct in a way as well, but zero rank arrays are
  2246. not really the same as Scheme values since they are boxed and
  2247. can be modified with array-set!, say.
  2248. */
  2249. scm_putc ('(', port);
  2250. scm_iprin1 (scm_i_cvref (v, base, 0), port, pstate);
  2251. scm_putc (')', port);
  2252. return 1;
  2253. }
  2254. else
  2255. return scm_i_print_array_dimension (array, 0, base, 0, port, pstate);
  2256. }
  2257. static int
  2258. scm_i_print_enclosed_array (SCM array, SCM port, scm_print_state *pstate)
  2259. {
  2260. size_t base;
  2261. scm_putc ('#', port);
  2262. base = SCM_I_ARRAY_BASE (array);
  2263. scm_puts ("<enclosed-array ", port);
  2264. scm_i_print_array_dimension (array, 0, base, 1, port, pstate);
  2265. scm_putc ('>', port);
  2266. return 1;
  2267. }
  2268. /* Read an array. This function can also read vectors and uniform
  2269. vectors. Also, the conflict between '#f' and '#f32' and '#f64' is
  2270. handled here.
  2271. C is the first character read after the '#'.
  2272. */
  2273. static SCM
  2274. tag_to_type (const char *tag, SCM port)
  2275. {
  2276. #if SCM_ENABLE_DEPRECATED
  2277. {
  2278. /* Recognize the old syntax.
  2279. */
  2280. const char *instead;
  2281. switch (tag[0])
  2282. {
  2283. case 'u':
  2284. instead = "u32";
  2285. break;
  2286. case 'e':
  2287. instead = "s32";
  2288. break;
  2289. case 's':
  2290. instead = "f32";
  2291. break;
  2292. case 'i':
  2293. instead = "f64";
  2294. break;
  2295. case 'y':
  2296. instead = "s8";
  2297. break;
  2298. case 'h':
  2299. instead = "s16";
  2300. break;
  2301. case 'l':
  2302. instead = "s64";
  2303. break;
  2304. case 'c':
  2305. instead = "c64";
  2306. break;
  2307. default:
  2308. instead = NULL;
  2309. break;
  2310. }
  2311. if (instead && tag[1] == '\0')
  2312. {
  2313. scm_c_issue_deprecation_warning_fmt
  2314. ("The tag '%c' is deprecated for uniform vectors. "
  2315. "Use '%s' instead.", tag[0], instead);
  2316. return scm_from_locale_symbol (instead);
  2317. }
  2318. }
  2319. #endif
  2320. if (*tag == '\0')
  2321. return SCM_BOOL_T;
  2322. else
  2323. return scm_from_locale_symbol (tag);
  2324. }
  2325. static int
  2326. read_decimal_integer (SCM port, int c, ssize_t *resp)
  2327. {
  2328. ssize_t sign = 1;
  2329. ssize_t res = 0;
  2330. int got_it = 0;
  2331. if (c == '-')
  2332. {
  2333. sign = -1;
  2334. c = scm_getc (port);
  2335. }
  2336. while ('0' <= c && c <= '9')
  2337. {
  2338. res = 10*res + c-'0';
  2339. got_it = 1;
  2340. c = scm_getc (port);
  2341. }
  2342. if (got_it)
  2343. *resp = sign * res;
  2344. return c;
  2345. }
  2346. SCM
  2347. scm_i_read_array (SCM port, int c)
  2348. {
  2349. ssize_t rank;
  2350. char tag[80];
  2351. int tag_len;
  2352. SCM shape = SCM_BOOL_F, elements;
  2353. /* XXX - shortcut for ordinary vectors. Shouldn't be necessary but
  2354. the array code can not deal with zero-length dimensions yet, and
  2355. we want to allow zero-length vectors, of course.
  2356. */
  2357. if (c == '(')
  2358. {
  2359. scm_ungetc (c, port);
  2360. return scm_vector (scm_read (port));
  2361. }
  2362. /* Disambiguate between '#f' and uniform floating point vectors.
  2363. */
  2364. if (c == 'f')
  2365. {
  2366. c = scm_getc (port);
  2367. if (c != '3' && c != '6')
  2368. {
  2369. if (c != EOF)
  2370. scm_ungetc (c, port);
  2371. return SCM_BOOL_F;
  2372. }
  2373. rank = 1;
  2374. tag[0] = 'f';
  2375. tag_len = 1;
  2376. goto continue_reading_tag;
  2377. }
  2378. /* Read rank.
  2379. */
  2380. rank = 1;
  2381. c = read_decimal_integer (port, c, &rank);
  2382. if (rank < 0)
  2383. scm_i_input_error (NULL, port, "array rank must be non-negative",
  2384. SCM_EOL);
  2385. /* Read tag.
  2386. */
  2387. tag_len = 0;
  2388. continue_reading_tag:
  2389. while (c != EOF && c != '(' && c != '@' && c != ':' && tag_len < 79)
  2390. {
  2391. tag[tag_len++] = c;
  2392. c = scm_getc (port);
  2393. }
  2394. tag[tag_len] = '\0';
  2395. /* Read shape.
  2396. */
  2397. if (c == '@' || c == ':')
  2398. {
  2399. shape = SCM_EOL;
  2400. do
  2401. {
  2402. ssize_t lbnd = 0, len = 0;
  2403. SCM s;
  2404. if (c == '@')
  2405. {
  2406. c = scm_getc (port);
  2407. c = read_decimal_integer (port, c, &lbnd);
  2408. }
  2409. s = scm_from_ssize_t (lbnd);
  2410. if (c == ':')
  2411. {
  2412. c = scm_getc (port);
  2413. c = read_decimal_integer (port, c, &len);
  2414. if (len < 0)
  2415. scm_i_input_error (NULL, port,
  2416. "array length must be non-negative",
  2417. SCM_EOL);
  2418. s = scm_list_2 (s, scm_from_ssize_t (lbnd+len-1));
  2419. }
  2420. shape = scm_cons (s, shape);
  2421. } while (c == '@' || c == ':');
  2422. shape = scm_reverse_x (shape, SCM_EOL);
  2423. }
  2424. /* Read nested lists of elements.
  2425. */
  2426. if (c != '(')
  2427. scm_i_input_error (NULL, port,
  2428. "missing '(' in vector or array literal",
  2429. SCM_EOL);
  2430. scm_ungetc (c, port);
  2431. elements = scm_read (port);
  2432. if (scm_is_false (shape))
  2433. shape = scm_from_ssize_t (rank);
  2434. else if (scm_ilength (shape) != rank)
  2435. scm_i_input_error
  2436. (NULL, port,
  2437. "the number of shape specifications must match the array rank",
  2438. SCM_EOL);
  2439. /* Handle special print syntax of rank zero arrays; see
  2440. scm_i_print_array for a rationale.
  2441. */
  2442. if (rank == 0)
  2443. {
  2444. if (!scm_is_pair (elements))
  2445. scm_i_input_error (NULL, port,
  2446. "too few elements in array literal, need 1",
  2447. SCM_EOL);
  2448. if (!scm_is_null (SCM_CDR (elements)))
  2449. scm_i_input_error (NULL, port,
  2450. "too many elements in array literal, want 1",
  2451. SCM_EOL);
  2452. elements = SCM_CAR (elements);
  2453. }
  2454. /* Construct array.
  2455. */
  2456. return scm_list_to_typed_array (tag_to_type (tag, port), shape, elements);
  2457. }
  2458. SCM_DEFINE (scm_array_type, "array-type", 1, 0, 0,
  2459. (SCM ra),
  2460. "")
  2461. #define FUNC_NAME s_scm_array_type
  2462. {
  2463. if (SCM_I_ARRAYP (ra))
  2464. return scm_i_generalized_vector_type (SCM_I_ARRAY_V (ra));
  2465. else if (scm_is_generalized_vector (ra))
  2466. return scm_i_generalized_vector_type (ra);
  2467. else if (SCM_I_ENCLOSED_ARRAYP (ra))
  2468. scm_wrong_type_arg_msg (NULL, 0, ra, "non-enclosed array");
  2469. else
  2470. scm_wrong_type_arg_msg (NULL, 0, ra, "array");
  2471. }
  2472. #undef FUNC_NAME
  2473. #if SCM_ENABLE_DEPRECATED
  2474. SCM_DEFINE (scm_array_prototype, "array-prototype", 1, 0, 0,
  2475. (SCM ra),
  2476. "Return an object that would produce an array of the same type\n"
  2477. "as @var{array}, if used as the @var{prototype} for\n"
  2478. "@code{make-uniform-array}.")
  2479. #define FUNC_NAME s_scm_array_prototype
  2480. {
  2481. if (SCM_I_ARRAYP (ra))
  2482. return scm_i_get_old_prototype (SCM_I_ARRAY_V (ra));
  2483. else if (scm_is_generalized_vector (ra))
  2484. return scm_i_get_old_prototype (ra);
  2485. else if (SCM_I_ENCLOSED_ARRAYP (ra))
  2486. return SCM_UNSPECIFIED;
  2487. else
  2488. scm_wrong_type_arg_msg (NULL, 0, ra, "array");
  2489. }
  2490. #undef FUNC_NAME
  2491. #endif
  2492. static SCM
  2493. array_mark (SCM ptr)
  2494. {
  2495. return SCM_I_ARRAY_V (ptr);
  2496. }
  2497. static size_t
  2498. array_free (SCM ptr)
  2499. {
  2500. scm_gc_free (SCM_I_ARRAY_MEM (ptr),
  2501. (sizeof (scm_i_t_array)
  2502. + SCM_I_ARRAY_NDIM (ptr) * sizeof (scm_t_array_dim)),
  2503. "array");
  2504. return 0;
  2505. }
  2506. #if SCM_ENABLE_DEPRECATED
  2507. SCM
  2508. scm_make_ra (int ndim)
  2509. {
  2510. scm_c_issue_deprecation_warning
  2511. ("scm_make_ra is deprecated. Use scm_make_array or similar instead.");
  2512. return scm_i_make_ra (ndim, 0);
  2513. }
  2514. SCM
  2515. scm_shap2ra (SCM args, const char *what)
  2516. {
  2517. scm_c_issue_deprecation_warning
  2518. ("scm_shap2ra is deprecated. Use scm_make_array or similar instead.");
  2519. return scm_i_shap2ra (args);
  2520. }
  2521. SCM
  2522. scm_cvref (SCM v, unsigned long pos, SCM last)
  2523. {
  2524. scm_c_issue_deprecation_warning
  2525. ("scm_cvref is deprecated. Use scm_c_generalized_vector_ref instead.");
  2526. return scm_c_generalized_vector_ref (v, pos);
  2527. }
  2528. void
  2529. scm_ra_set_contp (SCM ra)
  2530. {
  2531. scm_c_issue_deprecation_warning
  2532. ("scm_ra_set_contp is deprecated. There should be no need for it.");
  2533. scm_i_ra_set_contp (ra);
  2534. }
  2535. long
  2536. scm_aind (SCM ra, SCM args, const char *what)
  2537. {
  2538. scm_t_array_handle handle;
  2539. ssize_t pos;
  2540. scm_c_issue_deprecation_warning
  2541. ("scm_aind is deprecated. Use scm_array_handle_pos instead.");
  2542. if (scm_is_integer (args))
  2543. args = scm_list_1 (args);
  2544. scm_array_get_handle (ra, &handle);
  2545. pos = scm_array_handle_pos (&handle, args) + SCM_I_ARRAY_BASE (ra);
  2546. scm_array_handle_release (&handle);
  2547. return pos;
  2548. }
  2549. int
  2550. scm_raprin1 (SCM exp, SCM port, scm_print_state *pstate)
  2551. {
  2552. scm_c_issue_deprecation_warning
  2553. ("scm_raprin1 is deprecated. Use scm_display or scm_write instead.");
  2554. scm_iprin1 (exp, port, pstate);
  2555. return 1;
  2556. }
  2557. #endif
  2558. void
  2559. scm_init_unif ()
  2560. {
  2561. scm_i_tc16_array = scm_make_smob_type ("array", 0);
  2562. scm_set_smob_mark (scm_i_tc16_array, array_mark);
  2563. scm_set_smob_free (scm_i_tc16_array, array_free);
  2564. scm_set_smob_print (scm_i_tc16_array, scm_i_print_array);
  2565. scm_set_smob_equalp (scm_i_tc16_array, scm_array_equal_p);
  2566. scm_i_tc16_enclosed_array = scm_make_smob_type ("enclosed-array", 0);
  2567. scm_set_smob_mark (scm_i_tc16_enclosed_array, array_mark);
  2568. scm_set_smob_free (scm_i_tc16_enclosed_array, array_free);
  2569. scm_set_smob_print (scm_i_tc16_enclosed_array, scm_i_print_enclosed_array);
  2570. scm_set_smob_equalp (scm_i_tc16_enclosed_array, scm_array_equal_p);
  2571. scm_add_feature ("array");
  2572. scm_tc16_bitvector = scm_make_smob_type ("bitvector", 0);
  2573. scm_set_smob_free (scm_tc16_bitvector, bitvector_free);
  2574. scm_set_smob_print (scm_tc16_bitvector, bitvector_print);
  2575. scm_set_smob_equalp (scm_tc16_bitvector, bitvector_equalp);
  2576. init_type_creator_table ();
  2577. #include "libguile/unif.x"
  2578. }
  2579. /*
  2580. Local Variables:
  2581. c-file-style: "gnu"
  2582. End:
  2583. */