unif.c 76 KB

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