fns1.c 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083
  1. /* fns1.c Copyright (C) 1989-2002 Codemist Ltd */
  2. /*
  3. * Basic functions part 1.
  4. */
  5. /*
  6. * This code may be used and modified, and redistributed in binary
  7. * or source form, subject to the "CCL Public License", which should
  8. * accompany it. This license is a variant on the BSD license, and thus
  9. * permits use of code derived from this in either open and commercial
  10. * projects: but it does require that updates to this code be made
  11. * available back to the originators of the package.
  12. * Before merging other code in with this or linking this code
  13. * with other packages or libraries please check that the license terms
  14. * of the other material are compatible with those of this.
  15. */
  16. /* Signature: 7c43b906 10-Oct-2002 */
  17. #include <stdarg.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include "machine.h"
  21. #include "tags.h"
  22. #include "cslerror.h"
  23. #include "externs.h"
  24. #include "entries.h"
  25. #include "arith.h"
  26. #ifdef TIMEOUT
  27. #include "timeout.h"
  28. #endif
  29. /*****************************************************************************/
  30. /* Some basic functions */
  31. /*****************************************************************************/
  32. Lisp_Object integerp(Lisp_Object p)
  33. {
  34. Lisp_Object nil = C_nil;
  35. int tag = ((int)p) & TAG_BITS;
  36. if (tag == TAG_FIXNUM) return lisp_true;
  37. if (tag == TAG_NUMBERS)
  38. { Header h = *(Header *)((char *)p - TAG_NUMBERS);
  39. if (type_of_header(h) == TYPE_BIGNUM) return lisp_true;
  40. }
  41. return nil;
  42. }
  43. /*****************************************************************************/
  44. /* Storage allocation. */
  45. /*****************************************************************************/
  46. Lisp_Object cons(Lisp_Object a, Lisp_Object b)
  47. {
  48. nil_as_base
  49. Lisp_Object r = (Lisp_Object)((char *)fringe - sizeof(Cons_Cell));
  50. qcar(r) = a;
  51. qcdr(r) = b;
  52. fringe = r;
  53. if ((char *)r <= (char *)heaplimit)
  54. return reclaim((Lisp_Object)((char *)r + TAG_CONS),
  55. "internal cons", GC_CONS, 0);
  56. else return (Lisp_Object)((char *)r + TAG_CONS);
  57. }
  58. Lisp_Object cons_no_gc(Lisp_Object a, Lisp_Object b)
  59. {
  60. nil_as_base
  61. Lisp_Object r = (Lisp_Object)((char *)fringe - sizeof(Cons_Cell));
  62. qcar(r) = a;
  63. qcdr(r) = b;
  64. fringe = r;
  65. return (Lisp_Object)((char *)r + TAG_CONS);
  66. }
  67. /*
  68. * cons_gc_test() MUST be called after any sequence of cons_no_gc() calls.
  69. */
  70. Lisp_Object cons_gc_test(Lisp_Object p)
  71. {
  72. nil_as_base
  73. if ((char *)fringe <= (char *)heaplimit)
  74. return reclaim(p, "cons gc test", GC_CONS, 0);
  75. else return p;
  76. }
  77. Lisp_Object ncons(Lisp_Object a)
  78. {
  79. Lisp_Object nil = C_nil;
  80. Lisp_Object r = (Lisp_Object)((char *)fringe - sizeof(Cons_Cell));
  81. qcar(r) = a;
  82. qcdr(r) = nil;
  83. fringe = r;
  84. if ((char *)r <= (char *)heaplimit)
  85. return reclaim((Lisp_Object)((char *)r + TAG_CONS),
  86. "internal ncons", GC_CONS, 0);
  87. else return (Lisp_Object)((char *)r + TAG_CONS);
  88. }
  89. Lisp_Object list2(Lisp_Object a, Lisp_Object b)
  90. {
  91. /* Note that building two cons cells at once saves some overhead here */
  92. Lisp_Object nil = C_nil;
  93. Lisp_Object r = (Lisp_Object)((char *)fringe - 2*sizeof(Cons_Cell));
  94. qcar(r) = a;
  95. qcdr(r) = (Lisp_Object)((char *)r + sizeof(Cons_Cell) + TAG_CONS);
  96. qcar((char *)r+sizeof(Cons_Cell)) = b;
  97. qcdr((char *)r+sizeof(Cons_Cell)) = nil;
  98. fringe = r;
  99. if ((char *)r <= (char *)heaplimit)
  100. return reclaim((Lisp_Object)((char *)r + TAG_CONS),
  101. "internal list2", GC_CONS, 0);
  102. else return (Lisp_Object)((char *)r + TAG_CONS);
  103. }
  104. Lisp_Object list2star(Lisp_Object a, Lisp_Object b, Lisp_Object c)
  105. {
  106. nil_as_base
  107. Lisp_Object r = (Lisp_Object)((char *)fringe - 2*sizeof(Cons_Cell));
  108. qcar(r) = a;
  109. qcdr(r) = (Lisp_Object)((char *)r + sizeof(Cons_Cell) + TAG_CONS);
  110. qcar((char *)r+sizeof(Cons_Cell)) = b;
  111. qcdr((char *)r+sizeof(Cons_Cell)) = c;
  112. fringe = r;
  113. if ((char *)r <= (char *)heaplimit)
  114. return reclaim((Lisp_Object)((char *)r + TAG_CONS),
  115. "internal list2*", GC_CONS, 0);
  116. else return (Lisp_Object)((char *)r + TAG_CONS);
  117. }
  118. Lisp_Object acons(Lisp_Object a, Lisp_Object b, Lisp_Object c)
  119. {
  120. nil_as_base
  121. Lisp_Object r = (Lisp_Object)((char *)fringe - 2*sizeof(Cons_Cell));
  122. qcar(r) = (Lisp_Object)((char *)r + sizeof(Cons_Cell) + TAG_CONS);
  123. qcdr(r) = c;
  124. qcar((char *)r+sizeof(Cons_Cell)) = a;
  125. qcdr((char *)r+sizeof(Cons_Cell)) = b;
  126. fringe = r;
  127. if ((char *)r <= (char *)heaplimit)
  128. return reclaim((Lisp_Object)((char *)r + TAG_CONS),
  129. "internal acons", GC_CONS, 0);
  130. else return (Lisp_Object)((char *)r + TAG_CONS);
  131. }
  132. Lisp_Object list3(Lisp_Object a, Lisp_Object b, Lisp_Object c)
  133. {
  134. Lisp_Object nil = C_nil;
  135. Lisp_Object r = (Lisp_Object)((char *)fringe - 3*sizeof(Cons_Cell));
  136. qcar(r) = a;
  137. qcdr(r) = (Lisp_Object)((char *)r + sizeof(Cons_Cell) + TAG_CONS);
  138. qcar((char *)r+sizeof(Cons_Cell)) = b;
  139. qcdr((char *)r+sizeof(Cons_Cell)) =
  140. (Lisp_Object)((char *)r + 2*sizeof(Cons_Cell) + TAG_CONS);
  141. qcar((char *)r+2*sizeof(Cons_Cell)) = c;
  142. qcdr((char *)r+2*sizeof(Cons_Cell)) = nil;
  143. fringe = r;
  144. if ((char *)r <= (char *)heaplimit)
  145. return reclaim((Lisp_Object)((char *)r + TAG_CONS),
  146. "internal list3", GC_CONS, 0);
  147. else return (Lisp_Object)((char *)r + TAG_CONS);
  148. }
  149. /*****************************************************************************/
  150. /*****************************************************************************/
  151. /*** Lisp-callable versions of all the above ***/
  152. /*****************************************************************************/
  153. /*****************************************************************************/
  154. /*
  155. * The set of car/cdr combinations here seem pretty dull, but they
  156. * are fairly important for performance...
  157. */
  158. Lisp_Object Lcar(Lisp_Object nil, Lisp_Object a)
  159. {
  160. CSL_IGNORE(nil);
  161. if (!car_legal(a)) return error(1, err_bad_car, a);
  162. else return onevalue(qcar(a));
  163. }
  164. /*
  165. * (car* a) = (car a) if a is non-atomic, but just a otherwise.
  166. */
  167. Lisp_Object Lcar_star(Lisp_Object nil, Lisp_Object a)
  168. {
  169. CSL_IGNORE(nil);
  170. if (!car_legal(a)) return onevalue(a);
  171. else return onevalue(qcar(a));
  172. }
  173. Lisp_Object Lcdr(Lisp_Object nil, Lisp_Object a)
  174. {
  175. CSL_IGNORE(nil);
  176. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  177. else return onevalue(qcdr(a));
  178. }
  179. Lisp_Object Lcaar(Lisp_Object nil, Lisp_Object a)
  180. {
  181. CSL_IGNORE(nil);
  182. if (!car_legal(a)) return error(1, err_bad_car, a);
  183. else a = qcar(a);
  184. if (!car_legal(a)) return error(1, err_bad_car, a);
  185. else return onevalue(qcar(a));
  186. }
  187. Lisp_Object Lcadr(Lisp_Object nil, Lisp_Object a)
  188. {
  189. CSL_IGNORE(nil);
  190. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  191. else a = qcdr(a);
  192. if (!car_legal(a)) return error(1, err_bad_car, a);
  193. else return onevalue(qcar(a));
  194. }
  195. Lisp_Object Lcdar(Lisp_Object nil, Lisp_Object a)
  196. {
  197. CSL_IGNORE(nil);
  198. if (!car_legal(a)) return error(1, err_bad_car, a);
  199. else a = qcar(a);
  200. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  201. else return onevalue(qcdr(a));
  202. }
  203. Lisp_Object Lcddr(Lisp_Object nil, Lisp_Object a)
  204. {
  205. CSL_IGNORE(nil);
  206. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  207. else a = qcdr(a);
  208. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  209. else return onevalue(qcdr(a));
  210. }
  211. Lisp_Object Lcaaar(Lisp_Object nil, Lisp_Object a)
  212. {
  213. CSL_IGNORE(nil);
  214. if (!car_legal(a)) return error(1, err_bad_car, a);
  215. else a = qcar(a);
  216. if (!car_legal(a)) return error(1, err_bad_car, a);
  217. else a = qcar(a);
  218. if (!car_legal(a)) return error(1, err_bad_car, a);
  219. else return onevalue(qcar(a));
  220. }
  221. Lisp_Object Lcaadr(Lisp_Object nil, Lisp_Object a)
  222. {
  223. CSL_IGNORE(nil);
  224. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  225. else a = qcdr(a);
  226. if (!car_legal(a)) return error(1, err_bad_car, a);
  227. else a = qcar(a);
  228. if (!car_legal(a)) return error(1, err_bad_car, a);
  229. else return onevalue(qcar(a));
  230. }
  231. Lisp_Object Lcadar(Lisp_Object nil, Lisp_Object a)
  232. {
  233. CSL_IGNORE(nil);
  234. if (!car_legal(a)) return error(1, err_bad_car, a);
  235. else a = qcar(a);
  236. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  237. else a = qcdr(a);
  238. if (!car_legal(a)) return error(1, err_bad_car, a);
  239. else return onevalue(qcar(a));
  240. }
  241. Lisp_Object Lcaddr(Lisp_Object nil, Lisp_Object a)
  242. {
  243. CSL_IGNORE(nil);
  244. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  245. else a = qcdr(a);
  246. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  247. else a = qcdr(a);
  248. if (!car_legal(a)) return error(1, err_bad_car, a);
  249. else return onevalue(qcar(a));
  250. }
  251. Lisp_Object Lcdaar(Lisp_Object nil, Lisp_Object a)
  252. {
  253. CSL_IGNORE(nil);
  254. if (!car_legal(a)) return error(1, err_bad_car, a);
  255. else a = qcar(a);
  256. if (!car_legal(a)) return error(1, err_bad_car, a);
  257. else a = qcar(a);
  258. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  259. else return onevalue(qcdr(a));
  260. }
  261. Lisp_Object Lcdadr(Lisp_Object nil, Lisp_Object a)
  262. {
  263. CSL_IGNORE(nil);
  264. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  265. else a = qcdr(a);
  266. if (!car_legal(a)) return error(1, err_bad_car, a);
  267. else a = qcar(a);
  268. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  269. else return onevalue(qcdr(a));
  270. }
  271. Lisp_Object Lcddar(Lisp_Object nil, Lisp_Object a)
  272. {
  273. CSL_IGNORE(nil);
  274. if (!car_legal(a)) return error(1, err_bad_car, a);
  275. else a = qcar(a);
  276. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  277. else a = qcdr(a);
  278. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  279. else return onevalue(qcdr(a));
  280. }
  281. Lisp_Object Lcdddr(Lisp_Object nil, Lisp_Object a)
  282. {
  283. CSL_IGNORE(nil);
  284. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  285. else a = qcdr(a);
  286. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  287. else a = qcdr(a);
  288. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  289. else return onevalue(qcdr(a));
  290. }
  291. Lisp_Object Lcaaaar(Lisp_Object nil, Lisp_Object a)
  292. {
  293. CSL_IGNORE(nil);
  294. if (!car_legal(a)) return error(1, err_bad_car, a);
  295. else a = qcar(a);
  296. if (!car_legal(a)) return error(1, err_bad_car, a);
  297. else a = qcar(a);
  298. if (!car_legal(a)) return error(1, err_bad_car, a);
  299. else a = qcar(a);
  300. if (!car_legal(a)) return error(1, err_bad_car, a);
  301. else return onevalue(qcar(a));
  302. }
  303. Lisp_Object Lcaaadr(Lisp_Object nil, Lisp_Object a)
  304. {
  305. CSL_IGNORE(nil);
  306. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  307. else a = qcdr(a);
  308. if (!car_legal(a)) return error(1, err_bad_car, a);
  309. else a = qcar(a);
  310. if (!car_legal(a)) return error(1, err_bad_car, a);
  311. else a = qcar(a);
  312. if (!car_legal(a)) return error(1, err_bad_car, a);
  313. else return onevalue(qcar(a));
  314. }
  315. Lisp_Object Lcaadar(Lisp_Object nil, Lisp_Object a)
  316. {
  317. CSL_IGNORE(nil);
  318. if (!car_legal(a)) return error(1, err_bad_car, a);
  319. else a = qcar(a);
  320. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  321. else a = qcdr(a);
  322. if (!car_legal(a)) return error(1, err_bad_car, a);
  323. else a = qcar(a);
  324. if (!car_legal(a)) return error(1, err_bad_car, a);
  325. else return onevalue(qcar(a));
  326. }
  327. Lisp_Object Lcaaddr(Lisp_Object nil, Lisp_Object a)
  328. {
  329. CSL_IGNORE(nil);
  330. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  331. else a = qcdr(a);
  332. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  333. else a = qcdr(a);
  334. if (!car_legal(a)) return error(1, err_bad_car, a);
  335. else a = qcar(a);
  336. if (!car_legal(a)) return error(1, err_bad_car, a);
  337. else return onevalue(qcar(a));
  338. }
  339. Lisp_Object Lcadaar(Lisp_Object nil, Lisp_Object a)
  340. {
  341. CSL_IGNORE(nil);
  342. if (!car_legal(a)) return error(1, err_bad_car, a);
  343. else a = qcar(a);
  344. if (!car_legal(a)) return error(1, err_bad_car, a);
  345. else a = qcar(a);
  346. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  347. else a = qcdr(a);
  348. if (!car_legal(a)) return error(1, err_bad_car, a);
  349. else return onevalue(qcar(a));
  350. }
  351. Lisp_Object Lcadadr(Lisp_Object nil, Lisp_Object a)
  352. {
  353. CSL_IGNORE(nil);
  354. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  355. else a = qcdr(a);
  356. if (!car_legal(a)) return error(1, err_bad_car, a);
  357. else a = qcar(a);
  358. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  359. else a = qcdr(a);
  360. if (!car_legal(a)) return error(1, err_bad_car, a);
  361. else return onevalue(qcar(a));
  362. }
  363. Lisp_Object Lcaddar(Lisp_Object nil, Lisp_Object a)
  364. {
  365. CSL_IGNORE(nil);
  366. if (!car_legal(a)) return error(1, err_bad_car, a);
  367. else a = qcar(a);
  368. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  369. else a = qcdr(a);
  370. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  371. else a = qcdr(a);
  372. if (!car_legal(a)) return error(1, err_bad_car, a);
  373. else return onevalue(qcar(a));
  374. }
  375. Lisp_Object Lcadddr(Lisp_Object nil, Lisp_Object a)
  376. {
  377. CSL_IGNORE(nil);
  378. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  379. else a = qcdr(a);
  380. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  381. else a = qcdr(a);
  382. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  383. else a = qcdr(a);
  384. if (!car_legal(a)) return error(1, err_bad_car, a);
  385. else return onevalue(qcar(a));
  386. }
  387. Lisp_Object Lcdaaar(Lisp_Object nil, Lisp_Object a)
  388. {
  389. CSL_IGNORE(nil);
  390. if (!car_legal(a)) return error(1, err_bad_car, a);
  391. else a = qcar(a);
  392. if (!car_legal(a)) return error(1, err_bad_car, a);
  393. else a = qcar(a);
  394. if (!car_legal(a)) return error(1, err_bad_car, a);
  395. else a = qcar(a);
  396. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  397. else return onevalue(qcdr(a));
  398. }
  399. Lisp_Object Lcdaadr(Lisp_Object nil, Lisp_Object a)
  400. {
  401. CSL_IGNORE(nil);
  402. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  403. else a = qcdr(a);
  404. if (!car_legal(a)) return error(1, err_bad_car, a);
  405. else a = qcar(a);
  406. if (!car_legal(a)) return error(1, err_bad_car, a);
  407. else a = qcar(a);
  408. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  409. else return onevalue(qcdr(a));
  410. }
  411. Lisp_Object Lcdadar(Lisp_Object nil, Lisp_Object a)
  412. {
  413. CSL_IGNORE(nil);
  414. if (!car_legal(a)) return error(1, err_bad_car, a);
  415. else a = qcar(a);
  416. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  417. else a = qcdr(a);
  418. if (!car_legal(a)) return error(1, err_bad_car, a);
  419. else a = qcar(a);
  420. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  421. else return onevalue(qcdr(a));
  422. }
  423. Lisp_Object Lcdaddr(Lisp_Object nil, Lisp_Object a)
  424. {
  425. CSL_IGNORE(nil);
  426. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  427. else a = qcdr(a);
  428. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  429. else a = qcdr(a);
  430. if (!car_legal(a)) return error(1, err_bad_car, a);
  431. else a = qcar(a);
  432. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  433. else return onevalue(qcdr(a));
  434. }
  435. Lisp_Object Lcddaar(Lisp_Object nil, Lisp_Object a)
  436. {
  437. CSL_IGNORE(nil);
  438. if (!car_legal(a)) return error(1, err_bad_car, a);
  439. else a = qcar(a);
  440. if (!car_legal(a)) return error(1, err_bad_car, a);
  441. else a = qcar(a);
  442. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  443. else a = qcdr(a);
  444. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  445. else return onevalue(qcdr(a));
  446. }
  447. Lisp_Object Lcddadr(Lisp_Object nil, Lisp_Object a)
  448. {
  449. CSL_IGNORE(nil);
  450. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  451. else a = qcdr(a);
  452. if (!car_legal(a)) return error(1, err_bad_car, a);
  453. else a = qcar(a);
  454. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  455. else a = qcdr(a);
  456. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  457. else return onevalue(qcdr(a));
  458. }
  459. Lisp_Object Lcdddar(Lisp_Object nil, Lisp_Object a)
  460. {
  461. CSL_IGNORE(nil);
  462. if (!car_legal(a)) return error(1, err_bad_car, a);
  463. else a = qcar(a);
  464. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  465. else a = qcdr(a);
  466. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  467. else a = qcdr(a);
  468. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  469. else return onevalue(qcdr(a));
  470. }
  471. Lisp_Object Lcddddr(Lisp_Object nil, Lisp_Object a)
  472. {
  473. CSL_IGNORE(nil);
  474. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  475. else a = qcdr(a);
  476. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  477. else a = qcdr(a);
  478. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  479. else a = qcdr(a);
  480. if (!car_legal(a)) return error(1, err_bad_cdr, a);
  481. else return onevalue(qcdr(a));
  482. }
  483. Lisp_Object Lrplaca(Lisp_Object nil,
  484. Lisp_Object a, Lisp_Object b)
  485. {
  486. CSL_IGNORE(nil);
  487. if (!consp(a)) return error(1, err_bad_rplac, a);
  488. qcar(a) = b;
  489. return onevalue(a);
  490. }
  491. Lisp_Object Lrplacd(Lisp_Object nil,
  492. Lisp_Object a, Lisp_Object b)
  493. {
  494. CSL_IGNORE(nil);
  495. if (!consp(a)) return error(1, err_bad_rplac, a);
  496. qcdr(a) = b;
  497. return onevalue(a);
  498. }
  499. Lisp_Object Lsymbolp(Lisp_Object nil, Lisp_Object a)
  500. {
  501. return onevalue(Lispify_predicate(symbolp(a)));
  502. }
  503. Lisp_Object Latom(Lisp_Object nil, Lisp_Object a)
  504. {
  505. return onevalue(Lispify_predicate(!consp(a)));
  506. }
  507. Lisp_Object Lconsp(Lisp_Object nil, Lisp_Object a)
  508. {
  509. return onevalue(Lispify_predicate(consp(a)));
  510. }
  511. Lisp_Object Lconstantp(Lisp_Object nil, Lisp_Object a)
  512. /*
  513. * This version is as required for Standard Lisp - it is inadequate
  514. * for Common Lisp.
  515. */
  516. {
  517. /*
  518. * Standard Lisp requires that I report that "Function Pointers" are
  519. * "constant" here. It is not at all clear that I have a way of
  520. * doing that. I will go some way my ensuring that code-vectors are.
  521. */
  522. #ifdef COMMON
  523. return onevalue(Lispify_predicate(
  524. a == nil || a == lisp_true ||
  525. is_char(a) ||
  526. is_number(a) ||
  527. is_vector(a) ||
  528. is_bps(a)));
  529. #else
  530. return onevalue(Lispify_predicate(
  531. is_number(a) ||
  532. is_vector(a) || /* Vectors include strings here */
  533. is_bps(a)));
  534. #endif
  535. }
  536. Lisp_Object Lidentity(Lisp_Object nil, Lisp_Object a)
  537. {
  538. CSL_IGNORE(nil);
  539. return onevalue(a);
  540. }
  541. #ifdef COMMON
  542. Lisp_Object Llistp(Lisp_Object nil, Lisp_Object a)
  543. {
  544. return onevalue(Lispify_predicate(is_cons(a)));
  545. }
  546. #endif
  547. Lisp_Object Lnumberp(Lisp_Object nil, Lisp_Object a)
  548. {
  549. return onevalue(Lispify_predicate(is_number(a)));
  550. }
  551. Lisp_Object Lintegerp(Lisp_Object nil, Lisp_Object a)
  552. {
  553. CSL_IGNORE(nil);
  554. return onevalue(integerp(a));
  555. }
  556. Lisp_Object Leq_safe(Lisp_Object nil, Lisp_Object a)
  557. {
  558. /*
  559. * True if you can safely use EQ tests to check equality. Thus true for
  560. * things that are represented in "immediate" form...
  561. */
  562. #ifdef COMMON
  563. return onevalue(is_fixnum(a) ||
  564. is_sfloat(a) ||
  565. is_odds(a) ? lisp_true : nil);
  566. #else
  567. return onevalue(is_fixnum(a) ||
  568. is_odds(a) ? lisp_true : nil);
  569. #endif
  570. }
  571. Lisp_Object Lfixp(Lisp_Object nil, Lisp_Object a)
  572. {
  573. #ifdef COMMON
  574. return onevalue(is_fixnum(a) ? lisp_true : nil);
  575. #else
  576. /*
  577. * Standard Lisp defines fixp to say yes to bignums as well as
  578. * fixnums.
  579. */
  580. CSL_IGNORE(nil);
  581. return onevalue(integerp(a));
  582. #endif
  583. }
  584. Lisp_Object Lfloatp(Lisp_Object nil, Lisp_Object p)
  585. {
  586. int tag = TAG_BITS & (int)p;
  587. #ifdef COMMON
  588. if (tag == TAG_SFLOAT) return onevalue(lisp_true);
  589. #endif
  590. if (tag == TAG_BOXFLOAT) return onevalue(lisp_true);
  591. else return onevalue(nil);
  592. }
  593. #ifdef COMMON
  594. static Lisp_Object Lshort_floatp(Lisp_Object nil, Lisp_Object p)
  595. {
  596. int tag = TAG_BITS & (int)p;
  597. if (tag == TAG_SFLOAT) return onevalue(lisp_true);
  598. else return onevalue(nil);
  599. }
  600. static Lisp_Object Lsingle_floatp(Lisp_Object nil, Lisp_Object p)
  601. {
  602. int tag = TAG_BITS & (int)p;
  603. if (tag == TAG_BOXFLOAT &&
  604. type_of_header(flthdr(p)) == TYPE_SINGLE_FLOAT)
  605. return onevalue(lisp_true);
  606. else return onevalue(nil);
  607. }
  608. static Lisp_Object Ldouble_floatp(Lisp_Object nil, Lisp_Object p)
  609. {
  610. int tag = TAG_BITS & (int)p;
  611. if (tag == TAG_BOXFLOAT &&
  612. type_of_header(flthdr(p)) == TYPE_DOUBLE_FLOAT)
  613. return onevalue(lisp_true);
  614. else return onevalue(nil);
  615. }
  616. static Lisp_Object Llong_floatp(Lisp_Object nil, Lisp_Object p)
  617. {
  618. int tag = TAG_BITS & (int)p;
  619. if (tag == TAG_BOXFLOAT &&
  620. type_of_header(flthdr(p)) == TYPE_LONG_FLOAT)
  621. return onevalue(lisp_true);
  622. else return onevalue(nil);
  623. }
  624. Lisp_Object Lrationalp(Lisp_Object nil, Lisp_Object a)
  625. {
  626. CSL_IGNORE(nil);
  627. return onevalue(
  628. Lispify_predicate(
  629. is_fixnum(a) ||
  630. (is_numbers(a) &&
  631. (is_bignum(a) || is_ratio(a)))));
  632. }
  633. Lisp_Object Lcomplexp(Lisp_Object nil, Lisp_Object a)
  634. {
  635. CSL_IGNORE(nil);
  636. return onevalue(Lispify_predicate(is_numbers(a) && is_complex(a)));
  637. }
  638. CSLbool complex_stringp(Lisp_Object a)
  639. /*
  640. * true if the arg is a string, but NOT a simple string. In general
  641. * when this is true simplify_string() will then be called to do
  642. * an adjustment.
  643. */
  644. {
  645. Header h;
  646. Lisp_Object w, nil = C_nil;
  647. if (!is_vector(a)) return NO;
  648. h = vechdr(a);
  649. if (type_of_header(h) != TYPE_ARRAY) return NO;
  650. /*
  651. * Note that the cheery Common Lisp Committee decided the abolish the
  652. * separate type 'string-char, so the test here is maybe dubious...
  653. */
  654. else if (elt(a, 0) != string_char_sym) return NO;
  655. w = elt(a, 1);
  656. if (!consp(w) || consp(qcdr(w))) return NO;
  657. else return YES;
  658. }
  659. #endif
  660. Lisp_Object Lwarn_about_protected_symbols(Lisp_Object nil, Lisp_Object a)
  661. {
  662. Lisp_Object retval = Lispify_predicate(warn_about_protected_symbols);
  663. warn_about_protected_symbols = (a != nil);
  664. return onevalue(retval);
  665. }
  666. Lisp_Object Lprotect_symbols(Lisp_Object nil, Lisp_Object a)
  667. {
  668. Lisp_Object retval = Lispify_predicate(symbol_protect_flag);
  669. symbol_protect_flag = (a != nil);
  670. return onevalue(retval);
  671. }
  672. CSLbool stringp(Lisp_Object a)
  673. /*
  674. * True if arg is a simple OR a general string
  675. */
  676. {
  677. Header h;
  678. #ifdef COMMON
  679. Lisp_Object w, nil = C_nil;
  680. #endif
  681. if (!is_vector(a)) return NO;
  682. h = vechdr(a);
  683. if (type_of_header(h) == TYPE_STRING) return YES;
  684. #ifdef COMMON
  685. else if (type_of_header(h) != TYPE_ARRAY) return NO;
  686. /*
  687. * Beware abolition of 'string-char
  688. */
  689. else if (elt(a, 0) != string_char_sym) return NO;
  690. w = elt(a, 1);
  691. if (!consp(w) || consp(qcdr(w))) return NO;
  692. else return YES;
  693. #else
  694. else return NO;
  695. #endif
  696. }
  697. Lisp_Object Lstringp(Lisp_Object nil, Lisp_Object a)
  698. /*
  699. * simple-string-p
  700. */
  701. {
  702. if (!(is_vector(a)) || type_of_header(vechdr(a)) != TYPE_STRING)
  703. return onevalue(nil);
  704. else return onevalue(lisp_true);
  705. }
  706. #ifdef COMMON
  707. static Lisp_Object Lc_stringp(Lisp_Object nil, Lisp_Object a)
  708. {
  709. return onevalue(Lispify_predicate(stringp(a)));
  710. }
  711. #endif
  712. Lisp_Object Lhash_table_p(Lisp_Object nil, Lisp_Object a)
  713. /*
  714. * hash-table-p
  715. */
  716. {
  717. if (!(is_vector(a)) || type_of_header(vechdr(a)) != TYPE_HASH)
  718. return onevalue(nil);
  719. else return onevalue(lisp_true);
  720. }
  721. #ifdef COMMON
  722. static Lisp_Object Lsimple_bit_vector_p(Lisp_Object nil,
  723. Lisp_Object a)
  724. /*
  725. * simple-bit-vector-p
  726. */
  727. {
  728. if (!(is_vector(a))) return onevalue(nil);
  729. else return onevalue(Lispify_predicate(header_of_bitvector(vechdr(a))));
  730. }
  731. #endif
  732. Lisp_Object Lsimple_vectorp(Lisp_Object nil, Lisp_Object a)
  733. /*
  734. * simple-vector-p
  735. */
  736. {
  737. if (!(is_vector(a))) return onevalue(nil);
  738. else return onevalue(Lispify_predicate(
  739. type_of_header(vechdr(a))==TYPE_SIMPLE_VEC));
  740. }
  741. Lisp_Object Lbpsp(Lisp_Object nil, Lisp_Object a)
  742. {
  743. if (!(is_bps(a))) return onevalue(nil);
  744. else return onevalue(lisp_true);
  745. }
  746. Lisp_Object Lthreevectorp(Lisp_Object nil, Lisp_Object a)
  747. /*
  748. * This is useful for REDUCE - it checks if something is a vector
  749. * of size 3!
  750. */
  751. {
  752. if (!(is_vector(a))) return onevalue(nil);
  753. return onevalue(Lispify_predicate(
  754. vechdr(a) == (TAG_ODDS + TYPE_SIMPLE_VEC + ((4*CELL)<<10))));
  755. }
  756. #ifdef COMMON
  757. static Lisp_Object Larrayp(Lisp_Object nil, Lisp_Object a)
  758. {
  759. Header h;
  760. if (!(is_vector(a))) return onevalue(nil);
  761. h = vechdr(a);
  762. /*
  763. * I could consider accepting TYPE_VEC16 and TYPE_VEC32 etc here...
  764. */
  765. if (type_of_header(h)==TYPE_ARRAY ||
  766. type_of_header(h)==TYPE_STRING ||
  767. type_of_header(h)==TYPE_SIMPLE_VEC ||
  768. header_of_bitvector(h)) return onevalue(lisp_true);
  769. else return onevalue(nil);
  770. }
  771. static Lisp_Object Lcomplex_arrayp(Lisp_Object nil, Lisp_Object a)
  772. {
  773. if (!(is_vector(a))) return onevalue(nil);
  774. else return onevalue(Lispify_predicate(
  775. type_of_header(vechdr(a))==TYPE_ARRAY));
  776. }
  777. static Lisp_Object Lconvert_to_array(Lisp_Object nil, Lisp_Object a)
  778. {
  779. if (!(is_vector(a))) return onevalue(nil);
  780. vechdr(a) = TYPE_ARRAY + (vechdr(a) & ~header_mask);
  781. return onevalue(a);
  782. }
  783. #endif
  784. static Lisp_Object Lstructp(Lisp_Object nil, Lisp_Object a)
  785. /*
  786. * structp
  787. */
  788. {
  789. if (!(is_vector(a))) return onevalue(nil);
  790. else return onevalue(Lispify_predicate(
  791. type_of_header(vechdr(a))==TYPE_STRUCTURE));
  792. }
  793. static Lisp_Object Lconvert_to_struct(Lisp_Object nil, Lisp_Object a)
  794. {
  795. if (!(is_vector(a))) return onevalue(nil);
  796. vechdr(a) = TYPE_STRUCTURE + (vechdr(a) & ~header_mask);
  797. return onevalue(a);
  798. }
  799. Lisp_Object Lcons(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  800. {
  801. Lisp_Object r;
  802. CSL_IGNORE(nil);
  803. r = (Lisp_Object)((char *)fringe - sizeof(Cons_Cell));
  804. qcar(r) = a;
  805. qcdr(r) = b;
  806. fringe = r;
  807. if ((char *)r <= (char *)heaplimit)
  808. return onevalue(reclaim((Lisp_Object)((char *)r + TAG_CONS),
  809. "cons", GC_CONS, 0));
  810. else return onevalue((Lisp_Object)((char *)r + TAG_CONS));
  811. }
  812. Lisp_Object Lxcons(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  813. {
  814. Lisp_Object r;
  815. CSL_IGNORE(nil);
  816. r = (Lisp_Object)((char *)fringe - sizeof(Cons_Cell));
  817. qcar(r) = b;
  818. qcdr(r) = a;
  819. fringe = r;
  820. if ((char *)r <= (char *)heaplimit)
  821. return onevalue(reclaim((Lisp_Object)((char *)r + TAG_CONS),
  822. "xcons", GC_CONS, 0));
  823. else return onevalue((Lisp_Object)((char *)r + TAG_CONS));
  824. }
  825. Lisp_Object Lncons(Lisp_Object nil, Lisp_Object a)
  826. {
  827. Lisp_Object r;
  828. r = (Lisp_Object)((char *)fringe - sizeof(Cons_Cell));
  829. qcar(r) = a;
  830. qcdr(r) = nil;
  831. fringe = r;
  832. if ((char *)r <= (char *)heaplimit)
  833. return onevalue(reclaim((Lisp_Object)((char *)r + TAG_CONS),
  834. "ncons", GC_CONS, 0));
  835. else return onevalue((Lisp_Object)((char *)r + TAG_CONS));
  836. }
  837. Lisp_Object Llist2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  838. {
  839. a = list2(a, b);
  840. errexit();
  841. return onevalue(a);
  842. }
  843. Lisp_Object Lmkquote(Lisp_Object nil, Lisp_Object a)
  844. {
  845. a = list2(quote_symbol, a);
  846. errexit();
  847. return onevalue(a);
  848. }
  849. Lisp_Object MS_CDECL Llist2star(Lisp_Object nil, int nargs, ...)
  850. {
  851. va_list aa;
  852. Lisp_Object a, b, c;
  853. argcheck(nargs, 3, "list2*");
  854. va_start(aa, nargs);
  855. a = va_arg(aa, Lisp_Object);
  856. b = va_arg(aa, Lisp_Object);
  857. c = va_arg(aa, Lisp_Object);
  858. va_end(aa);
  859. a = list2star(a,b,c);
  860. errexit();
  861. return onevalue(a);
  862. }
  863. Lisp_Object MS_CDECL Lacons(Lisp_Object nil, int nargs, ...)
  864. {
  865. va_list aa;
  866. Lisp_Object a, b, c;
  867. argcheck(nargs, 3, "acons");
  868. va_start(aa, nargs);
  869. a = va_arg(aa, Lisp_Object);
  870. b = va_arg(aa, Lisp_Object);
  871. c = va_arg(aa, Lisp_Object);
  872. va_end(aa);
  873. a = acons(a,b,c);
  874. errexit();
  875. return onevalue(a);
  876. }
  877. Lisp_Object MS_CDECL Llist3(Lisp_Object nil, int nargs, ...)
  878. {
  879. va_list aa;
  880. Lisp_Object a, b, c;
  881. argcheck(nargs, 3, "list3");
  882. va_start(aa, nargs);
  883. a = va_arg(aa, Lisp_Object);
  884. b = va_arg(aa, Lisp_Object);
  885. c = va_arg(aa, Lisp_Object);
  886. va_end(aa);
  887. a = list3(a,b,c);
  888. errexit();
  889. return onevalue(a);
  890. }
  891. #ifdef COMMON
  892. /*
  893. * In non-COMMON mode I implement list and list* as special forms
  894. * rather than as functions, guessing that that will be more efficient.
  895. */
  896. Lisp_Object MS_CDECL Llist(Lisp_Object nil, int nargs, ...)
  897. {
  898. Lisp_Object r = nil, w, w1;
  899. va_list a;
  900. va_start(a, nargs);
  901. push_args(a, nargs);
  902. while (nargs > 1)
  903. { pop2(w, w1);
  904. nargs-=2;
  905. r = list2star(w1, w, r);
  906. errexitn(nargs);
  907. }
  908. while (nargs > 0)
  909. { pop(w);
  910. nargs--;
  911. r = cons(w, r);
  912. errexitn(nargs);
  913. }
  914. return onevalue(r);
  915. }
  916. static Lisp_Object MS_CDECL Lliststar(Lisp_Object nil, int nargs, ...)
  917. {
  918. Lisp_Object r, w, w1;
  919. va_list a;
  920. if (nargs == 0) return onevalue(nil);
  921. va_start(a, nargs);
  922. push_args(a, nargs);
  923. pop(r);
  924. nargs--;
  925. while (nargs > 1)
  926. { pop2(w, w1);
  927. nargs-=2;
  928. r = list2star(w1, w, r);
  929. errexitn(nargs);
  930. }
  931. while (nargs > 0)
  932. { pop(w);
  933. nargs--;
  934. r = cons(w, r);
  935. errexitn(nargs);
  936. }
  937. return onevalue(r);
  938. }
  939. /*
  940. * fill-vector is used for open-compilation of (vector ...) to avoid
  941. * passing grossly unreasonable numbers of arguments. The expansion of
  942. * (vector e1 ... en) should be
  943. * (let ((v (mkvect <n-1>)) (i 0))
  944. * (setq i (fill-vector v i e1 e2 ... e10))
  945. * (setq i (fill-vector v i e11 e12 ... ))
  946. * ...
  947. * v)
  948. */
  949. static Lisp_Object MS_CDECL Lfill_vector(Lisp_Object nil, int nargs, ...)
  950. {
  951. va_list a;
  952. Lisp_Object v, il;
  953. int32 i;
  954. CSL_IGNORE(nil);
  955. if (nargs < 3) return aerror("fill-vector");
  956. va_start(a, nargs);
  957. v = va_arg(a, Lisp_Object);
  958. il = va_arg(a, Lisp_Object);
  959. if (!is_vector(v) || !is_fixnum(il)) return aerror("fill-vector");
  960. i = int_of_fixnum(il);
  961. nargs -= 2;
  962. while (nargs != 0)
  963. { elt(v, i++) = va_arg(a, Lisp_Object);
  964. nargs--;
  965. }
  966. return onevalue(fixnum_of_int(i));
  967. }
  968. #endif
  969. Lisp_Object Lpair(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  970. {
  971. Lisp_Object r = nil;
  972. while (consp(a) && consp(b))
  973. { push2(a, b);
  974. r = acons(qcar(a), qcar(b), r);
  975. pop2(b, a);
  976. errexit();
  977. a = qcdr(a);
  978. b = qcdr(b);
  979. }
  980. a = nil;
  981. while (r != nil)
  982. { b = qcdr(r);
  983. qcdr(r) = a;
  984. a = r;
  985. r = b;
  986. }
  987. return onevalue(a);
  988. }
  989. static int32 membercount(Lisp_Object a, Lisp_Object b)
  990. /*
  991. * Counts how many times a is a member of the list b
  992. */
  993. {
  994. int32 r = 0;
  995. #ifdef COMMON
  996. Lisp_Object nil = C_nil;
  997. #endif
  998. if (is_symbol(a) || is_fixnum(a))
  999. { while (consp(b))
  1000. { if (a == qcar(b)) r++;
  1001. b = qcdr(b);
  1002. }
  1003. return r;
  1004. }
  1005. while (consp(b))
  1006. { Lisp_Object cb = qcar(b);
  1007. if (equal(a, cb)) r++;
  1008. b = qcdr(b);
  1009. }
  1010. return r;
  1011. }
  1012. /*
  1013. * INTERSECTION(A,B)
  1014. * The result will have its items in the order that they occur in A.
  1015. * If lists A and B contain duplicate items these will appear in the
  1016. * output if and only if the items involved are duplicated in both
  1017. * input lists.
  1018. */
  1019. Lisp_Object Lintersect(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  1020. {
  1021. Lisp_Object r = nil, w;
  1022. push(b);
  1023. while (consp(a))
  1024. { push2(a, r);
  1025. w = Lmember(nil, qcar(a), stack[-2]);
  1026. errexitn(3);
  1027. /* Here I ignore any item in a that is not also in b */
  1028. if (w != nil)
  1029. { int32 n1 = membercount(qcar(stack[-1]), stack[0]);
  1030. errexitn(3);
  1031. /*
  1032. * Here I want to arrange that items only appear in the result list multiple
  1033. * times if they occur multipl times in BOTH the input lists.
  1034. */
  1035. if (n1 != 0)
  1036. { int32 n2 = membercount(qcar(stack[-1]), stack[-2]);
  1037. errexitn(3);
  1038. if (n2 > n1) n1 = 0;
  1039. }
  1040. if (n1 == 0)
  1041. { pop(r);
  1042. a = stack[0];
  1043. r = cons(qcar(a), r);
  1044. errexitn(2);
  1045. pop(a);
  1046. }
  1047. else pop2(r, a);
  1048. }
  1049. else pop2(r, a);
  1050. a = qcdr(a);
  1051. }
  1052. popv(1);
  1053. a = nil;
  1054. while (consp(r))
  1055. { b = r;
  1056. r = qcdr(r);
  1057. qcdr(b) = a;
  1058. a = b;
  1059. }
  1060. return onevalue(a);
  1061. }
  1062. /*
  1063. * UNION(A, B)
  1064. * This works by consing onto the front of B each element of A that
  1065. * is not already in B. Thus items in A (but not already in B) get
  1066. * added in reversed order. Duplicates in B remain there, and but
  1067. * duplicates in A are dropped.
  1068. */
  1069. Lisp_Object Lunion(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  1070. {
  1071. while (consp(a))
  1072. { Lisp_Object c;
  1073. push2(a, b);
  1074. c = Lmember(nil, qcar(a), b);
  1075. errexitn(2);
  1076. pop(b);
  1077. if (c == nil)
  1078. { b = cons(qcar(stack[0]), b);
  1079. errexitn(1);
  1080. }
  1081. pop(a);
  1082. a = qcdr(a);
  1083. }
  1084. return onevalue(b);
  1085. }
  1086. Lisp_Object Lenable_backtrace(Lisp_Object nil, Lisp_Object a)
  1087. {
  1088. int32 n = miscflags;
  1089. if (a == nil) miscflags &= ~MESSAGES_FLAG;
  1090. else miscflags |= MESSAGES_FLAG;
  1091. return onevalue(Lispify_predicate((n & MESSAGES_FLAG) != 0));
  1092. }
  1093. #ifdef NAG
  1094. Lisp_Object MS_CDECL Lunwind(Lisp_Object nil, int nargs, ...)
  1095. {
  1096. argcheck(nargs, 0, "unwind");
  1097. exit_reason = (miscflags & (MESSAGES_FLAG|ALWAYS_NOISY)) ? UNWIND_ERROR :
  1098. UNWIND_UNWIND;
  1099. exit_count = 0;
  1100. exit_tag = nil;
  1101. flip_exception();
  1102. return nil;
  1103. }
  1104. #endif
  1105. /*
  1106. * If the variable *break-function* has as its value a symbol, and that
  1107. * symbol names a function, then the function concerned will be called
  1108. * with one argument after the headline for the diagnostic. When it returns
  1109. * the system will unwind in the usual manner.
  1110. */
  1111. Lisp_Object MS_CDECL Lerror(Lisp_Object nil, int nargs, ...)
  1112. {
  1113. va_list a;
  1114. Lisp_Object w;
  1115. #ifdef COMMON
  1116. Lisp_Object r = nil, w1;
  1117. #else
  1118. int i;
  1119. #endif
  1120. if (nargs == 0) return aerror("error");
  1121. va_start(a, nargs);
  1122. push_args(a, nargs);
  1123. #ifdef COMMON
  1124. while (nargs > 1)
  1125. { pop2(w, w1);
  1126. nargs -= 2;
  1127. w = list2star(w1, w, r);
  1128. nil = C_nil;
  1129. if (exception_pending()) flip_exception();
  1130. else r = w;
  1131. }
  1132. while (nargs > 0)
  1133. { pop(w);
  1134. nargs--;
  1135. w = cons(w, r);
  1136. nil = C_nil;
  1137. if (exception_pending()) flip_exception();
  1138. else r = w;
  1139. }
  1140. if (miscflags & (HEADLINE_FLAG|ALWAYS_NOISY))
  1141. { push(r);
  1142. err_printf("\n+++ error: ");
  1143. /*
  1144. * I will use FORMAT to handle error messages provided the first arg
  1145. * to error had been a string and also provided (for bootstrapping) that
  1146. * the function FORMAT seems to be defined.
  1147. */
  1148. if (qfn1(format_symbol) == undefined1 ||
  1149. !consp(r) ||
  1150. !stringp(qcar(r))) loop_print_error(r);
  1151. else Lapply_n(nil, 3, format_symbol, qvalue(error_output), r);
  1152. ignore_exception();
  1153. err_printf("\n");
  1154. pop(r);
  1155. ignore_exception();
  1156. }
  1157. qvalue(emsg_star) = r; /* "Error message" in CL world */
  1158. exit_value = fixnum_of_int(0); /* "Error number" in CL world */
  1159. #else
  1160. if (miscflags & (HEADLINE_FLAG|ALWAYS_NOISY))
  1161. { err_printf("\n+++ error: ");
  1162. loop_print_error(stack[1-nargs]);
  1163. for (i=1; i<nargs; i++)
  1164. { err_printf(" ");
  1165. loop_print_error(stack[1+i-nargs]);
  1166. }
  1167. err_printf("\n");
  1168. }
  1169. if (nargs == 1)
  1170. { push(nil);
  1171. nargs++;
  1172. }
  1173. qvalue(emsg_star) = stack[2-nargs]; /* "Error message" in SL world */
  1174. exit_value = stack[1-nargs]; /* "Error number" in SL world */
  1175. popv(nargs);
  1176. #endif
  1177. if ((w = qvalue(break_function)) != nil &&
  1178. symbolp(w) &&
  1179. qfn1(w) != undefined1)
  1180. { (*qfn1(w))(qenv(w), qvalue(emsg_star));
  1181. ignore_exception();
  1182. }
  1183. exit_reason = (miscflags & (MESSAGES_FLAG|ALWAYS_NOISY)) ? UNWIND_ERROR :
  1184. UNWIND_UNWIND;
  1185. exit_count = 0;
  1186. exit_tag = nil;
  1187. flip_exception();
  1188. return nil;
  1189. }
  1190. Lisp_Object Lerror1(Lisp_Object nil, Lisp_Object a1)
  1191. {
  1192. return Lerror(nil, 1, a1);
  1193. }
  1194. Lisp_Object Lerror2(Lisp_Object nil, Lisp_Object a1, Lisp_Object a2)
  1195. {
  1196. return Lerror(nil, 2, a1, a2);
  1197. }
  1198. Lisp_Object MS_CDECL Lerror0(Lisp_Object nil, int nargs, ...)
  1199. {
  1200. /*
  1201. * Silently provoked error - unwind to surrounding errorset level. Note that
  1202. * this will NEVER enter a user-provided break loop...
  1203. */
  1204. argcheck(nargs, 0, "error0");
  1205. miscflags &= ~(MESSAGES_FLAG | HEADLINE_FLAG);
  1206. exit_reason = UNWIND_UNWIND;
  1207. exit_value = exit_tag = nil;
  1208. exit_count = 0;
  1209. flip_exception();
  1210. return nil;
  1211. }
  1212. Lisp_Object Lstop(Lisp_Object env, Lisp_Object code)
  1213. {
  1214. /*
  1215. * I ignore "env" and set up nil for myself here to make it easier to call
  1216. * this function from random places in my interface code...
  1217. */
  1218. Lisp_Object nil = C_nil;
  1219. CSL_IGNORE(env);
  1220. if (!is_fixnum(code)) return aerror("stop");
  1221. exit_value = code;
  1222. exit_tag = fixnum_of_int(0); /* Flag to say "stop" */
  1223. exit_reason = UNWIND_RESTART;
  1224. exit_count = 1;
  1225. flip_exception();
  1226. return nil;
  1227. }
  1228. Lisp_Object Lmake_special(Lisp_Object nil, Lisp_Object a)
  1229. {
  1230. CSL_IGNORE(nil);
  1231. if (!symbolp(a)) return aerror1("make-special", a);
  1232. qheader(a) |= SYM_SPECIAL_VAR;
  1233. return onevalue(a);
  1234. }
  1235. Lisp_Object Lmake_global(Lisp_Object nil, Lisp_Object a)
  1236. {
  1237. CSL_IGNORE(nil);
  1238. if (!symbolp(a)) return aerror("make-global");
  1239. qheader(a) |= (SYM_SPECIAL_VAR | SYM_GLOBAL_VAR);
  1240. return onevalue(a);
  1241. }
  1242. Lisp_Object Lunmake_special(Lisp_Object nil, Lisp_Object a)
  1243. {
  1244. if (!symbolp(a)) return onevalue(nil);
  1245. qheader(a) &= ~(SYM_SPECIAL_VAR | SYM_GLOBAL_VAR);
  1246. return onevalue(a);
  1247. }
  1248. Lisp_Object Lunmake_global(Lisp_Object nil, Lisp_Object a)
  1249. {
  1250. if (!symbolp(a)) return onevalue(nil);
  1251. qheader(a) &= ~(SYM_SPECIAL_VAR | SYM_GLOBAL_VAR);
  1252. return onevalue(a);
  1253. }
  1254. Lisp_Object Lsymbol_specialp(Lisp_Object nil, Lisp_Object a)
  1255. {
  1256. if (!symbolp(a)) return onevalue(nil);
  1257. else if ((qheader(a) & (SYM_SPECIAL_VAR | SYM_GLOBAL_VAR)) ==
  1258. SYM_SPECIAL_VAR) return onevalue(lisp_true);
  1259. else return onevalue(nil);
  1260. }
  1261. Lisp_Object Lsymbol_globalp(Lisp_Object nil, Lisp_Object a)
  1262. {
  1263. if (!symbolp(a)) return onevalue(nil);
  1264. else if ((qheader(a) & SYM_GLOBAL_VAR) != 0) return onevalue(lisp_true);
  1265. else return onevalue(nil);
  1266. }
  1267. Lisp_Object Lboundp(Lisp_Object nil, Lisp_Object a)
  1268. {
  1269. if (!symbolp(a)) return onevalue(nil);
  1270. #ifndef COMMON
  1271. /*
  1272. * In COMMON Lisp it seems that this is intended to just check if the
  1273. * value cell in a shallow-bound implementation contains some marker value
  1274. * that stands for "junk". In Standard Lisp mode I deem that variables
  1275. * that have not been declared fluid are unbound. Seems to me like a
  1276. * classical mix-up between the concept of binding and of having some
  1277. * particular value... Oh well.
  1278. */
  1279. else if ((qheader(a) & SYM_SPECIAL_VAR) == 0) return onevalue(nil);
  1280. #endif
  1281. else if (qvalue(a) == unset_var) return onevalue(nil); /* no value yet */
  1282. else return onevalue(lisp_true);
  1283. }
  1284. Lisp_Object Lsymbol_value(Lisp_Object nil, Lisp_Object a)
  1285. {
  1286. CSL_IGNORE(nil);
  1287. if (!symbolp(a)) return onevalue(a);
  1288. else return onevalue(qvalue(a));
  1289. }
  1290. Lisp_Object Lset(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  1291. {
  1292. if (!symbolp(a) || a == nil || a == lisp_true) return aerror("set");
  1293. qvalue(a) = b;
  1294. return onevalue(b);
  1295. }
  1296. Lisp_Object Lsymbol_function(Lisp_Object nil, Lisp_Object a)
  1297. {
  1298. one_args *f1;
  1299. two_args *f2;
  1300. n_args *fn;
  1301. if (!symbolp(a)) return onevalue(nil);
  1302. f1 = qfn1(a); f2 = qfn2(a); fn = qfnn(a);
  1303. if ((qheader(a) & (SYM_SPECIAL_FORM | SYM_MACRO)) != 0 ||
  1304. (f1 == undefined1 && f2 == undefined2 &&
  1305. fn == undefinedn)) return onevalue(nil);
  1306. else if (f1 == interpreted1 ||
  1307. f2 == interpreted2 ||
  1308. fn == interpretedn)
  1309. /* I wonder if onevalue(cons(...)) is really valid here. It is OK in SL mode */
  1310. return onevalue(cons(lambda, qenv(a)));
  1311. else if (f1 == funarged1 ||
  1312. f2 == funarged2 ||
  1313. fn == funargedn)
  1314. return onevalue(cons(funarg, qenv(a)));
  1315. else if (f1 == traceinterpreted1 ||
  1316. f2 == traceinterpreted2 ||
  1317. fn == traceinterpretedn)
  1318. return onevalue(cons(lambda, qcdr(qenv(a))));
  1319. else if (f1 == tracefunarged1 ||
  1320. f2 == tracefunarged2 ||
  1321. fn == tracefunargedn)
  1322. return onevalue(cons(funarg, qcdr(qenv(a))));
  1323. else
  1324. {
  1325. #ifdef COMMON
  1326. Lisp_Object b = get(a, work_symbol, nil);
  1327. #else
  1328. Lisp_Object b = get(a, work_symbol);
  1329. #endif
  1330. /*
  1331. * If I have already manufactured a code pointer for this function I
  1332. * can find it on the property list - in that case I will re-use it.
  1333. */
  1334. while (b != nil)
  1335. { Lisp_Object c = qcar(b);
  1336. if ((qheader(c) & (SYM_C_DEF | SYM_CODEPTR)) ==
  1337. (SYM_CODEPTR | (qheader(a) & SYM_C_DEF)))
  1338. return onevalue(c);
  1339. b = qcdr(b);
  1340. }
  1341. push(a);
  1342. /*
  1343. * To carry a code-pointer I manufacture a sort of gensym, flagging
  1344. * it in its header as a "code pointer object" and sticking the required
  1345. * definition in with it. I need to link this to the originating
  1346. * definition in some cases to allow for preserve/restart problems wrt
  1347. * the initialisation of function addresses that refer to C code.
  1348. * I make the carrier using GENSYM1, but need to clear the gensym flag bit
  1349. * to show I have a regular name for the object, and that I will not need
  1350. * to append a serial number later on. In Common Lisp mode I let the name
  1351. * of the gensym be just the name of the function, while in Standard Lisp
  1352. * mode I will append a numeric suffix. I do this because in Common Lisp
  1353. * mode the thing will print as (say) #:apply which is visibly different
  1354. * from the name 'apply of the base function, while in Standard Lisp a name
  1355. * like apply775 is needed to make the distinction (easily) visible.
  1356. */
  1357. #ifdef COMMON
  1358. b = Lgensym2(nil, a);
  1359. #else
  1360. b = Lgensym1(nil, a);
  1361. #endif
  1362. pop(a);
  1363. errexit();
  1364. set_fns(b, f1, f2, fn);
  1365. qenv(b) = qenv(a);
  1366. #ifdef COMMON
  1367. /* in Common Lisp mode gensyms that are "unprinted" are not special */
  1368. qheader(b) ^= (SYM_ANY_GENSYM | SYM_CODEPTR);
  1369. #else
  1370. qheader(b) ^= (SYM_UNPRINTED_GENSYM | SYM_ANY_GENSYM | SYM_CODEPTR);
  1371. #endif
  1372. if ((qheader(a) & SYM_C_DEF) != 0)
  1373. { Lisp_Object c, w;
  1374. #ifdef COMMON
  1375. c = get(a, unset_var, nil);
  1376. #else
  1377. c = get(a, unset_var);
  1378. #endif
  1379. if (c == nil) c = a;
  1380. push3(a, b, c);
  1381. qheader(b) |= SYM_C_DEF;
  1382. putprop(b, unset_var, c);
  1383. errexitn(3);
  1384. c = stack[0]; b = stack[-1];
  1385. #ifdef COMMON
  1386. w = get(c, work_symbol, nil);
  1387. #else
  1388. w = get(c, work_symbol);
  1389. #endif
  1390. w = cons(b, w);
  1391. pop(c);
  1392. errexitn(2);
  1393. putprop(c, work_symbol, w);
  1394. pop2(b, a);
  1395. errexit();
  1396. }
  1397. return onevalue(b);
  1398. }
  1399. }
  1400. Lisp_Object Lspecial_form_p(Lisp_Object nil, Lisp_Object a)
  1401. {
  1402. if (!symbolp(a)) return onevalue(nil);
  1403. else if ((qheader(a) & SYM_SPECIAL_FORM) != 0) return onevalue(lisp_true);
  1404. else return onevalue(nil);
  1405. }
  1406. Lisp_Object Lcodep(Lisp_Object nil, Lisp_Object a)
  1407. /*
  1408. * This responds TRUE for the special pseudo-symbols that are used to
  1409. * carry compiled code objects. It returns NIL on the symbols that
  1410. * are normally used by the user.
  1411. */
  1412. {
  1413. if (!symbolp(a)) return onevalue(nil);
  1414. if ((qheader(a) & (SYM_CODEPTR | SYM_C_DEF)) == SYM_CODEPTR)
  1415. return onevalue(lisp_true);
  1416. else return onevalue(nil);
  1417. }
  1418. Lisp_Object getvector(int tag, int32 type, intxx size)
  1419. {
  1420. /*
  1421. * tag is the value (e.g. TAG_SYMBOL) that will go in the low order
  1422. * 3 bits of the pointer result.
  1423. * type is the code (e.g. TYPE_SYMBOL) that gets packed, together with
  1424. * the size, into a header word.
  1425. * size is measured in bytes and must allow space for the header word.
  1426. * [Note that this last issue - size including the header - was probably
  1427. * a mistake since the header size depends on whether I am using a
  1428. * 32-bit or 64-bit representation. However it would be hard to unwind
  1429. * that now!]
  1430. */
  1431. Lisp_Object nil = C_nil;
  1432. #ifdef CHECK_FOR_CORRUPT_HEAP
  1433. validate_all();
  1434. #endif
  1435. for (;;)
  1436. { char *r = (char *)vfringe;
  1437. unsigned int free = (unsigned int)((char *)vheaplimit - r);
  1438. /*
  1439. * On a 64-bit system the allocation size will be a multiple of 8 anyway, so
  1440. * the doubleword_align here will have no effect! The result is that I never
  1441. * need or use a padding word at the end of a vector in that case.
  1442. */
  1443. int32 alloc_size = (int32)doubleword_align_up(size);
  1444. /*
  1445. * There is a real NASTY here - it is quite possible that I ought to implement
  1446. * a scheme whereby large vectors can be allocated as a series of chunks so as
  1447. * to avoid the current absolute limit on size. Remember that the page size
  1448. * is about 64 Kbytes for small machines but on larger ones I can have bigger
  1449. * pages (typically 256K) and hence bigger vectors.
  1450. */
  1451. if (alloc_size > CSL_PAGE_SIZE - 32)
  1452. return aerror("vector request too big");
  1453. if (alloc_size > (intxx)free)
  1454. { char msg[40];
  1455. /*
  1456. * I go to a whole load of trouble here to tell the user what sort of
  1457. * vector request provoked this garbage collection. I wonder if the user
  1458. * really cares - but I do very much when I am chasing after GC bugs!
  1459. */
  1460. switch (tag)
  1461. {
  1462. case TAG_SYMBOL:
  1463. sprintf(msg, "symbol header");
  1464. break;
  1465. case TAG_NUMBERS:
  1466. switch (type)
  1467. {
  1468. case TYPE_BIGNUM:
  1469. sprintf(msg, "bignum(%ld)", (long)size);
  1470. break;
  1471. default:
  1472. sprintf(msg, "numbers(%lx,%ld)", (long)type, (long)size);
  1473. break;
  1474. }
  1475. break;
  1476. case TAG_VECTOR:
  1477. switch (type)
  1478. {
  1479. case TYPE_STRING:
  1480. sprintf(msg, "string(%ld)", (long)size);
  1481. break;
  1482. case TYPE_BPS:
  1483. sprintf(msg, "BPS(%ld)", (long)size);
  1484. break;
  1485. case TYPE_SIMPLE_VEC:
  1486. sprintf(msg, "simple vector(%ld)", (long)size);
  1487. break;
  1488. case TYPE_HASH:
  1489. sprintf(msg, "hash table(%ld)", (long)size);
  1490. break;
  1491. default:
  1492. sprintf(msg, "vector(%lx,%ld)", (long)type, (long)size);
  1493. break;
  1494. }
  1495. break;
  1496. case TAG_BOXFLOAT:
  1497. sprintf(msg, "float(%ld)", (long)size);
  1498. break;
  1499. default:
  1500. sprintf(msg, "getvector(%lx,%ld)", (long)tag, (long)size);
  1501. break;
  1502. }
  1503. reclaim(nil, msg, GC_VEC, alloc_size);
  1504. errexit();
  1505. continue;
  1506. }
  1507. vfringe = (Lisp_Object)(r + alloc_size);
  1508. *((Header *)r) = type + (size << 10) + TAG_ODDS;
  1509. /*
  1510. * DANGER: the vector allocated here is left uninitialised at this stage.
  1511. * This is OK if the vector will contain binary information, but if it
  1512. * will hold any Lisp_Objects it needs safe values put in PDQ.
  1513. */
  1514. return (Lisp_Object)(r + tag);
  1515. }
  1516. }
  1517. Lisp_Object getvector_init(intxx n, Lisp_Object k)
  1518. {
  1519. Lisp_Object p, nil;
  1520. push(k);
  1521. p = getvector(TAG_VECTOR, TYPE_SIMPLE_VEC, n);
  1522. pop(k);
  1523. errexit();
  1524. #ifndef ADDRESS_64
  1525. if ((n & 4) != 0) n += 4; /* Ensure last doubleword is tidy */
  1526. #endif
  1527. while (n > CELL)
  1528. { n -= CELL;
  1529. *(Lisp_Object *)((char *)p - TAG_VECTOR + n) = k;
  1530. }
  1531. return p;
  1532. }
  1533. clock_t base_time;
  1534. double *clock_stack, consolidated_time[10], gc_time;
  1535. void push_clock(void)
  1536. {
  1537. clock_t t0 = read_clock();
  1538. /*
  1539. * Provided that I do this often enough I will not suffer clock
  1540. * wrap-around or overflow.
  1541. */
  1542. double delta = (double)(t0 - base_time)/(double)CLOCKS_PER_SEC;
  1543. base_time = t0;
  1544. *clock_stack += delta;
  1545. *++clock_stack = 0.0;
  1546. }
  1547. double pop_clock(void)
  1548. {
  1549. clock_t t0 = read_clock();
  1550. double delta = (double)(t0 - base_time)/(double)CLOCKS_PER_SEC;
  1551. base_time = t0;
  1552. return delta + *clock_stack--;
  1553. }
  1554. Lisp_Object MS_CDECL Ltime(Lisp_Object nil, int nargs, ...)
  1555. {
  1556. unsigned32 tt;
  1557. Lisp_Object r;
  1558. if (clock_stack == &consolidated_time[0])
  1559. { clock_t t0 = read_clock();
  1560. double delta = (double)(t0 - base_time)/(double)CLOCKS_PER_SEC;
  1561. base_time = t0;
  1562. consolidated_time[0] += delta;
  1563. }
  1564. argcheck(nargs, 0, "time");
  1565. CSL_IGNORE(nil);
  1566. tt = (unsigned32)(1000.0 * consolidated_time[0]);
  1567. /*
  1568. * Overflow here is around 49 days. I suppose that that is almost a
  1569. * thinkable amount of CPU time to use.... Oh dear!
  1570. */
  1571. if ((tt & fix_mask) == 0) return onevalue(fixnum_of_int(tt));
  1572. if (!signed_overflow(tt)) r = make_one_word_bignum(tt);
  1573. else r = make_two_word_bignum((tt>>31) & 1, tt & 0x7fffffff);
  1574. errexit();
  1575. return onevalue(r);
  1576. }
  1577. Lisp_Object MS_CDECL Lgctime(Lisp_Object nil, int nargs, ...)
  1578. {
  1579. argcheck(nargs, 0, "gctime");
  1580. CSL_IGNORE(nil);
  1581. return onevalue(fixnum_of_int((int32)(1000.0 * gc_time)));
  1582. }
  1583. #ifdef COMMON
  1584. Lisp_Object MS_CDECL Ldecoded_time(Lisp_Object nil, int nargs, ...)
  1585. {
  1586. time_t t0 = time(NULL);
  1587. /*
  1588. * tm_sec -- seconds 0..59
  1589. * tm_min -- minutes 0..59
  1590. * tm_hour -- hour of day 0..23
  1591. * tm_mday -- day of month 1..31
  1592. * tm_mon -- month 0..11
  1593. * tm_year -- years since 1900
  1594. * tm_wday -- day of week, 0..6 (Sunday..Saturday)
  1595. * tm_yday -- day of year, 0..365
  1596. * tm_isdst -- >0 if daylight savings time
  1597. * -- ==0 if not DST
  1598. * -- <0 if don't know
  1599. */
  1600. struct tm *tbuf = localtime(&t0);
  1601. Lisp_Object r, *p = &mv_2;
  1602. int w;
  1603. argcheck(nargs, 0, "get-decoded-time");
  1604. r = fixnum_of_int(tbuf->tm_sec);
  1605. *p++ = fixnum_of_int(tbuf->tm_min);
  1606. *p++ = fixnum_of_int(tbuf->tm_hour);
  1607. *p++ = fixnum_of_int(tbuf->tm_mday);
  1608. *p++ = fixnum_of_int(tbuf->tm_mon+1);
  1609. *p++ = fixnum_of_int(tbuf->tm_year+1900);
  1610. w = tbuf->tm_wday;
  1611. *p++ = fixnum_of_int(w == 0 ? 6 : w-1);
  1612. *p++ = tbuf->tm_isdst > 0 ? lisp_true : nil;
  1613. *p++ = fixnum_of_int(0); /* Time zone info not available? */
  1614. return nvalues(r, 9);
  1615. }
  1616. #endif
  1617. Lisp_Object MS_CDECL Ldate(Lisp_Object nil, int nargs, ...)
  1618. {
  1619. Lisp_Object w;
  1620. time_t t = time(NULL);
  1621. char today[32];
  1622. argcheck(nargs, 0, "date");
  1623. CSL_IGNORE(nil);
  1624. strcpy(today, ctime(&t)); /* e.g. "Sun Sep 16 01:03:52 1973\n" */
  1625. today[24] = 0; /* loses final '\n' */
  1626. w = make_string(today);
  1627. errexit();
  1628. return onevalue(w);
  1629. }
  1630. Lisp_Object MS_CDECL Ldatestamp(Lisp_Object nil, int nargs, ...)
  1631. /*
  1632. * Returns date-stamp integer, which on many systems will be the
  1633. * number of seconds between 1970.0.0 and now, but which could be
  1634. * pretty-well other things, as per the C "time_t" type.
  1635. */
  1636. {
  1637. Lisp_Object w;
  1638. time_t t = time(NULL);
  1639. /*
  1640. * Hmmm - I need to check time_t on a 64-bit machine!
  1641. */
  1642. unsigned32 n = (unsigned32)t; /* NON-PORTABLE assumption about time_t */
  1643. argcheck(nargs, 0, "datestamp");
  1644. CSL_IGNORE(nil);
  1645. if ((n & fix_mask) == 0) w = fixnum_of_int(n);
  1646. else if ((n & 0xc0000000U) == 0) w = make_one_word_bignum(n);
  1647. else w = make_two_word_bignum((n >> 31) & 1, n & 0x7fffffff);
  1648. errexit();
  1649. return onevalue(w);
  1650. }
  1651. #define STR24HDR (TAG_ODDS+TYPE_STRING+((24+CELL)<<10))
  1652. static int getint(char *p, int len)
  1653. {
  1654. int r = 0;
  1655. while (len-- != 0)
  1656. { int c = *p++;
  1657. if (c == ' ') c = '0';
  1658. r = 10*r + (c - '0');
  1659. }
  1660. return r;
  1661. }
  1662. static int getmon(char *s)
  1663. {
  1664. int c1 = s[0], c2 = s[1], c3 = s[2], r = -1, w;
  1665. char *m = "janfebmaraprmayjunjulaugsepoctnovdec";
  1666. if (isupper(c1)) c1 = tolower(c1);
  1667. if (isupper(c2)) c2 = tolower(c2);
  1668. if (isupper(c3)) c3 = tolower(c3);
  1669. for (w=0; w<12; w++)
  1670. { if (c1==m[0] && c2==m[1] && c3==m[2])
  1671. { r = w;
  1672. break;
  1673. }
  1674. m += 3;
  1675. }
  1676. return r;
  1677. }
  1678. static Lisp_Object Ldatelessp(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  1679. /*
  1680. * This is maybe a bit of an abomination! The functions (date) and
  1681. * (filedate "filename") [and also (modulep 'modulename)] return times
  1682. * as strings of 24 characters. This function decodes these and
  1683. * sorts out which time is earlier. The alternative would be to provide
  1684. * a collection of functions that returned coded times (as in C "time_t"),
  1685. * but I have greater doubts about making those utterly portable, while the
  1686. * textual arrangement used here seems fairly robust (until you start
  1687. * worrying about carrying a portable machine across time zones or switching
  1688. * to daylight savings time).
  1689. */
  1690. {
  1691. char *aa, *bb;
  1692. CSLbool res;
  1693. int wa, wb;
  1694. if (!is_vector(a) || !is_vector(b) ||
  1695. vechdr(a) != STR24HDR ||
  1696. vechdr(b) != STR24HDR) return aerror2("datelessp", a, b);
  1697. aa = (char *)a + (CELL - TAG_VECTOR);
  1698. bb = (char *)b + (CELL - TAG_VECTOR);
  1699. /*
  1700. * Layout is eg. "Wed May 12 15:50:23 1993"
  1701. * 012345678901234567890123
  1702. * Note that the year is 4 digits so that the year 2000 should hold
  1703. * no special terrors JUST here.
  1704. */
  1705. if ((wa = getint(aa+20, 4)) != (wb = getint(bb+20, 4))) res = wa < wb;
  1706. else if ((wa = getmon(aa+4)) != (wb = getmon(bb+4))) res = wa < wb;
  1707. else if ((wa = getint(aa+8, 2)) != (wb = getint(bb+8, 2))) res = wa < wb;
  1708. else if ((wa = getint(aa+11, 2)) != (wb = getint(bb+11, 2))) res = wa < wb;
  1709. else if ((wa = getint(aa+14, 2)) != (wb = getint(bb+14, 2))) res = wa < wb;
  1710. else if ((wa = getint(aa+17, 2)) != (wb = getint(bb+17, 2))) res = wa < wb;
  1711. else res = NO;
  1712. return onevalue(Lispify_predicate(res));
  1713. }
  1714. static Lisp_Object Lrepresentation1(Lisp_Object nil, Lisp_Object a)
  1715. /*
  1716. * Intended for debugging, and use with indirect (q.v.)
  1717. */
  1718. {
  1719. #ifdef ADDRESS_64
  1720. /* /* unreconstructed - may need to build a 64-bit int here */
  1721. int32 top = (int32)a & 0xf8000000U;
  1722. CSL_IGNORE(nil);
  1723. if (top == 0 || top == 0xf8000000U)
  1724. return onevalue(fixnum_of_int((int32)a));
  1725. a = make_one_word_bignum((int32)a);
  1726. errexit();
  1727. return onevalue(a);
  1728. #else
  1729. int32 top = (int32)a & 0xf8000000U;
  1730. CSL_IGNORE(nil);
  1731. if (top == 0 || top == 0xf8000000U)
  1732. return onevalue(fixnum_of_int((int32)a));
  1733. a = make_one_word_bignum((int32)a);
  1734. errexit();
  1735. return onevalue(a);
  1736. #endif
  1737. }
  1738. static Lisp_Object Lrepresentation2(Lisp_Object nil,
  1739. Lisp_Object a, Lisp_Object b)
  1740. /*
  1741. * Intended for debugging, and use with indirect (q.v.). arg2, if
  1742. * present and non-nil makes this more verbose.
  1743. */
  1744. {
  1745. #ifdef ADDRESS_64
  1746. /* /* Unreconstructed wrt return value but trace printing is 64 bit */
  1747. int32 top = (int32)a & 0xf8000000U;
  1748. CSL_IGNORE(nil);
  1749. if (b != nil) trace_printf(" %.16lx ", (long)(unsigned64)a);
  1750. if (top == 0 || top == 0xf8000000U)
  1751. return onevalue(fixnum_of_int((int32)a));
  1752. a = make_one_word_bignum((int32)a);
  1753. errexit();
  1754. return onevalue(a);
  1755. #else
  1756. int32 top = (int32)a & 0xf8000000U;
  1757. CSL_IGNORE(nil);
  1758. if (b != nil) trace_printf(" %.8lx ", (long)(unsigned32)a);
  1759. if (top == 0 || top == 0xf8000000U)
  1760. return onevalue(fixnum_of_int((int32)a));
  1761. a = make_one_word_bignum((int32)a);
  1762. errexit();
  1763. return onevalue(a);
  1764. #endif
  1765. }
  1766. Lisp_Object Lindirect(Lisp_Object nil, Lisp_Object a)
  1767. {
  1768. CSL_IGNORE(nil);
  1769. #ifdef ADDRESS_64
  1770. return onevalue(*(Lisp_Object *)sixty_four_bits(a));
  1771. #else
  1772. return onevalue(*(Lisp_Object *)thirty_two_bits(a));
  1773. #endif
  1774. }
  1775. setup_type const funcs1_setup[] =
  1776. {
  1777. {"acons", wrong_no_na, wrong_no_nb, Lacons},
  1778. {"atom", Latom, too_many_1, wrong_no_1},
  1779. {"boundp", Lboundp, too_many_1, wrong_no_1},
  1780. {"car", Lcar, too_many_1, wrong_no_1},
  1781. {"car*", Lcar_star, too_many_1, wrong_no_1},
  1782. {"cdr", Lcdr, too_many_1, wrong_no_1},
  1783. {"caar", Lcaar, too_many_1, wrong_no_1},
  1784. {"cadr", Lcadr, too_many_1, wrong_no_1},
  1785. {"cdar", Lcdar, too_many_1, wrong_no_1},
  1786. {"cddr", Lcddr, too_many_1, wrong_no_1},
  1787. {"caaar", Lcaaar, too_many_1, wrong_no_1},
  1788. {"caadr", Lcaadr, too_many_1, wrong_no_1},
  1789. {"cadar", Lcadar, too_many_1, wrong_no_1},
  1790. {"caddr", Lcaddr, too_many_1, wrong_no_1},
  1791. {"cdaar", Lcdaar, too_many_1, wrong_no_1},
  1792. {"cdadr", Lcdadr, too_many_1, wrong_no_1},
  1793. {"cddar", Lcddar, too_many_1, wrong_no_1},
  1794. {"cdddr", Lcdddr, too_many_1, wrong_no_1},
  1795. {"caaaar", Lcaaaar, too_many_1, wrong_no_1},
  1796. {"caaadr", Lcaaadr, too_many_1, wrong_no_1},
  1797. {"caadar", Lcaadar, too_many_1, wrong_no_1},
  1798. {"caaddr", Lcaaddr, too_many_1, wrong_no_1},
  1799. {"cadaar", Lcadaar, too_many_1, wrong_no_1},
  1800. {"cadadr", Lcadadr, too_many_1, wrong_no_1},
  1801. {"caddar", Lcaddar, too_many_1, wrong_no_1},
  1802. {"cadddr", Lcadddr, too_many_1, wrong_no_1},
  1803. {"cdaaar", Lcdaaar, too_many_1, wrong_no_1},
  1804. {"cdaadr", Lcdaadr, too_many_1, wrong_no_1},
  1805. {"cdadar", Lcdadar, too_many_1, wrong_no_1},
  1806. {"cdaddr", Lcdaddr, too_many_1, wrong_no_1},
  1807. {"cddaar", Lcddaar, too_many_1, wrong_no_1},
  1808. {"cddadr", Lcddadr, too_many_1, wrong_no_1},
  1809. {"cdddar", Lcdddar, too_many_1, wrong_no_1},
  1810. {"cddddr", Lcddddr, too_many_1, wrong_no_1},
  1811. {"qcar", Lcar, too_many_1, wrong_no_1},
  1812. {"qcdr", Lcdr, too_many_1, wrong_no_1},
  1813. {"qcaar", Lcaar, too_many_1, wrong_no_1},
  1814. {"qcadr", Lcadr, too_many_1, wrong_no_1},
  1815. {"qcdar", Lcdar, too_many_1, wrong_no_1},
  1816. {"qcddr", Lcddr, too_many_1, wrong_no_1},
  1817. {"bpsp", Lbpsp, too_many_1, wrong_no_1},
  1818. {"codep", Lcodep, too_many_1, wrong_no_1},
  1819. {"constantp", Lconstantp, too_many_1, wrong_no_1},
  1820. {"date", wrong_no_na, wrong_no_nb, Ldate},
  1821. {"datestamp", wrong_no_na, wrong_no_nb, Ldatestamp},
  1822. {"enable-backtrace", Lenable_backtrace, too_many_1, wrong_no_1},
  1823. {"error", Lerror1, Lerror2, Lerror},
  1824. {"error1", wrong_no_na, wrong_no_nb, Lerror0},
  1825. #ifdef NAG
  1826. {"unwind", wrong_no_na, wrong_no_nb, Lunwind},
  1827. #endif
  1828. {"eq-safe", Leq_safe, too_many_1, wrong_no_1},
  1829. {"fixp", Lfixp, too_many_1, wrong_no_1},
  1830. {"floatp", Lfloatp, too_many_1, wrong_no_1},
  1831. {"fluidp", Lsymbol_specialp, too_many_1, wrong_no_1},
  1832. {"gctime", wrong_no_na, wrong_no_nb, Lgctime},
  1833. {"globalp", Lsymbol_globalp, too_many_1, wrong_no_1},
  1834. {"hash-table-p", Lhash_table_p, too_many_1, wrong_no_1},
  1835. {"indirect", Lindirect, too_many_1, wrong_no_1},
  1836. {"integerp", Lintegerp, too_many_1, wrong_no_1},
  1837. {"intersection", too_few_2, Lintersect, wrong_no_2},
  1838. {"list2", too_few_2, Llist2, wrong_no_2},
  1839. {"list2*", wrong_no_na, wrong_no_nb, Llist2star},
  1840. {"list3", wrong_no_na, wrong_no_nb, Llist3},
  1841. {"make-global", Lmake_global, too_many_1, wrong_no_1},
  1842. {"make-special", Lmake_special, too_many_1, wrong_no_1},
  1843. {"mkquote", Lmkquote, too_many_1, wrong_no_1},
  1844. {"ncons", Lncons, too_many_1, wrong_no_1},
  1845. {"numberp", Lnumberp, too_many_1, wrong_no_1},
  1846. {"pair", too_few_2, Lpair, wrong_no_2},
  1847. {"protect-symbols", Lprotect_symbols, too_many_1, wrong_no_1},
  1848. {"protected-symbol-warn", Lwarn_about_protected_symbols, too_many_1, wrong_no_1},
  1849. {"put", wrong_no_na, wrong_no_nb, Lputprop},
  1850. {"remprop", too_few_2, Lremprop, wrong_no_2},
  1851. {"representation", Lrepresentation1, Lrepresentation2, wrong_no_2},
  1852. {"rplaca", too_few_2, Lrplaca, wrong_no_2},
  1853. {"rplacd", too_few_2, Lrplacd, wrong_no_2},
  1854. {"set", too_few_2, Lset, wrong_no_2},
  1855. {"special-form-p", Lspecial_form_p, too_many_1, wrong_no_1},
  1856. {"stop", Lstop, too_many_1, wrong_no_1},
  1857. {"symbol-function", Lsymbol_function, too_many_1, wrong_no_1},
  1858. {"symbol-value", Lsymbol_value, too_many_1, wrong_no_1},
  1859. {"time", wrong_no_na, wrong_no_nb, Ltime},
  1860. {"datelessp", too_few_2, Ldatelessp, wrong_no_2},
  1861. {"union", too_few_2, Lunion, wrong_no_2},
  1862. {"unmake-global", Lunmake_global, too_many_1, wrong_no_1},
  1863. {"unmake-special", Lunmake_special, too_many_1, wrong_no_1},
  1864. {"xcons", too_few_2, Lxcons, wrong_no_2},
  1865. /* I provide both IDP and SYMBOLP in both modes... */
  1866. {"symbolp", Lsymbolp, too_many_1, wrong_no_1},
  1867. {"idp", Lsymbolp, too_many_1, wrong_no_1},
  1868. /* I support the Common Lisp names here in both modes */
  1869. {"simple-string-p", Lstringp, too_many_1, wrong_no_1},
  1870. {"simple-vector-p", Lsimple_vectorp, too_many_1, wrong_no_1},
  1871. #ifdef COMMON
  1872. {"fill-vector", wrong_no_na, wrong_no_nb, Lfill_vector},
  1873. {"get", too_few_2, Lget, Lget_3},
  1874. {"get-decoded-time", wrong_no_0a, wrong_no_0b, Ldecoded_time},
  1875. {"arrayp", Larrayp, too_many_1, wrong_no_1},
  1876. {"complex-arrayp", Lcomplex_arrayp, too_many_1, wrong_no_1},
  1877. {"short-floatp", Lshort_floatp, too_many_1, wrong_no_1},
  1878. {"single-floatp", Lsingle_floatp, too_many_1, wrong_no_1},
  1879. {"double-floatp", Ldouble_floatp, too_many_1, wrong_no_1},
  1880. {"long-floatp", Llong_floatp, too_many_1, wrong_no_1},
  1881. {"rationalp", Lrationalp, too_many_1, wrong_no_1},
  1882. {"complexp", Lcomplexp, too_many_1, wrong_no_1},
  1883. {"consp", Lconsp, too_many_1, wrong_no_1},
  1884. {"convert-to-array", Lconvert_to_array, too_many_1, wrong_no_1},
  1885. {"convert-to-struct", Lconvert_to_struct, too_many_1, wrong_no_1},
  1886. {"identity", Lidentity, too_many_1, wrong_no_1},
  1887. {"list", Lncons, Llist2, Llist},
  1888. {"list*", Lidentity, Lcons, Lliststar},
  1889. {"listp", Llistp, too_many_1, wrong_no_1},
  1890. {"bit-vector-p", Lsimple_bit_vector_p, too_many_1, wrong_no_1},
  1891. {"simple-bit-vector-p", Lsimple_bit_vector_p, too_many_1, wrong_no_1},
  1892. {"stringp", Lc_stringp, too_many_1, wrong_no_1},
  1893. {"structp", Lstructp, too_many_1, wrong_no_1},
  1894. {"flag", too_few_2, Lflag, wrong_no_2},
  1895. {"flagp", too_few_2, Lflagp, wrong_no_2},
  1896. {"flagpcar", too_few_2, Lflagpcar, wrong_no_2},
  1897. {"remflag", too_few_2, Lremflag, wrong_no_2},
  1898. {"time*", wrong_no_na, wrong_no_nb, Ltime},
  1899. #else
  1900. {"get", too_few_2, Lget, wrong_no_2},
  1901. {"convert-to-evector", Lconvert_to_struct, too_many_1, wrong_no_1},
  1902. {"evectorp", Lstructp, too_many_1, wrong_no_1},
  1903. {"get*", too_few_2, Lget, wrong_no_2},
  1904. {"pairp", Lconsp, too_many_1, wrong_no_1},
  1905. /* I provide CONSP as well as PAIRP since otherwise I get muddled */
  1906. {"consp", Lconsp, too_many_1, wrong_no_1},
  1907. {"flag", too_few_2, Lflag, wrong_no_2},
  1908. {"flagp", too_few_2, Lflagp, wrong_no_2},
  1909. {"flagpcar", too_few_2, Lflagpcar, wrong_no_2},
  1910. {"flagp**", too_few_2, Lflagp, wrong_no_2},
  1911. {"remflag", too_few_2, Lremflag, wrong_no_2},
  1912. {"stringp", Lstringp, too_many_1, wrong_no_1},
  1913. {"threevectorp", Lthreevectorp, too_many_1, wrong_no_1},
  1914. {"vectorp", Lsimple_vectorp, too_many_1, wrong_no_1},
  1915. #endif
  1916. {NULL, 0, 0, 0}
  1917. };
  1918. /* end of fns1.c */