psl-support-1.lsp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379
  1. % This file contains a mixture of two sorts of things:
  2. % (A) PSL functions that are not defined in the files that I will
  3. % load to make myself a compiler, but that are required. For instance
  4. % various bits of the PSL compiler use "word" arithmetic (as in
  5. % wplus2). That would compile inline into a single machine code instruction
  6. % but it does not make good sense during cross-compilation where the issue
  7. % or word-length and data tagging on the host can not be relied on.
  8. %
  9. % (B) Replacements for some things that are defined in the compiler-related
  10. % sources but where the definitions are sufficiently PSL-specific that
  11. % I need to introduce my own replacements if I am to survive using some
  12. % alternative Lisp for bootstrapping. A significant set of functions
  13. % here are those that simulate a raw block of memory that can be accessed
  14. % either by bytes or words. Such memory is used to collect an image of
  15. % generated code and that is then written out to create a fasl file. PSL
  16. % can use memory directly. I simulate it using a vector in which I place
  17. % 64-bit integers, and I have ugly code involving shift and mask operations
  18. % for when I need to accesss it as if it was arranged in bytes.
  19. % There are other places where the code exploits or relies on detailed
  20. % PSL representation of data (eg idinf).
  21. % A further understandable jolly is that the PSL sources contain a number
  22. % of instances of definitions along the line
  23. % (de stringp (u) (stringp u))
  24. % which rely on the compiler generating in-line code for the body of
  25. % the function. Some such definitions are present within files i wish to
  26. % load to pick up other things in them! So instating my own version and
  27. % then setting a 'lose flag lets me make progress.
  28. %
  29. % (C) At the end of this file I read in "mytrace.lsp" which is my own
  30. % implementation of tracing code. Both VSL and PSL have perfectly
  31. % respectable trace capabilities of their own, but having my own one
  32. % here lets me arrange that test runs produce (almost) identical output
  33. % whichever platform they are run on, and the ability to do direct
  34. % log file comparisons to track down discrepancies is very useful.
  35. %
  36. %
  37. % I hope that every function (and macro) defined here ends up flagged
  38. % as 'lose so that a subsequent apparent definition in a PSL file that I
  39. % process does not override it.
  40. % At least for bootstrapping I need to restore MY version of SPACES
  41. (de spaces (n) % Print n blanks.
  42. (cond
  43. ((zerop n) nil)
  44. (t (princ " ") (spaces (sub1 n)))))
  45. (de intp (x) (and (fixp x) (not (bignump x))))
  46. (de flag1 (x y) (flag (list x) y))
  47. (de remflag1 (x y) (remflag (list x) y))
  48. (dm control (x)
  49. (list 'logand (list 'char-code (list 'quote (cadr x))) 31))
  50. (dm cntrl (x)
  51. (list 'logand (list 'char-code (list 'quote (cadr x))) 31))
  52. (de continuableerror (errnum message errorform*)
  53. (progn (errorprintf "***** %l" message)))
  54. (de main ())
  55. % Now the things just needed for creating fasl files... I will add things in
  56. % here to start with and maybe move them to psl-support-2.lsp later...
  57. (de concat (a b) (string-concat a b))
  58. (de binarywrite (stream val)
  59. (binarywritebyte stream val)
  60. (binarywritebyte stream (setq val (rsh val 8)))
  61. (binarywritebyte stream (setq val (rsh val 8)))
  62. (binarywritebyte stream (setq val (rsh val 8)))
  63. (binarywritebyte stream (setq val (rsh val 8)))
  64. (binarywritebyte stream (setq val (rsh val 8)))
  65. (binarywritebyte stream (setq val (rsh val 8)))
  66. (binarywritebyte stream (rsh val 8)))
  67. % This writes 16 identical bytes as a way of putting a mark in a binary
  68. % output stream...
  69. (de binarymarker (stream n)
  70. %- (setq n (lor (lsh n 8) n))
  71. %- (setq n (lor (lsh n 16) n))
  72. %- (setq n (lor (lsh n 32) n))
  73. %- (binarywrite stream n)
  74. %- (binarywrite stream n)
  75. nil)
  76. (de binarywritebyte (stream val)
  77. (prog (of)
  78. (setq of (wrs stream))
  79. (prinbyte (land val 255))
  80. (wrs of)
  81. (return val)))
  82. % I will simulate byte vectors using vectors of 64-bit integers, and here
  83. % I will pack the bytes little-endian. Note that the implementation here
  84. % requires that the Lisp used for bootstrapping can work with full 64-bit
  85. % integers.
  86. % I will arrange that 16, 32 and 64-bit values can be read and written
  87. % from arbitrarily-aligned addresses. This is done by expanding the
  88. % access code to work byte by byte.
  89. (de byte (v n)
  90. (prog (o s)
  91. (setq n (plus2 v n))
  92. (setq o (rsh n 3))
  93. (setq s (times2 (land n 7) 8))
  94. (return (land 255 (rsh (getv memory o) s)))))
  95. (de putbyte (v n val)
  96. (prog (o s w)
  97. (setq n (plus2 v n))
  98. (setq o (rsh n 3))
  99. (setq s (times (land n 7) 8))
  100. (setq w (getv memory o))
  101. (setq m (difference 16#ffffffffffffffff (lsh 16#ff s)))
  102. (setq w (land w m))
  103. (setq w (lor w (lsh val s)))
  104. (putv memory o w)
  105. (return val)))
  106. % Now similar for halfwords (16 bits)
  107. (de halfword (v n)
  108. (lor (byte v n)
  109. (lsh (byte v (plus n 1)) 8)))
  110. (de puthalfword (v n val)
  111. (putbyte v n (land val 16#ff))
  112. (putbyte v (plus n 1) (land (rsh val 8) 16#ff))
  113. val)
  114. % ... and 32-bit words
  115. (de word32 (v n)
  116. (lor (halfword v n)
  117. (lsh (halfword v (plus n 2)) 16)))
  118. (de putword32 (v n val)
  119. (puthalfword v n (land val 16#ffff))
  120. (puthalfword v (plus n 2) (land (rsh val 16) 16#ffff))
  121. val)
  122. % This one tricked me for some while - a "halfword" here is a 32-bit value!
  123. (de put_a_halfword (addr val)
  124. (putword32 addr 0 val))
  125. (de word (v n)
  126. (lor (word32 v n)
  127. (lsh (word32 v (plus n 4)) 32)))
  128. (de putword (v n val)
  129. % PSL seems to be willing to pass NIL or a symbol whose name is a single
  130. % character here. I will patch that up in a gruesome manner!
  131. (if (and (idp val) (leq (id2int val) 128))
  132. (setq val (plus (id2int val) (lsh 254 56))))
  133. (putword32 v n (land val 16#ffffffff))
  134. (putword32 v (plus n 4) (land (rsh val 32) 16#ffffffff))
  135. val)
  136. (de wgetv (v n)
  137. (getv memory (plus (rsh v 3) n)))
  138. (de wputv (v n val)
  139. (putv memory (plus (rsh v 3) n) val))
  140. (de known-free-space ()
  141. (mkint (wquotient (wdifference heapupperbound heaplast)
  142. addressingunitsperitem)))
  143. (de free-bps ()
  144. (wquotient (wdifference lastbps nextbps)
  145. addressingunitsperitem)
  146. )
  147. (de gtheap (number-of-items)
  148. % Allocates heap space. As soon as all uses of (GTHEAP NIL) are
  149. % removed from code, this function can be removed, and REAL-GTHEAP
  150. % can become GTHEAP.
  151. (if (null number-of-items)
  152. (known-free-space)
  153. (real-gtheap number-of-items)
  154. )
  155. )
  156. (de real-gtheap (number-of-items)
  157. % This function handles the normal case where there is no trap handling
  158. % to be done. It is written so that no stack frame is allocated, which
  159. % vastly improves performance (at least on the 68000).
  160. (let ((result heaplast))
  161. (setf heaplast (wplus2 heaplast (wtimes2 number-of-items
  162. addressingunitsperitem)))
  163. (if (wlessp heaplast heaptrapbound)
  164. result
  165. (error "out of heap"))))
  166. (de delheap (lowpointer highpointer)
  167. (when (weq highpointer heaplast)
  168. (setq heaplast lowpointer)))
  169. %(de gtstr (upper-bound)
  170. % % Allocate a string of UPPER-BOUND+1 characters.
  171. % (let* ((n-words (strpack upper-bound))
  172. % (str (gtheap (+ 1 n-words))))
  173. % (setf (getmem str) (mkitem hbytes-tag upper-bound))
  174. % (setf (wgetv str n-words) 0) % clear last word, including last byte
  175. % str
  176. % ))
  177. (de gtstr (upper-bound)
  178. % Allocate a string of UPPER-BOUND+1 characters.
  179. (let* ((n-words (strpack upper-bound))
  180. (str (gtheap (+ 1 n-words))))
  181. % Note that wputv uses a word index not a byte one.
  182. (wputv str 0 (mkitem hbytes-tag upper-bound))
  183. (wputv str n-words 0) % clear last word, including last byte
  184. str
  185. ))
  186. % GTCONSTSTR is defined in the kernel
  187. %(de gthalfwords (upper-bound)
  188. % % Allocate space for a halfwords vector of UPPER-BOUND+1 elements.
  189. % (let* ((n-words (halfwordpack upper-bound))
  190. % (ptr (gtheap (+ n-words 1))))
  191. % (setf (getmem ptr) (mkitem hhalfwords-tag upper-bound))
  192. % ptr
  193. % ))
  194. (de gthalfwords (upper-bound)
  195. % Allocate space for a halfwords vector of UPPER-BOUND+1 elements.
  196. (let* ((n-words (halfwordpack upper-bound))
  197. (ptr (gtheap (+ n-words 1))))
  198. (wputv ptr 0 (mkitem hhalfwords-tag upper-bound))
  199. ptr
  200. ))
  201. %(de gtvect (upper-bound)
  202. % % Allocate space for a vector of UPPER-BOUND+1 elements.
  203. % (let ((ptr (gtheap (+ (vectpack upper-bound) 1))))
  204. % (setf (getmem ptr) (mkitem hvect-tag upper-bound))
  205. % ptr
  206. % ))
  207. (de gtvect (upper-bound)
  208. % Allocate space for a vector of UPPER-BOUND+1 elements.
  209. (let ((ptr (gtheap (+ (vectpack upper-bound) 1))))
  210. (wputv ptr 0 (mkitem hvect-tag upper-bound))
  211. ptr
  212. ))
  213. %(de gtevect (upper-bound)
  214. % % Allocate space for an evector of UPPER-BOUND+1 elements.
  215. % (let ((ptr (gtheap (+ (evectpack upper-bound) 1))))
  216. % (setf (getmem ptr) (mkitem hvect-tag upper-bound))
  217. % ptr
  218. % ))
  219. (de gtevect (upper-bound)
  220. % Allocate space for an evector of UPPER-BOUND+1 elements.
  221. (let ((ptr (gtheap (+ (evectpack upper-bound) 1))))
  222. (wputv ptr 0 (mkitem hvect-tag upper-bound))
  223. ptr
  224. ))
  225. %(de gtcontext ()
  226. % % allocate space for an environment descriptor (7 entries)
  227. % (let ((ptr (gtheap (+ (contextpack) 1))))
  228. % (setf (getmem ptr) (mkitem hvect-tag (contextpack)))
  229. % ptr))
  230. (de gtcontext ()
  231. % allocate space for an environment descriptor (7 entries)
  232. (let ((ptr (gtheap (+ (contextpack) 1))))
  233. (wputv ptr 0 (mkitem hvect-tag (contextpack)))
  234. ptr))
  235. %(de gtbvect (upper-bound)
  236. % % allocate space for a bvector - four words per entry
  237. % (let ((ptr (gtheap (+ (bvectpack upper-bound) 1))))
  238. % (setf (getmem ptr) (mkitem hvect-tag (bvectpack upper-bound)))
  239. % ptr))
  240. (de gtbvect (upper-bound)
  241. % allocate space for a bvector - four words per entry
  242. (let ((ptr (gtheap (+ (bvectpack upper-bound) 1))))
  243. (wputv ptr 0 (mkitem hvect-tag (bvectpack upper-bound)))
  244. ptr))
  245. % GTWRDS is defined in the kernel
  246. %(de gtfixn ()
  247. % % Allocate space for a fixnum.
  248. % (let ((ptr (gtheap (+ (fixpack) 1))))
  249. % (setf (getmem ptr) (mkitem hwords-tag (- (fixpack) 1)))
  250. % ptr
  251. % ))
  252. (de gtfixn ()
  253. % Allocate space for a fixnum.
  254. (let ((ptr (gtheap (+ (fixpack) 1))))
  255. (wputv ptr 0 (mkitem hwords-tag (- (fixpack) 1)))
  256. ptr
  257. ))
  258. (de gtfltn ()
  259. % Allocate space for a floating point number on a double-word boundary.
  260. (let ((x (gtheap 0))
  261. ptr)
  262. (if (neq (remainder x 8) 4)
  263. (gtheap 1))
  264. (setf ptr (gtheap (+ (floatpack) 1)))
  265. (setf (getmem ptr) (mkitem hwords-tag (- (floatpack) 1)))
  266. ptr
  267. ))
  268. % GTID is defined in the kernel.
  269. % GTBPS is defined in the kernel.
  270. %% Attempt to allocate more bps space at the end of the image by calling
  271. %% external-allocatemorebps. Warn user and set fluid so we can head off
  272. %% an unexec.
  273. %%
  274. (de try-other-bps-spaces (number-of-items)
  275. (let ((morebps (external-allocatemorebps)))
  276. (when (wgreaterp morebps 0)
  277. (printf "Warning, allocating additional bps space of %w items.%n"
  278. (quotient morebps 4))
  279. (printf " Cannot savesystem after allocating additional bps space.%n")
  280. (setq using-other-bps-spaces* t))))
  281. % Return space to BPS, but make sure that nextbps will not intrude down into
  282. % the heap, as might be the case after calling try-other-bps-spaces.
  283. (de delbps (bottom top)
  284. (when (and (weq nextbps top)
  285. (wgreaterp bottom bpslowerbound))
  286. (setq nextbps bottom)))
  287. (de gtwarray (n)
  288. %. Allocate N words for WVar/WArray/WString
  289. (if (null n)
  290. (wquotient (wdifference lastbps nextbps)
  291. addressingunitsperitem)
  292. (let ((b (wdifference lastbps (wtimes2 n addressingunitsperitem))))
  293. (if (wgreaterp nextbps b)
  294. (stderror '"Ran out of WArray space")
  295. (setq lastbps b))
  296. )))
  297. (de delwarray (bottom top)
  298. %. Return space for WArray
  299. (when (weq lastbps bottom)
  300. (setq lastbps top)))
  301. (de allocatefaslspaces ()
  302. (prog (b)
  303. (setq b (gtwarray nil))
  304. % how much is left?
  305. (setq b (idifference b (iquotient b 3)))
  306. (setq faslblockend* (gtwarray 0))
  307. % pointer to top of space
  308. (setq bittablebase* (gtwarray b))
  309. % take 2/3 of whatever's left
  310. (setq currentoffset* 0)
  311. (setq bittableoffset* 0)
  312. % The "loc" here seems to be much like the C use of "&" to grab an
  313. % address. Well (loc (wgetv a n)) might be rather like (plus a n) but
  314. % in the end I will need to worry about byte vs word addressing.
  315. % (setq codebase*
  316. % (loc (wgetv bittablebase* % split the space between
  317. % (iquotient b % bit table and code
  318. % (iquotient bittable-entries-per-word
  319. % addressingunitsperitem)))))
  320. % Here is a first-try re-work.
  321. (setq codebase*
  322. (plus bittablebase* % split the space between
  323. (iquotient b % bit table and code
  324. (iquotient bittable-entries-per-word
  325. addressingunitsperitem))))
  326. % Ensure that codebase* is 8-byte aligned.
  327. (setq codebase* (times 8 (quotient codebase* 8)))
  328. (setq maxfasloffset* (idifference faslblockend* codebase*))
  329. (setq orderedidlist* (cons nil nil))
  330. (setq nextidnumber* first-local-id-number)))
  331. % This mess yields a value in the range 0 to 127 for symbols that are
  332. % 1 character long if that character has ASCII code in the range 0 to 127.
  333. % I also force nil to yield 128. For other symbols I return 256 and hope that
  334. % the only call to this is from findidnumber!
  335. (setq **nil-id-value** 128)
  336. (de idinf (u)
  337. (cond ((null u) **nil-is-value**)
  338. ((cdr (explode2 u)) 256)
  339. (t (char-code u))))
  340. % been inserted early, and a simple redefinition of idinf was thus
  341. % ineffective.
  342. (de findidnumber (u)
  343. (prog (i)
  344. (return (cond ((ileq (setq i (idinf u)) 128) i)
  345. ((setq i (get u fasl-idnumber-property*)) i)
  346. (t (put u fasl-idnumber-property* (setq i nextidnumber*))
  347. (setq orderedidlist* (tconc orderedidlist* u))
  348. (setq nextidnumber* (iadd1 nextidnumber*)) i)))))
  349. % OK, I am reconstructing my understanding by inspecting the code here..
  350. % this makes relocation information as 2 bits of tag within a 16, 32 or
  351. % 64 bit item, with the relocinf in the rest. Well in a 64-bit item
  352. % the tag has space for 10 bits. I think that is probably because it is in
  353. % the top 8 bits of where a fixnum could go, leaving the high 8 bits for the
  354. % tag that PSL uses for identifying sorts of data.
  355. %
  356. %(de makerelocword (reloctag relocinf)
  357. % (iplus2 (ilsh reloctag 30) (ilsh (ilsh relocinf 2) -2)))
  358. (de makerelocword (reloctag relocinf)
  359. (plus (lsh reloctag 30) (land relocinf 16#3fffffff)))
  360. % My belief is that the "54" here is so that there can be 2 bits of tag
  361. % just below where there would be 8 bits of PSL tag in a PSL finum. Now
  362. % on a 32-bit system one might still imagine 8 bits of PSL tag and 2 bits
  363. % of relocation-type tag leaving 22 bits for the real information in a
  364. % relocation word. However on a 64-bit system with the PSL tag in bits
  365. % 56-63 and the relocation tag in bits 54 and 55 that leaves 54 rather then
  366. % 22 bits for useful purposes. So my suspicion is that somebody was not
  367. % thinking things fully through when they adapted this bit of code...
  368. %(de makerelocinf (reloctag relocinf)
  369. % (iplus2 (ilsh reloctag 54) (field relocinf 42 22)))
  370. (de makerelocinf (reloctag relocinf)
  371. (plus2 (lsh reloctag 54) (land relocinf 16#003fffffffffffff)))
  372. % For a word the stored inf just loses the top 2 bits of the inf to
  373. % leave 30 bits.
  374. % For the "inf" case it keeps the low 22 (or matbe 54!) bits of 64
  375. % For the halfword case I suspect it is keeping the bottom 14 bits of 32. On
  376. % a 64-bit system this feels like the low 14 bits up the upper 32 bits of the
  377. % word ???????? So I will comment this out and expect that on a 64-it
  378. % target it is never used - if it is I will need to think harder.
  379. % (de makerelochalfword (reloctag relocinf)
  380. % (iplus2 (ilsh reloctag 14) (field relocinf 18 14)))
  381. % I think that the use if "field" here is not at all a help as regards
  382. % clarity! Simpler use of shift and mask operations will leave things
  383. % easier to understand!
  384. % (de getbittable (baseaddress bitoffset)
  385. % (field (ilsh (byte baseaddress (ilsh bitoffset -2))
  386. % (idifference (itimes2 (field bitoffset 62 2) 2) 6))
  387. % 62 2))
  388. %
  389. % (de putbittable (baseaddress bitoffset value2)
  390. % (prog (m b c)
  391. % (setq b
  392. % (iland (byte baseaddress (setq m (ilsh bitoffset -2)))
  393. % (ilsh (idifference -1 (itimes2 3 256))
  394. % (idifference -2
  395. % (setq c (itimes2 (field bitoffset 62 2) 2))))))
  396. % (putbyte baseaddress m (if (eq value2 0)
  397. % b
  398. % (ilor b (ilsh value2 (idifference 6 c)))))))
  399. % getbittable(base, offset) =
  400. % w = byte(base, offset/4); % 4 bitpairs per byte
  401. % n = offset & 3;
  402. % return (w >> (2*n)) & 3
  403. % I will find bits of this code look way neater if I have a right
  404. % shift operator as well as a left shift one.
  405. (de rsh (w n) (lsh w (iminus n)))
  406. (de irsh (w n) (ilsh w (iminus n)))
  407. % I am writing these out as sequences of operations and avoiding
  408. % use of the PSL "field" selector because I believe that what I have here
  409. % is much easier for me to read and understand.
  410. (de getbittable (baseaddress bitoffset)
  411. (prog (o b s)
  412. (setq o (irsh bitoffset 2)) % 4 nybbles in each byte
  413. (setq b (byte baseaddress o)) % the byte with data in
  414. (setq s (itimes 2 (iland bitoffset 3))) % bit position
  415. (setq s (idifference 6 s)) % make big-endian
  416. (return (iland (irsh b s) 3))))
  417. (de putbittable (baseaddress bitoffset value2)
  418. (prog (o b m s)
  419. (setq o (irsh bitoffset 2)) % address of relevant byte
  420. (setq b (byte baseaddress o)) % byte to work within
  421. (setq s (itimes 2 (iland bitoffset 3))) % position within byte
  422. (setq s (idifference 6 s)) % make big-endian
  423. (setq m (idifference 16#ff (ilsh 3 s))) % mask
  424. (setq b (iland b m)) % Clear existing
  425. (setq b (ilor b (ilsh value2 s)))
  426. (putbyte baseaddress o b)))
  427. % Maybe somebody needed to work out what name they were using...
  428. (de bittable (a b) (getbittable a b))
  429. (de mapobl (ff)
  430. (mapc (oblist) ff))
  431. (de binarywriteblock (stream vec len)
  432. (prog (o b i lenb)
  433. (binarymarker stream 16#bb)
  434. (setq o (wrs stream))
  435. (setq i 0)
  436. (setq lenb (times len 8)) % length is given in WORDS
  437. top(cond
  438. ((not (lessp i lenb)) (go done)))
  439. (prinbyte (byte vec i))
  440. (setq i (add1 i))
  441. (go top)
  442. done
  443. (wrs o)
  444. (binarymarker stream 16#ee)
  445. (return len)))
  446. (de mkstring (bound fill)
  447. (prog (s)
  448. (setq s (gtstr bound))
  449. (dotimes (i (add1 bound))
  450. (putbyte s i fill))
  451. (return (mkstr s))))
  452. % I think that PSL made a mistake when it defined FIELD to count bits
  453. % from the most significant, because that puts implicit information about
  454. % whether we are thinking of a 32 or 64 bit system within it.
  455. (de field (x start length)
  456. (prog ()
  457. (setq x (rsh x (difference 64 (plus start length))))
  458. (return (land x (sub1 (lsh 1 length))))))
  459. (de stderror (msg)
  460. (error 99 msg))
  461. (de exitlisp () (stop 0))
  462. % copyd is invoked (bothtimes ..) within the for-macro.sl source file,
  463. % but easy-non-sl.sl uses some macros defined in for-macro. To break the
  464. % circularity I define copyd here.
  465. (de copyd (new old)
  466. (prog (olddef)
  467. (setq olddef (getd old))
  468. (if (pairp olddef)
  469. (putd new (car olddef) (cdr olddef))
  470. (stderror (bldmsg "%r has no definition in CopyD" old)))
  471. (return new)))
  472. (dm defun (u) (cons 'de (cdr u)))
  473. (de codep (u) nil)
  474. (de ncons (u) (cons u nil))
  475. (de posintp (n) (and (fixp n) (geq n 0)))
  476. (dm errorprintf (u)
  477. (list 'errorprintf1 (cadr u) (cons 'list (cddr u))))
  478. (de errorprintf1 (fmt args)
  479. (terpri)
  480. (printf_internal fmt args)
  481. nil)
  482. (de remob (u)
  483. (terpri)
  484. (princ "+++ REMOB not performed on ")
  485. (print u)
  486. u)
  487. % This definition of totalcopy may be insufficient? The issue of copying
  488. % strings and vectors presumably arises.
  489. (de totalcopy (x)
  490. (copy x))
  491. % This definition is from nonkernel/loop-macros.sl, but that file contains
  492. % a definition of FOR that clashes with the version that I seem to need (which
  493. % is in util/for-macro.sl).
  494. (dm foreach (u)
  495. %. Macro for MAP functions
  496. %
  497. % From RLISP
  498. %
  499. % Possible forms are:
  500. % (foreach x in u do (foo x)) --> (mapc u (function (lambda (x) (foo x))))
  501. % (foreach x in u collect (foo x)) --> (mapcar u ...)
  502. % (foreach x in u conc (foo x)) --> (mapcan u ...)
  503. % (foreach x in u join (foo x)) --> (mapcan u ...)
  504. % (foreach x on u do (foo x)) --> (map u ...)
  505. % (foreach x on u collect (foo u)) --> (maplist u ...)
  506. % (foreach x on u conc (foo x)) --> (mapcon u ...)
  507. % (foreach x on u join (foo x)) --> (mapcon u ...)
  508. %
  509. (prog (action body fn lst mod var)
  510. (setq var (cadr u))
  511. (setq u (cddr u))
  512. (setq mod (car u))
  513. (setq u (cdr u))
  514. (setq lst (car u))
  515. (setq u (cdr u))
  516. (setq action (car u))
  517. (setq body (cdr u))
  518. (setq fn
  519. (cond ((eq action 'do) (if (eq mod 'in)
  520. 'mapc
  521. 'map))
  522. ((or (eq action 'conc) (eq action 'join)) (if (eq mod
  523. 'in)
  524. 'mapcan
  525. 'mapcon))
  526. ((eq action 'collect) (if (eq mod 'in)
  527. 'mapcar
  528. 'maplist))
  529. (t (stderror
  530. (bldmsg "%r is an illegal action in ForEach"
  531. action)))))
  532. (return (list fn lst
  533. (list 'function
  534. (cons 'lambda (cons (list var) body)))))))
  535. (dm repeat (u)
  536. %
  537. % From RLISP
  538. % Form is (repeat exp1 ... expN bool)
  539. % Repeat until bool is true, similar to Pascal, etc.
  540. %
  541. (cons 'prog
  542. (cons 'nil
  543. (cons '$loop$
  544. (foreach x on (cdr u) collect (if (null (cdr x))
  545. (list 'cond (list (list 'not (car x)) '(go $loop$)))
  546. (car x)))))))
  547. (de first (u) (car u))
  548. (de second (u) (cadr u))
  549. (de third (u) (caddr u))
  550. (de fourth (u) (cadddr u))
  551. (de nth (u n)
  552. (cond
  553. ((equal n 1) (car u))
  554. (t (nth (cdr u) (sub1 n)))))
  555. % I will also want IFOR, but the other things defined in util/inum.sl would
  556. % potentially clobber VSL versions of iplus etc.. so I lift the definition
  557. % out to here.
  558. (dm ifor (u)
  559. % U is of the form: (IFOR (FROM var start end step) (DO body))
  560. (let ((step (nth (second u) 5)))
  561. (if (fixp step)
  562. (constant-increment-ifor u)
  563. (variable-increment-ifor u)
  564. )))
  565. (de variable-increment-ifor (u)
  566. (let* ((var (second (second u)))
  567. (start (third (second u)))
  568. (finish (fourth (second u)))
  569. (step (nth (second u) 5))
  570. (action (first (third u)))
  571. (body (cons 'progn (cdr (third u))))
  572. (result (list (list 'setq var start)))
  573. (x (list 'IDIFFERENCE finish var))
  574. (label1 (gensym))
  575. (label2 (gensym)))
  576. (unless (onep step)
  577. (setf x (list 'ITIMES2 step x))
  578. )
  579. (unless (eq action 'DO)
  580. (stderror "Only do expected in SysLisp FOR")
  581. )
  582. `(PROG (,var)
  583. (SETQ ,var ,start)
  584. ,label1
  585. (COND ((ILESSP ,x 0) (GO ,label2)))
  586. ,body
  587. (SETQ ,var (IPLUS2 ,var ,step))
  588. (GO ,label1)
  589. ,label2
  590. )))
  591. (de constant-increment-ifor (u)
  592. (let* ((var (second (second u)))
  593. (start (third (second u)))
  594. (finish (fourth (second u)))
  595. (step (nth (second u) 5))
  596. (action (first (third u)))
  597. (body (cons 'progn (cdr (third u))))
  598. (result (list (list 'setq var start)))
  599. (comparison(if (minusp step) 'ILESSP 'IGREATERP))
  600. (label1 (gensym)))
  601. (unless (eq action 'DO)
  602. (stderror "Only do expected in SysLisp FOR")
  603. )
  604. `(PROG (,var)
  605. (SETQ ,var ,start)
  606. ,label1
  607. (COND ((,comparison ,var ,finish) (RETURN 0)))
  608. ,body
  609. (SETQ ,var (IPLUS2 ,var ,step))
  610. (GO ,label1)
  611. )))
  612. (de onoff* (u val)
  613. (foreach x in u do
  614. (cond ((idp x) (set (intern (list2string (cons '!* (explode2 x)))) val)))))
  615. (dm on (u)
  616. (list 'onoff* (mkquote (cdr u)) t))
  617. (dm off (u)
  618. (list 'onoff* (mkquote (cdr u)) nil))
  619. (flag '(on off) 'ignore)
  620. (de int2id-internal (u)
  621. (cond ((equal u **nil-id-value**) nil)
  622. ((and (greaterp u -1) (lessp u 256)) (code-char u))
  623. (t 'unknown)))
  624. (dm load (x)
  625. (list 'evload (mkquote (cdr x))))
  626. (de evload (x)
  627. (foreach u in x do (load1 u)))
  628. (setq modules-loaded* nil)
  629. (de load1 (u)
  630. (cond ((memq u modules-loaded*) nil)
  631. ((memq u '(fasl-decls hash-decls))
  632. (dskin (string-concat "$pxk/" (string-concat (id2string u) ".sl"))))
  633. ((memq u '(fast-vector))
  634. (dskin (string-concat "$pu/" (string-concat (id2string u) ".sl"))))
  635. )
  636. (setq modules-loaded* (cons u modules-loaded*)))
  637. (de unboundp (u) (not (boundp u)))
  638. (de fboundp (u) (not (null (getd u))))
  639. (de funboundp (u) (null (getd u)))
  640. (de dskin (u) (rdf u))
  641. (flag '(dskin) 'ignore)
  642. (de pp (x) (prettyprint x))
  643. (de string-concat (a b)
  644. (setq a (explode a))
  645. (setq b (explode b))
  646. (compress (append
  647. (reverse (cdr (reverse a)))
  648. (cdr b))))
  649. %%%% This doesn't work, as gtbps must return the address of the vector
  650. %(de gtbps (n) (mkvect n))
  651. (de gtbps (n) 47114711)
  652. (de string-equal (x y) (equal x y))
  653. (de channelprin2 (ch x)
  654. (let!* ((s (wrs ch)))
  655. (prog1
  656. (prin2 x)
  657. (wrs s))))
  658. (de channelterpri (ch)
  659. (let!* ((s (wrs ch)))
  660. (prog1
  661. (terpri)
  662. (wrs s))))
  663. (setq stringgensymcounter* 0)
  664. (de stringgensym ()
  665. (let ((x (explode2 (setq stringgensymcounter* (plus2 stringgensymcounter* 1)))))
  666. (while (lessp (length x) 4)
  667. (setq x (cons '!0 x)))
  668. (compress (cons '!" (append (cons 'l x) '(!"))))))
  669. (dm errset (u)
  670. (list 'errorset (list 'quote (cadr u))
  671. (if (null (cddr u)) t (caddr u))
  672. nil))
  673. (de id2int (x) (print (list "ID2INT called on" x)) 4711)
  674. (de id2int (x)
  675. (cond ((null x) **nil-id-value**)
  676. ((equal (length (explode2 x)) 1) (char-code (car (explode2 x))))
  677. (t 4711)))
  678. % converts a binary integer in a machine word into a lisp integer
  679. (de int2sys (x) x)
  680. (de sys2fixn (x) x)
  681. (de binaryopenwrite (name) (open name 'output))
  682. (de binaryclose (ff) (close ff))
  683. % Functions that operate on machine words
  684. % use integer functions for now
  685. (de wshift (x y) (lshift x y))
  686. (de wplus2 (x y) (plus2 x y))
  687. (de wtimes2 (x y) (times2 x y))
  688. (de wquotient (x y) (quotient x y))
  689. (de wdifference (x y) (difference x y))
  690. (de wgreaterp (x y) (greaterp x y))
  691. (de wlessp (x y) (lessp x y))
  692. (de wgeq (x y) (geq x y))
  693. (de wleq (x y) (leq x y))
  694. (de weq (a b) (equal a b))
  695. (de wand (x y) (logand x y))
  696. (de wor (x y) (logor x y))
  697. (dm land (u) (cons 'logand (cdr u)))
  698. (dm lor (u) (cons 'logor (cdr u)))
  699. (dm iland (u) (cons 'logand (cdr u)))
  700. (dm ilor (u) (cons 'logor (cdr u)))
  701. (dm string (u) (list 'list2string (cons 'list (cdr u))))
  702. (de evectorp (x) nil)
  703. (de bigp (u) (bignump u))
  704. (de isizev (u) (size u))
  705. (de igetv (a b) (indx a b))
  706. (de channelposn (f)
  707. (prog (r)
  708. (setq f (wrs f))
  709. (setq r (posn))
  710. (wrs f)
  711. (return r)))
  712. (de channelwritechar (f ch)
  713. (setq f (wrs f))
  714. (prin2 (if (numberp ch) (code-char ch) ch))
  715. (wrs f)
  716. ch)
  717. % This mess yields a value in the range 0 to 127 for symbols that are
  718. % 1 character long if that character has ASCII code in the range 0 to 127.
  719. % I also force nil to yield 128. For other symbols I return 256 and hope that
  720. % the only call to this is from findidnumber!
  721. (de idinf (u)
  722. (cond ((null u) 128)
  723. ((cdr (explode2 u)) 256)
  724. (t (char-code u))))
  725. % Here we have sometihng of a joke! in PSL the compiler generates calls
  726. % to functions that are part of the PSL kernel in an abbreviated way
  727. % because it know that they are present in compiled not interpreted form.
  728. % I have not yet understood what the consequences would be if a user then
  729. % redefined one of these with an interpreted version! Anyway to have any
  730. % prospect of binary compatibility between cross-build code and native
  731. % build code I have to know what PSL had happened to implement this way!
  732. (flag '(
  733. !%clear!-catch!-stack !%displaced!-macro !%get !%reclaim !%throw
  734. !%uncatch !*!*float!*!* !*catch !*define!-constant !*doubletofloat
  735. !*fassign !*fdifference !*fgreaterp !*flessp !*floattodouble
  736. !*fp!-check!-for!-exceptions !*fplus2 !*fquotient !*freset !*fsqrt
  737. !*ftimes2 !*load!-for!-compiler !*throw !*wfix !*wfloat !_slowcons
  738. !_slowgtfltn abs aconc add1 add1!-hardcase addload addressapply0
  739. adjoin adjoinq adjustcase alghandler allocate!-string allocate!-words
  740. allocatemorebps and ans anyuser!-homedir!-string append apply ass
  741. assoc assoc!* atom atsoc backtrace beforegcsystemhook bigp binaryclose
  742. binaryopenappend binaryopenread binaryopenupdate binaryopenwrite
  743. binarypositionfile binaryread binaryreadblock binarywrite binarywriteblock
  744. bindeval bldmsg bothtimes break breakcontinue breakedit breakerrmsg
  745. breakeval breakquit breakretry bstackoverflow bstackunderflow bstructp
  746. build!-trap!-message bvectorp caaaar caaadr caaar caadar caaddr caadr
  747. caar cadaar cadadr cadar caddar cadddr caddr cadr captureenvironment car
  748. case catch catch!-all catchsetup catchsetupaux cd cdaaar cdaadr cdaar
  749. cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr cdddr cddr
  750. cdr cfserror channeleject channelerror channelfindposition channelflush
  751. channellinelength channellposn channelnotopen channelposn channelprin1
  752. channelprin2 channelprin2t channelprinc channelprint channelprintbstruct
  753. channelprintbvector channelprintcontext channelprintevector channelprintf
  754. channelprintfunarg channelprintid channelprintpair channelprintsgd
  755. channelprintstring channelprintunbound channelprintvector channelread
  756. channelreadch channelreadchar channelreadeof channelreadline
  757. channelreadlistordottedpair channelreadquotedexpression
  758. channelreadrightparen channelreadtoken channelreadtokenwithhooks
  759. channelreadvector channelspaces channelspaces2 channeltab channelterpri
  760. channeltyi channeltyo channelunreadchar channelwritebitstraux
  761. channelwritebitstring channelwriteblankoreol channelwritebstruct
  762. channelwritebvector channelwritebytes channelwritechar
  763. channelwritecodepointer channelwritecontext channelwriteevector
  764. channelwritefixnum channelwritefloat channelwritefunarg
  765. channelwritehalfwords channelwriteid channelwriteinteger
  766. channelwritepair channelwritesgd channelwritestring channelwritesysfloat
  767. channelwritesysinteger channelwriteunbound channelwriteunknownitem
  768. channelwritevector channelwritewords charsininputbuffer checklinefit
  769. clear!-warray clear!-wstring clearbindings clearcompresschannel clearerr
  770. cleario clearonechannel close code!-number!-of!-arguments code!-putd
  771. codeaddressp codeapply codeevalapply codep coerce1 coerce2 commentoutcode
  772. compiledcallinginterpretedaux compiler!-constant compiletime compress
  773. compresserror compressreadchar compute!-prompt!-string compute!-relocation
  774. concat cond cons console!-newline console!-print!-number
  775. console!-print!-string const constantp conterror contextp
  776. continuableerror contopenerror copy copybytes copyevector copyevectortofrom
  777. copyfltn copyfromallbases copyfrombase copyfromrange copyfromstack
  778. copyfromstaticheap copyhalfwords copyhalfwordstofrom copyitem
  779. copyitem1 copypairitem copystring copystringtofrom copyvector
  780. copyvectortofrom copywarray copywrds copywrdstofrom ctime
  781. current!-stack!-pointer date date!-and!-time date!-int!-to!-string
  782. datebuffer!-to!-string de defconst define!-constant deflist del
  783. delasc delascip delatq delatqip delbps delete delete!-file deletip
  784. delheap delq delqip delwarray depositextrareglocation
  785. depositfunctioncelllocation depositvaluecelllocation df difference
  786. difference!-hardcase digit digittonumber divide dm dn do!-relocation
  787. do!-relocation!-new ds dskin dskin!-file dskin!-step dskin!-stream
  788. dumplisp echooff echoon egetv eject eputv eq eqcar eqn eqstr equal error
  789. errorprintf errorset errortrap errprin errset eupbv eval evalinitforms
  790. evand evcond evdefconst evectorequal evectorp evlis evload evor
  791. evprogn evreload exit exit!-with!-status exitlisp expand expand_file_name
  792. expandsetf explode explode2 explode2n explodecn exploden explodewritechar
  793. exprp expt!-rec external!-allocatemorebps external_alarm
  794. external_anyuser_homedir_string external_charsininputbuffer
  795. external_exit external_fullpath external_getenv external_link
  796. external_mkdir external_pwd external_rmdir external_setenv external_stat
  797. external_strlen external_system external_timc external_time
  798. external_ualarm external_unlink external_user_homedir_string faslin
  799. faslin!-bad!-file faslin!-intern fastapply fastlambdaapply fatalerror
  800. fclose fcntl fcodep fdummy fexprp fflush fgetc fgets filep filestatus
  801. findcatchmarkandthrow findfreechannel findposition first firstkernel
  802. fix fix!-hardcase fixp flag flagp flambdalinkp flatsize flatsize2
  803. flatsizewritechar float floatdifference floatgreaterp floatlessp floatp
  804. floatplus2 floatquotient floattimes2 floatzerop flock fluid fluid1
  805. fluidp flushbuffer flushstdoutputbuffer fopen force!-heap!-enlargement
  806. foreach fork fourth fpehandler fputc fread free!-bps fseek funargp
  807. funboundp function fwrite gc!-trap gc!-trap!-level gcstats gensym
  808. geq get get!-exec!-path get!-fullpath get!-heap!-trap get!-heap!-try!-reclaim
  809. get!-image!-path get!-registry!-value get_execfilepath get_file_status
  810. get_imagefilepath get_registry_value getd getenv getfcodepointer getfntype
  811. gethostid getpid getprintprecision getsocket getstartupname getunixargs
  812. getv gget global global1 globalinstall globallookup globalp globalremove
  813. go greaterp greaterp!-hardcase gtbps gtbps!-nil!-error gtbvect gtconststr
  814. gtcontext gtevect gtfixn gtfltn gthalfwords gtheap gtid gtstr gtvect
  815. gtwarray gtwrds hash!-function hash!-into!-table helpbreak hist
  816. history!-append history!-fetch history!-reset history!-set!-input
  817. history!-set!-output history!-state histprint id!-intern id2int
  818. id2string idapply idp ieee_flags ieee_handler illegalstandardchannelclose
  819. illhandler implode importforeignstring imports independentclosechannel
  820. independentreadchar independentwritechar indexerror indx init!-file!-string
  821. init!-fluids init!-gcarray init!-pointers initcode initialize!-new!-id
  822. initialize!-symbol!-table initialize!-warray initialize!-wstring
  823. initializeinterrupts initializeinterrupts!-1 inp input!-case
  824. instantiateinform int2code int2id intern internal_aftergcsystemhook
  825. internal_beforegcsystemhook interngensym internp interpbacktrace interrogate
  826. intersectionq intfloat inthandler ioerror iovhandler kernel!-fatal!-error
  827. killhandler known!-free!-space land land!-hardcase lapin lastcar lastkernel
  828. lastpair lbind1 lconc length leq lessp lessp!-hardcase linelength
  829. linux_close linux_open lisp2char list list2 list2set list2setq list2string
  830. list2vector list3 list4 list5 liter lnot lnot!-hardcase load
  831. load!-for!-compiler load1 loader!-main loadtime local!-to!-global!-id
  832. lor lor!-hardcase lposn lshift!-hardcase lxor lxor!-hardcase macrop
  833. make!-bytes make!-halfwords make!-manual!-evector make!-vector make!-words
  834. makeds makefcode makeflambdalink makefunbound makeidfreelist
  835. makeinputavailable makeunbound map map2 mapc mapc2 mapcan mapcar
  836. mapcon maplist mapobl markandcopyfromid max max2 mem member memq
  837. min min2 minus minus!-hardcase minusp minusp!-hardcase mkevector
  838. mkflagvar mkquote mkstring mkvect modeless!-dskin!-file modify
  839. modulep moreheap nconc ncons ne neq newid nexprp next noncharactererror
  840. noniderror noninteger2error nonintegererror noniochannelerror
  841. nonlisterror nonnumber1error nonnumber2error nonnumbererror nonpairerror
  842. nonpositiveintegererror nonsequenceerror nonstringerror nonvectorerror
  843. nonwordserror not nth null numberp oblist off old!-flag1 old!-put
  844. old!-remflag1 old!-remprop oldchannelprin1 oldchannelprin2 oldfloatfix
  845. on onep!-hardcase onoff!* open or os_cleanup_hook os_startup_hook
  846. output!-case package pair pairp pbind1 pclose plantcodepointer
  847. plantlambdalink plantunbound plus plus2 plus2!-hardcase pnth popen
  848. posn pp pre!-main prettyprint prin1 prin2 prin2l prin2t print printf
  849. printf1 printf2 printwithfreshline prog prog2 progn prop psl_main
  850. pslsignalhandler putc putentry putv putw pwd quit quote quotient
  851. quotient!-hardcase rangeerror rassoc ratom rdf rds read read!-id!-table
  852. readch readchar reader!-intern readinbuf readline readonlychannel
  853. real!-gtheap recip reclaim reclaim2 redo reload relocate!-inf relocate!-word
  854. remainder remainder!-hardcase remd remflag remob rempropl reset
  855. rest restoreenvironment return returnaddressp returnnil reverse reversip
  856. robustexpand rplaca rplacd rplacw safecar safecdr sassoc savesystem
  857. search!-string!-for!-character second seghandler semctl semget semop
  858. set set!-bndstk!-size set!-gc!-trap!-level set!-heap!-size set!-history!-state
  859. set_bndstk_size set_heap_size setenv setindx setlinebuf
  860. setmacroreference setprintprecision setprop setq setsub setsubseq
  861. sgdp shmat shmctl shmdt shmget signal sigrelse sigunwind size sleep
  862. spaces spaces2 standardlisp staticintfloat stderror step string string!=
  863. string!-intern string2list string2vector stringequal stringgensym stringp
  864. sub sub1 sub1!-hardcase subla sublis subseq substip suck!-in!-files
  865. sun3_sigset sys2fixn sys2int syscleario sysclose sysmaxbuffer sysopenread
  866. sysopenwrite syspowerof2p sysreadrec system systemmarkasclosedchannel
  867. systemopenfileforinput systemopenfileforoutput systemopenfilespecial
  868. syswriterec tab tconc terminalinputhandler terpri testlegalchannel
  869. third throw throwaux timc time times times2 times2!-hardcase
  870. top!-loop!-eval!-and!-print top!-loop!-read toploop tostringwritechar
  871. totalcopy tr trst try!-other!-bps!-spaces tyi tyo typeerror unbindn
  872. unboundp unchecked!-prop unchecked!-put unchecked!-setprop
  873. unchecked!-string!-equal unchecked!-string!-intern undefinedfunction!-aux
  874. unexec unfluid unfluid1 unionq unix!-profile unix!-time unixcd unixcleario
  875. unixclosesocket unixopen unixputc unixputn unixputs unixsocketopen
  876. unixstring unixstrlen unprotected!-dskin!-stream unreadchar unwind!-all
  877. unwind!-protect upbv usagetypeerror user!-homedir!-string uxacos
  878. uxasin uxassign uxatan uxatan2 uxcos uxdifference uxdoubletofloat uxexp
  879. uxfix uxfloat uxfloattodouble uxgreaterp uxlessp uxlog uxplus2
  880. uxquotient uxsin uxsqrt uxtan uxtimes2 uxwritefloat uxwritefloat8
  881. valuecell vaxreadchar vaxwritechar vector vector2list vector2string
  882. vectorp verbosebacktrace wait writechar writefloat writenumber1
  883. writeonlychannel writesocket writestring writesysinteger wrongcasecharp
  884. wrs xcons xgetw xidapply0 xidapply1 xidapply2 xidapply3 xidapply4
  885. xn xnq yesp zerop zerop!-hardcase)
  886. 'fastcallable)
  887. (de fastcallablep (u)
  888. (flagp u 'fastcallable))
  889. % Redefine a couple of functions that do not work out of the box
  890. (de printexpression (x)
  891. ((lambda (expressioncount*)
  892. (prog (hd tl fn)
  893. (setq x (resolvewconstexpression x))
  894. (cond ((or (numberp x) (stringp x)) (prin2 x))
  895. ((idp x) (prin2 (findlabel x)))
  896. ((atom x)
  897. (errorprintf "***** Oddity in expression %r" x)
  898. (prin2 x))
  899. (t
  900. (setq hd (car x)) (setq tl (cdr x))
  901. (cond
  902. ((setq fn (get hd 'binaryasmop))
  903. (when (greaterp expressioncount* 0)
  904. (prin2 asmopenparen*))
  905. (printexpression (car tl)) (prin2 fn)
  906. (printexpression (cadr tl))
  907. (when (greaterp expressioncount* 0)
  908. (prin2 asmcloseparen*)))
  909. ((setq fn (get hd 'unaryasmop)) (prin2 fn)
  910. (printexpression (car tl)))
  911. ((setq fn (get hd 'asmexpressionformat))
  912. (apply 'printf_internal
  913. (list fn
  914. (foreach y in tl collect
  915. (list 'printexpression
  916. (mkquote y))))))
  917. ((and (setq fn (getd hd))
  918. (equal (car fn) 'macro))
  919. (printexpression (apply (cdr fn) (list x))))
  920. ((setq fn (get hd 'asmexpressionfunction))
  921. (apply fn (list x)))
  922. (t
  923. (errorprintf "***** Unknown expression %r"
  924. x)
  925. (printf "*** Expression error %r ***" x)))))))
  926. (plus expressioncount* 1)))
  927. (de size (x)
  928. (cond ((stringp x) (difference (length (explode2 x)) 1))
  929. ((vectorp x) (upbv x))
  930. ((bignump x) (difference (length (cdr x)) 1))
  931. (t nil)))
  932. (de indx (s n)
  933. (cond ((stringp s) (char-code (nth (explode2 s) (plus2 n 1))))
  934. (t (getv s n))))
  935. (de intp (x) (and (fixp x) (not (bignump x))))
  936. (de sunsymbolp (x)
  937. (setq x (explode2 x))
  938. (prog nil
  939. lbl
  940. (cond ((null x) (return t))
  941. ((not (or (liter (car x)) (eq (car x) '!_))) (return nil)))
  942. (setq x (cdr x))
  943. (go lbl)))
  944. (de asm-char-downcase (c)
  945. (if (and (leq 65 c) (leq c 90))
  946. (plus c 32)
  947. x)))
  948. (de auxaux (i)
  949. (list2string (list (code-char i))))
  950. (dm codeprintf (x) (cons 'fprintf (cons 'codeout* (cdr x))))
  951. (dm dataprintf (x) (cons 'fprintf (cons 'dataout* (cdr x))))
  952. %(def-pass-1-macro Char (u)
  953. %. PSL Character constant macro
  954. % (DoChar U))
  955. % Table driven char macro expander
  956. (de DoChar (u)
  957. (cond
  958. ((idp u) (or
  959. (get u 'charvalue)
  960. ((lambda (n) (cond ((lessp n 128) n))) (id2int u))
  961. (CharError u)))
  962. ((pairp u) % Here's the real change -- let users add "functions"
  963. ((lambda (fn)
  964. (cond
  965. (fn (apply fn (list (dochar (cadr u)))))
  966. (t (CharError u))))
  967. (cond ((idp (car u)) (get (car u) 'char-prefix-function)))))
  968. ((and (fixp u) (geq u 0) (leq u 9)) (plus u 48)) % 48 = (char 0)
  969. (t (CharError u))))
  970. (de CharError (u)
  971. (ErrorPrintF "*** Unknown character constant: %r" u)
  972. 0)
  973. % This is needed for ASM generation, see $pxk/main-start.sl
  974. (put 'symnam 'symbol 'symnam)
  975. (put 'symfnc 'symbol 'symfnc)
  976. (put 'symget 'symbol 'symget)
  977. (put 'symval 'symbol 'symval)
  978. (put 'symprp 'symbol 'symprp)
  979. (setq toploopeval* 'eval)
  980. %(de OperandPrintIndirect (x) % (Indirect x)
  981. % (progn (setq x (cadr x))
  982. % (if (regp x) (progn
  983. % (prin2 "(")
  984. % (PrintOperand x)
  985. % (Prin2 ")"))
  986. % (prin2 "*")
  987. % (PrintOperand x)
  988. % (prin2 " / ")
  989. % (prin1 x)
  990. % (Prin2 ""))
  991. %))
  992. %
  993. %
  994. %(de asmprintvaluecell (x)
  995. % (printexpression (list 'plus2 'symval
  996. % (list 'times (compiler-constant 'addressingunitsperitem)
  997. % (list 'idloc (cadr x)))))
  998. % (princ " / ")
  999. % (prin1 x))
  1000. (flag '(evload) 'ignore)
  1001. % $pu/if.sl defines an IF macro that uses symbols as keywords THEN, ELIF
  1002. % and ELSE. It is coded using the NEXT macro from $pnk/loop-macros.sl, but
  1003. % if I load that file then it gives a version of FOR that conflicts with
  1004. % $pu/for-macro.sl. So I will provide NEXT manually here - not that I think
  1005. % that use of it was a good idea!
  1006. (dm next (u) % Continue Loop
  1007. '(go $loop$))
  1008. (dm bothtimes (x) (cons 'progn (cdr x)))
  1009. (dm compiletime (x) (cons 'progn (cdr x)))
  1010. (dm loadtime (x) (cons 'progn (cdr x)))
  1011. % This seems to be called at cross-compile time with NIL as the
  1012. % second argument. That seems a bit weird to me.
  1013. (de mkitem (tag x)
  1014. (cond
  1015. ((null (integerp tag)) (print (list '++++ 'mkitem tag x)) (mkitem 0 x))
  1016. ((null (integerp x)) (print (list '++++ 'mkitem tag x)) (mkitem tag 0))
  1017. (t (land 16#ffffffffffffffff (lor
  1018. (lsh tag 56)
  1019. (land x 16#00ffffffffffffff))))))
  1020. (de imports (u) nil)
  1021. % (de codewritestring (x)
  1022. % (setq x (strinf x))
  1023. % (setq s (strlen x))
  1024. % (binarywrite codeout* s)
  1025. % (binarywriteblock codeout* (strbase x) (strpack s)))
  1026. (de codewritestring (x)
  1027. (prog (len w)
  1028. (binarymarker codeout* 16#55)
  1029. (setq x (explode2 x))
  1030. (setq len (sub1 (length x)))
  1031. (setq w (times 8 (strpack len))) % 8 bytes per word
  1032. (binarywrite codeout* len)
  1033. (foreach b in x do (binarywritebyte codeout* (char-code b)))
  1034. (while (lessp (setq len (add1 len)) w)
  1035. (binarywritebyte codeout* 0))))
  1036. (de codefiletrailer ()
  1037. (prog (s len)
  1038. (binarymarker codeout* 16#22)
  1039. (systemfaslfixup)
  1040. (binarywrite codeout* (idifference (isub1 nextidnumber*)
  1041. first-local-id-number))
  1042. (binarymarker codeout* 16#33)
  1043. % Number of local IDs
  1044. (foreach x in (car orderedidlist*) do
  1045. (progn (remprop x fasl-idnumber-property*)
  1046. (codewritestring (faslid2string x))))
  1047. (binarymarker codeout* 16#44)
  1048. (binarywrite codeout* % S is size in words
  1049. (setq s
  1050. (iquotient
  1051. (iplus2 currentoffset*
  1052. (isub1 addressingunitsperitem))
  1053. addressingunitsperitem)))
  1054. (binarymarker codeout* 16#66)
  1055. (binarywrite codeout* initoffset*)
  1056. (binarywriteblock codeout* codebase* s)
  1057. (if *compact-bittable
  1058. (let((b (compact-bittable bittablebase* bittableoffset*))
  1059. (bpw (quotient bitsperword 8)))
  1060. (binarywrite codeout*
  1061. (setq s (iquotient
  1062. (iplus2 (car b)
  1063. (isub1 bpw))
  1064. bpw)))
  1065. (setq b (explode2 (cdr b)))
  1066. (setq len (length b))
  1067. (setq s (times 8 s))
  1068. (binarymarker codeout* 16#77)
  1069. (foreach b1 in b do
  1070. (binarywritebyte codeout* (char-code b1)))
  1071. (while (lessp (setq len (add1 len)) s)
  1072. (binarywritebyte codeout* 0))
  1073. % (binarywriteblock codeout* (strbase(strinf (cdr b))) s)
  1074. )
  1075. (binarymarker codeout* 16#88)
  1076. (progn
  1077. (binarywrite codeout*
  1078. (setq s
  1079. (iquotient
  1080. (iplus2 bittableoffset*
  1081. (isub1 bittable-entries-per-word))
  1082. bittable-entries-per-word)))
  1083. (binarywriteblock codeout* bittablebase* s)
  1084. ))
  1085. (binarymarker codeout* 16#99)
  1086. (deallocatefaslspaces)))
  1087. (de compact-bittable(base max)
  1088. (prog (i d bl b l s sb)
  1089. (setq i (setq d 0))
  1090. (ifor (from i 0 (isub1 max) 1)
  1091. (do
  1092. (progn
  1093. (setq b (bittable base i))
  1094. (if (or (not (eq b 0)) % nonzero entry
  1095. (eq d 16#3f) % maximum offset
  1096. )
  1097. (progn
  1098. (push (logor (lsh b 6) d) bl)
  1099. (setq d 1)
  1100. )
  1101. (setq d (iadd1 d))
  1102. )
  1103. )))
  1104. % OK - we have now built up a list bl of the non-zero entries. Each
  1105. % has the entry number in the low 6 bits and then 2 bits of data at the top.
  1106. (setq bl (cons 0 bl))
  1107. (setq bl (reversip bl))
  1108. % Now in the correct order.
  1109. (setq l (length bl))
  1110. % I want to pack it as a string. BEWARE of several issues. Firstly this
  1111. % string contains a pretty arbitrary sequence of bytes, the last of which
  1112. % is a zero byte and that must be included as part of the string. It may
  1113. % not be valid UTF8 so passing it through print code could potentially cause
  1114. % trouble.
  1115. (setq s (list-to-string bl))
  1116. % (setq s (mkstring (isub1 l) 0))
  1117. % (setq sb (strbase (strinf s)))
  1118. % (setq b (isub1 l))
  1119. % (ifor (from i 0 b 1) (do (setf (byte sb i) (pop bl))))
  1120. (return (cons l s))))
  1121. (de initialize-wstring (address init n)
  1122. (prog (i)
  1123. (setq init (explode2 init))
  1124. (setq n (times n 8))
  1125. (setq i 0)
  1126. top (cond
  1127. ((lessp i n) (return nil))
  1128. (init (putbyte address i (char-code (car init)))
  1129. (setq init (cdr init)))
  1130. (t (putbyte address i 0)))
  1131. (setq i (add1 i))
  1132. (go top)))
  1133. (flag '(spaces intp flag1 remflag1 control cntrl continuableerror main
  1134. concat binarywrite binarywritebyte byte putbyte halfword
  1135. puthalfword put_a_halfword putword wgetv wputv known-free-space
  1136. free-bpsgtheap real-gtheap delheap gtstrgthalfwords gtvect
  1137. gtevect gtcontext gtbvect gtfixn gtfltn try-other-bps-spaces
  1138. delbps gtwarray delwarray allocatefaslspaces isinf
  1139. findidnumber makerelocword makerelocinf makerelochalfword
  1140. lsh rsh getbittable putbittable bittable mapobl binarywriteblock
  1141. mkstring field stderror exitlisp copyd codep ncons posintp
  1142. errorprintf1 remobtotalcopy variable-increment-ifor
  1143. constant-increment-ifor onoff* int2id-internal evload load1
  1144. unboundp fboundp funboundp dskin pp string-concat gtbps
  1145. string-equal channelprin2 channelterpri stringgensym id2int
  1146. id2int int2sys sys2fixn binaryopenwrite binaryclose wshift
  1147. wplus2 wtimes2 wquotient wdifference wgreaterp wlessp wgeq wleq
  1148. weq wand wor evectorp bigp isizev igetv channelposn
  1149. channelwritechar idinf fastcallablep defun errorprintf foreach
  1150. repeat ifor on off imports putmem putbyte put_a_halfword int2id
  1151. load errset land lor iland ilor string putword next bothtimes
  1152. compiletime loadtime mkitem imports codewritestring codefiletrailer
  1153. compact-bittable length member memq last lastcar lastpair
  1154. initialize-wstring)
  1155. 'lose)
  1156. (rdf "mytrace.lsp")
  1157. % A function ASSOC1 is defined using LAP in one of the source files
  1158. % I need to load as part of the compiler - thus tending to require that
  1159. % a working compiler/LAP is available at an early stage. By putting in
  1160. % a dummy definition here I avoid that crashing things, and as I read in
  1161. % more files I will instate a locally workable version of LAP - but note
  1162. % that I will install one suitable for cross rather than local compilation.
  1163. (de lap (u)
  1164. (print "+++++ lap called before it is defined +++++")
  1165. (print u)
  1166. nil)
  1167. % end of file