vsl.lsp 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751
  1. % This is a collection of commonly useful Lisp
  2. % functions that can be defined in terms of the
  3. % things that are built into vsl.
  4. % The vsl system supports big-number arithmetic via Lisp
  5. % code in this file. It can not even read in numbers properly
  6. % until arithmetic is working. So the next two definitions
  7. % instate temporary versions of "plus2" and "times2" that will
  8. % make it possible to read this file.
  9. (de plus2 (u v) (iplus u v))
  10. (de times2 (u v) (itimes u v))
  11. (de minus (u) (iminus u))
  12. % There are a number of pre-defined symbols that stand for
  13. % characters and the like. Define them here.
  14. (setq blank '! )
  15. (setq tab (code!-char 9))
  16. (setq !$eol!$ (code!-char 10))
  17. (setq dollar '!$)
  18. (setq lpar '!()
  19. (setq rpar '!))
  20. (setq f nil)
  21. % The following names are used with "#\name" to get the character code of
  22. % various special characters.
  23. (put 'null 'charvalue 0)
  24. (put 'bell 'charvalue 7)
  25. (put 'backspace 'charvalue 8)
  26. (put 'tab 'charvalue 9)
  27. (put 'lf 'charvalue 10)
  28. (put 'eol 'charvalue 10)
  29. (put 'ff 'charvalue 12)
  30. (put 'cr 'charvalue 13)
  31. (put 'eof 'charvalue -1)
  32. (put 'escape 'charvalue 27)
  33. (put 'space 'charvalue 32)
  34. (put 'rubout 'charvalue 8)
  35. (put 'rub 'charvalue 8)
  36. (put 'delete 'charvalue 127)
  37. (put 'del 'charvalue 127)
  38. % Many combinations of car and cdr are supported. Here I define
  39. % versions that do up to four accesses. These would of course be
  40. % trivial to move into C code!
  41. (de caar (x)
  42. (car (car x)))
  43. (de cadr (x)
  44. (car (cdr x)))
  45. (de cdar (x)
  46. (cdr (car x)))
  47. (de cddr (x)
  48. (cdr (cdr x)))
  49. (de caaar (x)
  50. (car (car (car x))))
  51. (de caadr (x)
  52. (car (car (cdr x))))
  53. (de cadar (x)
  54. (car (cdr (car x))))
  55. (de caddr (x)
  56. (car (cdr (cdr x))))
  57. (de cdaar (x)
  58. (cdr (car (car x))))
  59. (de cdadr (x)
  60. (cdr (car (cdr x))))
  61. (de cddar (x)
  62. (cdr (cdr (car x))))
  63. (de cdddr (x)
  64. (cdr (cdr (cdr x))))
  65. (de caaaar (x)
  66. (car (car (car (car x)))))
  67. (de caaadr (x)
  68. (car (car (car (cdr x)))))
  69. (de caadar (x)
  70. (car (car (cdr (car x)))))
  71. (de caaddr (x)
  72. (car (car (cdr (cdr x)))))
  73. (de cadaar (x)
  74. (car (cdr (car (car x)))))
  75. (de cadadr (x)
  76. (car (cdr (car (cdr x)))))
  77. (de caddar (x)
  78. (car (cdr (cdr (car x)))))
  79. (de cadddr (x)
  80. (car (cdr (cdr (cdr x)))))
  81. (de cdaaar (x)
  82. (cdr (car (car (car x)))))
  83. (de cdaadr (x)
  84. (cdr (car (car (cdr x)))))
  85. (de cdadar (x)
  86. (cdr (car (cdr (car x)))))
  87. (de cdaddr (x)
  88. (cdr (car (cdr (cdr x)))))
  89. (de cddaar (x)
  90. (cdr (cdr (car (car x)))))
  91. (de cddadr (x)
  92. (cdr (cdr (car (cdr x)))))
  93. (de cdddar (x)
  94. (cdr (cdr (cdr (car x)))))
  95. (de cddddr (x)
  96. (cdr (cdr (cdr (cdr x)))))
  97. % "not" and "eqcar" are used while processing some parts of
  98. % this file and so get defined early.
  99. (de not (x)
  100. (null x))
  101. (de eqcar (a b) % Is (car a) the same as b?
  102. (and (not (atom a)) (eq (car a) b)))
  103. % The vsl kernel checks for a function called macroexpand_list
  104. % whenever it is about to define a function, and expects it to
  105. % expand macros in all the expressions in a list. So before
  106. % I define any macros that could usefully be expanded I will
  107. % define it!
  108. (de macroexpand_cond (l)
  109. (cond
  110. ((null l) nil)
  111. (t (cons (macroexpand_list (car l))
  112. (macroexpand_cond (cdr l))))))
  113. (de macroexpand (x)
  114. (cond
  115. ((atom x) x)
  116. ((not (atom (car x)))
  117. (cons (macroexpand (car x))
  118. (macroexpand_list (cdr x))))
  119. ((eqcar x 'quote) x)
  120. ((eqcar x 'cond)
  121. (cons 'cond (macroexpand_cond (cdr x))))
  122. ((or (eqcar x 'prog) (eqcar x 'lambda))
  123. (cons (car x) (cons (cadr x)
  124. (macroexpand_list (cddr x)))))
  125. ((eqcar (getd (car x)) 'macro)
  126. (macroexpand (apply (cdr (getd (car x)))
  127. (list x))))
  128. (t (cons (car x) (macroexpand_list (cdr x))))))
  129. (de macroexpand_list (l)
  130. (cond
  131. ((atom l) l)
  132. (t (cons (macroexpand (car l))
  133. (macroexpand_list (cdr l))))))
  134. % Now I start on defining the proper arithmetic including
  135. % in particular support for big integers. The function
  136. % "expand" is used to map (plus a b c d) onto
  137. % (plus2 a (plus2 b (plus2 c d))) [and similarly for other
  138. % arithmetic functions that take arbitrary numbers of arguments].
  139. (de expand (l fn)
  140. (cond
  141. ((null (cdr l)) (car l))
  142. (t (list fn (car l) (expand (cdr l) fn)))))
  143. (dm plus (u) (expand (cdr u) 'plus2))
  144. (dm times (u) (expand (cdr u) 'times2))
  145. (dm logand (u) (expand (cdr u) 'logand2))
  146. (dm logor (u) (expand (cdr u) 'logor2))
  147. (dm logxor (u) (expand (cdr u) 'logxor2))
  148. (dm max (u) (expand (cdr u) 'max2))
  149. (dm min (u) (expand (cdr u) 'min2))
  150. % The function "iplus2" behaved like "iplus" but accepts
  151. % exactly two arguments. And similarly for several others.
  152. (de iplus2 (u v) (iplus u v))
  153. (de itimes2 (u v) (itimes u v))
  154. (de ilogand2 (u v) (ilogand u v))
  155. (de ilogor2 (u v) (ilogor u v))
  156. (de ilogxor2 (u v) (ilogxor u v))
  157. % Back to defining what are sometimes merely alternate
  158. % names for very basic operations.
  159. (de idp (x)
  160. (symbolp x))
  161. (de pairp (x)
  162. (null (atom x)))
  163. (de prog1 (a b)
  164. a)
  165. (de prog2 (a b)
  166. b)
  167. (de reverse (x)
  168. (prog (y)
  169. loop
  170. (cond ((atom x) (return y)))
  171. (setq y (cons (car x) y))
  172. (setq x (cdr x))
  173. (go loop)))
  174. % "reverse" reverses a list, while "reversip" creates the
  175. % reversed version by overwriting the data that makes up its
  176. % input. This may be held to save a little space, but is
  177. % to be used with care.
  178. (de reversip2 (a b)
  179. (prog (w)
  180. loop
  181. (cond ((atom a) (return b)))
  182. (setq w (cdr a))
  183. (rplacd a b)
  184. (setq b a)
  185. (setq a w)
  186. (go loop)))
  187. (de reversip (x) (reversip2 x nil)) % Destructive reverse
  188. (de append (a b) % Append a pair of lists.
  189. (cond
  190. ((atom a) b)
  191. (t (cons (car a) (append (cdr a) b)))))
  192. % I have written various of these in ugly imperative styles so that they
  193. % end up iterative not recursive...
  194. (de length (l) % Find length of a list.
  195. (prog (n)
  196. (setq n 0)
  197. top(cond ((atom l) (return n)))
  198. (setq n (add1 n))
  199. (setq l (cdr l))
  200. (go top)))
  201. (de last (l) % Last element of a (non-empty) list.
  202. (cond
  203. ((atom l) (error 1 "last on emtpy list"))
  204. ((atom (cdr l)) (car l))
  205. (t (last (cdr l)))))
  206. (de lastcar (x) % Not in Standard Lisp
  207. (cond
  208. ((atom x) nil)
  209. ((atom (cdr x)) (car x))
  210. (t (lastcar (cdr x)))))
  211. (de lastpair (l) % Last pair of a (non-empty) list,
  212. (cond % or nil if the input is empty.
  213. ((atom l) nil)
  214. ((atom (cdr l)) l)
  215. (t (lastpair (cdr l)))))
  216. % #else /* XXX */
  217. % (prog ()
  218. % (cond
  219. % ((null l) (error 1 "last on emtpy list")))
  220. % top(cond
  221. % ((atom (cdr l)) (return l)))
  222. % (setq l (cdr l))
  223. % (go top)))
  224. %
  225. % (de lastcar (l) % Not in Standard Lisp
  226. % (prog ()
  227. % (cond
  228. % ((null l) (error 1 "lastcar on emtpy list")))
  229. % top(cond
  230. % ((atom (cdr l)) (return (car l))))
  231. % (setq l (cdr l))
  232. % (go top)))
  233. %
  234. % (de lastpair (l) % Last pair of a (non-empty) list.
  235. % (prog ()
  236. % (cond
  237. % ((null l) (error 1 "lastpair on emtpy list")))
  238. % top(cond
  239. % ((atom (cdr l)) (return l)))
  240. % (setq l (cdr l))
  241. % (go top)))
  242. % #endif /* XXX */
  243. (de member (a l)
  244. (cond
  245. ((atom l) nil)
  246. ((equal a (car l)) l)
  247. (t (member a (cdr l)))))
  248. % "member" checks it a value is present in a list using the
  249. % "equal" test, while "memq" uses "eq".
  250. % #else /* XXX */
  251. % (prog ()
  252. % top
  253. % (cond
  254. % ((null l) (return nil))
  255. % ((equal a (car l)) (return l)))
  256. % (setq l (cdr l))
  257. % (go top)))
  258. % #endif /* XXX */
  259. (de memq (a l)
  260. (cond
  261. ((atom l) nil)
  262. ((eq a (car l)) l)
  263. (t (memq a (cdr l)))))
  264. % #else /* XXX */
  265. % (prog ()
  266. % top
  267. % (cond
  268. % ((null l) (return nil))
  269. % ((eq a (car l)) (return l)))
  270. % (setq l (cdr l))
  271. % (go top)))
  272. % #endif /* XXX */
  273. (de delete (a l)
  274. (cond
  275. ((atom l) l)
  276. ((equal a (car l)) (cdr l))
  277. (t (cons (car l) (delete a (cdr l))))))
  278. (de intersection (a b)
  279. (cond
  280. ((atom a) nil)
  281. ((member (car a) b) (cons (car a) (intersection (cdr a) b)))
  282. (t (intersection (cdr a) b))))
  283. (de union (a b)
  284. (cond
  285. ((atom a) b)
  286. ((member (car a) b) (union (cdr a) b))
  287. (t (cons (car a) (union (cdr a) b)))))
  288. (de neq (a b) % Not equal.
  289. (null (equal a b)))
  290. (de assoc (a l) % Look item up in association list using equal.
  291. (cond
  292. ((atom l) nil)
  293. ((and (not (atom (car l)))
  294. (equal (caar l) a)) (car l))
  295. (t (assoc a (cdr l)))))
  296. (de atsoc (a l) % Look item up in association list using eq.
  297. (cond
  298. ((atom l) nil)
  299. ((and (not (atom (car l)))
  300. (eq (caar l) a)) (car l))
  301. (t (atsoc a (cdr l)))))
  302. (de subst (a b c) % Substitute a for b in c
  303. (cond
  304. ((equal b c) a)
  305. ((atom c) c)
  306. (t (cons (subst a b (car c)) (subst a b (cdr c))))))
  307. (de sublis (x y)
  308. (if (atom x) y
  309. (prog (u)
  310. (setq u (assoc y x))
  311. (return (cond
  312. ((not (atom u)) (cdr u))
  313. ((atom y) y)
  314. (t (cons (sublis x (car y))
  315. (sublis x (cdr y)))))))))
  316. (de subla (x y)
  317. (if (atom x) y
  318. (prog (u)
  319. (setq u (atsoc y x))
  320. (return (cond
  321. ((not (atom u)) (cdr u))
  322. ((atom y) y)
  323. (t (cons (subla x (car y))
  324. (subla x (cdr y)))))))))
  325. (de pair (u v)
  326. (cond
  327. ((or (atom u) (atom v)) nil)
  328. (t (cons (cons (car u) (car v)) (pair (cdr u) (cdr v))))))
  329. (de spaces (n) % Print n blanks.
  330. (cond
  331. ((zerop n) nil)
  332. (t (princ " ") (spaces (sub1 n)))))
  333. % The prettyprint code here is a version of the code described
  334. % as an example of the use of vsl.
  335. (de prettyprint (x) % Display something with indentation.
  336. (terpri)
  337. (pprint x 0)
  338. (terpri)
  339. nil)
  340. (de pprint (x n) % Sub-function for prettyprint.
  341. (cond
  342. ((or (atom x)
  343. (lessp (length (explode x)) 40)) (prin x))
  344. (t (princ "(")
  345. (pprint (car x) (add1 n))
  346. (pprintail (cdr x) (plus n 3)))))
  347. (de pprintail (x n) % Sub-function for prettyprint.
  348. (cond
  349. ((null x) (princ ")"))
  350. ((atom x) (princ " . ")
  351. (prin x)
  352. (princ ")"))
  353. (t (terpri)
  354. (spaces n)
  355. (pprint (car x) n)
  356. (pprintail (cdr x) n))))
  357. (de rplacw (a b) (progn (rplaca a (car b)) (rplacd a (cdr b))))
  358. % The "map" functions apply some function to each item defined by
  359. % a list.
  360. % mapc and map return nil
  361. % mapcar and maplist build a list out of the computed values
  362. % mapcan and mapcon expect the values to be lists, and use "nconc"
  363. % to join them.
  364. % map, maplist and mapcon pass a pointer into the list itself
  365. % as argument to the function, while mapc, mapcar and mapcon pass
  366. % items from the list.
  367. % Note that some other Lisp systems have functions like this that take
  368. % the function as their first argument and the list as second, unlike the
  369. % argument order used here.
  370. % The use of awkward variables names such as "!~l" here is because under
  371. % the dynamic scoping regime in vsl if the function passed relied on a
  372. % free variable whose name clashed with a name used locally in these
  373. % definitions there could be confusion.
  374. (de mapcar (!~l !~fn)
  375. (prog (!~r)
  376. top (cond ((atom !~l) (return (reversip !~r))))
  377. (setq !~r (cons (apply !~fn (list (car !~l))) !~r))
  378. (setq !~l (cdr !~l))
  379. (go top)))
  380. (de maplist (!~l !~fn)
  381. (prog (!~r)
  382. top (cond ((atom !~l) (return (reversip !~r))))
  383. (setq !~r (cons (apply !~fn (list !~l)) !~r))
  384. (setq !~l (cdr !~l))
  385. (go top)))
  386. (de mapcan (!~l !~fn)
  387. (cond ((atom !~l) nil)
  388. (t (nconc (apply !~fn (list (car !~l))) (mapcan (cdr !~l) !~fn)))))
  389. (de mapcon (!~l !~fn)
  390. (cond ((atom !~l) nil)
  391. (t (nconc (apply !~fn (list !~l)) (mapcon (cdr !~l) !~fn)))))
  392. (de mapc (!~l !~fn)
  393. (prog ()
  394. top (cond ((atom !~l) (return nil)))
  395. (apply !~fn (list (car !~l)))
  396. (setq !~l (cdr !~l))
  397. (go top)))
  398. (de map (!~l !~fn)
  399. (prog ()
  400. top (cond ((atom !~l) (return nil)))
  401. (apply !~fn (list !~l))
  402. (setq !~l (cdr !~l))
  403. (go top)))
  404. (de copy (a)
  405. (cond
  406. ((atom a) a)
  407. (t (cons (copy (car a)) (copy (cdr a))))))
  408. (de sassoc (a l fn)
  409. (cond
  410. ((atom l) (apply fn nil))
  411. ((equal a (caar l)) (car l))
  412. (t (sassoc a (cdr l) fn))))
  413. (de rassoc (x l) % Not in Standard Lisp
  414. (prog ()
  415. loop (cond ((atom l) (return nil))
  416. ((equal x (cdar l)) (return (car l)))
  417. (t (setq l (cdr l)) (go loop))) ))
  418. (de deflist (a b)
  419. (prog (r)
  420. top (cond ((atom a) (return (reversip r))))
  421. (put (caar a) b (cadar a))
  422. (setq r (cons (caar a) r))
  423. (setq a (cdr a))
  424. (go top)))
  425. % The Lisp "backquote" capability is coped with in vsl by having
  426. % `(a b c) read in as (!` (a b c)) [and similarly for "," and ",@"]
  427. % and then using macro-expansion to convert into executable code.
  428. (de expand_backquote (x)
  429. (cond
  430. ((and (symbolp x) (null (null x))) (list 'quote x))
  431. ((atom x) x) % nil, number or string
  432. ((eq (car x) '!,) (cadr x))
  433. ((eq (car x) '!`) (expand_backquote (expand_backquote (cadr x))))
  434. ((eqcar (car x) '!,!@)
  435. (list 'append (cadar x) (expand_backquote (cdr x))))
  436. ((eqcar (car x) '!,!.)
  437. (list 'nconc (cadar x) (expand_backquote (cdr x))))
  438. (t (list 'cons (expand_backquote (car x)) (expand_backquote (cdr x))))))
  439. (dm !` (x) (expand_backquote (cadr x)))
  440. % Now a few things not needed by Standard Lisp but maybe helpful
  441. % when using Lisp directly.
  442. % Reduce uses the name "let" and so if I called this what I naturally
  443. % want to there would be a clash and trouble. So I use a mangled name here.
  444. % I also use let!* rather than let in those cases here where I can...
  445. % Both "let" and "let!*" expand naturally into uses of lambda-expressions.
  446. (de let_name (x)
  447. (if (atom x) x (car x)))
  448. (de let_val (x)
  449. (if (or (atom x) (atom (cdr x)))
  450. nil
  451. (cadr x)))
  452. (dm !~let (x) % (!~let ((v1 E1) (v2 E2) ...) body)
  453. (cons (cons 'lambda (cons (mapcar (cadr x) 'let_name) (cddr x)))
  454. (mapcar (cadr x) 'let_val)))
  455. (de expand_let!* (b x)
  456. (cond
  457. ((null b) x)
  458. (t (list (list 'lambda (list (let_name (car b))) (expand_let!* (cdr b) x))
  459. (let_val (car b))))))
  460. (dm let!* (x) % As !~let, but do bindings sequentially
  461. (expand_let!* (cadr x) (cons 'progn (cddr x))))
  462. % A set of macros provide various neat and easy-to-use control structures.
  463. % Note that tis version of IF allows a sequence of forms in the place
  464. % that gets processed if the predicate evaluates to nil.
  465. (dm if (x) % (IF predicate yes no*) or (IF predicate yes)
  466. `(cond
  467. (,(cadr x) ,(caddr x))
  468. (t ,@(cdddr x))))
  469. (dm when (x) % (WHEN predicate yes yes yes ...)
  470. `(cond
  471. (,(cadr x) ,@(cddr x))))
  472. (dm unless (x) % (UNLESS predicate no no no ...)
  473. `(cond
  474. ((null ,(cadr x)) ,@(cddr x))))
  475. (dm while (x) % (WHILE predicate body body body ...)
  476. (let!* ((g (gensym)))
  477. `(prog nil
  478. ,g (cond ((null ,(cadr x)) (return nil)))
  479. ,@(cddr x)
  480. (go ,g)))))
  481. % (psetq a A b B) must arrange to evaluate both A and B before
  482. % either is saved in a or b. This can be expressed in terms of
  483. % use of "let" - but the expansion process is a little messy to
  484. % establish.
  485. (de make_psetq_vars (u)
  486. (if (null u)
  487. nil
  488. (if (null (cdr u))
  489. (error "odd number of items in psetq")
  490. (cons (gensym) (make_psetq_vars (cddr u))))))
  491. (de make_psetq_bindings (vars u)
  492. (if (null u)
  493. nil
  494. (cons
  495. (list (car vars) (cadr u))
  496. (make_psetq_bindings (cdr vars) (cddr u)))))
  497. (de make_psetq_assignments (vars u)
  498. (if (null u)
  499. nil
  500. (cons
  501. (list 'setq (car u) (car vars))
  502. (make_psetq_assignments (cdr vars) (cddr u)))))
  503. (dm psetq (x) % parallel setq as in (psetq x X y Y z Z)
  504. (let!* ((vars (make_psetq_vars (cdr x))))
  505. `(let!* ,(make_psetq_bindings vars (cdr x))
  506. ,@(make_psetq_assignments vars (cdr x)))))
  507. % The "do" macro provides a rather general iteration capabilty
  508. % of the form
  509. % (do ((var init step) ..)
  510. % (endcondition result ...)
  511. % body)
  512. % and again can be expressed via macro-expansion into simpler or
  513. % more basic constructions.
  514. (de do_bindings (u)
  515. (if (null u)
  516. nil
  517. (if (atom (car u))
  518. (cons (car u) (do_bindings (cdr u)))
  519. (if (null (cdar u))
  520. (cons (list (caar u) nil) (do_bindings (cdr u)))
  521. (cons (list (caar u) (cadar u)) (do_bindings (cdr u)))))))
  522. (de do_endtest (u)
  523. (if (null u)
  524. nil
  525. (car u)))
  526. (de do_result (u)
  527. (if (null u)
  528. nil
  529. (cdr u)))
  530. (de do_updates (u)
  531. (if (null u)
  532. nil
  533. (let!* ((v (car u))
  534. (x (do_updates (cdr u))))
  535. (if (or (atom v)
  536. (null (cdr v))
  537. (null (cddr v)))
  538. x
  539. (cons (car v) (cons (caddr v) x))))))
  540. (de expand_do (u letter setter)
  541. (let!* ((bindings (do_bindings (car u)))
  542. (result (do_result (cadr u)))
  543. (updates (do_updates (car u)))
  544. (body (cddr u))
  545. (endtest (do_endtest (cadr u)))
  546. (upd (if updates (list (cons setter updates)) nil))
  547. (res (if (null result)
  548. nil
  549. (if (null (cdr result))
  550. (car result)
  551. (cons 'progn result))))
  552. (x (if (null endtest) nil
  553. `((when ,endtest (return ,res)))))
  554. (g (gensym)))
  555. (if bindings
  556. `(,letter ,bindings
  557. (prog nil
  558. ,g ,@x
  559. ,@body
  560. ,@upd
  561. (go ,g)))
  562. `(prog nil
  563. ,g ,@x
  564. ,@body
  565. ,@upd
  566. (go ,g)))))
  567. (dm do (u) (expand_do (cdr u) '!~let 'psetq))
  568. (dm do!* (u) (expand_do (cdr u) 'let!* 'setq))
  569. % "dolist" is much simpler, and is used as in
  570. % (dolist (a '(1 2 3)) (print a))
  571. (de expand_dolist (vir b)
  572. (prog (l v var init res)
  573. (setq var (car vir))
  574. (setq init (car (setq vir (cdr vir))))
  575. (setq res (cdr vir))
  576. (setq v (gensym))
  577. (setq l (gensym))
  578. (return `(prog (,v ,var)
  579. (setq ,v ,init)
  580. ,l (cond ((null ,v) (return (progn ,@res))))
  581. (setq ,var (car ,v))
  582. ,@b
  583. (setq ,v (cdr ,v))
  584. (go ,l)))))
  585. (dm dolist (u) (expand_dolist (cadr u) (cddr u)))
  586. % "dotimes" arranges to perform some actions a fixed number of times,
  587. % counting (starting from 0) in a variable that the user can name.
  588. % (dotimes (i 10) (prin i) (princ blank) (print (times i i)))
  589. (de expand_dotimes (vnr b)
  590. (prog (l v var count res)
  591. (setq var (car vnr))
  592. (setq count (car (setq vnr (cdr vnr))))
  593. (setq res (cdr vnr))
  594. (setq v (gensym))
  595. (setq l (gensym))
  596. (return `(prog (,v ,var)
  597. (setq ,v ,count)
  598. (setq ,var 0)
  599. ,l (cond ((geq ,var ,v) (return (progn ,@res))))
  600. ,@b
  601. (setq ,var (add1 ,var))
  602. (go ,l)))))
  603. (dm dotimes (u) (expand_dotimes (cadr u) (cddr u)))
  604. (de nconc (u v)
  605. (if (atom u) v
  606. (let!* ((w u))
  607. (while (not (atom (cdr u))) (setq u (cdr u)))
  608. (rplacd u v)
  609. w)))
  610. % Now the main body of the arithmetic code. the vsl kernel provides
  611. % functions with names like iplus, itimes, igreaterp, ... that
  612. % work with either floating point values or with integers up to 64-bits.
  613. % Building on that this code allows a list of the form
  614. % (!~bignum d0 d1 d2 ...)
  615. % to stand for a number expressed with radix 2^30 and with d0 as its
  616. % least significant digit. A very small number of hooks within vsl
  617. % allow reading and printing of general numbers to divert into the
  618. % code written here.
  619. % Implementing arithmetic in (interpreted) Lisp like this will be
  620. % seriously inefficient, so there would be big gains from re-working
  621. % the C code to make this stuff irrelevant!
  622. (setq !~radix (itimes 1024 1024 1024))
  623. (setq !~fpradix (ifloat !~radix))
  624. % The numeric data type must now include these cases.
  625. % The "atom" test in vsl needs to know that a bit of
  626. % data stored as (!~bignum ...) should viewed as atomic.
  627. (de fixp (u) (and (numberp u) (not (floatp u))))
  628. (de numberp (u) (or (inumberp u) (bignump u)))
  629. (de integerp (u) (and (numberp u) (not (floatp u))))
  630. % There are two representations of numbers. The one used in the
  631. % main parts of the code are
  632. % integer < 2^30
  633. % float
  634. % (!~bignum list of digits ...)
  635. %
  636. % but within the code that implements big arithemetic I want
  637. % to keep things JUST as lists of digits with the "~bignum"
  638. % marker omitted. I need functions that map between these two
  639. % formats are here they are.
  640. (de !~embiggen (n)
  641. (cond
  642. ((zerop n) nil)
  643. ((ifixp n) (list n))
  644. ((bignump n) (cdr n))
  645. (t (error "number expected but received" n))))
  646. (de !~sizecheck (l)
  647. (cond
  648. ((null l) 0)
  649. ((null (cdr l)) (car l))
  650. (t (cons '!~bignum l))))
  651. % Various two-argument functions will be able to use built-in
  652. % vsl functions on floating point input but need to do more
  653. % if they have a potentially big integer. The dispatch between
  654. % these cases can be encapsulated within a macro...
  655. (dm !~bignum_dispatch2 (u)
  656. `(cond
  657. ((or (floatp ,(cadr u)) (floatp ,(caddr u)))
  658. (,(car (cdddr u)) (float ,(cadr u)) (float ,(caddr u))))
  659. (t (!~sizecheck (,(cadr (cdddr u))
  660. (!~embiggen ,(cadr u)) (!~embiggen ,(caddr u)))))))
  661. % The version above converts its result back into a "number". But eg
  662. % comparison operations do not want to do that, so here is a
  663. % second version that does not insert calls to !~sizecheck.
  664. (dm !~bignum_dispatch2a (u)
  665. `(cond
  666. ((or (floatp ,(cadr u)) (floatp ,(caddr u)))
  667. (,(car (cdddr u)) (float ,(cadr u)) (float ,(caddr u))))
  668. (t (,(cadr (cdddr u))
  669. (!~embiggen ,(cadr u)) (!~embiggen ,(caddr u))))))
  670. % The Lisp reader in vsl will call plus2 and times2 when it reads
  671. % in integers, so I defer defining either until all their sub-functions
  672. % are in place.
  673. %(de plus2 (u v)
  674. % (!~bignum_dispatch2 u v iplus !~bigplus2))
  675. % The internal functions used here are all given names starting with
  676. % "~" to reduce the prospect of clashes with user-written code.
  677. (de !~bigplus2 (u v) (!~bigplus2carry u v 0))
  678. % "~xdivide" is like divide on native small numbers except that
  679. % it guarantees that the remainder it returns is non-negative.
  680. (de !~xdivide (u v)
  681. (let!* ((r (idivide u v)))
  682. (if (iminusp (cdr r))
  683. (cons (isub1 (car r)) (iplus (cdr r) v))
  684. r)))
  685. % "~bigcons" arranged to avoid leaving superfluous leading zeros
  686. % as part of big-numbers.
  687. (de !~bigcons (a b)
  688. (cond
  689. ((and (zerop a) (null b)) nil)
  690. ((equal b '(-1)) (if (onep a) nil (cons (idifference a !~radix) nil)))
  691. (t (cons a b))))
  692. (de !~carryinto (u c)
  693. (cond
  694. ((zerop c) u)
  695. ((null u) (!~bigcons c nil))
  696. (t (let!* ((x (!~xdivide (iplus (car u) c) !~radix)))
  697. (!~bigcons (cdr x) (!~carryinto (cdr u) (car x)))))))
  698. (de !~bigplus2carry (u v c)
  699. (cond
  700. ((null u) (!~carryinto v c))
  701. ((null v) (!~carryinto u c))
  702. (t (let!* ((x (!~xdivide (iplus (car u) (car v) c) !~radix)))
  703. (!~bigcons (cdr x) (!~bigplus2carry (cdr u) (cdr v) (car x)))))))
  704. %(de times2 (u v)
  705. % (!~bignum_dispatch2 u v itimes !~bigtimes2))
  706. % Multiply a big-number by a simple small integer.
  707. (de !~bigtimesn (n u c)
  708. (cond
  709. ((null u) (if (zerop c) nil (list c)))
  710. (t (let!* ((x (!~xdivide (iplus (itimes n (car u)) c) !~radix)))
  711. (!~bigcons (cdr x) (!~bigtimesn n (cdr u) (car x)))))))
  712. (de !~bigtimes2 (u v)
  713. (cond
  714. ((or (null u) (null v)) nil)
  715. (t (!~bigplus2carry
  716. (!~bigtimesn (car u) v 0)
  717. (!~bigcons 0 (!~bigtimes2 (cdr u) v))
  718. 0))))
  719. (de logand2 (u v)
  720. (!~bignum_dispatch2 u v ilogand !~biglogand2))
  721. (de logor2 (u v)
  722. (!~bignum_dispatch2 u v ilogor !~biglogor2))
  723. (de logxor2 (u v)
  724. (!~bignum_dispatch2 u v ilogxor !~biglogxor2))
  725. (de difference (u v)
  726. (!~bignum_dispatch2 u v idifference !~bigdifference))
  727. (de divide (u v)
  728. (!~bigdivide (!~embiggen u) (!~embiggen v)))
  729. % Now a patched version that will report inputs that cause trouble
  730. (de divide (u v)
  731. (prog (r)
  732. (setq r (errorset
  733. (list '!~bigdivide
  734. (mkquote (!~embiggen u))
  735. (mkquote (!~embiggen v))) t t))
  736. (when (null (atom r)) (return (car r)))
  737. (printc "divide failed")
  738. (print u)
  739. (print v)
  740. (error 99 "division messup")))
  741. (de geq (u v)
  742. (not (greaterp v u)))
  743. (de greaterp (u v)
  744. (cond
  745. ((floatp u) (igreaterp u (float v)))
  746. ((floatp v) (igreaterp (float u) v))
  747. ((or (bignump u) (bignump v))
  748. (!~biggreaterp (!~embiggen u) (!~embiggen v)))
  749. (t (igreaterp u v))))
  750. (de leftshift (u v)
  751. (if (iminusp v)
  752. (rightshift u (iminus v))
  753. (times u (expt 2 v))))
  754. (de leq (u v)
  755. (not (greaterp u v)))
  756. (de lessp (u v)
  757. (greaterp v u)))
  758. (de quotient (u v)
  759. (cond
  760. ((floatp u) (iquotient u (float v)))
  761. ((floatp v) (iquotient (float u) v))
  762. (t (car (divide u v)))))
  763. (de remainder (u v)
  764. (cdr (divide u v)))
  765. (de rightshift (u v)
  766. (if (iminusp v)
  767. (leftshift u (iminus v))
  768. (let!* ((p (expt 2 v)))
  769. (if (minusp u)
  770. (quotient (add1 (difference u p)) p)
  771. (quotient u p)))))
  772. % Negative numbers give special fun for boolean operations because
  773. % they have to be treated rather as if they had unlimited numbers of
  774. % leading 1 bits.
  775. % Here u will be negative but v positive. The two are about to be ANDed
  776. % together. This delivers a version of u that has been truncated it is
  777. % is longer than v or extended out with additional "-1" values if it
  778. % is shorter. That can be ANDed digit by digit to yield the evenual
  779. % result.
  780. (de !~bigpos (u v)
  781. (cond
  782. ((null v) u)
  783. ((null u) (cons -1 (!~bigpos nil (cdr v))))
  784. (t (cons (car u) (!~bigpos (cdr u) (cdr v))))))
  785. % Strategy for -ve numbers:
  786. % (1) Both args +ve. AND digit by digit
  787. % (2) Both args -v1. use ~(~u | ~v) knowing that the OR will be on +ve vals
  788. % (3) Mixed. adjust length of negetive value either by padding
  789. % with extra leading -1s or by trincating it. Then
  790. % treat as case (a).
  791. % For OR work digit by digit if both args +ve otherwise use ~(~u & ~v)
  792. % knowing that this will not be re-converted to use of OR.
  793. (de !~biglogand2 (u v)
  794. (if (!~bigminusp u)
  795. (if (!~bigminusp v)
  796. (!~biglognot (!~biglogor2a (!~biglognot u) (!~biglognot v)))
  797. (!~biglogand2a v (!~bigpos u v)))
  798. (if (!~bigminusp v)
  799. (!~biglogand2a u (!~bigpos v u))
  800. (!~biglogand2a u v))))
  801. (de !~biglogand2a (u v)
  802. (cond
  803. ((null u) nil)
  804. ((null v) nil)
  805. (t (!~bigcons (ilogand (car u) (car v))
  806. (!~biglogand2a (cdr u) (cdr v))))))
  807. (de !~biglogor2 (u v)
  808. (if (or (!~bigminusp u) (!~bigminusp v))
  809. (!~biglognot (!~biglogand2 (!~biglognot a) (!~biglognot b)))
  810. (!~biglogor2 u v)))
  811. (de !~biglogor2a (u v)
  812. (cond
  813. ((null u) v)
  814. ((null v) u)
  815. (t (!~bigcons (ilogor (car u) (car v))
  816. (!~biglogor2a (cdr u) (cdr v))))))
  817. (de !~biglogxor2 (u v)
  818. (prog (s)
  819. (when (!~bigminusp u) (setq u (!~biglognot u)) (setq s t))
  820. (when (!~bigminusp v) (setq v (!~biglognot v)) (setq s (null s)))
  821. (setq u (!~biglogxor2a u v))
  822. (when s (setq u (!~biglognot u)))
  823. (return u)))
  824. (de !~biglogxor2a (u v)
  825. (cond
  826. ((null u) v)
  827. ((null v) u)
  828. (t (!~bigcons (ilogxor (car u) (car v))
  829. (!~biglogxor2 (cdr u) (cdr v))))))
  830. (de !~bigdifference (u v)
  831. (!~bigplus2carry u (!~bigminus v) 0))
  832. % Division is pretty well the messiest thing to implement
  833. % here. The first function deals with the consequences of
  834. % negative values, while the second ones actually does the work.
  835. (de !~bigdivide (u v)
  836. (prog (su sv)
  837. (when (null u) (return (cons 0 0)))
  838. (when (null v) (error "attempt to divide by zero" u))
  839. (when (!~bigminusp u) (setq su t u (!~bigminus u)))
  840. (when (!~bigminusp v) (setq sv t v (!~bigminus v)))
  841. (if (null (cdr v))
  842. (progn
  843. (setq u (!~shortdivide 0 (reverse u) (car v)))
  844. (setq v (car u))
  845. (while (eqcar v 0) (setq v (cdr v)))
  846. (setq u (cons
  847. (reverse v)
  848. (if (zerop (cdr u)) nil (list (cdr u))))))
  849. (setq u (!~bigdivide1 u v)))
  850. (return (cons
  851. (!~sizecheck (if (eq su sv) (car u) (!~bigminus (car u))))
  852. (!~sizecheck (if su (!~bigminus (cdr u)) (cdr u)))))))
  853. (de !~shortdivide (u1 u v)
  854. (cond
  855. ((null u) (cons nil u1))
  856. (t (let!* ((d (idivide (iplus (itimes !~radix u1) (car u)) v))
  857. (d1 (!~shortdivide (cdr d) (cdr u) v)))
  858. (cons (cons (car d) (car d1)) (cdr d1))))))
  859. (de !~bigdivide1 (u v) % Positive arguments and v is at least 2 digits
  860. (prog (r d)
  861. (while (not (!~biggreaterp1 v u))
  862. (setq d (!~approx_quotient u v))
  863. (setq u (!~bigdifference u (!~bigtimes2 d v)))
  864. (if (!~bigminusp u)
  865. (error 99 (list "approx was overestimate, v=" v " d=" d " u=" u)))
  866. (setq r (!~bigplus2carry r d 0)))
  867. (return (cons r u))))
  868. (setq !~big (itimes 1024 1024 1024 1024 1024 512))
  869. (de !~approx_quotient (u v) % v has at least 2 digits and u >= v
  870. (prog (x xx un vn q)
  871. (when (null (cddr u)) % then v must also be short
  872. (setq un (iplus (car u) (itimes !~radix (cadr u))))
  873. (setq vn (iplus (car v) (itimes !~radix (cadr v))))
  874. (return (list (iquotient un vn))))
  875. (while (cddr v) (setq u (cdr u) v (cdr v)))
  876. (setq x 0)
  877. (while (cddr u) (setq u (cdr u) x (add1 x)))
  878. (setq un (iplus (car u) (itimes !~radix (cadr u))))
  879. (setq vn (iplus (car v) (itimes !~radix (cadr v))))
  880. (setq xx 0)
  881. (while (ilessp un !~big) (setq un (ileftshift un 1) xx (iadd1 xx)))
  882. (while (igeq vn !~radix) (setq vn (irightshift vn 1) xx (iadd1 xx)))
  883. (setq q (iquotient un (iadd1 vn)))
  884. (when (igeq xx 30) (setq x (isub1 x) xx (idifference xx 30)))
  885. (if (zerop xx)
  886. (setq un q vn 0)
  887. (progn
  888. (setq un (irightshift q xx))
  889. (setq vn (ileftshift (idifference q (ileftshift un xx))
  890. (idifference 30 xx)))))
  891. (setq q nil)
  892. (if (igreaterp x 0) (dotimes (i x) (setq q (cons 0 q))))
  893. (setq q (cons un (cons vn q)))
  894. (setq q (cdr (reverse q)))
  895. (if (equal x -1) (setq q (cdr q)))
  896. % (printc (list "result = " q (cons '!~bignum q)))
  897. (if (or (null q) (equal q '(0))) (setq q '(1)))
  898. (return q)))
  899. % All the arithmetic comparisons can be expressed in terms of
  900. % a single basic case. Here I choose to make "greaterp" the
  901. % one that is actually coded.
  902. (de !~biggreaterp (u v)
  903. (if (!~bigminusp u)
  904. (if (!~bigminusp v) (!~biggreaterp1 (!~bigminus v) (!~bigminus u)) nil)
  905. (if (!~bigminusp v) t (!~biggreaterp1 u v))))
  906. (de !~biggreaterp1 (u v)
  907. (cond
  908. ((null u) nil)
  909. ((null v) t)
  910. ((equal (cdr u) (cdr v)) (igreaterp (car u) (car v)))
  911. (t (!~biggreaterp1 (cdr u) (cdr v)))))
  912. % Now for some one-argument arithmetic functions.
  913. % In these cases it does not seem worth having a macro
  914. % to dispatch between the various cases.
  915. (de add1 (u)
  916. (plus2 u 1))
  917. (de ceiling (u)
  918. (cond
  919. ((floatp u) (!~bigceiling u))
  920. (t u)))
  921. (de fix (u)
  922. (cond
  923. ((floatp u) (!~bigfix u))
  924. (t u)))
  925. (de float (u)
  926. (cond
  927. ((floatp u) u)
  928. ((inumberp u) (ifloat u))
  929. ((bignump u) (!~bigfloat (cdr u)))
  930. (t (error "bad arg to float" u))))
  931. (de floor (u)
  932. (cond
  933. ((floatp u) (!~bigfloor u))
  934. (t u)))
  935. (de lognot (u)
  936. (cond
  937. ((ifixp u) (!~biglognot (list '!~bignum u)))
  938. ((bignump u) (!~biglognot (cdr u)))
  939. (t (error "bad arg to lognot" u))))
  940. (de minus (u)
  941. (cond
  942. ((or (ifixp u) (floatp u)) (iminus u))
  943. ((bignump u) (!~sizecheck (!~bigminus (cdr u))))
  944. (t (error "bad arg to minus" u))))
  945. (de minusp (u)
  946. (cond
  947. ((or (floatp u) (inumberp u)) (iminusp u))
  948. ((bignump u) (and (cdr u) (iminusp (last (cdr u)))))
  949. (t nil)))
  950. (de sub1 (u)
  951. (plus2 u -1))
  952. (de !~bigceiling (u)
  953. (if (iminusp u)
  954. (minus (!~bigfloor (iminus u)))
  955. (!~bigfixer u 1)))
  956. (de !~bigfloor (u)
  957. (if (iminusp u)
  958. (minus (!~bigceiling (iminus u)))
  959. (!~bigfixer u -1)))
  960. (de !~bigfix (u)
  961. (if (iminusp u)
  962. (minus (!~bigfix (iminus u)))
  963. (!~bigfixer u 0)))
  964. (de !~bigfixer (u updown)
  965. (cond
  966. ((ilessp u !~fpradix)
  967. (cond
  968. ((zerop updown) (ifix u))
  969. ((onep updown) (iceiling u))
  970. (t (ifloor u))))
  971. (t (prog (w) % Now u is definitely large!
  972. (setq w (fix (iquotient u !~fpradix)))
  973. (setq u (idifference u (itimes !~fpradix (float w))))
  974. (return (plus (times w !~radix) (!~bigfixer u updown)))))))
  975. (de !~bigfloat (u)
  976. (cond
  977. ((null u) 0.0)
  978. (t (iplus (ifloat (car u))
  979. (itimes !~fpradix (!~bigfloat (cdr u)))))))
  980. (de !~biglognot (u)
  981. (cond
  982. ((null u) nil)
  983. ((null (cdr u)) (list (ilognot (car u))))
  984. (t (cons (ilogxor (isub1 !~radix) (car u))
  985. (!~biglognot (cdr u))))))
  986. (de !~bigminus (u)
  987. (cond
  988. ((null u) nil)
  989. ((zerop (car u)) (cons (car u) (!~bigminus (cdr u))))
  990. ((null (cdr u)) (list (iminus (car u))))
  991. (t (cons (ilogand (isub1 !~radix) (iminus (car u)))
  992. (!~biglognot (cdr u))))))
  993. (de !~bigminusp (u)
  994. (and u (iminusp (last u))))
  995. % onep and zerop are built-in, and although there is no real
  996. % merit in anybody using a function ionep or izerop I provide
  997. % both here just for completeness.
  998. (de ionep (u) (onep u))
  999. (de izerop (u) (zerop u))
  1000. % A handy macro arranges that a big-number will evaluate to itself.
  1001. (dm !~bignum (u) (list 'quote u))
  1002. % If vsl finds a big-number it calls this function to turn it
  1003. % into a string that it can then print. Again this is pretty
  1004. % inefficient! I provide a flag !*rawbig that, when set, causes
  1005. % big numbers to be displayed in terms of their internal representation
  1006. % as well as "properly" because that is sometimes useful while debugging.
  1007. % !*onlyraw is even more drastic and only shows the internal form,
  1008. % thereby avoiding division etc in this code.
  1009. (setq !*rawbig nil !*onlyraw nil)
  1010. (de !~big2str (n)
  1011. (prog (r neg)
  1012. (when (null n) (return "0"))
  1013. % In bad cases you may try to display a list whose first element is
  1014. % "~bignum" but which is then badly formatted.
  1015. (setq r n)
  1016. (while (and (not (atom r))
  1017. (inumberp (car r))) (setq r (cdr r)))
  1018. (when r (return nil))
  1019. (setq r '(!"))
  1020. (when (or !*rawbig !*onlyraw)
  1021. (setq r (cons '!] r))
  1022. (dolist (c (reverse (explode n)))
  1023. (setq r (cons c r)))
  1024. (setq r (cons '!: (cons '![ r))))
  1025. (when (not !*onlyraw)
  1026. (when (!~bigminusp n) (setq n (!~bigminus n) neg t))
  1027. (while (or (cdr n) (igreaterp (car n) 9))
  1028. % !~shortdivide is an internal function to this code with a slightly
  1029. % odd interface that involves numbers passed most significant digit
  1030. % first.
  1031. (setq n (!~shortdivide 0 (reverse n) 10))
  1032. (setq r (cons (car (explodec (cdr n))) r))
  1033. (setq n (car n))
  1034. (while (eqcar n 0) (setq n (cdr n)))
  1035. (setq n (reverse n)))
  1036. (setq r (cons (car (explodec (!~sizecheck n))) r))
  1037. (when neg (setq r (cons '!- r))))
  1038. (return (compress (cons '!" r)))))
  1039. (de list!-to!-vector (l)
  1040. (prog (n v)
  1041. (setq n (length l))
  1042. (setq v (mkvect (sub1 n)))
  1043. (setq n 0)
  1044. (while l
  1045. (putv v n (car l))
  1046. (setq n (add1 n))
  1047. (setq l (cdr l)))
  1048. (return v)))
  1049. (setq hexdigs
  1050. (list!-to!-vector
  1051. '(!0 !1 !2 !3 !4 !5 !6 !7 !8 !9 !a !b !c !d !e !f)))
  1052. (de !~big2strhex (n)
  1053. (prog (r neg)
  1054. (when (null n) (return "0"))
  1055. (setq r n)
  1056. (while (and (not (atom r))
  1057. (ifixnum (car r))) (setq r (cdr r)))
  1058. (when r (return nil))
  1059. (setq r '(!"))
  1060. (when (minusp n) (setq n (minus n) neg t))
  1061. (while (greaterp n 15)
  1062. (setq n (divide n 16))
  1063. (setq r (cons (getv hexdigs (cdr n)) r))
  1064. (setq n (car n)))
  1065. (setq r (cons (getv hexdigs n) r))
  1066. (when neg (setq r (cons '!- r)))
  1067. (return (compress (cons '!" r)))))
  1068. % I want to define these two AFTER I have defined all of the rest
  1069. % of the big-number support because they can be called by the vsl
  1070. % kernel when it tries to read numbers.
  1071. (de plus2 (u v)
  1072. (!~bignum_dispatch2 u v iplus !~bigplus2))
  1073. (de times2 (u v)
  1074. (!~bignum_dispatch2 u v itimes !~bigtimes2))
  1075. (de expt (a n)
  1076. (cond
  1077. ((zerop n) 1)
  1078. ((onep n) a)
  1079. ((minusp n) (expt (quotient 1.0 a) (minus n)))
  1080. ((zerop (remainder n 2)) (expt (times a a) (quotient n 2)))
  1081. (t (times a (expt (times a a) (quotient (sub1 n) 2))))))
  1082. % Now arithmetic is all in place.
  1083. (setq small!-modulus 3)
  1084. (de set!-small!-modulus (n)
  1085. (let!* ((r small!-modulus))
  1086. (setq small!-modulus n)
  1087. r))
  1088. (de small!-modular!-number (n)
  1089. (setq n (remainder n small!-modulus))
  1090. (when (minusp n) (setq n (plus n small!-modulus)))
  1091. n)
  1092. (de small!-modular!-plus (a b)
  1093. (small!-modular!-number (plus a b)))
  1094. (de small!-modular!-difference (a b)
  1095. (small!-modular!-number (difference a b)))
  1096. (de small!-modular!-times (a b)
  1097. (small!-modular!-number (times a b)))
  1098. (de small!-modular!-minus (a)
  1099. (small!-modular!-number (minus a)))
  1100. (de small!-modular!-quotient (a b)
  1101. (error "small-modular-quotient not implemented yet" (cons a b)))
  1102. % "fluid" and "global" are concepts that mainly belong with
  1103. % a compiler, but versions are provided here even if they
  1104. % are not terribly useful.
  1105. (de ensure_defined (v)
  1106. (when (not (boundp v))
  1107. (eval (list 'setq v nil))))
  1108. (de fluid (x)
  1109. (remflag x 'global)
  1110. (flag x 'fluid)
  1111. (dolist (v x) (ensure_defined v)))
  1112. (de global (x)
  1113. (remflag x 'fluid)
  1114. (flag x 'global)
  1115. (dolist (v x) (ensure_defined v)))
  1116. (de unfluid (x)
  1117. (remflag x 'fluid))
  1118. (de unglobal (x)
  1119. (remflag x 'global))
  1120. (de fluidp (x) (flagp x 'fluid))
  1121. (de globalp (x) (flagp x 'global))
  1122. % Now some more general-purpose small functions. Including
  1123. % cases that are alternative names for built-in ones that
  1124. % it is convenient to have for the support of some historic
  1125. % code.
  1126. (de flag (l tag)
  1127. (dolist (v l) (put v tag t)))
  1128. (de remflag (l tag)
  1129. (dolist (v l) (remprop v tag)))
  1130. (de flagp (v tag) (get v tag))
  1131. (de prin2 (x) (princ x))
  1132. (de explode2 (x) (explodec x))
  1133. (de mkquote (x) (list 'quote x))
  1134. (de apply1 (fn a1) (apply fn (list a1)))
  1135. (de apply2 (fn a1 a2) (apply fn (list a1 a2)))
  1136. (de apply3 (fn a1 a2 a3) (apply fn (list a1 a2 a3)))
  1137. (de special!-char (n)
  1138. (cond
  1139. ((equal n 0) (code!-char 32))
  1140. ((equal n 1) (code!-char 10))
  1141. ((equal n 2) (code!-char 8))
  1142. ((equal n 3) (code!-char 9))
  1143. ((equal n 4) (code!-char 11))
  1144. ((equal n 5) (code!-char 12))
  1145. ((equal n 6) (code!-char 13))
  1146. ((equal n 7) (code!-char 127))
  1147. ((equal n 8) !$eof!$)
  1148. ((equal n 9) (code!-char 7))
  1149. ((equal n 10) (code!-char 27))
  1150. (t (error "special-char" n))))
  1151. % Testing for letters and digits as done here makes
  1152. % assumptions about the character-code that is in use.
  1153. (de liter (x)
  1154. (let!* ((c (char!-code x)))
  1155. (or (and (leq 65 c) (leq c 90))
  1156. (and (leq 97 c) (leq c 122)))))
  1157. (de digit (x)
  1158. (let!* ((c (char!-code x)))
  1159. (and (leq 48 c) (leq c 57))))
  1160. (de tolower (x)
  1161. (let!* ((c (char!-code x)))
  1162. (if (and (leq 65 c) (leq c 90))
  1163. (code!-char (plus c 32))
  1164. x)))
  1165. (de char!-downcase (x) (tolower x))
  1166. (de explode2lc (x)
  1167. (mapcar (explodec x) 'tolower))
  1168. (de intern (x)
  1169. (if (stringp x)
  1170. (compress (mapcan (explodec x)
  1171. '(lambda (c) (list '!! c))))
  1172. x))
  1173. (setq !*raise nil)
  1174. (setq !*lower t)
  1175. (de putd (name type def)
  1176. (cond
  1177. ((eq type 'expr)
  1178. (eval (cons 'de (cons name (cdr def)))))
  1179. ((eq type 'macro)
  1180. (eval (cons 'dm (cons name (cdr def)))))
  1181. ((eq type 'subr)
  1182. (error "putd/subr not supported" (list name type def)))
  1183. (t (error "unknown type in putd" type))))
  1184. (setq !*redefmsg nil)
  1185. (de set!-print!-precision (n) n)
  1186. (de constantp (x)
  1187. (or (null x)
  1188. (numberp x)
  1189. (stringp x)
  1190. (eq x t)))
  1191. (dm declare (x) nil)
  1192. % The code for ordering items that is given here is
  1193. % required by Reduce, and the exact behaviour is
  1194. % intended to support what is needed there.
  1195. (de ordp (u v)
  1196. (cond
  1197. ((null u) (null v))
  1198. ((vectorp u) (cond
  1199. ((vectorp v) (ordpv u v))
  1200. (t (atom v))))
  1201. ((atom u) (cond
  1202. ((atom v) (cond
  1203. ((numberp u) (and (numberp v) (not (lessp u v))))
  1204. ((idp v) (orderp u v))
  1205. (t (numberp v))))
  1206. (t nil)))
  1207. ((atom v) t)
  1208. ((equal (car u) (car v)) (ordpl (cdr u) (cdr v)))
  1209. ((flagp (car u) 'noncom) (cond
  1210. ((flagp (car v) 'noncom) (ordp (car u) (car v)))
  1211. (t t)))
  1212. ((flagp (car v) 'noncom) nil)
  1213. (t (ordp (car u) (car v)))))
  1214. (de ordpl (u v)
  1215. (cond
  1216. ((atom u) (ordp u v))
  1217. ((equal (car u) (car v)) (ordpl (cdr u) (cdr v)))
  1218. (t (ordp (car u) (car v)))))
  1219. (de ordpv (u v)
  1220. (error "ordpv not yet implemented" (cons u v)))
  1221. (de orderp (u v)
  1222. (prog ()
  1223. (setq u (explodec u))
  1224. (setq v (explodec v))
  1225. (while (and u v (eq (car u) (car v)))
  1226. (setq u (cdr u) v (cdr v)))
  1227. (cond
  1228. ((and u v)
  1229. (return (lessp (char!-code (car u)) (char!-code (car v)))))
  1230. (v (return t))
  1231. (t (return nil)))))
  1232. (dm function (x) (cons 'quote (cdr x)))
  1233. (de sort (items fn)
  1234. (prog (tree)
  1235. (dolist (x items)
  1236. (setq tree (sort_insert x tree fn)))
  1237. (return (sort_flatten tree))))
  1238. (de sort_insert (item tree fn)
  1239. (cond
  1240. ((null tree) (list!* item nil nil))
  1241. ((apply2 fn item (car tree))
  1242. (sort_insertleft item tree fn))
  1243. (t (sort_insertright item tree fn))))
  1244. (de sort_insertleft (item tree fn)
  1245. (list!*
  1246. (car tree)
  1247. (sort_insert item (cadr tree) fn)
  1248. (cddr tree)))
  1249. (de sort_insertright (item tree fn)
  1250. (list!*
  1251. (car tree)
  1252. (cadr tree)
  1253. (sort_insert item (cddr tree) fn)))
  1254. (de sort_flatten (x)
  1255. (cond
  1256. ((null x) nil)
  1257. (t (append (sort_flatten (cadr x))
  1258. (cons (car x) (sort_flatten (cddr x)))))))
  1259. (de gcdn (a b)
  1260. (cond
  1261. ((minusp a) (gcdn (minus a) b))
  1262. ((minusp b) (gcdn a (minus b)))
  1263. ((greaterp b a) (gcdn b a))
  1264. ((zerop b) a)
  1265. (t (gcdn b (remainder a b)))))
  1266. (de lcmn (u v)
  1267. (cond
  1268. ((onep u) v)
  1269. ((onep v) u)
  1270. (t (times u (quotient v (gcdn u v))))))
  1271. (de abs (x)
  1272. (if (minusp x) (minus x) x))
  1273. (de max2 (a b)
  1274. (if (greaterp a b) a b))
  1275. (de min2 (a b)
  1276. (if (lessp a b) a b))
  1277. (de evenp (x) (zerop (remainder x 2)))
  1278. (de msd (n)
  1279. (prog (r)
  1280. (setq r 0)
  1281. (while (not (zerop n))
  1282. (setq n (quotient n 2))
  1283. (setq r (add1 r)))
  1284. (return r)))
  1285. (de lsd (n)
  1286. (if (zerop n)
  1287. 0
  1288. (prog (r)
  1289. (setq r 0)
  1290. (while (zerop (remainder n 2))
  1291. (setq n (quotient n 2))
  1292. (setq r (add1 r)))
  1293. (return r))))
  1294. (de ash (a n) (leftshift a n))
  1295. (de lsh (a n) (leftshift a n))
  1296. (de ilsh (a n) (leftshift a n))
  1297. (de lshift (a n) (leftshift a n))
  1298. (de ash1 (a n)
  1299. (if (minusp a) (minus (leftshift (minus a) n)) (leftshift a n)))
  1300. (de remd (x) nil)
  1301. % The "fasl" scheme here is used when building large programs.
  1302. % Code gets put in files in a directory called "xxx.img.modules".
  1303. (de filedate (x) 0)
  1304. (de datelessp (a b) t)
  1305. (fluid '(faslinfile!* faslinstack!* fasloutfile!* faslname!*))
  1306. (de start!-module (x)
  1307. (cond
  1308. ((null x)
  1309. (close fasloutfile!*)
  1310. (setq fasloutfile!* nil)
  1311. (princ "+++ FASLEND ")
  1312. (printc faslname!*)
  1313. t)
  1314. (t
  1315. (setq faslname!* x)
  1316. (setq fasloutfile!* (open!-module x 'output))
  1317. t)))
  1318. (de faslread ()
  1319. (let!* ((s (rds faslinfile!*)))
  1320. (prog1
  1321. (read)
  1322. (rds s))))
  1323. (de write!-module (x)
  1324. (let!* ((s (wrs fasloutfile!*)))
  1325. (prog1
  1326. (print x)
  1327. (wrs s))))
  1328. (fluid '(dfprint!*))
  1329. (de faslout (u)
  1330. (prog nil
  1331. (terpri)
  1332. (princ "FASLOUT ")
  1333. (prin u)
  1334. (printc ": IN files; or type in expressions")
  1335. (printc "When all done, execute FASLEND;")
  1336. (cond
  1337. ((not (atom u)) (setq u (car u))))
  1338. (if (equal u 'rlsupport) (setq !*echo t)
  1339. (setq !*echo nil)) % @@@
  1340. (cond ((not (start!-module u))
  1341. (progn
  1342. (cond ((neq (posn) 0) (terpri)))
  1343. (printc "+++ Failed to open FASL output file")
  1344. (return nil))))
  1345. (setq s!:faslmod_name (cons u nil))
  1346. (setq s!:dfprintsave dfprint!*)
  1347. (setq dfprint!* (quote s!:fslout0))
  1348. (setq !*defn t)))
  1349. (put (quote faslout) (quote stat) (quote rlis))
  1350. (de faslend nil
  1351. (prog ()
  1352. (cond
  1353. ((null s!:faslmod_name) (return nil)))
  1354. (princ "Completed FASL files for ")
  1355. (print (car s!:faslmod_name))
  1356. (start!-module nil)
  1357. (setq dfprint!* s!:dfprintsave)
  1358. (setq !*defn nil)
  1359. (setq s!:faslmod_name nil)
  1360. (return nil)))
  1361. (put (quote faslend) (quote stat) (quote endstat))
  1362. (flag '(faslend) 'eval)
  1363. (setq !*backtrace t)
  1364. (setq !*debug nil)
  1365. (de s!:fasl_supervisor nil
  1366. (prog (u w !*echo)
  1367. (setq !*echo !*debug)
  1368. top
  1369. (setq u (errorset (quote (read)) t !*backtrace))
  1370. (cond
  1371. ((atom u) (return nil)))
  1372. (setq u (car u))
  1373. (cond
  1374. ((equal u !$eof!$) (return nil)))
  1375. (cond ((not (atom u)) (setq u (macroexpand u))))
  1376. (cond
  1377. ((atom u) (go top))
  1378. ((eqcar u (quote faslend))
  1379. (return (apply (quote faslend) nil)))
  1380. ((eqcar u (quote rdf))
  1381. (setq w (open (setq u (eval (cadr u))) (quote input)))
  1382. (cond (w (progn (terpri)
  1383. (princ "Reading file ")
  1384. (prin u)
  1385. (terpri)
  1386. (setq w (rds w))
  1387. (s!:fasl_supervisor)
  1388. (princ "End of file ")
  1389. (prin u)
  1390. (terpri)
  1391. (close (rds w))))
  1392. (t (progn (princ "Failed to open file ")
  1393. (prin u)
  1394. (terpri)))))
  1395. (t (s!:fslout0 u)))
  1396. (go top)))
  1397. (de s!:fslout0 (u) (s!:fslout1 u nil))
  1398. (de s!:fslout1 (u loadonly)
  1399. (prog (w)
  1400. % Note that I check for eval-when BEFORE I do any macro-expansion here
  1401. % because otherwise eval-when gets expanded away. The consequence here is
  1402. % that eval-when is only honoured at the top-level.
  1403. (when (eqcar u 'eval!-when)
  1404. (if (memq 'compile (cadr u)) (eval (cons 'progn (cddr u))))
  1405. (if (memq 'load (cadr u))
  1406. (s!:fslout1 (cons 'progn (cddr u)) loadonly))
  1407. (return nil))
  1408. (when (or (eqcar u 'compiletime)
  1409. (eqcar u 'bothtimes))
  1410. (eval (cons 'progn (cdr u))))
  1411. (when (or (eqcar u 'loadtime)
  1412. (eqcar u 'bothtimes))
  1413. (s!:fslout1 (cons 'progn (cddr u)) loadonly))
  1414. (cond
  1415. ((not (atom u)) (setq u (macroexpand u))))
  1416. (cond
  1417. ((atom u) (return nil))
  1418. ((eqcar u (quote progn))
  1419. (prog (var1174)
  1420. (setq var1174 (cdr u))
  1421. lab1173 (cond
  1422. ((null var1174) (return nil)))
  1423. (prog (v)
  1424. (setq v (car var1174))
  1425. (s!:fslout1 v loadonly))
  1426. (setq var1174 (cdr var1174))
  1427. (go lab1173))
  1428. (return nil))
  1429. ((eqcar u (quote eval!-when))
  1430. (return (prog nil
  1431. (setq w (cadr u))
  1432. (setq u (cons (quote progn) (cddr u)))
  1433. (cond
  1434. ((and (memq (quote compile) w)
  1435. (not loadonly))
  1436. (eval u)))
  1437. (cond
  1438. ((memq (quote load) w) (s!:fslout1 u t)))
  1439. (return nil))))
  1440. ((or (flagp (car u) (quote eval))
  1441. (and (equal (car u) (quote setq))
  1442. (not (atom (caddr u)))
  1443. (flagp (caaddr u) (quote eval))))
  1444. (cond
  1445. ((not loadonly) (errorset u t !*backtrace)))))
  1446. (cond
  1447. ((eqcar u (quote rdf))
  1448. (prog nil
  1449. (setq w (open (setq u (eval (cadr u))) (quote input)))
  1450. (cond
  1451. (w (princ "Reading file ")
  1452. (prin u)
  1453. (terpri)
  1454. (setq w (rds w))
  1455. (s!:fasl_supervisor)
  1456. (princ "End of file ")
  1457. (prin u)
  1458. (terpri)
  1459. (close (rds w)))
  1460. (t (princ "Failed to open file ")
  1461. (prin u)
  1462. (terpri)))))
  1463. ((and (not (eqcar u (quote faslend)))
  1464. (not (eqcar u (quote carcheck))))
  1465. (write!-module u)))))))
  1466. (de verbos (x) nil)
  1467. (de linelength (n) (linelength!* n))
  1468. (de getenv (x) nil)
  1469. (de filep (x)
  1470. (let!* ((h (errorset (list 'open x ''input) nil nil)))
  1471. (if (atom h) nil
  1472. (progn (close (car h)) t))))
  1473. (de lengthc (x) (length (explodec x)))
  1474. % Various of the functions defined here are needed by Reduce
  1475. % and simplified or dummy versions are provided here so that the
  1476. % program as a whole can be built.
  1477. (de gctime () 0)
  1478. (de eqn (a b) (equal a b))
  1479. (de threevectorp (x)
  1480. (and (vectorp x) (equal (upbv x) 2)))
  1481. (de list!-to!-vector (l)
  1482. (prog (n v)
  1483. (setq n (length l))
  1484. (setq v (mkvect (sub1 n)))
  1485. (setq n 0)
  1486. (while l
  1487. (putv v n (car l))
  1488. (setq n (add1 n))
  1489. (setq l (cdr l)))
  1490. (return v)))
  1491. (de frexp (x)
  1492. (prog (n)
  1493. (if (zerop x) (return '(0 . 0.0)))
  1494. (setq n 0)
  1495. (while (geq x 1.0)
  1496. (setq x (times x 0.5))
  1497. (setq n (add1 n)))
  1498. (while (lessp x 0.5)
  1499. (setq x (times x 2.0))
  1500. (setq n (sub1 n)))
  1501. (return (cons n x))))
  1502. (de verbos (x) nil)
  1503. (de window!-heading (x) (print x))
  1504. (de make!-special (x)
  1505. (set x nil)
  1506. (flag (list x) 'fluid))
  1507. (de compile!-all () nil)
  1508. (de library!-members () nil)
  1509. (de delete!-module (x) nil)
  1510. (de list!-directory (x) nil)
  1511. (de checkpoint (a b) (preserve a))
  1512. (de list!-to!-string (a)
  1513. (prog (r)
  1514. (setq r '(!"))
  1515. (dolist (c a)
  1516. (if (ifixp c) (setq c (code!-char c)))
  1517. (if (eq c '!") (setq r (cons c r)))
  1518. (setq r (cons c r)))
  1519. (return (compress (reverse (cons '!" r))))))
  1520. (de list2string (a) (list!-to!-string a))
  1521. (de string2list (s)
  1522. (setq s (mapcar (explodec s) 'char!-code)))
  1523. (de string!-length (s) (length (explodec s)))
  1524. (de id2string (a)
  1525. (compress (cons '!" (append (explodec a) '(!")))))
  1526. (de setpchar (x) (setpchar!* x))
  1527. (de printprompt (u) nil)
  1528. (flag '(id2string printprompt) 'lose)
  1529. (de land (a b) (logand2 a b))
  1530. (de lshift (a n) (rightshift a (iminus n)))
  1531. (de allocate!-string (n)
  1532. (prog (i l)
  1533. (setq i 0)
  1534. (while (lessp i n)
  1535. (setq l (cons 0 l))
  1536. (setq i (iplus i 1)))
  1537. (return (list2string l))))
  1538. (dm string!-store (x)
  1539. `(prog (l)
  1540. (setq l (string2list ,(cadr x)))
  1541. (setq l (str!-store1 l ,(caddr x) ,(cadddr x)))
  1542. (setq ,(cadr x) (list2string l))
  1543. s))
  1544. (de str!-store1 (charlis len what)
  1545. (if (equal len 0)
  1546. (cons what (cdr charlis))
  1547. (cons (car charlis) (str!-store1 (cdr charlis) (iplus len -1) what))))
  1548. (de gensym1 (x) (gensym))
  1549. (de md60 (x) 123456789)
  1550. (de error1 () (error 99 nil))
  1551. (dm eval!-when (u)
  1552. (if (member 'eval (cadr u))
  1553. (cons 'progn (cddr u))
  1554. nil))
  1555. (de tmpnam () "./temporary-file.tmp")
  1556. % arithmetic left shift
  1557. (de ashift (n m)
  1558. (cond
  1559. ((equal n 0) 0)
  1560. ((equal m 0) n)
  1561. ((greaterp m 0) (leftshift n m))
  1562. ((greaterp n 0) (rightshift n (minus m)))
  1563. (t % arithmetic right shift of negative number
  1564. (minus (rightshift (minus n) (minus m))))))
  1565. (de prin1 (u) (prin u))
  1566. (de carcheck (fff) nil)
  1567. (de fp!-finite (x) t)
  1568. (de complexp (x) nil)
  1569. (dm nreverse (x) `(reversip ,(cadr x)))
  1570. (dm unwind!-protect (u)
  1571. (list
  1572. (list 'lambda '(!*x!*)
  1573. (cons 'progn (append (cddr u) '(!*x!*))))
  1574. (cadr u)))
  1575. (de widelengthc (u)
  1576. (cond
  1577. ((idp u) (length!-without!-followers (string2list (id2string u))))
  1578. ((stringp u) (length!-without!-followers (string2list u)))
  1579. (t (length (explode2 u)))))
  1580. %(de get!-lisp!-directory () ".")
  1581. (de smemql (u v)
  1582. (cond
  1583. ((null v) nil)
  1584. ((smemq (car u) v) (cons (car u) (smemq (cdr u) v)))
  1585. (t (smemql (cdr u) v))))
  1586. (dm commentoutcode (u) nil)
  1587. (de smember (u v)
  1588. (cond
  1589. ((eq u v) t)
  1590. ((atom v) nil)
  1591. (t (or (smember u (car v))
  1592. (smember u (cdr v))))))
  1593. (de smemqlp (u v)
  1594. (cond
  1595. ((or (null v) (numberp v)) nil)
  1596. ((atom v) (memq v u))
  1597. ((eq (car v) 'quote) nil)
  1598. (t (or (smemqlp u (car v)) (smemqlp u (cdr v))))))
  1599. (dm compiletime (x) (cons 'progn (cdr x)))
  1600. (dm loadtime (x) (cons 'progn (cdr x)))
  1601. (dm bothtimes (x) (cons 'progn (cdr x)))
  1602. (de find!-gnuplot ()
  1603. "gnuplot")
  1604. (dm load (x)
  1605. (terpri)
  1606. (prin2 "++++ LOAD ")
  1607. (prin (cdr x))
  1608. (printc " called")
  1609. nil)
  1610. (de posn () 0)
  1611. (de enable!-errorset (a b)
  1612. (setq !*backtrace b))
  1613. (de prin1 (x) (prin x))
  1614. (de iequal (x y) (equal x y))
  1615. % What follow is derived from reduce/packages/rlisp/rprintf.red
  1616. (de list2widestring (x)
  1617. (prog (r)
  1618. (setq r '(!"))
  1619. top
  1620. (cond
  1621. ((null x) (return (compress (reverse (cons '!" r))))))
  1622. (setq r (cons (car x) r))
  1623. (cond
  1624. ((eq (car x) '!") (setq r (cons '!" r))))
  1625. (setq x (cdr x))
  1626. (go top)))
  1627. (fluid '(bldmsg_chars!* !*ll!*))
  1628. (setq bldmsg_chars!* nil)
  1629. (de p_princ (u blankfirst)
  1630. (prog (w)
  1631. (setq w (explode2 u))
  1632. (cond
  1633. (bldmsg_chars!*
  1634. (progn
  1635. (cond
  1636. (blankfirst (setq bldmsg_chars!* (cons '! bldmsg_chars!*))))
  1637. (prog (c)
  1638. (setq c w)
  1639. lab (cond ((null c) (return nil)))
  1640. ((lambda (c) (setq bldmsg_chars!* (cons c bldmsg_chars!*)))
  1641. (car c))
  1642. (setq c (cdr c))
  1643. (go lab))))
  1644. (t (progn
  1645. (cond
  1646. (blankfirst
  1647. (progn
  1648. (cond
  1649. ((greaterp (plus (posn) (length w) 1) !*ll!*)
  1650. (terpri)))
  1651. (prin2 " ")))
  1652. ((greaterp (plus (posn) (length w)) !*ll!*) (terpri)))
  1653. (prin2 u)))) ))
  1654. (de p_prin (u blankfirst)
  1655. (prog (w)
  1656. (setq w (explode u))
  1657. (cond ((eqcar w '!_) (setq w (cons '!! w))))
  1658. (cond
  1659. (bldmsg_chars!*
  1660. (progn
  1661. (cond
  1662. (blankfirst (setq bldmsg_chars!* (cons '! bldmsg_chars!*))))
  1663. (prog (c)
  1664. (setq c w)
  1665. lab (cond ((null c) (return nil)))
  1666. ((lambda (c) (setq bldmsg_chars!* (cons c bldmsg_chars!*)))
  1667. (car c))
  1668. (setq c (cdr c))
  1669. (go lab))))
  1670. (t (progn
  1671. (cond
  1672. (blankfirst
  1673. (progn
  1674. (cond
  1675. ((greaterp (plus (posn) (length w) 1) !*ll!*)
  1676. (terpri)))
  1677. (prin2 " ")))
  1678. ((greaterp (plus (posn) (length w)) !*ll!*) (terpri)))
  1679. (prog (c)
  1680. (setq c w)
  1681. lab (cond ((null c) (return nil)))
  1682. ((lambda (c) (prin2 c)) (car c))
  1683. (setq c (cdr c))
  1684. (go lab)))) )))
  1685. (fluid '(!*print!-array!* !*print!-length!* !*print!-level!*))
  1686. (setq !*print!-array!* t)
  1687. (setq !*print!-length!* nil)
  1688. (setq !*print!-level!* nil)
  1689. (fluid '(!*prinl_visited_nodes!* !*prinl_index!*))
  1690. (setq !*prinl_visited_nodes!* (mkhash 10 0 1.5))
  1691. (de p_prinl0 (x escaped)
  1692. (prog (!*prinl_index!*)
  1693. (declare (special !*prinl_index!*))
  1694. (setq !*prinl_index!* 0)
  1695. (unwind!-protect
  1696. (progn (p_prinl1 x 0) (p_prinl2 x 0 escaped nil))
  1697. (clrhash !*prinl_visited_nodes!*))
  1698. (return x)))
  1699. (de p_prinl1 (x depth)
  1700. (prog (w length)
  1701. (cond
  1702. ((and (fixp !*print!-level!*) (greaterp depth !*print!-level!*))
  1703. (return nil)))
  1704. (setq length 0)
  1705. top (cond
  1706. ((and (atom x) (not (vectorp x)) (not (gensymp x))) (return nil))
  1707. ((setq w (gethash x !*prinl_visited_nodes!*))
  1708. (progn
  1709. (cond
  1710. ((equal w 0)
  1711. (progn
  1712. (setq !*prinl_index!* (plus !*prinl_index!* 1))
  1713. (puthash x !*prinl_visited_nodes!* !*prinl_index!*))))
  1714. (return nil)))
  1715. (t (progn
  1716. (puthash x !*prinl_visited_nodes!* 0)
  1717. (cond
  1718. ((vectorp x)
  1719. (progn
  1720. (cond
  1721. (!*print!-array!*
  1722. (progn
  1723. (setq length (upbv x))
  1724. (cond
  1725. ((and
  1726. (fixp !*print!-length!*)
  1727. (lessp !*print!-length!* length))
  1728. (setq length !*print!-length!*)))
  1729. (prog (i)
  1730. (setq i 0)
  1731. lab (cond
  1732. ((minusp (difference length i))
  1733. (return nil)))
  1734. (p_prinl1 (getv x i) (plus depth 1))
  1735. (setq i (plus2 i 1))
  1736. (go lab)))) )))
  1737. ((not (atom x))
  1738. (progn
  1739. (p_prinl1 (car x) (plus depth 1))
  1740. (cond
  1741. ((and
  1742. (fixp !*print!-length!*)
  1743. (greaterp
  1744. (setq length (plus length 1))
  1745. !*print!-length!*))
  1746. (return nil)))
  1747. (setq x (cdr x))
  1748. (go top)))) ))) ))
  1749. (de p_printref (w blankfirst ch)
  1750. (prog (len)
  1751. (setq len (length (explode w)))
  1752. (cond (blankfirst (setq len (plus len 1))))
  1753. (cond
  1754. ((and (not bldmsg_chars!*) (greaterp (plus (posn) 2 len) !*ll!*))
  1755. (progn (setq blankfirst nil) (terpri))))
  1756. (p_princ "#" blankfirst)
  1757. (p_princ w nil)
  1758. (p_princ ch nil)))
  1759. (de p_prinl2 (x depth escaped blankfirst)
  1760. (cond
  1761. ((and (fixp !*print!-level!*) (greaterp depth !*print!-level!*))
  1762. (p_princ "#" blankfirst))
  1763. ((and (atom x) (not (vectorp x)) (not (gensymp x)))
  1764. (progn
  1765. (cond (escaped (p_prin x blankfirst)) (t (p_princ x blankfirst)))) )
  1766. (t (prog (w length)
  1767. (setq w (gethash x !*prinl_visited_nodes!*))
  1768. (cond
  1769. ((and w (not (zerop w)))
  1770. (progn
  1771. (cond
  1772. ((lessp w 0)
  1773. (progn
  1774. (p_printref (minus w) blankfirst "#")
  1775. (return nil)))
  1776. (t (progn
  1777. (puthash x !*prinl_visited_nodes!* (minus w))
  1778. (p_printref w blankfirst "=")
  1779. (setq blankfirst nil)))) )))
  1780. (cond
  1781. ((vectorp x)
  1782. (progn
  1783. (p_princ "%(" blankfirst)
  1784. (cond
  1785. (!*print!-array!*
  1786. (progn
  1787. (setq length (upbv x))
  1788. (cond
  1789. ((and
  1790. (fixp !*print!-length!*)
  1791. (lessp !*print!-length!* length))
  1792. (setq length !*print!-length!*)))
  1793. (prog (i)
  1794. (setq i 0)
  1795. lab (cond
  1796. ((minusp (difference length i))
  1797. (return nil)))
  1798. (p_prinl2
  1799. (getv x i)
  1800. (plus depth 1)
  1801. escaped
  1802. (neq i 0))
  1803. (setq i (plus2 i 1))
  1804. (go lab))))
  1805. (t (p_princ "..." nil)))
  1806. (p_princ ")" nil)
  1807. (return nil)))
  1808. ((atom x)
  1809. (progn
  1810. (cond
  1811. (escaped (p_prin x blankfirst))
  1812. (t (p_princ x blankfirst)))
  1813. (return nil))))
  1814. (p_princ "(" blankfirst)
  1815. (p_prinl2 (car x) (plus depth 1) escaped nil)
  1816. (setq x (cdr x))
  1817. (setq length 0)
  1818. loop (cond
  1819. ((atom x)
  1820. (progn
  1821. (cond
  1822. ((neq x nil)
  1823. (progn
  1824. (p_princ "." t)
  1825. (p_prinl2 x depth escaped t))))
  1826. (return (p_princ ")" nil)))) )
  1827. (cond
  1828. ((and
  1829. (fixp !*print!-length!*)
  1830. (greaterp (setq length (plus length 1)) !*print!-length!*))
  1831. (progn (p_princ "..." t) (return (p_princ ")" nil)))) )
  1832. (setq w (gethash x !*prinl_visited_nodes!*))
  1833. (cond
  1834. ((and w (not (zerop w)))
  1835. (progn
  1836. (cond
  1837. ((lessp w 0)
  1838. (progn
  1839. (p_princ "." t)
  1840. (p_printref (minus w) t "#")
  1841. (return (p_princ ")" nil))))
  1842. (t (progn
  1843. (p_princ "." t)
  1844. (p_prinl2 x (plus depth 1) escaped t)
  1845. (return (p_princ ")" nil)))) ))) )
  1846. (p_prinl2 (car x) (plus depth 1) escaped t)
  1847. (setq x (cdr x))
  1848. (go loop)))) )
  1849. (de printl (x) (progn (prinl x) (terpri) x))
  1850. (de printcl (x) (progn (princl x) (terpri) x))
  1851. (de princl (x)
  1852. (prog (!*ll!*)
  1853. (declare (special !*ll!*))
  1854. (setq !*ll!* (difference (linelength nil) 2))
  1855. (p_prinl0 x nil)
  1856. (return x)))
  1857. (de prinl (x)
  1858. (prog (!*ll!*)
  1859. (declare (special !*ll!*))
  1860. (setq !*ll!* (difference (linelength nil) 2))
  1861. (p_prinl0 x t)
  1862. (return x)))
  1863. (de portable_print (x) (progn (portable_prin x) (terpri) x))
  1864. (de portable_printc (x) (progn (portable_princ x) (terpri) x))
  1865. (de portable_princ (x)
  1866. (prog (!*ll!*)
  1867. (declare (special !*ll!*))
  1868. (setq !*ll!* (difference (linelength nil) 2))
  1869. (p_prinl2 x 0 nil nil)
  1870. (return x)))
  1871. (de portable_prin (x)
  1872. (prog (!*ll!*)
  1873. (declare (special !*ll!*))
  1874. (setq !*ll!* (difference (linelength nil) 2))
  1875. (p_prinl2 x 0 t nil)
  1876. (return x)))
  1877. (de p_minus (u)
  1878. (cond
  1879. ((eqcar u 'minus) (cadr u))
  1880. ((eqcar u 'plus)
  1881. (cons
  1882. 'plus
  1883. (prog (v forall!-result forall!-endptr)
  1884. (setq v (cdr u))
  1885. (cond ((null v) (return nil)))
  1886. (setq forall!-result
  1887. (setq forall!-endptr
  1888. (cons ((lambda (v) (p_minus v)) (car v)) nil)))
  1889. looplabel
  1890. (setq v (cdr v))
  1891. (cond ((null v) (return forall!-result)))
  1892. (rplacd
  1893. forall!-endptr
  1894. (cons ((lambda (v) (p_minus v)) (car v)) nil))
  1895. (setq forall!-endptr (cdr forall!-endptr))
  1896. (go looplabel))))
  1897. ((eqcar u 'difference) (cons 'plus (cons (p_minus (cadr u)) (cddr u))))
  1898. (t (list 'minus u))))
  1899. (de p_diff2minus (u)
  1900. (prog (r)
  1901. (setq r (car u))
  1902. (prog nil
  1903. whilelabel
  1904. (cond ((not (setq u (cdr u))) (return nil)))
  1905. (setq r (cons (p_minus (car u)) r))
  1906. (go whilelabel))
  1907. (return (cons 'plus (reverse r)))) )
  1908. (de p_prefix (u prec)
  1909. (cond
  1910. ((atom u) (p_princ u nil))
  1911. ((eqcar u '!*sq) (p_prefix (prepsq (cadr u)) prec))
  1912. (t (prog (op p1)
  1913. (setq op (car u))
  1914. (cond
  1915. ((equal op 'expt)
  1916. (progn
  1917. (cond ((greaterp prec 3) (p_princ "(" nil)))
  1918. (p_prefix (cadr u) 4)
  1919. (p_princ "^" nil)
  1920. (p_prefix (caddr u) 3)
  1921. (cond ((greaterp prec 3) (p_princ ")" nil)))
  1922. (return nil)))
  1923. ((or (equal op 'times) (equal op 'quotient))
  1924. (progn
  1925. (cond ((greaterp prec 2) (p_princ "(" nil)))
  1926. (p_prefix (car (setq u (cdr u))) 2)
  1927. (cond
  1928. ((equal op 'times) (progn (setq p1 2) (setq op "*")))
  1929. (t (progn (setq p1 3) (setq op "/"))))
  1930. (prog nil
  1931. whilelabel
  1932. (cond
  1933. ((not (not (atom (setq u (cdr u)))) ) (return nil)))
  1934. (progn (p_princ op nil) (p_prefix (car u) p1))
  1935. (go whilelabel))
  1936. (cond ((greaterp prec 2) (p_princ ")" nil)))
  1937. (return nil))))
  1938. (cond
  1939. ((equal op 'difference)
  1940. (return (p_prefix (p_diff2minus (cdr u)) prec)))
  1941. ((equal op 'plus)
  1942. (progn
  1943. (cond ((greaterp prec 1) (p_princ "(" nil)))
  1944. (p_prefix (car (setq u (cdr u))) 1)
  1945. (prog nil
  1946. whilelabel
  1947. (cond
  1948. ((not (not (atom (setq u (cdr u)))) ) (return nil)))
  1949. (progn
  1950. (setq p1 (car u))
  1951. (cond
  1952. ((eqcar p1 'minus)
  1953. (progn
  1954. (setq p1 (cadr p1))
  1955. (p_princ " - " nil)))
  1956. (t (p_princ " + " nil)))
  1957. (p_prefix p1 1))
  1958. (go whilelabel))
  1959. (cond ((greaterp prec 1) (p_princ ")" nil)))
  1960. (return nil)))
  1961. ((equal op 'minus)
  1962. (progn
  1963. (p_princ "-" nil)
  1964. (cond ((lessp prec 2) (setq prec 2)))
  1965. (return (p_prefix (cadr u) prec)))) )
  1966. (cond
  1967. ((or (not (atom op)) (and (numberp op) (minusp op)))
  1968. (progn (p_princ "(" nil) (p_prefix op 0) (p_princ ")" nil)))
  1969. (t (p_princ op nil)))
  1970. (setq op "(")
  1971. (cond
  1972. ((atom (setq u (cdr u))) (p_princ "(" nil))
  1973. (t (prog (x)
  1974. (setq x u)
  1975. lab (cond ((null x) (return nil)))
  1976. ((lambda (x)
  1977. (progn (p_princ op nil) (setq op ",") (p_prefix x 0)))
  1978. (car x))
  1979. (setq x (cdr x))
  1980. (go lab))))
  1981. (return (p_princ ")" nil)))) ))
  1982. (de prin_with_margin (u)
  1983. (print_with_margin_sub
  1984. u
  1985. (posn)
  1986. (difference (linelength nil) 2)
  1987. (function explode)))
  1988. (de princ_with_margin (u)
  1989. (print_with_margin_sub
  1990. u
  1991. (posn)
  1992. (difference (linelength nil) 2)
  1993. (function explode2)))
  1994. (de print_with_margin (u) (progn (prin_with_margin u) (terpri) u))
  1995. (de printc_with_margin (u) (progn (princ_with_margin u) (terpri) u))
  1996. (de print_with_margin_sub (u left right explfn)
  1997. (prog (v)
  1998. (cond ((lessp right 10) (setq right 10)))
  1999. (cond
  2000. ((greaterp left (difference right 10))
  2001. (setq left (difference right 10))))
  2002. (setq v u)
  2003. (cond
  2004. ((not (atom v))
  2005. (progn
  2006. (cond ((geq (posn) right) (progn (terpri) (ttab left))))
  2007. (prin2 "(")
  2008. (print_with_margin_sub (car v) left right explfn)
  2009. (prog nil
  2010. whilelabel
  2011. (cond ((not (not (atom (setq v (cdr v)))) ) (return nil)))
  2012. (progn
  2013. (cond
  2014. ((geq (posn) right) (progn (terpri) (ttab left)))
  2015. (t (prin2 " ")))
  2016. (print_with_margin_sub (car v) left right explfn))
  2017. (go whilelabel))
  2018. (cond
  2019. ((not (null v))
  2020. (progn
  2021. (cond
  2022. ((geq (posn) (difference right 1))
  2023. (progn (terpri) (ttab left) (prin2 ". ")))
  2024. (t (prin2 " .")))
  2025. (print_with_margin_sub v left right explfn))))
  2026. (cond ((geq (posn) right) (progn (terpri) (ttab left))))
  2027. (prin2 ")")
  2028. (return u))))
  2029. (setq v (apply explfn (list u)))
  2030. verylong
  2031. (cond
  2032. ((lessp (plus (posn) (length v)) right)
  2033. (progn
  2034. (prog (c)
  2035. (setq c v)
  2036. lab (cond ((null c) (return nil)))
  2037. ((lambda (c) (prin2 c)) (car c))
  2038. (setq c (cdr c))
  2039. (go lab))
  2040. (return u)))
  2041. ((leq (length v) (difference right left))
  2042. (progn
  2043. (terpri)
  2044. (ttab left)
  2045. (prog (c)
  2046. (setq c v)
  2047. lab (cond ((null c) (return nil)))
  2048. ((lambda (c) (prin2 c)) (car c))
  2049. (setq c (cdr c))
  2050. (go lab))
  2051. (return u)))
  2052. ((lessp (length v) right)
  2053. (progn
  2054. (terpri)
  2055. (ttab (difference right (length v)))
  2056. (prog (c)
  2057. (setq c v)
  2058. lab (cond ((null c) (return nil)))
  2059. ((lambda (c) (prin2 c)) (car c))
  2060. (setq c (cdr c))
  2061. (go lab))
  2062. (return u)))
  2063. (t (progn
  2064. (cond
  2065. ((geq (posn) (difference right 5))
  2066. (progn (terpri) (ttab left))))
  2067. (prog nil
  2068. whilelabel
  2069. (cond
  2070. ((not (lessp (posn) (difference right 1))) (return nil)))
  2071. (progn (prin2 (car v)) (setq v (cdr v)))
  2072. (go whilelabel))
  2073. (prin2 "\")
  2074. (terpri)
  2075. (go verylong)))) ))
  2076. (de bldmsg_internal (fmt args)
  2077. (prog (bldmsg_chars!* u v)
  2078. (declare (special bldmsg_chars!*))
  2079. (setq bldmsg_chars!* t)
  2080. (printf_internal fmt args)
  2081. (prog nil
  2082. whilelabel
  2083. (cond ((not (not (atom bldmsg_chars!*))) (return nil)))
  2084. (progn
  2085. (setq u (cdr bldmsg_chars!*))
  2086. (rplacd bldmsg_chars!* v)
  2087. (setq v bldmsg_chars!*)
  2088. (setq bldmsg_chars!* u))
  2089. (go whilelabel))
  2090. (return (list2widestring v))))
  2091. (de p_posn nil
  2092. (cond
  2093. (bldmsg_chars!*
  2094. (prog (w n)
  2095. (setq n 0)
  2096. (setq w bldmsg_chars!*)
  2097. (prog nil
  2098. whilelabel
  2099. (cond
  2100. ((not (and (not (atom w)) (not (equal (car w) !$eol!$))))
  2101. (return nil)))
  2102. (progn (setq n (plus n 1)) (setq w (cdr w)))
  2103. (go whilelabel))
  2104. (return n)))
  2105. (t (posn))))
  2106. (global '(p_hexdigits!*))
  2107. (setq p_hexdigits!* (mkvect 15))
  2108. (putv p_hexdigits!* 0 '!0)
  2109. (putv p_hexdigits!* 1 '!1)
  2110. (putv p_hexdigits!* 2 '!2)
  2111. (putv p_hexdigits!* 3 '!3)
  2112. (putv p_hexdigits!* 4 '!4)
  2113. (putv p_hexdigits!* 5 '!5)
  2114. (putv p_hexdigits!* 6 '!6)
  2115. (putv p_hexdigits!* 7 '!7)
  2116. (putv p_hexdigits!* 8 '!8)
  2117. (putv p_hexdigits!* 9 '!9)
  2118. (putv p_hexdigits!* 10 'a)
  2119. (putv p_hexdigits!* 11 'b)
  2120. (putv p_hexdigits!* 12 'c)
  2121. (putv p_hexdigits!* 13 'd)
  2122. (putv p_hexdigits!* 14 'e)
  2123. (putv p_hexdigits!* 15 'f)
  2124. (de p_prinhex (n)
  2125. (cond
  2126. ((not (fixp n)) (p_princ "<not-a-number>" nil))
  2127. (t (prog (b w)
  2128. (cond
  2129. ((geq n 0)
  2130. (progn
  2131. (prog nil
  2132. whilelabel
  2133. (cond ((not (geq n 16)) (return nil)))
  2134. (progn
  2135. (setq b
  2136. (cons (getv p_hexdigits!* (setq w (mod n 16))) b))
  2137. (setq n (quotient (difference n w) 16)))
  2138. (go whilelabel))
  2139. (setq b (cons (getv p_hexdigits!* (mod n 16)) b))))
  2140. (t (progn
  2141. (prog nil
  2142. whilelabel
  2143. (cond ((not (lessp n (minus 1))) (return nil)))
  2144. (progn
  2145. (setq b
  2146. (cons (getv p_hexdigits!* (setq w (mod n 16))) b))
  2147. (setq n (quotient (difference n w) 16)))
  2148. (go whilelabel))
  2149. (setq b
  2150. (cons '!~ (cons (getv p_hexdigits!* (mod n 16)) b)))) ))
  2151. (cond
  2152. ((and
  2153. (null bldmsg_chars!*)
  2154. (greaterp (plus (posn) (length b)) !*ll!*))
  2155. (terpri)))
  2156. (prog (c)
  2157. (setq c b)
  2158. lab (cond ((null c) (return nil)))
  2159. ((lambda (c) (p_princ c nil)) (car c))
  2160. (setq c (cdr c))
  2161. (go lab)))) ))
  2162. (de p_prinoctal (n)
  2163. (cond
  2164. ((not (fixp n)) (p_princ "<not-a-number>" nil))
  2165. (t (prog (b w)
  2166. (cond
  2167. ((geq n 0)
  2168. (progn
  2169. (prog nil
  2170. whilelabel
  2171. (cond ((not (geq n 8)) (return nil)))
  2172. (progn
  2173. (setq b (cons (setq w (mod n 8)) b))
  2174. (setq n (quotient (difference n w) 8)))
  2175. (go whilelabel))
  2176. (setq b (cons (mod n 8) b))))
  2177. (t (progn
  2178. (prog nil
  2179. whilelabel
  2180. (cond ((not (lessp n (minus 1))) (return nil)))
  2181. (progn
  2182. (setq b (cons (setq w (mod n 8)) b))
  2183. (setq n (quotient (difference n w) 8)))
  2184. (go whilelabel))
  2185. (setq b (cons '!~ (cons (mod n 8) b)))) ))
  2186. (cond
  2187. ((and
  2188. (null bldmsg_chars!*)
  2189. (greaterp (plus (posn) (length b)) !*ll!*))
  2190. (terpri)))
  2191. (prog (c)
  2192. (setq c b)
  2193. lab (cond ((null c) (return nil)))
  2194. ((lambda (c) (p_princ c nil)) (car c))
  2195. (setq c (cdr c))
  2196. (go lab)))) ))
  2197. (de printf_internal (fmt args)
  2198. (prog (a c !*ll!*)
  2199. (declare (special !*ll!*))
  2200. (setq !*ll!* (difference (linelength nil) 2))
  2201. (setq fmt (explode2 fmt))
  2202. (prog nil
  2203. whilelabel
  2204. (cond ((not fmt) (return nil)))
  2205. (progn
  2206. (setq c (car fmt))
  2207. (setq fmt (cdr fmt))
  2208. (cond
  2209. ((neq c '!%) (p_princ c nil))
  2210. (t (progn
  2211. (setq c (car fmt))
  2212. (setq fmt (cdr fmt))
  2213. (cond
  2214. ((equal c 'f)
  2215. (progn
  2216. (cond
  2217. ((and
  2218. (not bldmsg_chars!*)
  2219. (not (zerop (posn))))
  2220. (terpri)))) )
  2221. ((or (equal c 'n) (equal c '!N)) (p_princ !$eol!$ nil))
  2222. ((equal c '!%) (p_princ c nil))
  2223. (t (progn
  2224. (cond
  2225. ((null args) (setq a nil))
  2226. (t (progn
  2227. (setq a (car args))
  2228. (setq args (cdr args)))) )
  2229. (cond
  2230. ((and (or (equal c 'b) (equal c '!B)) (fixp a))
  2231. (prog (i)
  2232. (setq i 1)
  2233. lab (cond
  2234. ((minusp (difference a i))
  2235. (return nil)))
  2236. (p_princ " " nil)
  2237. (setq i (plus2 i 1))
  2238. (go lab)))
  2239. ((or (equal c 'c) (equal c '!C))
  2240. (progn
  2241. (cond
  2242. ((fixp a)
  2243. (p_princ
  2244. (list2widestring (list a))
  2245. nil))
  2246. (t (p_princ a nil)))) )
  2247. ((or (equal c 'l) (equal c '!L))
  2248. (progn
  2249. (cond
  2250. ((not (atom a))
  2251. (progn
  2252. (portable_princ (car a))
  2253. (prog (x)
  2254. (setq x (cdr a))
  2255. lab (cond
  2256. ((null x) (return nil)))
  2257. ((lambda (x)
  2258. (progn
  2259. (p_princ " " nil)
  2260. (portable_princ x)))
  2261. (car x))
  2262. (setq x (cdr x))
  2263. (go lab)))) )))
  2264. ((or (equal c 'o) (equal c '!O))
  2265. (p_prinoctal a))
  2266. ((or (equal c 'p) (equal c '!P))
  2267. (portable_prin a))
  2268. ((or (equal c 'q) (equal c '!Q))
  2269. (prinl a))
  2270. ((or (equal c 'r) (equal c '!R))
  2271. (progn
  2272. (p_princ "'" nil)
  2273. (prinl a)
  2274. (p_princ "'" nil)))
  2275. ((and (or (equal c 't) (equal c '!T)) (fixp a))
  2276. (progn
  2277. (cond
  2278. ((greaterp (p_posn) a)
  2279. (p_princ !$eol!$ nil)))
  2280. (prog nil
  2281. whilelabel
  2282. (cond
  2283. ((not (lessp (p_posn) a))
  2284. (return nil)))
  2285. (p_princ " " nil)
  2286. (go whilelabel))))
  2287. ((or
  2288. (equal c 'w)
  2289. (equal c 'd)
  2290. (equal c 's)
  2291. (equal c '!W)
  2292. (equal c '!D)
  2293. (equal c '!S))
  2294. (portable_princ a))
  2295. ((or (equal c 'x) (equal c '!X)) (p_prinhex a))
  2296. ((equal c '!@)
  2297. (progn
  2298. (setq c (car fmt))
  2299. (setq fmt (cdr fmt))
  2300. (cond
  2301. ((or (equal c 'f) (equal c '!F))
  2302. (p_prefix (prepf a) 0))
  2303. ((or (equal c 'q) (equal c '!Q))
  2304. (p_prefix (prepsq a) 0))
  2305. ((or (equal c 'p) (equal c '!P))
  2306. (p_prefix a 0))
  2307. (t (progn
  2308. (p_princ "%@" nil)
  2309. (p_princ c nil)))) ))
  2310. ((equal c 'e) (eval a))
  2311. (t (progn
  2312. (p_princ "%" nil)
  2313. (p_princ c nil)))) ))) ))) )
  2314. (go whilelabel))))
  2315. (dm printf (u) (list 'printf_internal (cadr u) (cons 'list (cddr u))))
  2316. (dm bldmsg (u) (list 'bldmsg_internal (cadr u) (cons 'list (cddr u))))
  2317. (dm fprintf (u)
  2318. (list 'prog '(oldout)
  2319. (list 'setq 'oldout (list 'wrs (cadr u)))
  2320. (list 'printf_internal (caddr u) (cons 'list (cdddr u)))
  2321. '(wrs oldout)))
  2322. (flag '(printf bldmsg fprintf) 'variadic)
  2323. % End of vsl.lsp