home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / scm / !Scm / docs / code_doc < prev    next >
Encoding:
Text File  |  1994-03-31  |  30.2 KB  |  767 lines

  1. "code.doc", documentation for scm4e0.
  2.    Copyright (C) 1990, 1991, 1992, 1993, 1994 Aubrey Jaffer.
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 1, or (at your option)
  7. any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. The author can be reached at jaffer@ai.mit.edu or
  19. Aubrey Jaffer, 84 Pleasant St., Wakefield MA 01880
  20.  
  21. Scm is a portable Scheme implementation written in C.  Scm provides a
  22. machine independent platform for JACAL, a symbolic algebra system.
  23. SCM runs under VMS, MS-DOS, MacOS, Unix and similar systems.
  24.  
  25. Scm conforms to Revised^4 Report on the Algorithmic Language Scheme
  26. and the IEEE P1178 specification.  Scm is interpreted and implements
  27. tail recursion for interpreted code.  Scm has inexacts, 30 bit
  28. immediate integers and large precision integers.  Scm uses and garbage
  29. collects off the C-stack.  This allows routines to be written in C
  30. without regard to GC visibility. call-with-current-continuation is
  31. fully are supported.  ASCII and EBCDIC are supported.
  32.  
  33.                PROJECT HISTORY
  34.  
  35. Siod, written by George Carrette, was the starting point for scm.
  36. Here is the Siod notice:
  37. /* Scheme In One Defun, but in C this time.
  38.  
  39.  *              COPYRIGHT (c) 1989 BY                    *
  40.  *      PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS.        *
  41.  *               ALL RIGHTS RESERVED                    *
  42.  
  43. Permission to use, copy, modify, distribute and sell this software
  44. and its documentation for any purpose and without fee is hereby
  45. granted, provided that the above copyright notice appear in all copies
  46. and that both that copyright notice and this permission notice appear
  47. in supporting documentation, and that the name of Paradigm Associates
  48. Inc not be used in advertising or publicity pertaining to distribution
  49. of the software without specific, written prior permission.
  50.  
  51. PARADIGM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  52. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  53. PARADIGM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  54. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  55. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  56. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  57. SOFTWARE.
  58.  
  59. gjc@paradigm.com
  60.  
  61. Paradigm Associates Inc         Phone: 617-492-6079
  62. 29 Putnam Ave, Suite 6
  63. Cambridge, MA 02138
  64. */
  65.  
  66. The innovation from Siod which scm uses is being able to garbage
  67. collect off the c-stack.  All the code has been rewritten.  See the
  68. file "ChangeLog" for a log of recent changes that have been made to
  69. scm.
  70.  
  71.                 SCM DATA TYPES
  72.  
  73.                  IMMEDIATEs:
  74. pointer:    pointer to a cell
  75. inum:        immediate 30 bit integers
  76. ichr:        immediate characters
  77. iflags:        #t, #f, (), #<eof>, #<undefined>, and #<unspecified>
  78. isym:        `and', `begin', `case', `cond', `define', `do', `if',
  79.         `lambda', `let', `let*', `letrec', `or', `quote', `set!',
  80.         `#f', `#t', `#<undefined>', `#<eof>', `()', `#<unspecified>'
  81.                 IMCAR IMMEDIATEs: (only in car of evaluated code)
  82. ispcsym:    special symbols: syntax-checked versions of first 14 isyms
  83. iloc:        indexes to a variable's location in environment
  84. gloc:        pointer to a symbol's value cell
  85.  
  86.                 CELLs:
  87.         Cells represent all SCM objects besides the immediates.
  88.         A cell has a car and a cdr.  Low-order bits in car identify
  89.         the type of object. Rest of car and cdr hold object data.
  90.                 SIMPLE:
  91. cons:        scheme cons-cell returned by (cons arg1 arg2)
  92. closure:    applicable object returned by (lambda (args) ...)
  93.                    MALLOCs:
  94.  spare:        spare tc7 type code
  95. vector:        scheme vector
  96. ssymbol:    static scheme symbol (part of initial system)
  97. msymbol:    malloced scheme symbol (can be GCed)
  98. string:        scheme string
  99. bvect:        uniform vector of booleans (bit-vector)
  100. ivect:        uniform vector of integers
  101. uvect:        uniform vector of non-negative integers
  102. fvect:        uniform vector of short inexact real numbers
  103. dvect:        uniform vector of double precision inexact real numbers
  104. cvect:        uniform vector of double precision inexact complex numbers
  105. contin:        applicable object produced by call-with-current-continuation
  106. cclo:        environment and SUBR for compiled closure
  107.  
  108.                 SUBRs:
  109. asubr:        associative C function of 2 arguments.
  110.  
  111. subr_0:        C function of no arguments.
  112. subr_1:        C function of one argument.
  113. cxr:        car, cdr, cadr, cddr, ...
  114. subr_3:        C function of 3 arguments.
  115.  
  116. subr_2:        C function of 2 arguments.
  117. rpsubr:        transitive relational predicate C function of 2 arguments.
  118. subr_1o:    C function of one optional argument.
  119. subr_2o:    C function of 1 required and 1 optional argument.
  120.                    LSUBRs:
  121. lsubr_2:    C function of 2 arguments and a list of arguments.
  122. lsubr:        C function of list of arguments.
  123.                 PTOBs:
  124. inport:        input port.
  125. outport:    output port.
  126. ioport:        input-output port.
  127. inpipe:        input pipe.
  128. outpipe:    output pipe.
  129.                 SMOBs:
  130. free_cell:    unused cell on the freelist.
  131. flo:        single-precision float.
  132. dblr:        double-precision float.
  133. dblc:        double-precision complex.
  134. bigpos:        positive bignum.
  135. bigneg:        negative bignum.
  136. promise:    made by DELAY.
  137. arbiter:    synchronization object.
  138. macro:        macro expanding function.
  139. array:        multi-dimensional array.
  140.  
  141.  
  142.               DATA TYPE REPRESENTATIONS
  143. IMMEDIATE:    B,D,E,F=data bit, C=flag code, P=pointer address bit
  144.     ................................
  145. pointer PPPPPPPPPPPPPPPPPPPPPPPPPPPPP000
  146. inum    BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB10
  147. ichr    BBBBBBBBBBBBBBBBBBBBBBBB11110100
  148. iflag            CCCCCCC101110100
  149. isym            CCCCCCC001110100
  150.     IMCAR:    only in car of evaluated code, cdr has cell's GC bit
  151. ispcsym            000CCCC00CCCC100
  152. iloc    0DDDDDDDDDDDDDDDEFFFFFFF11111100
  153. gloc    PPPPPPPPPPPPPPPPPPPPPPPPPPPPP001
  154.  
  155.    HEAP CELL:    G=gc_mark; 1 during mark, 0 other times.
  156.     1s and 0s here indicate type.      G missing means sys (not GC'd)
  157.     SIMPLE:
  158. cons    ..........SCM car..............0  ...........SCM cdr.............G
  159. closure ..........SCM code...........011  ...........SCM env.............G
  160.     MALLOCs:
  161. ssymbol    .........long length....G0000101  ..........char *chars...........
  162. msymbol    .........long length....G0000111  ..........char *chars...........
  163. string    .........long length....G0001101  ..........char *chars...........
  164. vector    .........long length....G0001111  ...........SCM **elts...........
  165. bvect    .........long length....G0010101  ..........long *words...........
  166.  spare                G0010111
  167. ivect    .........long length....G0011101  ..........long *words...........
  168. uvect    .........long length....G0011111  ......unsigned long *words......
  169.  spare                G0100101
  170.  spare                G0100111
  171. fvect    .........long length....G0101101  .........float *words...........
  172. dvect    .........long length....G0101111  ........double *words...........
  173. cvect    .........long length....G0110101  ........double *words...........
  174.  
  175. contin    .........long length....G0111101  .............*regs..............
  176. cclo    .........long length....G0111111  ...........SCM **elts...........
  177.     SUBRs:
  178.  spare                010001x1
  179.  spare                010011x1
  180. subr_0    ..........int hpoff.....01010101  ...........SCM (*f)()...........
  181. subr_1    ..........int hpoff.....01010111  ...........SCM (*f)()...........
  182. cxr    ..........int hpoff.....01011101  ...........SCM (*f)()...........
  183. subr_3    ..........int hpoff.....01011111  ...........SCM (*f)()...........
  184. subr_2    ..........int hpoff.....01100101  ...........SCM (*f)()...........
  185. asubr    ..........int hpoff.....01100111  ...........SCM (*f)()...........
  186. subr_1o    ..........int hpoff.....01101101  ...........SCM (*f)()...........
  187. subr_2o    ..........int hpoff.....01101111  ...........SCM (*f)()...........
  188. lsubr_2    ..........int hpoff.....01110101  ...........SCM (*f)()...........
  189. lsubr_2n..........int hpoff.....01110111  ...........SCM (*f)()...........
  190. rpsubr    ..........int hpoff.....01111101  ...........SCM (*f)()...........
  191.             PTOBs:
  192.    port           00wroxxxxxxxxG1110111  ..........FILE *stream..........
  193.  inport    uuuuuuuuuuU00011xxxxxxxxG1110111  ..........FILE *stream..........
  194. outport    0000000000000101xxxxxxxxG1110111  ..........FILE *stream..........
  195.  ioport    uuuuuuuuuuU00111xxxxxxxxG1110111  ..........FILE *stream..........
  196. fport           00   00000000G1110111  ..........FILE *stream..........
  197. pipe           00   00000001G1110111  ..........FILE *stream..........
  198.             SMOBs:
  199. free_cell
  200.     000000000000000000000000G1111111  ...........*free_cell........000
  201. flo    000000000000000000000001G1111111  ...........float num............
  202. dblr    000000000000000100000001G1111111  ..........double *real..........
  203. dblc    000000000000001100000001G1111111  .........complex *cmpx..........
  204. bignum    ...int length...0000001 G1111111  .........short *digits..........
  205. bigpos    ...int length...00000010G1111111  .........short *digits..........
  206. bigneg    ...int length...00000011G1111111  .........short *digits..........
  207.             xxxxxxxx = code assigned by newsmob();
  208. promise 000000000000000fxxxxxxxxG1111111  ...........SCM val..............
  209. arbiter    000000000000000lxxxxxxxxG1111111  ...........SCM name.............
  210. macro    000000000000000mxxxxxxxxG1111111  ...........SCM name.............
  211. array    ...short rank...xxxxxxxxG1111111  ............*array..............
  212.  
  213.                 SMOBs
  214.  
  215. SMOBs are a collection of miscellaneous types.  The type code and
  216. GCMARK bit occupy the lower order 16 bits of the CAR half of the cell.
  217. The rest of the CAR can be used for sub-type or other information.
  218. The CDR contains data of size long.
  219.  
  220. Inexact data types are subtypes of type tc16_flo.  If the sub-type is:
  221. 0 - a single precision float is contained in the CDR.
  222. 1 - CDR is a pointer to a malloced double.
  223. 3 - CDR is a pointer to a malloced pair of doubles.
  224.  
  225. To add a new type to scm:
  226.   [1] long tc16_???;
  227.     The type code which will be used to identify the new type.
  228.   [2] static smobfuns ???smob = {mark???,free???,print???,equalp???};
  229.     smobfuns is a structure composed of 4 functions:
  230.     smob.mark is a function of one argument of type SCM (the cell
  231.       to mark) and returns type SCM which will then be marked.  If
  232.       no further objects need to be marked then return an
  233.       immediate object such as BOOL_F.  2 functions are provided:
  234.         markcdr(ptr) which marks the current cell and
  235.       returns the CDR.
  236.         mark0(ptr) which marks the current cell and returns
  237.       BOOL_F.
  238.     smob.free is a function of one argument of type CELLPTR (the
  239.       cell to collected) and returns type sizet which is the
  240.       number of malloced bytes which were freed.  Smob.free should
  241.       free any malloced storage associated with this object.  The
  242.       function free0(ptr) is provided which does not free any
  243.       storage and returns 0.
  244.     smob.print is 0 or a function of 3 arguments.  The first, of
  245.       type SCM, is the smob object.  The second, of type SCM, is
  246.       the stream on which to write the result.  The third, of type
  247.       int, is 1 if the object should be WRITEn, 0 if it should be
  248.       DISPLAYed.  This function should return non-zero if it
  249.       printed, and zero otherwise (in which case a hexadecimal
  250.       number will be printed).
  251.     smob.equalp is 0 or a function of 2 SCM arguments.  Both of
  252.       these arguments will be of type tc16???.  This function
  253.       should return BOOL_T if the SMOBs are equal, BOOL_F if they
  254.       are not.  If smob.equalp is 0, EQUAL? will return BOOL_F if
  255.       they are not EQ?.
  256.   [3] tc16_??? = newsmob(&???smob);
  257.     Allocates the new type with the functions from [2].
  258.  
  259. Promises and macros in eval.c and arbiters in repl.c provide examples
  260. of SMOBs.  There are a maximum of 256 SMOBs.
  261.  
  262.                 PTOBs
  263.  
  264. PTOBs are similar to SMOBs but define new types of port to which SCM
  265. can read or write.  The following functions are defined in the ptobfuns:
  266.  
  267. typedef struct {
  268.     SCM (*mark)();
  269.     int (*free)();
  270.     int (*print)();
  271.     SCM (*equalp)();
  272.     int (*putc)();
  273.     int (*fputs)();
  274.     sizet (*fwrite)();
  275.     int (*fflush)();
  276.     int (*getc)();
  277.     int (*fclose)();
  278. } ptobfuns;
  279.  
  280. The "free" component to the structure takes a FILE * or other C
  281. construct as its argument, unlike "free" in in a SMOB which takes the
  282. whole SMOB cell.  Often, "free" and "fclose" can be the same function.
  283. See fptob and pipob in sys.c for examples of how to define PTOBs.
  284.  
  285.               GARBAGE COLLECTION
  286.  
  287. The garbage collector is in the latter half of sys.c.  Immediates
  288. always appear as parts of other objects, so they are not subject to
  289. explicit garbage collection.  There is a heap (composed of heap
  290. segments) in which all cells reside.  The storage for strings,
  291. vectors, continuations, doubles, complexes, and bignums is managed by
  292. malloc.  There is only one pointer to each malloc object from its
  293. type-header cell in the heap.  This allows malloc objects to be freed
  294. when the associated heap object is garbage collected.
  295.  
  296. To garbage collect, first certain protected objects are marked (such
  297. as symhash).  Then the stack (and marked continuations) are traversed.
  298. Each longword in the stack is tried to see if it is a valid SCM
  299. pointer into the heap.  If it is, the object itself and any objects it
  300. points to are marked.  If the stack is word rather than longword
  301. aligned (#define WORD_ALIGN), both alignments are tried.  This
  302. arrangement will occasionally mark an object which is no longer used.
  303. This has not been a problem in practice and the advantage of using the
  304. c-stack far outweighs it.
  305.  
  306. The heap is then swept.  If a type-header cell pointing to malloc
  307. space is collected the malloc object is then freed.  If the type
  308. header of smob is collected, the smob's free procedure is called to
  309. free its storage.
  310.  
  311.                   INTERRUPTS
  312.  
  313. If they are supported by the C implementation, init_signals() in scm.c
  314. sets up handlers for SIGINT and SIGALRM.  The low level handlers for
  315. SIGINT and SIGALRM are int_signal() and alrm_signal().  All of the
  316. signal handlers immediately reestablish themselves by a call to
  317. signal().
  318.  
  319. If an interrupt handler is defined when the interrupt is received, the
  320. code is interpreted.  If the code returns, execution resumes from
  321. where the interrupt happened.  Call-with-current-continuation allows
  322. the stack to be saved and restored.
  323.  
  324. SCM does not use any signal masking system calls.  These are not a
  325. portable feature.  However, code can run uninterrupted by use of the C
  326. macros DEFER_INTS and ALLOW_INTS.  DEFER_INTS sets the global variable
  327. ints_disabled to 1.  If an interrupt occurs during a time when
  328. ints_disabled is 1 one of the global variables sig_deferred or
  329. alrm_deferred is set to 1 and the handler returns.  When ALLOW_INTS is
  330. executed the deferred variables are checked and if set the appropriate
  331. handler is called.
  332.  
  333. DEFER_INTS can not be nested.  An ALLOW_INTS must happen before
  334. another DEFER_INTS can be done.  In order to check that this
  335. constraint is satisfied #define CAREFUL_INTS in scmfig.h.
  336.  
  337.                  CHANGING SCM
  338.  
  339. When writing C-code a precaution is recommended.  If your routine
  340. allocates a malloc type header from the heap make sure that a local
  341. SCM variable in your routine points to the type-header cell of the
  342. malloc object as long as you are using the malloced storage.  This
  343. will prevent the malloc object from being freed before you are done
  344. with it.
  345.  
  346. Also, if you maintain a static pointer to some (non-immediate) SCM
  347. object, you must either make your pointer be the value cell of a
  348. symbol (see errobj for an example) or make your pointer be one of the
  349. sys_protects (see symhash for an example).  The former method is
  350. prefered since it does not require any changes to the SCM distribution.
  351.  
  352. The macro ASSERT(_cond,_arg,_pos,_subr) signals an error if the
  353. expression (_cond) is 0.  _arg is the offending object, _subr is the
  354. string naming the subr, and _pos indicates the position or type of
  355. error.  _pos can be one of
  356.     `ARG1',
  357.     `ARG2',
  358.     `ARG3',
  359.     `ARG4',
  360.     `ARG5',
  361.     `WNA' (wrong number of args),
  362.     `OVFLOW'
  363.     `OUTOFRANGE'
  364.     `NALLOC'
  365.     `EXIT'
  366.     `HUP_SIGNAL'
  367.     `INT_SIGNAL'
  368.     `FPE_SIGNAL'
  369.     `BUS_SIGNAL'
  370.     `SEGV_SIGNAL'
  371.     `ALRM_SIGNAL'
  372.     or a C string (char *).
  373.  
  374. Error checking is not done by ASSERT if the flag RECKLESS
  375. is defined.  An error condition can still be signaled in this case
  376. with a call to wta(_arg,_pos,_subr).
  377.  
  378. To add a C routine to scm:
  379.   [1] choose the appropriate subr type from the type list.
  380.   [2] write the code and put into scm.c.
  381.   [3] add a make_subr call to init_scm.  Or put an entry into the
  382.       appropriate iproc structure.
  383.  
  384. To add a package of new procedures to scm (see crs.c for example):
  385.   [1] create a new C file (foo.c).
  386.   [2] at the front of foo.c put declarations for strings for your
  387.       procedure names.
  388.     static char s_twiddle_bits[]="twiddle-bits!";
  389.     static char s_bitsp[]="bits?";
  390.   [3] choose the appropriate subr types from the type list in code.doc.
  391.   [4] write the code for the procedures and put into foo.c
  392.   [5] create one iproc structure for each subr type used in foo.c
  393.     static iproc subr3s[]={
  394.         {s_twiddle-bits,twiddle-bits},
  395.         {s_bitsp,bitsp},
  396.         {0,0}};
  397.   [6] create an init_<name of file> routine at the end of the
  398.       file which calls init_iprocs with the correct type for each
  399.       of the iprocs created in step 5.
  400.     void init_foo()
  401.     {
  402.       init_iprocs(subr1s, tc7_subr_1);
  403.       init_iprocs(subr3s, tc7_subr_3);
  404.     }
  405.       If your package needs to have a "finalization" routine called to
  406.       free up storage, close files, etc, then also have a line in
  407.       init_foo like:
  408.     add_final(final_foo);
  409.       final_foo should be a (void) procedure of no arguments.
  410.       The finals will be called in opposite order from their definition.
  411.       The line:
  412.     add_feature("foo");
  413.       will append a symbol 'foo to the (list) value of *features*.
  414.   [7] put any scheme code which needs to be run as part of your
  415.       package into Ifoo.scm.
  416.   [8] put an IF into Init.scm which calls Ifoo.scm if your
  417.       package is included:
  418.     (if (defined? twiddle-bits!)
  419.         (load (in-vicinity (implementation-vicinity)
  420.                    "Ifoo"
  421.                    (scheme-file-suffix))))
  422.       or use (PROVIDED? 'FOO) instead of (DEFINED? TWIDDLE-BITS!) if
  423.       you have added the feature.
  424.   [9] put documentation of the new procedures into foo.doc
  425.   [10] add lines to your makefile to compile and link SCM with your
  426.        object file.  Add a init_foo\(\)\; to the INITS=... line at the
  427.        beginning of the makefile.
  428.  
  429. These steps should allow your package to be linked into SCM with a
  430. minimum of difficulty.  Your package should also work with dynamic
  431. linking if your SCM has this capability.
  432.  
  433. Special forms (new syntax) can be added to scm.
  434.   [1] define a new MAKISYM in scm.h and increment NUM_ISYMS.
  435.   [2] add a string with the new name in the corresponding place
  436.       in isymnames in repl.c.
  437.   [3] add case clause to ceval near i_quasiquote (in eval.c).
  438.  
  439. New syntax can now be added without recompiling SCM by the use of the
  440. PROCEDURE->SYNTAX, PROCEDURE->MACRO, PROCEDURE->MEMOIZING-MACRO, and
  441. DEFMACRO.  See MANUAL for details.
  442.  
  443. To use scm from another program call init_scm or run_scm as is done in
  444. main() in "scm.c".
  445.  
  446.                 CONTINUATIONS
  447.  
  448. The scm procedure call-with-current-continuation calls it's argument
  449. with an object of type `contin'.
  450.  
  451. If CHEAP_CONTINUATIONS is #defined (in "scmfig.h") the contin just
  452. contains a jmp_buf.  When the contin is applied, a longjmp of the
  453. jmp_buf is done.
  454.  
  455. If CHEAP_CONTINUATIONS is not #defined the contin contains the jmp_buf
  456. and a copy of the C stack between the call_cc stack frame and
  457. BASE(rootcont).  When the contin is applied:
  458.   [1] the stack is grown larger than the saved stack, if neccessary.
  459.   [2] the saved stack is copied back into it's original position.
  460.   [3] longjmp of the jmp_buf is called.
  461.  
  462. On systems with nonlinear stack disciplines (multiple stacks or
  463. non-contiguous stack frames) copying the stack will not work properly.
  464. These systems need to #define CHEAP_CONTINUATIONS in "scmfig.h".
  465.  
  466.                    INTEGERS
  467.  
  468. Scm has 30 bit immediate signed numbers called INUMs.  An INUM instead
  469. of a pointer to a cell is flagged by a `1' in the second to low order
  470. bit position.  Since cells are always 8 byte aligned a pointer to a
  471. cell has the low order 3 bits `0'.  The high order 30 bits are used
  472. for the integer's value.
  473.  
  474. Computations on INUMs are performed by converting the arguments to C
  475. integers (by a shift), operating on the integers, and converting the
  476. result to an INUM.  The result is checked for overflow by converting
  477. back to integer and checking the reverse operation.
  478.  
  479. The shifts used for conversion need to be signed shifts.  If the C
  480. implementation does not support signed right shift this fact is
  481. detected in a #if statement in scmfig.h and a signed right shift (SRS)
  482. is constructed in terms of unsigned right shift.
  483.  
  484. Scm also has large precision integers called bignums.  They are stored
  485. as sign-magnitude with the sign occuring in the type code of the SMOBs
  486. bigpos and bigneg.  The magnitude is stored as a malloced array of
  487. type BIGDIG which must be an unsigned integral type with size smaller
  488. than long.  BIGRAD is the radix associated with BIGDIG.
  489.  
  490.                   EVALUATION
  491.  
  492. Top level symbol values are stored in the symhash table.  Symhash is
  493. an array of lists of ISYMs and pairs of symbols and values.
  494.  
  495. Whenever a symbol's value is found in the local environment the
  496. pointer to the symbol in the code is replaced with an immediate object
  497. (ILOC) which specifies how many environment frames down and how far in
  498. to go for the value.  When this immediate object is subsequently
  499. encountered, the value can be retrieved quickly.
  500.  
  501. Pointers to symbols not defined in local environments are changed to
  502. one plus the value cell address in symhash.  This incremented pointer
  503. is called a GLOC.  The low order bit is normally reserved for GCmark;
  504. But, since references to variables in the code always occur in the CAR
  505. position and the GCmark is in the CDR, there is no conflict.
  506.  
  507. Number of argument checks for closures are made only when the function
  508. position (whose value is the closure) of a combination is not an ILOC
  509. or GLOC.  When the function position of a combination is a symbol it
  510. will be checked only the first time it is evaluated because it will
  511. then be replaced with an ILOC or GLOC.
  512.  
  513.              IMPROVEMENTS TO MAKE
  514.  
  515. If an open fails because there are no unused file handles, GC should
  516. be done so that file handles which are no longer used can be
  517. collected.
  518.  
  519. Copying all of the stack is wasteful of storage.  Any time a
  520. call-with-current-continuation is called the stack could be re-rooted
  521. with a frame which calls the contin just created.  This in combination
  522. with checking stack depth could also be used to allow stacks deeper
  523. than 64K on the IBM PC.
  524.  
  525. If the symhash array is specially marked in garbage collection,
  526. msymbols with value #[undefined] which have no pointers to them can be
  527. collected.  In Maclisp this was called GCTWA.
  528.  
  529. Compaction could be done to malloced objects by freeing and reallocing
  530. all the malloc objects encountered in a scan of the heap.  Whether
  531. compactions would actually occur is system depenedent.
  532.  
  533. lgcd() needs to generate at most one bignum.
  534.  
  535. divide() could use shifts instead of multiply and divide when scaling.
  536.  
  537. (get-universal-time) should return the time since Midnight Jan 1, 1900
  538. GMT when BIGDIG is #defined.
  539.  
  540.                DYNAMIC LINKING
  541.  
  542. This note should help with porting to Windows NT and finishing the
  543. port for dynamic linking under VMS.
  544. ================================================================
  545. Return-Path: <gjc@newjak.mitech.com>
  546. Date: Fri,  3 Sep 93 10:38:18 EDT
  547. From: gjc@newjak.mitech.com
  548. To: jaffer@ai.mit.edu
  549. Subject: dynamic linking.
  550.  
  551.                                     George Carrette
  552.                                     GJC@MITECH.COM
  553.                                     3-SEP-1993
  554.  
  555.  
  556. Dear Aubrey:
  557.  
  558. On the subject of shared libraries and dynamic linking for VMS and WINDOWS NT,
  559. and SunOs. Let us take VMS first.
  560.  
  561. (1) Say you have this main.c program:
  562.  
  563. main()
  564. {init_lisp();
  565.  lisp_repl();}
  566.  
  567. (2) and you have your lisp in files repl.c,gc.c,eval.c
  568.     and there are some toplevel non-static variables
  569.     in use called the_heap,the_environment, and some read-only
  570.     toplevel structures, such as the_subr_table.
  571.  
  572.   $ LINK/SHARE=LISPRTL.EXE/DEBUG REPL.OBJ,GC.OBJ,EVAL.OBJ,LISPRTL.OPT/OPT
  573.  
  574. (3) where LISPRTL.OPT must contain at least this:
  575.  
  576. SYS$LIBRARY:VAXCRTL/SHARE
  577. UNIVERSAL=init_lisp
  578. UNIVERSAL=lisp_repl
  579. PSECT_ATTR=the_subr_table,SHR,NOWRT,LCL
  580. PSECT_ATTR=the_heap,NOSHR,LCL
  581. PSECT_ATTR=the_environment,NOSHR,LCL
  582.  
  583. Notice: The "psect" (Program Section) attributes.
  584.  LCL means to keep the name local to the shared library. You almost always want
  585.  to do that for a good clean library.
  586.  SHR,NOWRT means shared-read-only. Which is the default for code, and is also
  587.  good for efficiency of some data structures.
  588.  NOSHR,LCL is what you want for everything else.
  589.  
  590. Note: If you do not have a handy list of all these toplevel variables,
  591. do not dispair. Just do your link with the /MAP=LISPRTL.MAP/FULL
  592. and then search the map file,
  593.  
  594.  $SEARCH/OUT=LISPRTL.LOSERS LISPRTL.MAP  ",  SHR,NOEXE,  RD,  WRT"
  595.  
  596. And use an emacs keyboard macro to muck the result into the proper form.
  597. Of course only the programmer can tell if things can be made read-only.
  598. I have a DCL command procedure to do this if you want it.
  599.  
  600.  
  601. (4) Now MAIN.EXE would be linked thusly:
  602.  
  603.    $ DEFINE LISPRTL USER$DISK:[JAFFER]LISPRTL.EXE
  604.  
  605.    $LINK MAIN.OBJ,SYS$INPUT:/OPT
  606.     SYS$LIBRARY:VAXCRTL/SHARE
  607.     LISPRTL/SHARE
  608.  
  609. Note the definition of the LISPRTL logical name. Without such a definition
  610. you will need to copy LISPRTL.EXE over to SYS$SHARE: (aka SYS$LIBRARY:)
  611. in order to invoke the main program once it is linked.
  612.  
  613. (5) Now say you have a file of optional subrs. MYSUBRS.C
  614.     And there is a routine INIT_MYSUBRS that must be called before using it.
  615.  
  616.    $ CC MYSUBRS.C
  617.    $ LINK/SHARE=MYSUBRS.EXE MYSUBRS.OBJ,SYS$INPUT:/OPT
  618.      SYS$LIBRARY:VAXCRTL/SHARE
  619.      LISPRTL/SHARE
  620.      UNIVERSAL=INIT_MYSUBRS
  621.  
  622.    Ok. Another hint is that you can avoid having to add the PSECT
  623.    declaration of NOSHR,LCL by declaring variables 'status' in the
  624.    C language source. That works great for most things.
  625.  
  626. (6) Then the dynamic loader would have to do this:
  627.  
  628.     {void (*init_fcn)();
  629.      long retval;
  630.      retval = lib$find_image_symbol("MYSUBRS","INIT_MYSUBRS",&init_fcn,
  631.                                     "SYS$DISK:[].EXE");
  632.      if (retval != SS$_NORMAL) error(...);
  633.      (*init_fcn)();}
  634.  
  635. But of course all string arguments must be (struct dsc$descriptor *)
  636. and the last argument is optional if MYSUBRS is defined as a logical
  637. name or if MYSUBRS.EXE has been copied over to SYS$SHARE.
  638. The other consideration is that you will want to turn off CONTROL-C
  639. or other interrupt handling while you are inside most lib$ calls.
  640.  
  641. As far as the generation of all the UNIVERSAL=... declarations.
  642. Well, you could do well to have that automatically generated from
  643. the public LISPRTL.H file, of course.
  644.  
  645. VMS has a good manual called the "Guide to Writing Modular Procedures"
  646. or something like that, which covers this whole area rather well,
  647. and also talks about advanced techniques, such as a way to declare
  648. a program section with a pointer to a procedure that will be automatically
  649. invoked whenever any shared image is dynamically activated. Also,
  650. how to set up a handler for normal or abnormal program exit so that
  651. you can clean up side effects (such as opening a database).
  652. But for use with LISPRTL you probably don't need that hair.
  653.  
  654. One fancier option that is useful under VMS for LISPLIB.EXE is to
  655. define all your exported procedures through an CALL VECTOR instead
  656. of having them just be pointers into random places in the image,
  657. which is what you get by using UNIVERSAL.
  658.  
  659. If you set up the call vector thing correctly it will allow you to
  660. modify and relink LISPLIB.EXE without having to relink programs
  661. that have been linked against it.
  662.  
  663. WINDOWS NT:
  664.  
  665. The Software Developers Kit has a sample called SIMPLDLL.
  666. Here is the gist of it, following along the lines of the VMS description
  667. above (contents of a makefile for the SDK NMAKE)
  668.  
  669. LISPLIB.exp:
  670. LISPLIB.lib: LISPLIB.def
  671.     $(implib) -machine:$(CPU) -def:LISPLIB.def -out:LISPLIB.lib
  672.  
  673. LISPLIB.DLL : $(LISPLIB_OBJS) LISPLIB.EXP
  674.     $(link) $(linkdebug)              \
  675.     -dll                 \
  676.     -out:LISPLIB.DLL     \
  677.     LISPLIB.EXP $(LISPLIB_OBJS) $(conlibsdll)
  678.  
  679. The LISPDEF.DEF file has this:
  680.  
  681.  LIBRARY lisplib
  682.  EXPORT
  683.   init_lisp
  684.   init_repl
  685.  
  686. And MAIN.EXE using:
  687.  
  688.  CLINK = $(link) $(ldebug) $(conflags) -out:$*.exe $** $(conlibsdll)
  689.  
  690.  MAIN.EXE : MAIN.OBJ LISPLIB.LIB
  691.   $(CLINK)
  692.  
  693. And MYSUBRS.DLL is produced using:
  694.  
  695. mysubrs.exp:
  696. mysubrs.lib: mysubrs.def
  697.     $(implib) -machine:$(CPU) -def:MYSUBRS.def -out:MYSUBRS.lib
  698.  
  699. mysubrs.dll : mysubrs.obj mysubrs.exp mysubrs.lib
  700.     $(link) $(linkdebug) \
  701.     -dll                 \
  702.     -out:mysubrs.dll     \
  703.     MYSUBRS.OBJ MYSUBRS.EXP LISPLIB.LIB $(conlibsdll)
  704.  
  705. Where MYSUBRS.DEF has
  706.  
  707.  LIBRARY mysubrs
  708.  EXPORT
  709.   INIT_MYSUBRS
  710.  
  711. And the dynamic loader looks something like this, calling
  712. the two procedures LoadLibrary and GetProcAddress.
  713.  
  714. LISP share_image_load(LISP fname)
  715. {long iflag;
  716.  LISP retval,(*fcn)(void);
  717.  HANDLE hLib;
  718.  DWORD err;
  719.  char *libname,fcnname[64];
  720.  iflag = nointerrupt(1);
  721.  libname = c_string(fname);
  722.  _snprintf(fcnname,sizeof(fcnname),"INIT_%s",libname);
  723.  if (!(hLib = LoadLibrary(libname)))
  724.    {err = GetLastError();
  725.     retval = list2(fname,LSPNUM(err));
  726.     serror1("library failed to load",retval);}
  727.  if (!(fcn = (LISP (*)(void)) GetProcAddress(hLib,fcnname)))
  728.    {err = GetLastError();
  729.     retval = list2(fname,LSPNUM(err));
  730.     serror1("could not find library init procedure",retval);}
  731.  retval = (*fcn)();
  732.  nointerrupt(iflag);
  733.  return(retval);}
  734.  
  735. Note: in VMS the linker and dynamic loader is case sensitive,
  736.       but all the language compilers, including C, will by default 
  737.       upper-case external symbols for use by the linker, although the
  738.       debugger gets its own symbols and case sensitivity is language
  739.       mode dependant. In Windows NT things are case sensitive generally
  740.       except for file and device names, which are case canonicalizing
  741.       like in the Symbolics filesystem.
  742.  
  743. Also: All this WINDOWS NT stuff will work in MS-DOS MS-Windows 3.1
  744.       too, by a method of compiling and linking under Windows NT,
  745.       and then copying various files over to MS-DOS/WINDOWS.
  746.  
  747. SUN-OS.
  748.  
  749. I haven't tried any of this yet. The loading looks simple enough from
  750. the man command, but I do not know of the complexity or restrictions of
  751. creating the shared libraries.
  752.  
  753. man dlopen
  754.  
  755. DLOPEN(3X)       MISCELLANEOUS LIBRARY FUNCTIONS       DLOPEN(3X)
  756.  
  757. NAME
  758.      dlopen, dlsym, dlerror, dlclose - simple programmatic inter-
  759.      face to the dynamic linker
  760.  
  761. If you decide to employ this technology on SUN please let send me
  762. a summary so I can update this note.
  763.  
  764. Obviously you want to hack your lisp compiler to automatically generate
  765. all the required linking and options files for the particular operating
  766. systems you are going to be using.
  767.