0notes 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. RANDOM NOTES ON CSL/CCL
  2. =======================
  3. The code tries to be in fairly conservative C, but in quite a lot
  4. of places it depends on "the spirit of C" rather than the letter of
  5. the language standards.
  6. "machine.h" contains a catalogue of systems and compilers that the
  7. code has AT SOME STAGE been at least tested once on. At present the
  8. most tested configurations are
  9. Windows, Watcom C 11.5
  10. Linux x86, gcc
  11. and other cases may well have glitches remaining. But I hope that the long
  12. list of tested cases will give encouragement that the code is respectably
  13. portable. Only the Windows version (using The Microsoft Foundation Classes)
  14. has a currently-supported windowed interface: other versions use a command-
  15. line style. Both Mac and X have at times experimenented with the "StdWin"
  16. application framework but the code here does not guarantee to work with it
  17. still or well.
  18. I have adopted an indentation and code layout style that I like. I am aware
  19. that it is not the default one supported my emacs etc, but I have been using
  20. it for a long while and feel very set in my ways.
  21. This Lisp uses an agressive garbage collector that MUST be able to identify
  22. all root pointers reliably. C local variables are not marked by the GC, and
  23. because the GC can relocate things a reference held in a simple C variable
  24. is NOT SAFE across anything that could cause a GC. The macros push() and
  25. pop() place data on a Lisp-safe stack. The coding conventions needed to make
  26. GC safe are ones that take a significant time to get used to. They are not
  27. coder-friendly. If you breach them then the code may work most of the time
  28. but fail later in a messy way. I can only say "you have been warned"!
  29. This Lisp needs to control error recovery and general unwinding. Thus any
  30. function call that could possibly fail MUST be followed by a test to
  31. see if it did. In some cases this will need to do pop() operations (which are
  32. NOT automatically balanced across procedure calls: the programmer has to
  33. take full responsibility for matchiing push and pops). See the code for
  34. examples of what is needed. Again this is not coder-friendly and errors in
  35. applying the conventions can have delayed and unpleasant effect. Again "you
  36. have been warned"
  37. Common Lisp supports functions that return multiple values. Thus the normal
  38. simple case MUST use the onevalue() macro to indicate that what is returned
  39. is a singleton. Failure to do this can mess up error recovery or the
  40. garbage collector.
  41. The above three issues lead to significantly ugly and delicate code. They
  42. are easy for somebody whos is not neurotic enough to overlook. The
  43. trouble that they can lead to will often be deferred, only showing up
  44. occasionally on garbage collection or when recovering from an unrelated
  45. exception. This situation where errors can go undetected for a long while
  46. makes the need for care over these issues especially high priority!
  47. For several platforms it seems to be a really good thing to be able to
  48. respond well to asynchronous events. These may be "^C", or mouse clicks.
  49. Especially with windowed systems some form of threading would be very very
  50. helpful. This is hard wrt portability. Thus for essentially all systems I
  51. use the idea of a "tick stream" of more or less regular events that can
  52. be used to activate polling etc. Having tried genuine timer-based systems and
  53. having had a LOT of trouble with them I mostly use a software count-down
  54. scheme under the guard SOFTWARE_TICKS. If you feel tempted to discard this
  55. in favour of real threads or of nothing then consider the issues of back-
  56. porting to (eg) the Mac, or DOS where you must poll before even ^C is
  57. noticed. I do not want this code to lose portability, please!
  58. The basic data representation here is that small integers (and characters)
  59. are represented as value types, with some of the low 3 bits used as tags.
  60. Cons cells, vectors, big-numbers etc are handled by reference. By arranging
  61. that all items are stored aligne dto an 8-byte boundary the low 3 bits
  62. in a pointer are available for use as tags. More details can be seen in
  63. "tags.h". The most significant bit in a pointer is used for garbage
  64. collection, so heap memory must all be allocated in one half of the
  65. machine'e address space (it does not matter which!).
  66. The Lisp system here was designed for delivery of code that had already
  67. been developed and was basically working. It was not designed as a
  68. development environment. This means that in some respects it is
  69. inflexible! For instance there is a Lisp to C compiler, but it is
  70. configured so that the generated C is statically linked into the Lisp.
  71. The Lisp does not have very clever windowed interfaces, browsers etc.
  72. The Lisp compiler has its master version coded in RLISP (an Algol-like
  73. surface syntax for Lisp, popularised by the REDUCE algebra system). A
  74. yacc-based parser can translate this into raw Lisp, but enhancements would
  75. be better made to the RLISP version.
  76. I leave a notation that sort-of looks like an attempt to nest comments
  77. in places in the code where I know there are issues that have not been
  78. fully resolved. Eg comments such as
  79. /* /* This is not yet fully up to Common Lisp specification */
  80. etc etc. I do this because I can then make (some) C compilers generate
  81. warnings that remind me of these worries. Ideally I would fix them all! Or
  82. ideally C would have been specified with a #warn as well as and #error
  83. preprocessor directive!
  84. The notation "/* Signature ... */" present towards the top of each file
  85. is maintained using a utility called "filesign". It provides a checksum
  86. on the file, which I find much more reliable as a way of confirming
  87. versions than date-stamps, especially when files are copied between
  88. a number of different machines, perhaps in different time-zones.
  89. [more random comments follow...]
  90. double-execute() and undouble-execute() are like trace() and untrace() but
  91. cause the nominated functions to double their costs. Only at first actually
  92. does anything for functions with fixed numbers of args.
  93. PRESERVE optional args. First specifies a restart function
  94. to be called, the second is a banner to display when the image is reloaded.
  95. Reduce now uses this mechanism to gets its banner displayed. Third arg can be
  96. stuff to pass to the restart function - passing is via a text-string interface
  97. so it is a bit delicate!
  98. Lexical closures supported in the bytecode compiler (for variable reference
  99. but not GO or RETURN-FROM) and 3 new opcodes (closure, loadlex, storelex)
  100. introduced in bytes1.c to support same.
  101. By default the MSB of pointers is now determined at run time (rather than
  102. being a manifest value compiled into the code).
  103. Support for calls to functions with large numbers of arguments is
  104. improved. In particular in Common Lisp mode it is possible to have
  105. more than 50 args.
  106. Line-length overflow checking for printing of big numbers implemented.
  107. binary printing for numbers, and case fold up as well as down, supported.
  108. -------------------------------------------------------------------------------
  109. DATA REPRESENTATION
  110. ===================
  111. All objects in CSL are represented by 32-bit words(*), and each object in
  112. memory is aligned at an 8-byte boundary. The bottom 3 bits of a word
  113. aare used as tags, and indicate how the rest of the word should be
  114. interpreted. In some cases the rest of the word is just direct information
  115. (eg small integers are handled this way) and then the 0x8-bit is used by
  116. the garbage collecter. In other cases the 32-bit word contains the address
  117. in memory of some object, and in that case its most significant bit is
  118. reserved for use by the garbage collector. Thus all valid addresses must have
  119. the same sign (but this can be either + or -). Many objects in memory have
  120. a header word at their start that indicates their length and gives more
  121. details about their type. The encoding of object lengths means that the
  122. largest possible single object in CSL would be 4 Mbytes long. Also CSL
  123. memory is allocated in chunks (typically 256 Kbytes) and that puts another,
  124. usually more severe, limit on maximum object size. This may matter for
  125. arrays and bignums.
  126. (*) well on some machines they may be 64-bits but not much changes!
  127. The coding in the low bits of a word is as follows:
  128. x x x | x 0 0 0 cons cell (and NIL in Common Lisp mode)
  129. x x x | G 0 0 1 28-bit integer (G = garbage collector bit)
  130. x x x | G 0 1 0 characters, vec-hdrs, other oddities (immediate)
  131. x x x | G 0 1 1 28-bit short float if Common Lisp mode
  132. x x x | x 1 0 0 a symbol
  133. x x x | x 1 0 1 bignum. {rational number, complex number}
  134. x x x | x 1 1 0 Lisp vector (includes strings etc)
  135. x x x | x 1 1 1 pointer to boxed floating point number
  136. Pointers reserve the 0x80000000L bit for the garbage collector,
  137. assuming that all addresses are in the same half of the space. This
  138. of course is a slightly dodgy assumption that may be false on some
  139. computers. On 64-bit machines it is again the top bit that is used by
  140. the GC.
  141. Header words in the vector heap
  142. If the bottom 3 bits of a word are 010 (TAG_ODDS) the word is
  143. treated as immediate data. In that case the 1000 bit (GC_BIT_I)
  144. is kept free for use as a mark bit. The next bits up classify the
  145. object:
  146. | x x 0 0 | * 0 1 0 valid immediate date in heap
  147. but can also be used as vector headers
  148. | x x 0 1 | * 0 1 0 symbol headers
  149. | x x 1 0 | * 0 1 0 number headers
  150. | x x 1 1 | * 0 1 0 vector headers
  151. Data that could be in the heap or on the stack decodes further:
  152. x x | 0 0 0 0 | * 0 1 0 character
  153. x x | 0 1 0 0 | * 0 1 0 handle/offset to BPS page
  154. x x | 1 0 0 0 | * 0 1 0 [handle/offset to literal vector]
  155. x x | 1 1 0 0 | * 0 1 0 special marker (SPID) left on stack
  156. to help interpreter
  157. The remaining 24 bits of the word are available for data. The BPS and
  158. literal vector handles in this case are for a segmented memory
  159. implementation, and the 24 bit address has its top 10 bits identifying
  160. a page number, then 14 bits giving a WORD offset into the associated
  161. page, which can thus be up to 64 Kbytes large. Or more depending on
  162. PAGE_BITS. Literal vectors done this way are not used at present.
  163. For Standard Lisp only 8 bits of character information is needed - the
  164. remaining bits are there to support font etc information in a Common
  165. Lisp world.
  166. . . . . | g f 0 1 | * 0 1 0 symbol header
  167. g global variable
  168. f fluid (special) variable
  169. The remaining bits in the word are used as follows
  170. 00000100 symbol names a special form
  171. 00000200 symbol has a definition as a macro
  172. 00000400 an unprinted gensym (so print-name is not complete yet)
  173. 00000800 has a definition in C from the C-coded kernel
  174. 00001000 just carries a code-pointer (codep test)
  175. 00002000 any gensym, printed or not
  176. 000fc000 fastget code in this is used as a p-list indicator
  177. 00100000 traced
  178. 00200000 is external in its home package
  179. ffc00000 reachability in first 10 packages!!!
  180. The remaining header words hold the length (in bytes) of the object
  181. (including the length of the header word) in the upper 22 bits of the
  182. word. This puts a limit of 4 Mbytes on the largest possible single
  183. object in this Lisp.
  184. 0 0 | 0 0 1 0 | * 0 1 0 bignum header word
  185. 0 0 | 0 1 1 0 | * 0 1 0 ratnum
  186. 0 0 | 1 0 1 0 | * 0 1 0 complex number
  187. 0 0 | 1 1 1 0 | * 0 1 0 NOT USED (non-float number)
  188. 0 1 | 0 0 1 0 | * 0 1 0 single float
  189. 0 1 | 0 1 1 0 | * 0 1 0 double float
  190. 0 1 | 1 0 1 0 | * 0 1 0 long float
  191. 0 1 | 1 1 1 0 | * 0 1 0 NOT USED (floating number)
  192. Note that headers for numbers are 0x|xx10|x010 and the 0x100 bit flags
  193. floating point cases
  194. n n | n 0 1 1 | * 0 1 0 bitvector with nnn bits in last byte
  195. 0 0 | 0 1 1 1 | * 0 1 0 string
  196. 0 0 | 1 0 1 1 | * 0 1 0 (bitvector)
  197. 0 0 | 1 1 1 1 | * 0 1 0 simple vector
  198. 0 1 | 0 0 1 1 | * 0 1 0 (bitvector)
  199. 0 1 | 0 1 1 1 | * 0 1 0 BPS
  200. 0 1 | 1 0 1 1 | * 0 1 0 (bitvector)
  201. 0 1 | 1 1 1 1 | * 0 1 0 hash table
  202. 1 0 | 0 0 1 1 | * 0 1 0 (bitvector)
  203. 1 0 | 0 1 1 1 | * 0 1 0 SPARE contains binary data
  204. 1 0 | 1 0 1 1 | * 0 1 0 (bitvector)
  205. 1 0 | 1 1 1 1 | * 0 1 0 Common Lisp array (header block)
  206. 1 1 | 0 0 1 1 | * 0 1 0 (bitvector)
  207. 1 1 | 0 1 1 1 | * 0 1 0 encapsulated stack pointer
  208. 1 1 | 1 0 1 1 | * 0 1 0 (bitvector)
  209. 1 1 | 1 1 1 1 | * 0 1 0 Common Lisp structure
  210. (use BPS for vector of 8-bit ints)
  211. 1 0 | 0 0 1 0 | * 0 1 0 vector of 16-bit integers
  212. 1 0 | 0 1 1 0 | * 0 1 0 vector of 32-bit integers
  213. 1 0 | 1 0 1 0 | * 0 1 0 MIXED1 [3 words of pointers, then binary]
  214. 1 0 | 1 1 1 0 | * 0 1 0 MIXED2
  215. 1 1 | 0 0 1 0 | * 0 1 0 vector of single-precision floats
  216. 1 1 | 0 1 1 0 | * 0 1 0 vector of double-precision floats
  217. 1 1 | 1 0 1 0 | * 0 1 0 MIXED3
  218. 1 1 | 1 1 1 0 | * 0 1 0 Stream handle (aka MIXED4)
  219. -------------------------------------------------------------------------------
  220. FAST PROPERTY ACCESS IN CSL/CCL
  221. ===============================
  222. The "fast-get" facility in CSL arranges that for a number of user-specified
  223. property names (used with both GET and FLAGP) the access has constant cost.
  224. Normally access to a property involves searching a property list, and if one
  225. symbol has many properties this can be tedious - with a worst case in the
  226. fairly common circumstance that the property is not found.
  227. To speed up CSL I allocate 6 bits in a symbol header that influence how that
  228. symbol is treated when used as a property name. One code is reserved to
  229. mean "use a normal property list", leaving 63 codes for fast access. The
  230. first of these is reserved for a property called 'NONCOM because the built-in
  231. ORDERP function wants to use this for compatibility with REDUCE(!!).
  232. A tag must be marked as "fast" before any properties with that indicated are
  233. set up. If this constraint is not adhered to then properties can end up
  234. stored in inconsistent or redundant forms. The protocol is to select an
  235. integer in the range 0 to 63 for each tag to be handled specially, and then
  236. to make a call such as
  237. (symbol-make-fastget 'noncom 0)
  238. (symbol-make-fastget 'my_property_name 1)
  239. (flag '(a b c) 'noncom)
  240. (put 'x 'my_property_name 'y)
  241. or (setf (get 'x 'my_property_name) 'y)
  242. The fast-get status of a symbol can be inspected using
  243. (symbol-fast-get 'x nil)
  244. or reset to have no special treatment (please do not do this!)
  245. (symbol-fast-get 'x -1)
  246. When a symbol is given a "fast" property a vector of length 63 is created
  247. and a word in the symbol's header is made to point to it. The vector contains
  248. either property values ir a marker that indicates that no property is
  249. present. A call (symbol-fastgets 'x) can retrieve the vector and can be
  250. useful while debugging, maybe.
  251. If you inspect the property list of an object (using the PLIST function) then
  252. any fast properties are extracted from the vector and built onto the front
  253. of the property list as returned. Of course this means that altering the
  254. property list using RPLACx may not be useful!
  255. The function GET retrieves a property. In Common Lisp mode the three-argument
  256. version (GET a b c) allows c to be returned as a default value if the
  257. property sought is not present. The two-argument version can not distinguish
  258. between a property whose value is NIL and not having a property present
  259. at all. The function FLAGP returns T if a property is present (whatever
  260. value is associated, including the case where the stored value is NIL). The
  261. function FLAG just sets properties, giving them the value T in a somewhat
  262. arbitrary way.
  263. Clearly use of fast gets consumes memory, but because many of the extra
  264. vectors contain many NIL elements they compress well in image files, which
  265. therefore do not grow too badly. To decide which properties are most
  266. critical you can run tests using the profiled version of the bytecode
  267. interpreter (bytes.c rather than bytes1.c), and after a run call the
  268. function (BYTECOUNTS). You need to adjust your build sequence so that
  269. the file bytes.c is compiled with RECORD_GET defined, e.g. by putting
  270. -DRECORD_GET
  271. among the flags passed to your C compiler. Note that this option will slow
  272. things down noticeably. The output from BYTECOUNTS indicates which property
  273. tags were used, and how many unsuccessful searches for each tag occurred. This
  274. latter information is collected because unsuccessful searches are the worst
  275. case for a traditional property list search.
  276. Note that when a property is handled "fast" it is not stored on the regular
  277. property list (the only information about it is in the vector). Thus if the
  278. most commonly used properties have been handled this way the average length
  279. of property lists will shrink and so access to all other properties is
  280. slightly speeded up too.
  281. By editing FASTGET_SIZE in the source file "tags.h" if would be possible to
  282. make the symbol extension vectors smaller than 63 items long, so in
  283. cases where a much smaller set of tags is important the system can
  284. be configured to save some memory.
  285. -----------------------------------------------------------------------
  286. [This issue was responded to during the Axiom customisation process]
  287. Subject: Interface for dynamic opening and closing of libraries
  288. Arthur:
  289. I've discussed the specification of the "dynamic libraries" interface with
  290. Barry and this is what we think we need. For a user's own code, we will
  291. always know the full pathname of the library it is in, so we can load the
  292. module explicitly.
  293. 1. A function that loads a particular module from a particular library, e.g.
  294. (load-module <module> <pathname>)
  295. The library need not be open for input. You might wish to have separate
  296. open-library, load-module, and close-library operations if that is more
  297. efficient.
  298. 2. A function that opens a library for output, e.g.
  299. (open-library <pathname>)
  300. The function need not be responsible for checking if the library is open
  301. already.
  302. 3. A function that reads a lisp source file, translates it into byte codes,
  303. and writes the results into a named library, e.g.
  304. (fasl-out <filename> <library>)
  305. This could either:
  306. (a) Overwrite an existing module with the same name (our preferred option),
  307. or
  308. (b) replace the entire library if it already exists.
  309. 4. A function that closes an open library and, if option 3a above is
  310. implemented, does all the necessary tidying-up, compaction etc, e.g.
  311. (close-library <pathname>)
  312. 5. Facilities for setting the library search path from within Lisp:
  313. (a) deleting a library from the search path;
  314. (b) adding a new library to the front of the search path;
  315. (c) adding a new library to the end of the search path.
  316. ------------------------------------------------------------------------
  317. This shows the proportionate use of the various byte opcodes
  318. on one particular test run. The information was collected while I was
  319. trying to optimise the bytecode design. If any elaborate bytecode or
  320. combination of bytecodes was getting very heavy use I might provide
  321. special-case variants etc. Of course with different test programs the
  322. profile may end up somewhat different.
  323. 7.3400 LOADLOC6
  324. 3.8160 LOADFREE
  325. 3.6256 CARLOC6
  326. 2.8646 LOADFREE2
  327. 2.7618 EXIT
  328. 2.6747 PUSH
  329. 2.6054 LOADLOC1
  330. 2.2990 LITGET
  331. 2.2175 LOADLOC3
  332. 2.0495 STOREFREE
  333. 2.0072 JUMPNIL_L
  334. 2.0046 CONS
  335. 1.8176 BUILTIN2
  336. 1.7415 JUMPNIL
  337. 1.7210 LOADLOC0
  338. 1.5494 JUMPST1NI
  339. 1.5250 BUILTIN1
  340. 1.4593 JUMPNIL_B
  341. 1.4564 CALL1
  342. 1.4206 STORELOC1
  343. 1.3783 PUSHNIL2
  344. 1.3783 LOSE2
  345. 1.3624 FREERSTR
  346. 1.3624 FREEBIND
  347. 1.2805 JUMPT
  348. 1.2565 JUMP_B
  349. 1.1196 CDR
  350. 1.0389 LOADLOC5
  351. 1.0384 VNIL
  352. 0.9265 STORELOC2
  353. 0.9265 STORELOC0
  354. 0.9200 JUMPNEQCA
  355. 0.8966 CAR
  356. 0.8812 LOADLOC10
  357. 0.8712 JUMP_BL
  358. 0.8607 LOADLOC2
  359. 0.8244 STOREFREE
  360. 0.7828 LOADLOC4
  361. 0.7735 GREATERP
  362. 0.7659 JUMPNFLAG
  363. 0.7408 JUMPLITNE
  364. 0.7264 CALL2_1
  365. 0.7089 LOADLIT
  366. 0.6966 ADD1
  367. 0.6903 CARLOC2
  368. 0.6749 LOADLOC7
  369. 0.6739 JUMPT_BL
  370. 0.6556 CADR
  371. 0.6501 JUMPNATOM
  372. 0.6448 JUMPFLAGP
  373. 0.6395 CALL2
  374. 0.6369 JUMPLITEQ
  375. 0.6357 LOSE
  376. 0.6287 STORELOC
  377. 0.6274 SWOP
  378. 0.6003 LOADLIT4
  379. 0.5577 STORELOC5
  380. 0.5397 APPLY1
  381. 0.5004 LOADLOC9
  382. 0.4910 CDRLOC2
  383. 0.4772 JUMPL2T
  384. 0.4630 CARLOC10
  385. 0.4404 LOADLIT1
  386. 0.4196 CARLOC0
  387. 0.4178 CDRLOC0
  388. 0.4173 JUMPNIL_B
  389. 0.4029 JUMPFREE3
  390. 0.3861 STORELOC4
  391. 0.3767 STORELOC3
  392. 0.3659 NCONS
  393. 0.3613 LOADLOC8
  394. 0.3589 PUSHNIL
  395. 0.3164 JUMPB2NIL
  396. 0.3108 JUMPFREEN
  397. 0.3030 JUMPATOM
  398. 0.2955 JUMPFREET
  399. 0.2879 PUSHNILS
  400. 0.2823 LOADLOC
  401. 0.2672 CALL1_3
  402. 0.2587 CARLOC1
  403. 0.2554 CDDR
  404. 0.2515 CARLOC5
  405. 0.2469 CALL1_1
  406. 0.2457 LOADLOC11
  407. 0.2298 LOSES
  408. 0.2275 PUSHNIL3
  409. 0.2109 JUMPLIT2N
  410. 0.2024 NUMBERP
  411. 0.2013 CALL3
  412. 0.2004 JUMPT_L
  413. 0.1952 JUMPL0T
  414. 0.1930 CALL2R
  415. 0.1910 JUMPLIT1N
  416. 0.1840 JUMPL1T
  417. 0.1835 LOSE3
  418. 0.1789 STORELOC7
  419. 0.1785 CALL2_4
  420. 0.1706 CALL1_2
  421. 0.1696 CAARLOC2
  422. 0.1673 POP
  423. 0.1645 JUMPL1NIL
  424. 0.1582 LOADFREE1
  425. 0.1533 JCALL
  426. 0.1516 JUMPNE
  427. 0.1512 CARLOC4
  428. 0.1463 LOADLIT2
  429. 0.1418 JUMPL1NAT
  430. 0.1414 CARLOC11
  431. 0.1382 CDRLOC1
  432. 0.1373 CDRLOC5
  433. 0.1352 JUMPL0NIL
  434. 0.1350 JUMPB1NIL
  435. 0.1251 LOADLIT3
  436. 0.1238 LOADLIT5
  437. 0.1180 LOADFREE3
  438. 0.1173 CDAR
  439. 0.1163 CARLOC7
  440. 0.1127 CAAR
  441. 0.1120 JUMPST0NI
  442. 0.1108 ACONS
  443. 0.1080 LOADLIT6
  444. 0.1077 XCONS
  445. 0.1061 CALLN
  446. 0.0986 JUMPT_B
  447. 0.0973 CALL1_5
  448. 0.0959 CARLOC9
  449. 0.0890 LOADFREE4
  450. ----------------------------------------------------------------------
  451. [some comments from when NAG were getting Axiom support fully up to
  452. scratch: these are now probably only of historical interest!]
  453. 15 May [PAB] sys*.c: get_truename should preserve '/' at end of string
  454. print.c: fix memory leak in Ltruename
  455. 21 May [PAB] syscwin.c: use STARTF_USESTDHANDLES
  456. 17 Jun [MCD] scandir.c: Changed the NT version of scan_files to check
  457. for a trailing '\' before adding '\*.*'.
  458. 12 Aug [MCD] all files: merged with latest version from ACN.
  459. 14 Aug [MCD] fns3.c: Added C-coded version of subseq and auxilliaries.
  460. 22 Aug [TTT] arith03.c arith11.c: changed quotib,Cremainder to treat
  461. properly the case (DIVIDE -134217728 134217728)
  462. 23 Aug [TTT] fns1.c: changed a comment to refer to *break-loop* not *break-function*
  463. 30 Aug [TTT] machine.h: SYS_TIMES macro name changed because of collision
  464. with system-defined macro in HP/UX
  465. also affected :sys.h restart.c sysunix.c sysvms.c sysxwin.c
  466. 20 Sep [TTT] fns3.c: added hashtable-flavour thingies
  467. 9 Oct [TTT] sockets.c: added glnag calls for all platforms
  468. added NANQ support
  469. 28 Oct [TTT] scandir.c: use realloc_wnull instead of realloc
  470. to cure SunOS4.1.2 problems with realloc(0,...)
  471. 20 Nov [TTT] read.c: typo Lrdfn Lddfn fixed
  472. 20 Nov [TTT] read.c: Lrdf4 : changed the Lopen to honour :if-does-not-exist
  473. keyword
  474. 21 Nov [MCD] All files: merged latest changes from Arthur.
  475. 2 Dec [TTT] gc.c : added timnag_ license management call in reclaim
  476. 2 Dec [TTT] csl.c: added init_lm call in ENTRYPOINT
  477. 3 Dec [TTT] sockets.c: changed product codes to AX???23NA
  478. added nullary init_lm function
  479. ------1997
  480. 24 Jan [TTT] sysunix.c: changed mkdir(filename,0770) to
  481. mkdir(filename,0777) to respect world setting of umask
  482. in create_directory.
  483. 23 April [MCD] externs.h restart.c csl.c fasl.c fns1.c fns2.c eval2.c
  484. Introduced mechanism (using symbol_protect_flag) to toggle
  485. protection of symbols in kernel.
  486. 10 July [MCD] csl.c Added initialisation of symbol_protect_flag to 1
  487. syscwin.c: Fixed bug in truename which stuck extra trailing
  488. slashes on directory names, causing directoryp to fail.
  489. 19 Sep [MCD] csl.c : Disabled CCL break messages on interrupt
  490. 3 Dec [PAB] read.c, gc.c: Added call-counting mode to mapstore
  491. (yes, it is a hack).
  492. -------------------------------------------------------------------------
  493. I have just manufactured a version of CSL that is (perhaps) easy to call
  494. from other C code. What follows is the main chunk of code that shows
  495. what the interface is. What this means wrt REDUCE is that I will want to
  496. manufacture an alternative to (BEGIN) that reads-simplifies-prints just
  497. one REDUCE expression/command at a time rather than the current single
  498. function that gobbles things for ever....
  499. /*
  500. * The next fragment of code is to help with the use of CSL (and hence
  501. * packages written in Lisp and supported under CSL) as OEM products
  502. * embedded within larger C-coded packages. There is (of course) a
  503. * significant issue about clashes between the names of external symbols
  504. * if CSL is to be linked with anything else, but I will not worry about that
  505. * just yet.
  506. * The protocol for calling Lisp code from C is as follows:
  507. *
  508. * cslstart(argc, argv, writer);allocate memory and Lisp heap etc. Args
  509. * should be "as if" CSL was being called
  510. * directly and this was the main entrypoint.
  511. * The extra arg accepts output from this
  512. * stage. Use NULL to get standard I/O.
  513. * execute_lisp_function(fname, reader, writer);
  514. * fname is a (C) string that names a Lisp
  515. * function of 0 args. This is called with
  516. * stdin/stdout access redirected to use the
  517. * two character-at-a-time functions passed
  518. * down. [Value returned indicates if
  519. * the evaluation succeeded?]
  520. * cslfinish(writer); Tidies up ready to stop.
  521. */
  522. int execute_lisp_function(char *fname,
  523. character_reader *r, character_writer *w)
  524. {
  525. Lisp_Object nil;
  526. Lisp_Object ff = make_undefined_symbol(fname);
  527. nil = C_nil;
  528. if (exception_pending()) return 1; /* Failed to make the symbol */
  529. procedural_input = r;
  530. procedural_output = w;
  531. Lapply0(nil, ff);
  532. procedural_input = NULL;
  533. procedural_output = NULL;
  534. nil = C_nil;
  535. if (exception_pending()) return 2; /* Failure during evaluation */
  536. return 0;
  537. }
  538. #ifdef SAMPLE_OF_PROCEDURAL_INTERFACE
  539. static char ibuff[100], obuff[100];
  540. static int ibufp = 0, obufp = 0;
  541. static int iget()
  542. {
  543. int c = ibuff[ibufp++];
  544. if (c == 0) return EOF;
  545. else return c;
  546. }
  547. static void iput(int c)
  548. {
  549. if (obufp < sizeof(obuff)-1)
  550. { obuff[obufp++] = c;
  551. obuff[obufp] = 0;
  552. }
  553. }
  554. #endif
  555. int MS_CDECL main(int argc, char *argv[])
  556. {
  557. cslstart(argc, argv, NULL);
  558. #ifdef SAMPLE_OF_PROCEDURAL_INTERFACE
  559. strcpy(ibuff, "(print '(a b c d))");
  560. execute_lisp_function("oem-supervisor", iget, iput);
  561. printf("Buffered output is <%s>\n", obuff);
  562. #else
  563. cslaction();
  564. #endif
  565. my_exit(cslfinish(NULL));
  566. return 0;
  567. }
  568. ...............................end
  569. Arthur Norman. 2002