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