home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / lisp211.zip / PC-LISP.DOC < prev    next >
Text File  |  1986-05-16  |  136KB  |  2,929 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.           
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.                    A GUIDE TO THE PC-LISP INTERPRETER  (V2.11)  
  18.                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  19.  
  20.                              By Peter Ashwood-Smith  
  21.                              ~~~~~~~~~~~~~~~~~~~~~~ 
  22.  
  23.                              University of Toronto,     
  24.                              ~~~~~~~~~~~~~~~~~~~~~
  25.  
  26.                                 Ontario, Canada.                
  27.                                 ~~~~~~~~~~~~~~~
  28.              
  29.  
  30.                                  
  31.                                  
  32.              With thanks to Brian Robertson for the math functions 
  33.  
  34.  
  35.                             
  36.                                   May 15 1986, 
  37.  
  38.  
  39.                                   for Guylaine
  40.  
  41.  
  42.                         email: petera!utcsri or br!utcsri
  43.  
  44.                            mail:  Peter Ashwood-Smith
  45.                             #811, 120 St. Patrick St. 
  46.                                 Toronto, Ontario,
  47.                                      Canada,
  48.                                     M5T-2X7.
  49.  
  50.                              phone: (416) 593-7574.
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.                                         1
  62.  
  63.  
  64.  
  65.              INTRODUCTION
  66.              ~~~~~~~~~~~~
  67.              PC-LISP  is  a small implementation of LISP for  ANY  MS-DOS 
  68.         machine.  While  small,  it  is capable of running a pretty  good 
  69.         subset  of Franz LISP.  The functions are supposed to perform  in 
  70.         the same way as Franz with a few exceptions made for effeciencies 
  71.         sake. Version 2.11 has the following features.
  72.              
  73.                   - Types fixnum, flonum, list, port, symbol, string and 
  74.                     hunk, lambda, nlambda, macro and lexpr.
  75.              
  76.                   - Read Macros including splicing read macros.
  77.  
  78.                   - Full garbage collection of ALL types.     
  79.  
  80.                   - Compacting relocating heap management.     
  81.  
  82.                   - Access to some MSDOS BIOS graphics routines.
  83.             
  84.                   - Over 150 built in functions, sufficient to allow you 
  85.                     to implement many other Franz functions in PC-LISP.
  86.  
  87.                   - Stack overflow detection & full error checking
  88.                     on all calls, tracing of user defined functions,
  89.                     and dumping of stack via (showstack).
  90.  
  91.                   - One level of break from which bindings at point
  92.                     of error can be seen.
  93.  
  94.                   - Access to as much (non extended) memory as you've 
  95.                     got and control over how this memory is spread 
  96.                     among the various data types.
  97.                        
  98.                   - Will run on 256K PC/AT(w/woEGA)/XT and just about any
  99.                     other MS-DOS machine. It is not hardware dependent. 
  100.              
  101.              This  program is Shareware.  This means that it you are free 
  102.         to  distribute it or post it to any BBS that you want.  The  more 
  103.         the better. The idea is that if you feel you like the program and 
  104.         are  pleased with it then send us $15 to help  cover  development 
  105.         costs.  Source  code for this program is available upon  request. 
  106.         You  must  however send me 3 blank diskettes and about  $1.50  to 
  107.         cover  first class postage.  The program can be compiled with any 
  108.         good  C compiler that has a pretty complete libc.  In  particular 
  109.         the  program  will  compile with almost no changes on  most  Unix 
  110.         systems.  A source code guide will probably be included with  the 
  111.         source  if  it  is  finished at the time I  receive  your  source 
  112.         request. Please do not request source unless you plan to use it.
  113.                                       
  114.              Thanks to Brian Robertson also of the University of  Toronto 
  115.         Department  of  Computer Science for the math functions  that  he 
  116.         wrote  for the otherwise excellent Lattice C V2.03 compiler which 
  117.         did not originally come with a math library.
  118.  
  119.  
  120.  
  121.  
  122.                                         2
  123.  
  124.  
  125.  
  126.              A WARNING
  127.              ~~~~~~~~~
  128.              As I mentioned previously this program was compiled with the 
  129.         Lattice  C compiler,  as such the program contains code to  which 
  130.         Lattice Inc.  holds a copyright.  If you sell it I can  only  get 
  131.         angry  but  Lattice could take you to court.  And,  as  with  all 
  132.         software, you  use  it  at your own risk.  I  will  not  be  held 
  133.         responsible  for  loss of any kind as a result of the correct  or 
  134.         incorrect  use  of  this program.  
  135.                   
  136.              A NOTE
  137.              ~~~~~~
  138.              The  rest  of this manual assumes some  knowledge  of  LISP, 
  139.         MSDOS and a little programming experience. If you are new to LISP 
  140.         or programming in general you should work your way through a book 
  141.         on  LISP such as LISPcraft by Robert Wilensky.  You can  use  the 
  142.         interpreter  to  run  almost all of the examples in  the  earlier 
  143.         chapters.  I  obviously  cannot attempt to teach  you  LISP  here 
  144.         because  it  would require many hundreds of pages and  there  are 
  145.         much better books on the subject than I could write.  Also, there  
  146.         are other good books on Franz LISP besides LISPcraft. I recommend 
  147.         LISPcraft because it is the book I happen to use.
  148.  
  149.              IF YOU WANT TO TRY PC-LISP RIGHT NOW
  150.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  151.              Make  sure  that PC-LISP.EXE and PC-LISP.L are in  the  same 
  152.         directory.  Then type PC-LISP from the DOS prompt. Wait until you 
  153.         get the "-->" prompt.  If your machine has some sort of  graphics 
  154.         capability you can try the graphics demo as follows.  Type "(load 
  155.         'turtle)"  without  the "'s.  Wait until you see the "t" and  the 
  156.         prompt "-->" again,  then type "(GraphicsDemo)".  You should  see 
  157.         some  Logo  like squirals etc.  If you do not have  any  graphics 
  158.         capability  try  "(load  'queens)" or "(load  'hanoi)"  and  then 
  159.         (queens  5)  or  (hanoi 5) respectively.  For  a  more  extensive 
  160.         example turn to the last couple of chapters in LISPcraft and look 
  161.         at the deductive data base retriever. Type (load 'match) and look 
  162.         at  the  match.l documentation.  You can then play with  all  the 
  163.         funcions mentioned in LISPcraft. 
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.                                         3
  184.  
  185.  
  186.  
  187.              EXAMPLE LOAD FILES AND THE PC-LISP.L FILE
  188.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  189.              Included  with  PC-LISP  (V2.11) are a number of  .L  files. 
  190.         These include: PC-LISP.L, MATCH.L, TURTLE.L, DRAGON.L and perhaps 
  191.         a few others. These are as follows.
  192.  
  193.              PC-LISP.L
  194.              ~~~~~~~~~
  195.              A  file  of extra functions to help fill the gap between  PC 
  196.         and Franz LISP. This file defines the pretty print function and a 
  197.         number  of macros etc.  It will be automatically loaded from  the 
  198.         current  directory  or from the directory whose path  is  set  in 
  199.         LISP%LIB when PC-LISP is executed. The functions in this file are 
  200.         NOT documented in this manual, look instead at a Franz manual.
  201.  
  202.              MATCH.L
  203.              ~~~~~~~
  204.              A  small programming example taken from the last 2  chapters 
  205.         of  LISPcraft.  It  is a deductive data base retriever.  This  is 
  206.         along the lines of PROLOG. Very few changes were necessary to get 
  207.         this to run under PC-LISP.
  208.  
  209.              TURTLE.L
  210.              ~~~~~~~~ 
  211.              Turtle   Graphics  primitives  and  a  small   demonstration 
  212.         program.  To  run the demo you call the  function  "GraphicsDemo" 
  213.         without  any  parameters.  This should run albeit slowly on  just 
  214.         about  every MS-DOS machine.  Note that the video functions  that 
  215.         are  still  experimental so use them for fun but  don't  rely  on 
  216.         them.  These  primitives  look  at the global variable  !Mode  to 
  217.         decide what resolution to use.  If you have mode 8 (640X400)  you 
  218.         should use it as the lines are much sharper. Turtle graphic modes 
  219.         can be set by typing (setq !Mode -number-).
  220.  
  221.              DRAGON.L
  222.              ~~~~~~~~
  223.              A  very  slow  example  of a  dragon  curve.  This  one  was 
  224.         translated from a FORTH example in the April/86 BYTE.  It takes a 
  225.         long  time on my 8Mhz 80186 machine so it will probably run for a 
  226.         few hours on a PC or AT.  I usually let it run for about 1/2 hour 
  227.         before  getting tired of waiting.  To run it you just type  (load 
  228.         'dragon)  then  type  (DragonCurve 16).  If  you  have  a  higher 
  229.         resolution  machine  like a Tandy 2000 then type (setq  !Mode  8) 
  230.         before  you  run  it and it will look sharper at  this  (640x400) 
  231.         resolution.
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.                                         4
  245.  
  246.  
  247.  
  248.              USERS GUIDE
  249.              ~~~~~~~~~~~
  250.              The  PC-LISP program is self contained.  To run it just type 
  251.         the command PC-LISP or whatever you called it.  When it starts it 
  252.         will start grabbing memory in chunks of 16K each.  By default PC-
  253.         LISP  will  grab  as much memory as possible but by  setting  the 
  254.         LISP%MEM  environment variable to an integer >= 3,  PC-LISP  will 
  255.         stop when this many 16K blocks have been allocated. These will be 
  256.         distributed to the three basic data types in percentages that you 
  257.         can specify via 2 environment variables.  The default is that  5% 
  258.         of  the  memory will be allocated for alpha atoms.   5%  will  be 
  259.         allocated  for heap space,  and the rest for  cons,port,  fixnum, 
  260.         string, flonum  and hunk cell types.If you  set  the  environment 
  261.         variables  LISP%HEAP and LISP%ALPH to an integer between 1 and 85 
  262.         these  will  become the new percentages for the  heap  and  alpha 
  263.         respectively,  the rest going to cons,  port,flonum, fixnum, hunk 
  264.         and string cells.  Note that the percentages are only accurate to 
  265.         the  nearest 16K boundary.  In other words the set of 16K  blocks 
  266.         are  divided among the three types as closely to the  percentages 
  267.         that you specify as possible. If the percentages that you specify 
  268.         are  unreasonable  PC-LISP  will  stop  with  an  error  message, 
  269.         otherwise  PC-LISP  will  continue by giving back  a  very  small 
  270.         amount  of memory for use by the standard I/O routines.  You  can 
  271.         alter  the amount given back by setting the environment  variable 
  272.         LISP%KEEP  to  the  amount  you want to  give  back  (See  memory 
  273.         management).   PC-LISP  will then print the banner  message,  the 
  274.         total  memory  available  and the  actual  percentages  that  are 
  275.         allocated to each object.  Before processing the command line PC-
  276.         LISP  will look for a file called PC-LISP.L first in the  current 
  277.         directory,  next  in  the library directories  specified  in  the 
  278.         LISP%LIB  environment variable as per the (load) function.  If it 
  279.         finds  PC-LISP.L it will be loaded.  Next PC-LISP will  read  the 
  280.         parameters on the command line. The usage is as follows.
  281.                                     *
  282.              PC-LISP [=nnnn]  [file]
  283.              
  284.              The  optional parameter =nnnn is the Lattice set stack  size 
  285.         option.  It  is preset to 32K and cannot be set smaller.  You may 
  286.         set it larger up to 64K if you wish.  A 32K stack gives you about 
  287.         466 recursive calls,  50K = 731 calls, 60K = 878 calls, and 64K = 
  288.         936  calls.  8086 machines do not allow effecient stacks > 64K.             
  289.                   
  290.              The files on the command line are processed one by one. This 
  291.         consists  of loading each file as per the (load)  function.  This 
  292.         means  that PC-LISP will look in the current directory for  file, 
  293.         then  in file.l,  then in the directories given in  the  LISP%LIB 
  294.         environment variable,  when found the file is read and every list 
  295.         is evaluated.  The results are NOT echoed to the console. Finally 
  296.         when  all  the files have been processed you will  find  yourself 
  297.         with the LISP top level prompt '-->'.  Typing control-Z and ENTER 
  298.         (MS-DOS end of file) when you see the '-->' prompt will cause PC-
  299.         LISP  to exit to whatever program called it.   If an error occurs 
  300.         you will see the prompt 'er>'. For more info see the 'TERMINATION 
  301.         OF   EVALUATION'  section  of  this  manual  and   the   commands 
  302.         (showstack), (trace), and (untrace).
  303.  
  304.  
  305.                                         5
  306.  
  307.  
  308.  
  309.              SYNTAX OR WHAT IS A LIST ANYWAY?
  310.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  311.  
  312.              You  will  now be in the LISP interpreter and can  start  to 
  313.         play  with  it.  Basically  it is expecting you  to  type  an  S-
  314.         expression whose value it will evaluate and return.   Formally an 
  315.         S-expression can be defined with a B.N.F Grammar where + means at 
  316.         least one occurence of and, * means any number of occurences of.
  317.  
  318.  
  319.              <S-expression> ::= <fixnum> | <flonum> | <string> | <symbol>
  320.                              |  '(' <elements> ')'
  321.  
  322.                                                  +
  323.              <elements>     ::=  (<S-expression>)  '.' <S-expression>
  324.                                                  *
  325.                              |   (<S-expression>)
  326.  
  327.  
  328.              Where characters whose ascii values are in 0..31 are ignored
  329.         and  have no effect other than delimiting other input items. Also
  330.         characters  between  ;  and the end of a line are ignored in  the 
  331.         same way as the white space characters just described,  these are 
  332.         used to introduce comments into your LISP programs.
  333.  
  334.              The the basic list elements <fixnum>, <flonum>, <string> and 
  335.         <symbol> are defined as follows.    
  336.  
  337.              A <fixnum> is a sign + , - or none followed by a sequence of 
  338.         digits 0..9. If the sequence of digits represents a fixnum larger 
  339.         than  can  be  stored in a 32 bit integer it is taken to  be  the 
  340.         nearest  <flonum>.  A <fixnum> can always be spotted when  it  is 
  341.         printed by the lack of a radix point.  Examples are:  2, +2,  -2, 
  342.         and -333333 .
  343.  
  344.              A  <flonum> is a sign + , - or none followed by digits  0..9 
  345.         which  may be followed by a radix point and more digits 0..9 this 
  346.         may  optionally be followed by an exponent specifier 'e'  or  'E' 
  347.         which  may  optionally  be followed by a  sign  +  ,  - or  none, 
  348.         optionally  followed by the exponent digits 0..9.  A <flonum> can 
  349.         always  be spotted when it is printed by the presence of either a 
  350.         radix point, or the exponent specifier 'e'.  Examples :  2.0,  
  351.         -2.0, +2.0, -2e10, -2e+20, -4.0E-13, 2E, -2E
  352.              
  353.              A <string> is a " followed by up to 254 characters  followed 
  354.         by  a  terminating " or |.  If the character \ is present in  the 
  355.         string and the following character is one of t,b,n,r or f the two 
  356.         characters are replaced by a tab,  backspace,  newline,  carriage 
  357.         return or form feed respectively. If the \ is not followed by one 
  358.         of  the previously mentioned special  characters,  the  following 
  359.         character  is  used to subtitute the \ and itself in the  string. 
  360.         The  \ is called the escape character and allows you to  put  non 
  361.         printing formatting characters into a string.  It also allows you 
  362.         to put a " or | into a string which you could not 
  363.         otherwise do. Examples: "abcd", "a\tb", "a\"b", "a\|b"
  364.  
  365.  
  366.                                         6
  367.  
  368.  
  369.  
  370.              SYNTAX OR WHAT IS A LIST ANYWAY? CONT'D
  371.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  372.             A  <symbol> is either a string delimited with |'s instead  of 
  373.         the "'s,  or a sequence of characters none of which are spaces or 
  374.         non printing characters with ascii values < 32 or > 126.  If  the 
  375.         symbol  is delimited with |'s the escape character \ may be  used 
  376.         in  exactly  the same manner as with a string and all  characters 
  377.         may be placed between the | delimiters with the exception of " or 
  378.         | which must be preceeded by the escape character if they are  to 
  379.         be  literally  included  in  the symbol.  If the  symbol  is  not 
  380.         delimited  by |'s then the characters must be in a sequence  that 
  381.         follows the following rules. The characters ( ) [ ] " | and ; are 
  382.         reserved  and will cause termination of the symbol.  The  set  of 
  383.         characters  that  are  skipped as white space (those  with  ascii 
  384.         values in the range 0..31) are termed white space characters. The 
  385.         set  of  characters  that have been defined as  read  macros  are 
  386.         termed macro trigger characters.  Only the ' char is initially  a 
  387.         read  macro trigger character.  The special characters are all of 
  388.         these above character classes.  Using these definitions, a symbol 
  389.         can   either start with a character in 0..9 or a character not in 
  390.         0..9.  If  the  character is not in 0..9 then the  the  following 
  391.         characters  can  be  chosen  from  among  all  but  the   special 
  392.         characters.  If the first character in the symbol is in 0..9 then 
  393.         the  last  character  must be chosen from among the  set  of  all 
  394.         characters  that  are neither special nor in 0..9.  A symbol  may 
  395.         be composed of up to 254 characters all of which are significant.  
  396.         Here  are a few examples:  a a1 1a 1- 1234abc #hi#  !hi%  An_ATOM 
  397.         |ab\nc| junk.l ThisIsOneRatherLargeAtomThatDemonstratesLength.
  398.  
  399.              An  atomic  S-expression is just one of  a  fixnum,  flonum, 
  400.         string and symbol.  The only other type of S-expression is a list 
  401.         S-expression.
  402.  
  403.              In order to describe what a list S-expression is you need to 
  404.         know some lisp terminology for the parts of a list.  First a list 
  405.         consists  of two parts,  the first element of the list is  called 
  406.         the  car of the list and the rest of the elements in the list  is 
  407.         called the cdr of the list.  Don't blame me I did not pick  these 
  408.         names,  they come from register names on an old IBM machine.  For 
  409.         example  the  list (a b c) has car a and cdr (b c).  Now that  we 
  410.         know  the  two parts of a list,  we need to know how to  build  a 
  411.         list.  A  list  is built with a cons  or  constructor  cell.  The 
  412.         constructor cell has two parts to it, the first is the car of the 
  413.         list  and the second is the cdr of the list.  Hence one cons cell 
  414.         describes one list.  Its car part describes the first element  in 
  415.         the list,  and its cdr part describes the list of the rest of the 
  416.         elements in the list.  For the example list (a b c), the internal 
  417.         structure may look something like this,  where a [ | ] represents 
  418.         a cons cell *--> is a pointer, / is a nil pointer.
  419.  
  420.                   [*|*] ---> [*|*] ---> [*|/]
  421.                    |          |          | 
  422.                    v          v          v          
  423.                    a          b          c
  424.  
  425.  
  426.  
  427.                                         7
  428.  
  429.  
  430.  
  431.              SYNTAX OR WHAT IS A LIST ANYWAY? CONT'D
  432.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  433.  
  434.              Here  is  an example of a simple nested list  which  can  be 
  435.         input as :  (a (b c) nil d) and which results in a structure like 
  436.         this:
  437.  
  438.                   [*|*] ---> [*|*] ---> [/|*] ---> [*|/]
  439.                    |          |                     |
  440.                    v          v                     v
  441.                    a         [*|*] ---> [*|*]       d
  442.                               |          |
  443.                               v          v
  444.                               b          c
  445.                   
  446.              The  dot  '.' can be used to separate the last element in  a 
  447.         list  from  the  others  in  the  list.   When  this  occurs  the 
  448.         constructed  list will have a slightly different last  cons  cell 
  449.         second field. Rather than pointing to another cons cell whose car 
  450.         points to the last element, this field will point directly to the 
  451.         last element. For example inputting (a . b) creates the following 
  452.         list structure, which will also print as (a . b). 
  453.  
  454.                   [*|*] 
  455.                    | |
  456.                    v v
  457.                    a b 
  458.  
  459.              However  if the last element in the list is another list and 
  460.         we preceed it by a dot,  the list is spliced into the upper  list 
  461.         as  if the last element were not really a list.  For example if I 
  462.         were to input (a .  (b .  (c))) the following structure which  is 
  463.         identical to that constructed by (a b c) would be built.  It will 
  464.         also print as (a b c).
  465.  
  466.                   [*|*] ---> [*|*] ---> [*|/]
  467.                    |          |          | 
  468.                    v          v          v          
  469.                    a          b          c
  470.                   
  471.  
  472.              The dotted pair is not normally used except when you wish to 
  473.         save  storage.  An  example  might be when you create a  list  of 
  474.         symbols  and  their associated values.  In this case  making  the 
  475.         symbol  and its associated value a dotted pair will save  1  cons 
  476.         cell or about 10 bytes per symbol value pair. 
  477.  
  478.              Finally, I have shown these structures with symbol elements. 
  479.         You  can  have  absolutly  any type as  an  element  of  a  list, 
  480.         including of course a list as shown in the second example above. 
  481.         This  is a very quick look at list structure and you should  look 
  482.         at LISPcraft for more details.
  483.  
  484.  
  485.  
  486.  
  487.  
  488.                                         8
  489.  
  490.  
  491.  
  492.              META SYNTAX
  493.              ~~~~~~~~~~~
  494.              Following  are  some syntactic properties  that  are  really 
  495.         above the level of the syntax of a simple S-expression. Thus they 
  496.         are  called  meta syntax conventions.  I consider Meta syntax  as 
  497.         anything  that does not conform to the B.N.F  grammar  previously 
  498.         given. These extensions to the syntax of S-expressions consist of 
  499.         any  extra  syntax intdoduced by built in or  user  defined  read 
  500.         macros  and the replacement of multiple parenthesis which  occurs 
  501.         when a single super parenthesis is used.
  502.  
  503.              PC-LISP supplies one built in read macro called 'quote'  and 
  504.         written  using  the little ' symbol.  This read macro is  just  a 
  505.         short hand way of writing the list (quote S).  Where S is the  S-
  506.         expression that follows the ' in the input stream.  Here are some 
  507.         examples of the simple conversion that the read macro performs on 
  508.         your input.
  509.  
  510.              'apples        -- goes to -->    (quote apples)
  511.              '|too late|                      (quote |too late|)
  512.              '(1 2 3)                         (quote (1 2 3))
  513.              ''a                              (quote (quote a))
  514.              '"hi"                            (quote "hi")
  515.              
  516.              If  you  are new to LISP you will soon see just  how  useful  
  517.         this little read macro is when you start typing  expressions.  It 
  518.         reduces  the amount of typing you must do,  reduces the amount of 
  519.         list  nesting you have to look at and draws attention to data  in 
  520.         your expressions.
  521.  
  522.              User  defined  read  macros  are  also  provided.   See  the 
  523.         (setsyntax)  function  in the next section  of  the  manual.  The 
  524.         backquote   macro  together  with  comma  (,)  and  at  (@)   are 
  525.         implemented  in the PC-LISP.L load file,  but are not  documented 
  526.         here. Again, see LISPcraft for a discussion of these read macros.
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.                                         9
  550.  
  551.  
  552.  
  553.              META SYNTAX CONT'D
  554.              ~~~~~~~~~~~~~~~~~~
  555.  
  556.              PC-LISP  also  provides the meta or super parenthesis  [  ]. 
  557.         One of the problems with LISP is the often overwhelming number of 
  558.         parenthesis.  It  is very common to not supply enough closing )'s 
  559.         and therefore have syntactic/semantic errors in your program. The 
  560.         [ and ] characters when properly used allow you to force  certain 
  561.         structures  even  if  enough )'s have  not  been  provided.  They 
  562.         operate  as follows.  When the [ is encountered in the input,  it 
  563.         acts  like  a  (  except that a note is made  of  the  number  of 
  564.         unclosed  ('s so far.  Now when a ] is encountered in the  input, 
  565.         all lists up to and including the matching [ are closed. If there 
  566.         is  no  matching [,  ie none has been entered or  all  have  been 
  567.         closed with a ] then all open lists are closed. These parenthesis 
  568.         may  be nested up to 16 levels deep.  But,  deep nesting  reduces 
  569.         their  usefullness.   NOTE:  If you open a list with a [ you must 
  570.         close  it with a ].  If you close it with a ) you will cause  the 
  571.         next  [  ]  pair  to  function  incorrectly.  The  super  nesting 
  572.         information  is   reset  whenever a new  file  is  processed,  or 
  573.         whenever  the break level is entered.  That is,  meta parenthesis 
  574.         cannot  be used accross a load or read of another file.  Finally, 
  575.         here  are  a  few  example  legal  inputs  which  use  the   meta 
  576.         parenthesis and the list that results from their input.
  577.  
  578.           ((("hello world\n"] -- goes to --> ((("hello world\n")))
  579.           (([(((8 9] 10 ]                    ((((((8 9)))) 10))
  580.           [[[[[a]]]]]                        (((((a)))))
  581.  
  582.  
  583.             I  should just mention again the fact that  meta  parenthesis 
  584.         will not operate accross multiple reads.  For example suppose you 
  585.         were  using  (read) to get sublists from lists in one  file,  and 
  586.         then swithced to reading lists from another file,  then  returned 
  587.         to the original file.  If the original input file made use of the 
  588.         super  parenthesis  and  the particular sublist  being  read  was 
  589.         between a pair of superparenthesis, this information will be lost 
  590.         when you resume reading the file.  Hence the next ] you hit  will 
  591.         terminate  all open lists rather than those opened after the lost 
  592.         [.  The moral of this example is not to use the super parenthesis 
  593.         in  a  data file whose reading may be interrupted by  other  I/O. 
  594.         This is not a particularly imposing limitation.
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.                                        10
  611.  
  612.  
  613.  
  614.              SYNTAX ERRORS
  615.              ~~~~~~~~~~~~~
  616.              When  you  enter a list which is not  correct  syntactically 
  617.         the  interpreter will return the wonderfully informative  'syntax 
  618.         error'  message.  This  message  will either  contain  a  further 
  619.         message describing the error,  or contain the text of the nearest 
  620.         token  to the error.  You will have to figure out where it is  in 
  621.         the  input list.  Note that if you do not finish entering a list, 
  622.         ie  you put one too few closing )'s on the end,  the  interpreter 
  623.         will  wait until you enter it before continuing.  If you are  not 
  624.         sure  what  has  happened just type "]]" and all  lists  will  be 
  625.         closed  and  the interpreter will try to do  something  with  the 
  626.         list.  If  you are running input from a file the interpreter will 
  627.         detect the end of file and give you a 'syntax error' because  the 
  628.         list was unclosed. Try also (showstack), it can help pinpoint the 
  629.         error  in  a large load file.  V2.11's syntax error  handling  is 
  630.         pretty  poor.  Hopefully  I  can  improve it  in  later  versions 
  631.         (suggestions are welcome).
  632.  
  633.              EVALUATING S-EXPRESSIONS
  634.              ~~~~~~~~~~~~~~~~~~~~~~~~
  635.              The  interpreter expects an S-expression to be typed at  the 
  636.         prompt  '-->'.  The interpreter will evaluate the expression  and 
  637.         print  the resulting S-expression.  If the expression is either a 
  638.         fixnum  or a flonum,  the interpreter just returns it  because  a 
  639.         number  evaluates to itself.  If the expression is a string,  the 
  640.         interpreter also returns it because a string evaluates to itself.
  641.         If  however the expression is a symbol,  the interpreter  returns 
  642.         the  binding of the symbol.  It is an error to try to evaluate  a 
  643.         symbol  that  has  no  binding.   Certain  predefined  atoms  are 
  644.         prebound,  while  all other symbols are unbound until bound by  a 
  645.         function call or a set / setq.  If the expression is a list, then 
  646.         the  first element in the list is taken to be a function name  or 
  647.         description,  the rest of the elements are taken to be parameters 
  648.         to  the  function.  The  interpreter will evaluate  each  of  the 
  649.         arguments  and  then pass them to the appropriate function  whose 
  650.         result is returned. For example: The list S-expression with a '+' 
  651.         as the first element and fixnums as elements will evaluate as the 
  652.         sum of the fixnums. Eg.
  653.  
  654.              -->(+ 2 4 6 8)
  655.              20
  656.  
  657.              We  can  also  compose these function calls  by  using  list 
  658.         nesting.  Sublists are evaluated prior to upper levels. Eg:
  659.  
  660.              -->(- (+ 6 8) (+ 2 4))
  661.              8
  662.  
  663.              We  can  also  perform operations on other  objects  besides 
  664.         numbers.  Suppose that we wanted to reverse the list (time  flies 
  665.         like arrows).  Trying the built in function reverse we get: 
  666.              
  667.              -->(reverse (time flies like arrows))
  668.              --- error in built in function [apply] ---
  669.  
  670.  
  671.                                        11
  672.  
  673.  
  674.  
  675.              EVALUATING S-EXPRESSIONS CONT'D
  676.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  677.              But the interpreter will be confused!  It does not know that 
  678.         'time'  is  data  and not a function  taking  arguments  'flies', 
  679.         'like'  and 'arrows'.  To indicate it is upset PC-LISP prints out 
  680.         the  error  message above and alters the  prompt.  More  on  this 
  681.         later.  What  can  we do to fix this?  We must use  the  function 
  682.         'quote'  which returns its arguments unevaluated,  hence the name 
  683.         "quote".
  684.  
  685.              -->(reverse (quote (time flies like arrows)))
  686.              (arrows like flies time)
  687.                
  688.              Will give us the desired result (arrows like flies time). We 
  689.         can  do  the  same  thing  without  using  the  (quote)  function 
  690.         directly.  Remember the read macro ' above?  Well it will replace 
  691.         the  entry '(time flies like arrows) with (quote(time flies  like 
  692.         arrows)). So more concisely we can ask PC-LISP to evaluate: 
  693.                        
  694.              -->(reverse '(time flies like arrows))
  695.              (arrows like flies time)
  696.  
  697.              This gives us the correct result without as much typing. You 
  698.         will  now  note that the subtraction of 2+4 from 6+8  could  also 
  699.         have been entered as:
  700.              
  701.              -->(- (+ '6 '8) (+ '2 '4))
  702.              8
  703.  
  704.              However,   the  extra  's  are  redundant  because  a fixnum 
  705.         evaluates to itself. In general a LISP expression is evaluated by 
  706.         first  evaluating each of its arguments,  and then  applying  the 
  707.         function to the arguments,  where the function is the first thing 
  708.         in the list.  Remember that evaluation of the function (quote s1) 
  709.         returns  s1 unevaluated.   LISP will also allow the function name 
  710.         to  be  replaced by a function body called a  lambda  expression. 
  711.         Which is just a function body without a name. Example:
  712.  
  713.              -->((lambda(x)(+ x 10)) 14)
  714.              24
  715.  
  716.              Which would be processed as follows. First the parameters to 
  717.         the  lambda expression are evaluated.  That's just 14.  Next  the 
  718.         body  of the lambda expression is evaluated but with the value 14 
  719.         bound to the formal parameter given in the lambda expression.  So 
  720.         the body evaluated is (+ x 10) where x is bound to 14. The result 
  721.         is  just  24.  Note  that lambda expressions  can  be  passed  as 
  722.         parameters  as can built in functions or user defined  functions. 
  723.         Hence  I  can  evaluate the following input.  Note I  use  the  ] 
  724.         character to close the three open lists rather than typing ))) at 
  725.         the end of the line.
  726.  
  727.              -->((lambda(f x)(f (car x))) '(lambda(l)(car l)) '((hi]   
  728.              hi                  
  729.  
  730.  
  731.  
  732.                                        12
  733.  
  734.  
  735.  
  736.              EVALUATING S-EXPRESSIONS CONT'D
  737.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  738.              Which evaluates as follows. The parameters to the call which 
  739.         are   the   expressions  '(lambda(l)(cdr  l))  and  '((hi))   are 
  740.         evaluated. This results in the expressions being returned because 
  741.         they are quoted.  These are then bound to 'f and 'x  respectively 
  742.         and  the body of the first lambda expression is  evaluated.  This 
  743.         means  that  the  expression ((lambda(l)(car l))(car  ((hi)))) is 
  744.         evaluated. So again the parameters to the function are evaluated. 
  745.         Since  the  only  parameter  is  (car  ((hi)))  it  is  evaluated 
  746.         resulting  in  (hi).  This  is then bound to l  and  (car  l)  is 
  747.         evaluated giving hi.   
  748.  
  749.              PC-LISP is also capable of handling all other function  body 
  750.         kinds.  These are lambda,  nlambda, lexpr, fexpr and macro kinds.  
  751.         These  expression  kinds may all have multiple bodies  which  are 
  752.         evaluated  in  order,  the last one producing the value  that  is 
  753.         returned.  See  the section on BUILT IN FUNCTIONS and MACROS  for 
  754.         more details on these kinds and how they operate. Better yet read 
  755.         LISPcraft.
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.                                        13
  794.  
  795.  
  796.  
  797.              TERMINATION OF EXPRESSION EVALUATION
  798.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  799.              There are three distinct ways that evaluation can terminate. 
  800.         First, evaluation can end naturally when there is no more work to 
  801.         do.  In  this  case the resulting S-expression is printed on  the 
  802.         console and you are presented with the prompt "-->".  Second, you 
  803.         can request premature termination by hitting the CONTROL-BREAK or 
  804.         CONTROL-C keys simultaneously (hereafter referred to as  CONTROL-
  805.         BREAK).  Note  that this will only interrupt list evaluation,  it 
  806.         will  NOT   interrupt  garbage  collection  which  continues   to  
  807.         completion.  So,  if  you hit CONTROL-BREAK or CONTROL-C and  you 
  808.         don't  get  any response,  wait a second or two because  it  will 
  809.         respond  after garbage collection ends.  Finally,  execution  can 
  810.         terminate  when  PC-LISP detects a bad parameter to  a  built  in 
  811.         function,  a stack overflows, a division by zero is attempted, or 
  812.         an atom is unbound etc. In all cases but a normal termination you 
  813.         will be returned to a break error level.  This is when the prompt 
  814.         looks  like  'er>'.  This means that variable bindings are  being 
  815.         held  for you to examine.  So if the evaluation aborts  with  the 
  816.         message  "error in built in function [car]",  you can examine the 
  817.         atom  bindings  that were in effect when this error  occurred  by 
  818.         typing the name of the atom desired.  This causes its binding  to 
  819.         be displayed. When you are finished with the break level just hit 
  820.         CONTROL-Z  plus  ENTER and you will be placed back in the  normal 
  821.         top  level  and all bindings that were non global will  be  gone. 
  822.         Note  you can do anything at the break level that you can  do  at 
  823.         the top level. If further errors occur you will stay in the break 
  824.         level and any bindings at the time of the second error will be in 
  825.         effect  as  well  as  any bindings that were  in  effect  at  the 
  826.         previous  break level.  If bindings effecting atoms whose  values 
  827.         are being held in the first break level are rebound at the second 
  828.         break  level these first bindings will be hidden by the secondary 
  829.         bindings.
  830.  
  831.              An  error  in built in functions 'eval' or 'apply' can  mean 
  832.         two  things.  First,  your expression could contain a bad  direct 
  833.         call  to eval or apply.  Or,  your code may be trying to apply  a 
  834.         function that does not exist to a list of parameters,  or  trying 
  835.         to apply a bad lambda form.  The interpreter does not distinguish 
  836.         an  error  made  in  a direct call by you  to  eval/apply  or  an 
  837.         indirect  call  to eval/apply,  made by the interpreter  on  your 
  838.         behalf to get the expression evaluated.
  839.  
  840.              It  is  also useful to know what the  circumstances  of  the 
  841.         failure  were.  You can display the last 20 evaluations with  the 
  842.         command  (showstack).  This will print the stack from the top  to 
  843.         the  20th  element  of the stack.  This gives  you  the  path  of 
  844.         evaluation  that lead to the error.  For more information on  the 
  845.         (showstack)  command  look  in the section  FUNCTIONS  WITH  SIDE 
  846.         EFFECTS OR THAT ARE EFFECTED BY SYSTEM.
  847.  
  848.              It  is  possible  but  hopefully pretty  unlikely  that  the 
  849.         interpreter  will stop on an internal error.  If this happens try 
  850.         to duplicate it and let me know so I can fix it.
  851.  
  852.  
  853.  
  854.                                        14
  855.  
  856.  
  857.  
  858.              DATA TYPES IN PC-LISP
  859.              ~~~~~~~~~~~~~~~~~~~~~
  860.              PC-LISP  has  the  following data types,  32  bit  integers, 
  861.         single  precision floating point numbers,  lists,  ports for file 
  862.         I/O, alpha atoms, strings and hunks (up to 126 in length just one 
  863.         short of Franz!). The (type) function returns these atoms:
  864.  
  865.               fixnum  - a 32 bit integer.
  866.  
  867.               flonum  - a single precision floating point number.
  868.  
  869.               list    - a list of cons cells.
  870.  
  871.               symbol  - an alpha atom, with print name up to 254 chars 
  872.                         which  may  include spaces tabs  etc,  but  which 
  873.                         should  not  include  an  (ascii  0)   character. 
  874.                         Symbols may have property, bindings and functions
  875.                         associated with them. Symbols with same print 
  876.                         name are the same object.
  877.  
  878.               string  - A string of characters up to 254 in length. It 
  879.                         has nothing else associated with it. Strings
  880.                         with same print name are not necessarily the
  881.                         same object.
  882.                        
  883.               port    - A stream that is open for read or write. This 
  884.                         type can only be created by (fileopen).
  885.  
  886.               hunk    - An array of 1 to 126 elements.  The elements may 
  887.                         be  of  any other  type  including  hunks.  Franz 
  888.                         allows 127, the missing element is due to a space
  889.                         saving decision. This type can only be created 
  890.                         by a call to (hunk) or (makhunk).
  891.  
  892.              Fixnums and flonums are together known as numbers.  The read 
  893.         function will always read a number as a flonum and then see if it 
  894.         can represent it as a fixnum without loss of precision.  Hence if 
  895.         the  number 50000000000 is entered it will be  represented  as  a 
  896.         flonum because it exceeds the precision of a fixnum.  If a number 
  897.         has a decimal point or exponent specifier 'e' or 'E' in it, it is 
  898.         assumed  to  be  a flonum even if there are no  non  zero  digits 
  899.         following the radix point.
  900.  
  901.              Fixnums  and flonums will not appear the same when  printed. 
  902.         The  print function will output a flonum with a radix  point  and 
  903.         perhaps an exponent specifier if it will make the output smaller.
  904.  
  905.              Hunks when printed appear as { e0 e1 e2 ....  eN }. They are 
  906.         indexed  from zero.  They cannot be entered,  ie there is no read 
  907.         mechanism for creating them you must create them with a  function 
  908.         call. It is possible to implement arrays and vectors  using hunks 
  909.         although I have not done this yet. See HUNKS.
  910.  
  911.  
  912.  
  913.  
  914.  
  915.                                        15
  916.  
  917.  
  918.  
  919.              THE BUILT IN FUNCTIONS AND VARIABLES
  920.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  921.  
  922.              Following is a list of each built in function. I will denote
  923.         the  allowed  arguments  as follows:  
  924.  
  925.            - a1...aN are alpha atom parameters, type symbol.
  926.            
  927.            - h1...hN are string or alpha atoms, type string or symbol.
  928.  
  929.            - x1...xN are integer atom parameters, type fixnum (32bits).
  930.  
  931.            - f1...fN are float atom parameters, type flonun.     
  932.  
  933.            - n1...nN are number atom parameters, type flonum or fixnum.
  934.  
  935.            - z1...zN are numbers but all are of the same type. 
  936.  
  937.            - l1...lN are lists, must be nil or of type list.          
  938.  
  939.            - p1...pN are port atom parameters, type port.
  940.  
  941.            - s1...sN  are  S-expressions (any atom type or list)
  942.  
  943.            - H is a hunk.  
  944.  
  945.            Additional Definitions:
  946.            ~~~~~~~~~~~~~~~~~~~~~~~
  947.            "{a|d}+"  means  any sequence of characters of length  greater      
  948.         than  0  consisting  of a's and  d's  in  any  combination.  This      
  949.         defines   the   car,cdr,cadr,caar,cadar...   function  class   as      
  950.         follows: "c{a|d}+r".
  951.  
  952.             "[ -stuff- ]" indicates  that -stuff-  is/are optional and if 
  953.         not provided a default will be provided for you.
  954.              
  955.             "*-stuff-*"  indicates  that  -stuff- is  not  evaluated.  An 
  956.         example  of  this  is the function (quote *s1*) whose  single  S-
  957.         expression parameter s1 is enclosed in *'s to indicate that quote 
  958.         is passed the argument s1 unevaluated.
  959.  
  960.              For  the  simpler functions I will describe  the   functions 
  961.         using  a sort of "if (condition) result1 else  result2"  notation 
  962.         which should be pretty obvious to most people. For functions that 
  963.         are a little more complex I will give a short English description 
  964.         and  perhaps  an  example.  If the example code shows  the  '-->' 
  965.         prompt  you  should  be able to type exactly  what  follows  each 
  966.         prompt  and get the same responses from PC-LISP.  If the  example 
  967.         does  not show a '-->' prompt the example is a code fragment  and 
  968.         will not necessarily produce the same results shown.
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.                                        16
  977.  
  978.  
  979.  
  980.              PREDEFINED GLOBAL VARIABLES (ATOMS)
  981.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  982.              
  983.              A  number of atoms are globally prebound by  PC-LISP.  These 
  984.         variables  are  testable and setable  by you but  in  some  cases 
  985.         altering the bindings is highly inadvisable.  Note that a binding 
  986.         can  be inadvertantly altered by defining one of these atoms as a 
  987.         local or parameter atom to a function or a prog,  or directly  by 
  988.         using 'set' or 'setq'.
  989.  
  990.              "displace-macros" - This atom when non nil will cause  macro 
  991.         expansion to be follwed by code substitution if such substitution 
  992.         is possible. The default value is nil meaning no substitution.
  993.                   
  994.              "t"  - This  atom   means 'true',  it is  bound  to  itself. 
  995.         Various predicates return this to indicate a true condition.  You 
  996.         should  NOT change the binding of this atom,  to do so will cause 
  997.         PC-LISP to produce incorrect answers.
  998.  
  999.              "nil" - This is not really an atom,  it represents the empty 
  1000.         list (). It is not bound to () but rather equivalent to () in all 
  1001.         contexts.  Any  attempt to create a symbol with print name  "nil" 
  1002.         will result in ().  
  1003.  
  1004.              "$ldprint" - Is initially  bound to "t".  When not bound  to 
  1005.         "nil"  this  atom  causes the printing of the -- [file loaded] -- 
  1006.         message  when  the function (load file) is executed.  When  "nil" 
  1007.         this  atom prevents the printing of the above  message.  This  is 
  1008.         useful  when  you  want  to load  files  silently  under  program 
  1009.         control.
  1010.  
  1011.              "$gcprint"  - Is  initially bound to "nil".  When  bound  to 
  1012.         "nil"  garbage collection proceeds silently.  If bound non  "nil" 
  1013.         then  at  the  end of a garbage collection cycle  4  numbers  are 
  1014.         printed.  The first is the number of collection cycles that  have 
  1015.         occured  since PC-LISP was started,  the second is the percentage 
  1016.         of cons cells that are in use,  the third the percentage of alpha 
  1017.         cells, and the third the percentage of heap space that is in use. 
  1018.         These  last  three numbers are exactly what you get back  with  a 
  1019.         call to (memstat).
  1020.  
  1021.              "$gccount$  - Is initially bound to 0.  It increases by  one 
  1022.         every time garbage collection occurs. This number is the  same as 
  1023.         the  first  number printed when $gcprint is bound non  "nil"  and 
  1024.         garbage  collection  occurs.  While you can set $gccount$ to  any 
  1025.         value you want,  its global binding will be reset to the  correct 
  1026.         garbage collection cycle count whenever collection finishes.
  1027.  
  1028.              "piport",  "poport",  "errport" - Are bound to the  standard 
  1029.         input, standard output and standard error ports respectively. You 
  1030.         can  use these to force patom,  princ,  print and pp-form to send 
  1031.         their output to the standard output or error.  Or,  to force read 
  1032.         and  readc to get their input from the standard input.  They  are 
  1033.         initially bound to the keyboard and screen.  You can alter  their 
  1034.         bindings if you wish but this is not recommended.
  1035.  
  1036.  
  1037.                                        17
  1038.  
  1039.  
  1040.  
  1041.              THE MATH FUNCTIONS
  1042.              ~~~~~~~~~~~~~~~~~~
  1043.              Functions that operate on numbers,  fixnums or flonums. Note 
  1044.         that the arrow --X--> may indicate what type is returned. If X is 
  1045.         's'  then the same type as the parameter(s) selected is returned. 
  1046.         If  X is 'f' then a flonum type is returned.  If X is 'x' then  a 
  1047.         fixnum is returned.  If X is 'b' then the best type is  returned, 
  1048.         this  means that a fixnum is returned if possible.  Note that you 
  1049.         should  use  fixnums  together  with  "1+,  1- zerop"  when  ever 
  1050.         possible because doing so gives nearly a 50% decrease in run time 
  1051.         for many expressions, especially counted loops or recursion.
  1052.  
  1053.              TRIG AND MIXED FUNCTIONS
  1054.              ~~~~~~~~~~~~~~~~~~~~~~~~
  1055.              (abs  n1)    --s-> absolute value of n1 is returned.
  1056.              (acos n1)    --f-> arc cosine of n1 is returned.
  1057.              (asin n1)    --f-> arc sine of n1 is returned.
  1058.              (atan n1 n2) --f-> arc tangent of (quotient n1 n2).      
  1059.              (cos n1)     --f-> cosine of n1, n1 is radians
  1060.              (exp n1)     --f-> returns e to the power n1.
  1061.              (expt n1 n2) - b-> n1^n2 via exp&log if n1 or n2 flonum. 
  1062.              (fact x1)    --x-> returns x1! ie x1*(x1-1)*(x1-2)*....1         
  1063.              (fix n1)     --x-> returns nearest fixnum to number n1.
  1064.              (float n1)   --f-> returns nearest flonum to number n1.
  1065.              (log n1)     --f-> natural logarithm of n1 (ie base e).
  1066.              (log10 n1)   --f-> log base 10 of n1 {not present in Franz}
  1067.              (lsh x1 x2)  --x-> x1 left shifted x2 bits (x2 may be < 0).
  1068.              (max n1..nN) --s-> largest of n1...nN or (0 if N = 0)
  1069.              (min n1..nN) --s-> smallest of n1..nN or (0 if N = 0)
  1070.              (mod x1 x2)  --x-> remainder of x1 divided by x2.
  1071.              (random [x1])--x-> random fixnum, or random in 0...x1-1.
  1072.              (sin n1)     --f-> sine of n1, n1 is radians.
  1073.              (sqrt n1)    --f-> square root of n1.
  1074.              (1+ x1)      --x-> x1+1. 
  1075.              (add1 n1)    --b-> n1+1 (done with fixnums if n1 is fixnum).
  1076.              (1- x1)      --x-> x1-1.
  1077.              (sub1 n1)    --b-> n1-1 (done with fixnums if n1 is fixnum).
  1078.  
  1079.              BASIC MATH FUNCTIONS 
  1080.              ~~~~~~~~~~~~~~~~~~~~
  1081.          (* x1 ...... ..xN) --x-> x1*x2*x3*.....nN (or 1 if N = 0)  
  1082.          (times n1 .. ..nN) --b-> n1*n2*n3......nN (or 1 if N = 0)
  1083.          (product n1....nN) --b-> Ditto                
  1084.          (+ x1....... ..xN) --x-> x1+x2+x3+.....xN (or 0 if N = 0)  
  1085.          (add n1 .......nN) --b-> n1+n2+n3+.....nN (or 0 if N = 0)
  1086.          (sum n1 .......nN) --b-> Ditto
  1087.          (plus n1.......nN) --b-> Ditto
  1088.          (- x1....... ..xN) --x-> x1-x2-x3-.....xN (or 0 if N = 0)  
  1089.          (diff n1.......nN) --b-> n1-n2-n3-.....nN (or 0 if N = 0)  
  1090.          (difference....nN) --b-> Ditto
  1091.          (/ x1....... ..xN) --x-> x1/x2/x3/.....xN (or 1 if N = 0)
  1092.          (quotient n1...nN) --b-> n1/n2/n3/.....xN (or 1 if N = 0)
  1093.  
  1094.              Note  that the Basic functions that operate on numbers  will 
  1095.         return a fixnum if the result can be stored in one.
  1096.  
  1097.  
  1098.                                        18
  1099.  
  1100.  
  1101.  
  1102.              THE BOOLEAN FUNCTIONS
  1103.              ~~~~~~~~~~~~~~~~~~~~~
  1104.              These functions all return boolean values. The objects t and 
  1105.         nil represent true and false respectively. Note however that most 
  1106.         functions  treat a non nil value as being t.  t is  a  predefined 
  1107.         atom  whose binding is  t while nil is not a real atom but rather 
  1108.         a  lexical item that is EQUIVALENT to () in all  contexts.  Hence 
  1109.         nil and () are legal as both an atom and a list in all functions.
  1110.  
  1111.              Note when comparing flonums and fixnums you cannot use  (eq) 
  1112.         because they are not identical objects. In Franz (eq 1 1) returns 
  1113.         t  because of a space saving trick.  You should not rely on  this 
  1114.         working in other LISPS including PC-LISP.
  1115.                   
  1116.              (alphalessp h1 h2) ---> if (h1 ASCII before h2) t else nil;
  1117.              (atom s1)          ---> if (s1 not type list) t else nil;
  1118.              (and s1 s2 .. sN)  ---> if (a1...aN all != nil) t else nil;
  1119.              (boundp a1)        ---> if (a1 bound) (a1.eval(a1)) else nil;
  1120.              (eq s1 s2)         ---> if (s1 & s2 same object) t else nil;
  1121.              (equal s1 s2)      ---> if (s1 has s2's structure) t else nil;
  1122.              (evenp n1)         ---> if (n1 mod 2 is zero) t else nil;
  1123.              (fixp s1)          ---> if (s1 of type fixnum) t else nil;
  1124.              (floatp s1)        ---> if (s1 of type flonum) t else nil;
  1125.              (greaterp n1...nN) ---> if (n1>n2>n3...>nN) t else nil;
  1126.              (hunkp s1)         ---> if (s1 of type hunk) t else nil;
  1127.              (lessp n1...nN)    ---> if (n1<n2<n3...<nN) t else nil;
  1128.              (listp s1)         ---> if (s1 of type list) t else nil;
  1129.              (minusp n1)        ---> if (n1 < 0 or 0.0) t else nil;
  1130.              (not s1)           ---> if (s1 != nil) nil else t;
  1131.              (null s1)          ---> Ditto                       
  1132.              (numberp s1)       ---> if (s1 is fix of float) t else nil;
  1133.              (numbp s1)         ---> Ditto. 
  1134.              (or s1 s2 .. sN)   ---> if (any si != nil) t else nil;
  1135.              (oddp n1)          ---> if (n1 mod2 is non zero) t else nil;
  1136.              (plusp n1)         ---> if (n1 > 0 or 0.0) t else nil; 
  1137.              (portp s1)         ---> if (s1 of type port) t else nil;
  1138.              (zerop n1)         ---> if (n1 = 0 or 0.0) t else nil;
  1139.              (< z1 z2)          ---> if (z1 < z2) t else nil;
  1140.              (= z1 z2)          ---> if (z1 = z2) t else nil;
  1141.              (> z1 z2)          ---> if (z1 > z2) t else nil;
  1142.  
  1143.              Note carefully the difference between (eq) and (equal).  One  
  1144.         checks for identical objects, ie the same object, while the other 
  1145.         checks  for  two  objects  that have  the  same  "structure"  and 
  1146.         identical leaves.                                      
  1147.  
  1148.              Note  that  the  (and) and  (or)  functions  evaluate  their 
  1149.         arguments one by one until the result is known. Ie, short circuit 
  1150.         evaluation is performed.
  1151.  
  1152.              Note  that proper choice of fixnums over flonums and  proper 
  1153.         choice   of   fixnum  functions  can  yield   large   performance 
  1154.         improvements.  For  example  (zerop  n) is faster than  (=  0  n) 
  1155.         because (zerop) like all functions that take number parameters is 
  1156.         biased towards fixnums.
  1157.  
  1158.  
  1159.                                        19
  1160.  
  1161.  
  1162.  
  1163.              LIST & ATOM CREATORS AND SELECTORS
  1164.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1165.  
  1166.              These functions will take lists and atoms as parameters  and 
  1167.         return  larger  or  smaller lists or atoms.  They  have  no  side 
  1168.         effects  on  the  LISP system nor are their results  affected  by 
  1169.         anything  other than the values of the parameters given to  them. 
  1170.         These  functions are all nondestructive they do not  alter  their 
  1171.         parameters in any way.
  1172.  
  1173.  
  1174.              (append l1..ln)    ---> list made by joining all of l1..ln.
  1175.                                      If any of l1..ln is nil they are
  1176.                                      ignored.
  1177.  
  1178.              (ascii n1)         ---> atom with name 'char' where 'char' 
  1179.                                      has ordinal value n1:(0 < n1 < 256).
  1180.                   
  1181.              (assoc s1 s2)      ---> if s2 is a list of (key.value) pairs
  1182.                                      then assoc --> (key.value) from s2,
  1183.                                      where (equal key a1) is t else nil.
  1184.  
  1185.              (car l1)           ---> first element in l1. If l1 is nil
  1186.                                      car returns nil.
  1187.  
  1188.              (cdr l1)           ---> Everything but the car of l1. If
  1189.                                      l1 is nil cdr returns nil. 
  1190.  
  1191.              (c{a|d}+r l1)      ---> performs repeated car or cdr's on
  1192.                                      l1 as given by reverse of {a|d}+.
  1193.                                      Returns nil if it cars or cdrs off
  1194.                                      the end of a list.
  1195.  
  1196.         (character-index h1 h2) -x-> Returns the index (from 1) of first
  1197.                                      char in h2 in h1. h2 can be a fixnum
  1198.                                      ascii value. Returns nil if none.
  1199.  
  1200.              (concat h1 .. hN)  ---> Forms a new atom by concatenating
  1201.                                      all the strings or atoms. Or nil if
  1202.                                      if N = 0.                         
  1203.  
  1204.              (cons s1 s2)       ---> list with s1 as 1st elem s2 is rest. 
  1205.                                      If  s2  is  nil  the  list  has  one 
  1206.                                      element. If s2 is an atom the pair 
  1207.                                      print with a dot. (cons 'a 'b) will
  1208.                                      print as (a . b).
  1209.  
  1210.              (explode h1)       ---> list of chars in print name of h1. 
  1211.                                      If h1 is nil returns (n i l)
  1212.  
  1213.              (exploden h1)      ---> list of ascii values of chars in h1.
  1214.                                      If h1 is nil returns (110 105 108).
  1215.  
  1216.              (get_pname h1)     ---> String equal to print name of atom
  1217.                                      h1 or same as string h1.
  1218.  
  1219.  
  1220.                                        20
  1221.  
  1222.  
  1223.  
  1224.              LIST & ATOM CREATORS AND SELECTORS (CONT'D)
  1225.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1226.  
  1227.              (hunk-to-list H)   ---> Returns a list whose elements are
  1228.                                      (eq) to those of hunk H and in the
  1229.                                      same order. 
  1230.  
  1231.              (implode l1)       ---> atom with name formed by compressing
  1232.                                      first char of each atoms print name  
  1233.                                      in l1. Imploding (n i l) returns 
  1234.                                      the empty list nil.
  1235.                   
  1236.              (last  l1)         ---> returns the last element in l1.  If 
  1237.                                      l1 is nil it returns nil.
  1238.  
  1239.              (length l1)        -x-> fixnum = to length of list l1.   
  1240.                                      The length of nil is 0.
  1241.  
  1242.              (list s1 s2...sN)  ---> a list with elements (s1 s2 ...sN)
  1243.                                      If N = 0 list returns nil. 
  1244.  
  1245.              (member s1 l1)     ---> If (s1 (equal) to a top level sub 
  1246.                                      list of l1) this sublist, else nil.
  1247.  
  1248.              (memq s1 l1)       ---> If (s1 (eq) to a top level sub list
  1249.                                      of l1) this sublist, else nil.
  1250.  
  1251.              (nth n1 l1)        ---> n1'th element of l1 (indexed from 0)
  1252.                                      like (cad...dr l1) with n1 d's.
  1253.                                       
  1254.              (nthcdr n1 l1)     ---> returns result of cdr'ing down the
  1255.                                      list n1 times. If n1 < 0 it returns
  1256.                                      (nil l1).
  1257.              
  1258.              (nthchar h1 n1)    ---> n1'th char in the print name of h1
  1259.                                      indexed from 1. 
  1260.              
  1261.              (pairlis l1 l2 l3) ---> l1 is list of atoms. l2 is a list 
  1262.                                      of S-expressions. l3 is a list of
  1263.                                      ((a1.s1)....) The result is the
  1264.                                      pairing of atoms in l1 with values
  1265.                                      in l2 with l3 appended (see assoc).
  1266.              
  1267.              (quote *s1*)       ---> exactly s1 unevaled without changes.
  1268.  
  1269.              (reverse l1)       ---> the list l1, reversed at top level.
  1270.              
  1271.              (type s1)          ---> list,flonum,port,symbol, fixnum or  
  1272.                                      hunk as determined by the type of
  1273.                                      the parameter s1.
  1274.  
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.                                        21
  1282.  
  1283.  
  1284.  
  1285.              LIST & ATOM CREATORS AND SELECTORS (CONT'D)
  1286.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1287.              
  1288.              (sizeof h1)
  1289.              ~~~~~~~~~~~
  1290.              Will return the number of bytes necessary to store an object 
  1291.         of  type  h1.  Legal  values for  h1  are  'list,'symbol,'flonum, 
  1292.         'fixnum,  'string  ,  'hunk and 'port.  The size returned is  the 
  1293.         amount  of memory used to store the cell,  incidental heap space, 
  1294.         property list space,  binding stack space and function body space 
  1295.         is not counted for types 'symbol, 'string or 'hunk.
  1296.  
  1297.              (stringp s1)
  1298.              ~~~~~~~~~~~~
  1299.              Will  return  t if the S-expression s1 is  of  type  string, 
  1300.         otherwise it returns nil.     
  1301.  
  1302.              (substring h1 n1 [n2])
  1303.              ~~~~~~~~~~~~~~~~~~~~~~
  1304.              If  n1  is positive substring will return the  substring  in 
  1305.         string  h1  starting  at  position n1 (indexed  from  1)  for  n2 
  1306.         characters  or until the end of the string if n2 is not  present. 
  1307.         If n1 is negative the substring starts at |n1| chars from the end 
  1308.         of  the string and continues for n2 characters or to the  end  of 
  1309.         the  string if n2 is not present.  If the range specified is  not 
  1310.         contained within the bounds of the string, nil is returned.
  1311.  
  1312.              (memusage s1)       { not in Franz }
  1313.              ~~~~~~~~~~~~~
  1314.              Will  return  the approximate amount of storage that the  S-
  1315.         expression s1 is occupying in bytes.  The printname heap space is 
  1316.         included  in this computation as are file true name  atoms.  This 
  1317.         function  is  not smart,  it will count an atom twice  if  it  is 
  1318.         referenced  more than once in the list.  The space count does not 
  1319.         include  storage needed for binding stacks,  property  lists,  or 
  1320.         function bodies that are associated with a particular atom.  Hunk 
  1321.         and string space include the heap space owned by the cell.
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.  
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.                                        22
  1343.  
  1344.  
  1345.  
  1346.              NONINTERNING/INTERNING FUNCTIONS
  1347.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1348.              Unless  otherwise stated in this manual,  any function  that 
  1349.         returns  an atom will intern it (put it on the  oblist).  However 
  1350.         the following functions are not included in the above statement.
  1351.         Note  also  that the list returned by (oblist) is a copy  of  the 
  1352.         real  oblist.  Note carefully that the atoms created by read  are 
  1353.         interned.  See a really good LISP manual on this stuff because it 
  1354.         can be really confusing. 
  1355.  
  1356.              (copysymbol a1 s1)
  1357.              ~~~~~~~~~~~~~~~~~~
  1358.              Returns an UNINTERNED copy of atom a1. If the flag parameter 
  1359.         s1  is non nil then the returned atom has  property,  value,  and 
  1360.         function  definitions eq to a1 otherwise its property,  value and 
  1361.         function   definitions   are   nil,undefined,    and    undefined 
  1362.         respectively.
  1363.  
  1364.              (gensym [a1])
  1365.              ~~~~~~~~~~~~~
  1366.              Returns  an UNINTERNED atom whose print name is of the  form 
  1367.         Xnnnnn  where  X is either 'g' or the print name of a1 (if a1  is 
  1368.         provided)  and  nnnnnn is some number such that  no  interned  or 
  1369.         uninterned atom in the system has the same print name.  Note that 
  1370.         the  the existence of a clashing interned or uninterned  atom  is 
  1371.         checked before selecting the value of nnnnn.
  1372.  
  1373.              (intern a1)
  1374.              ~~~~~~~~~~~
  1375.              Will INTERN a1 on the oblist. If an atom with the same print 
  1376.         name  as  a1  is  already on the oblist THIS  ATOM  IS  RETURNED, 
  1377.         otherwise a1 is physically added to the oblist and is returned.
  1378.  
  1379.              (remob a1)
  1380.              ~~~~~~~~~~
  1381.              Will  return a1 after having physically removed a1 from  the 
  1382.         oblist. Future calls to read will create a new atom with the same 
  1383.         print  name  as a1.  This can be confusing if a1 had  a  function 
  1384.         definition, property, or value assocaited with it.
  1385.  
  1386.              (maknam l1)  
  1387.              ~~~~~~~~~~~
  1388.              Takes a list of atoms as parameter and returns an UNINTERNED 
  1389.         atom whose print name is the concatenation of the first character 
  1390.         in the print names of every atom in the provided list  parameter. 
  1391.         This  is  the same as (implode) except that implode  interns  its 
  1392.         result.        
  1393.  
  1394.              (uconcat a1 a2 ... aN)  
  1395.              ~~~~~~~~~~~~~~~~~~~~~~
  1396.              Returns   an  UNINTERNED  atom  whose  print  name  is   the 
  1397.         concatenation of each of the print names of a1...aN.  If N=0,  or 
  1398.         if N=1 and a1 is nil,  then the empty list nil is returned.  Note 
  1399.         that the empty list nil is neither interned or uninterned because 
  1400.         it is not really an atom.
  1401.  
  1402.  
  1403.                                        23
  1404.  
  1405.  
  1406.  
  1407.              FILE I/O FUNCTIONS
  1408.              ~~~~~~~~~~~~~~~~~~
  1409.              These  functions perform simple list/atom and character  I/O 
  1410.         you must be careful when writing lists to files to terminate with 
  1411.         a  new  line before closing the file.  Otherwise they  may  cause 
  1412.         problems for some MS-DOS editors etc.  These functions operate on 
  1413.         type  'port'  which  is  returned by 'fileopen'  and  which  when 
  1414.         printed  is  just  %file@nn%  where 'file' is  the  name  of  the 
  1415.         associated  port  and  nn is the  file  number  0..(20?).  MS-DOS 
  1416.         imposes limits on the number of open files you can have.  This is 
  1417.         usually  more  than 16 with no more than 5 to the same file. 
  1418.  
  1419.              (close p1)
  1420.              ~~~~~~~~~~
  1421.              Closes  the  port p1 and returns t.  Note that you  must  be 
  1422.         careful  to  write  a  line feed (ascii 10) to  the  file  before 
  1423.         closing it in some cases. Certain MS-DOS text editors do not like 
  1424.         files with very large line lengths.
  1425.  
  1426.              (fileopen h1 h2)
  1427.              ~~~~~~~~~~~~~~~~
  1428.              Opens file whose name is h1 for mode h2 access. h1 should be 
  1429.         a file name optionally including a path.  h2 should be one of 'r, 
  1430.         'w, or 'a meaning read, write or append respecively. The function 
  1431.         if successful returns a port atom which will print as  %file@nn%. 
  1432.         If the function is not successful nil is returned.  Fileopen does 
  1433.         not  look in any but the current directory for a relative path or 
  1434.         file.  Note  devices  like "con:" are allowed in  place  of  file 
  1435.         names.
  1436.  
  1437.              (filepos p1 [x1])
  1438.              ~~~~~~~~~~~~~~~~~ 
  1439.              If  fixnum parameter x1 is not provided filepos will  return 
  1440.         the  current  file position where the next  read/write  operation 
  1441.         will take place for port p1.  If x1 is provided it is interpreted 
  1442.         as  a new position where the next read/write should  take  place. 
  1443.         The  read/write pointer is seeked accordingly and the value x1 is 
  1444.         returned if the seek completes successfully. Otherwise nil.
  1445.          
  1446.              (load h1) 
  1447.              ~~~~~~~~~
  1448.              Will  try to find the file whose name is h1 and load it into 
  1449.         PC-LISP. Loading means reading every list, and evaluating it. The 
  1450.         results  of  the evaluation are NOT printed on  the  console.  In 
  1451.         trying  to  find the file h1, load uses the  following  strategy. 
  1452.         First  it  looks for file h1 in the current  directory,  then  it 
  1453.         looks  for h1.l in the current directory.  Then it gets the value 
  1454.         of  the  environment variable LISP%LIB which should  be  a  comma 
  1455.         separated  sequence  of MS-DOS paths (exactly the same syntax  as 
  1456.         for PATH). It then repeats the above searching strategy for every 
  1457.         directory  in the path list.  For example if I entered this  from 
  1458.         the COMMAND shell:
  1459.  
  1460.  
  1461.  
  1462.  
  1463.  
  1464.                                        24
  1465.  
  1466.  
  1467.  
  1468.              FILE I/O FUNCTIONS (CONT'D)
  1469.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1470.  
  1471.              "set LISP%LIB= c:\usr\libs\lisp\bootup ; c:\lisp\work\;"
  1472.  
  1473.         then  ran PC-LISP,  it would try to load the file PC-LISP.L first 
  1474.         from the current directory,  then from the two directories on the 
  1475.         C drive that are specified in the above assignment.  Future calls 
  1476.         to  (load h1) will also look for files in the same  way.  When  a 
  1477.         file  has been successfully loaded PC-LISP examines the value  of 
  1478.         atom  $ldprint.  If this value is non-nil (default is t)  PC-LISP 
  1479.         will   print   a  message  saying  that  the  file   was   loaded 
  1480.         successfully. If this value is nil then no message is printed. In 
  1481.         either  case  if the load is successful a value of t is  returned 
  1482.         and if the load fails a value of nil is returned.
  1483.  
  1484.              (patom s1 [p1]) & (princ s1 [p1])
  1485.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1486.              Will  cause  the  S-expression  s1  to  be  printed  without   
  1487.         delimiters  or escapes on the output port p1,  or on the standard 
  1488.         output if no p1 parameter is given. Without delimiters means that 
  1489.         if  an  atom has a print name that is not legal without the  |  | 
  1490.         delimiters  or  with  an escape \,  neither will  be  added  when 
  1491.         printing  the  list  with patom.  patom returns  s1  while  princ 
  1492.         returns t. Strings will print without quotes or escapes.
  1493.  
  1494.              (print s1 [p1])
  1495.              ~~~~~~~~~~~~~~~
  1496.              Will cause the S-expression s1 to be printed with delimiters 
  1497.         and  escapes  if  necessary on the output  port  p1,  or  on  the 
  1498.         standard output if no p1 parameter is given. All atoms that would 
  1499.         require  | | delimiting,  strings that require " " delimiting and 
  1500.         characters  that would have to be preceeded by the escape  to  be 
  1501.         input,  will  be  printed with the delimiters and  any  necessary 
  1502.         escapes. If a character is one of the format characters tab, back 
  1503.         space,  carriage  return,  line feed or form feed,  it will print 
  1504.         preceeded by the escape as \t \b \r \n or \f respectively. If the 
  1505.         characters ordinal value is < 32 or > 126 and it is not a  format 
  1506.         character, it will print as \?. Print returns the expression s1.
  1507.  
  1508.              (read [p1 [s1]]) 
  1509.              ~~~~~~~~~~~~~~~~
  1510.              Reads  the  next S-expression from p1 or from  the  standard 
  1511.         input if p1 is not given and returns it.  If s1 is given and  end 
  1512.         of  file is read the read function will return s1.  If s1 is  not 
  1513.         given and end of file is read the read function will return nil.
  1514.  
  1515.              (readc [p1 [s1]])
  1516.              ~~~~~~~~~~~~~~~~~
  1517.              Reads  the next character from p1 or from the standard input 
  1518.         if  p1  is  not given and returns it as an  atom  with  a  single 
  1519.         character name.  If s1 is given and end of file is read the readc 
  1520.         function  will return s1.  If s1 is not given and end of file  is 
  1521.         read the readc function will return nil.
  1522.  
  1523.  
  1524.  
  1525.                                        25
  1526.  
  1527.  
  1528.  
  1529.              FILE I/O FUNCTIONS (CONT'D)
  1530.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1531.              (sys:unlink h1)
  1532.              ~~~~~~~~~~~~~~~
  1533.              Will erase the file whose name is the print name of atom h1. 
  1534.         If the erase is successful a value of 0 is returned. If the erase 
  1535.         is unsuccessful a value of -1 is returned.
  1536.  
  1537.              (truename p1)
  1538.              ~~~~~~~~~~~~~
  1539.              Will return an atom whose print name is the same as the name 
  1540.         of the file associated with port p1. This is just the same as the 
  1541.         value printed between the % and @ signs when a port is printed.
  1542.             
  1543.              (flatsize s1 [x1])
  1544.              ~~~~~~~~~~~~~~~~~~
  1545.              Returns the number of character positions necessary to print 
  1546.         s1 using the call (print s1). If x1 is present then flatsize will 
  1547.         stop  computing  the output size of s1 as soon as  it  determines 
  1548.         that  the size is larger than x1.  This feature is useful if  you 
  1549.         want  to see if something will fit in some small given amount  of 
  1550.         space but not knowing if the list is very big or not.
  1551.  
  1552.              (flatc s1 [x1])
  1553.              ~~~~~~~~~~~~~~~
  1554.              Returns the number of character positions necessary to print 
  1555.         s1 using the call (patom s1). x1 is the same as in flatsize.
  1556.  
  1557.              (pp-form s1 [ p1 [x1] ] )
  1558.              ~~~~~~~~~~~~~~~~~~~~~~~~~
  1559.              Causes  the  expression s1 to be pretty-printed on  port  p1 
  1560.         indented  by x1 spaces.  If p1 is absent  the standard output  is 
  1561.         assumed.  If  x1  is  absent  an indent of 0 is  assumed.  If  s1 
  1562.         contains  a list such as (prog ....  label1  ...  label2...)  the 
  1563.         normal  indenting will be ignored for label1 & label2  etc.  This 
  1564.         causes  the  labels to stand out.  For example IF  the  following 
  1565.         function were present in PC-LISP then I could run pp-form:
  1566.  
  1567.              -->(pp-form (getd 'character-index-written-in-lisp))   
  1568.              (lambda (a c)
  1569.                      (prog (n)
  1570.                            (setq n 1 a (explode a))
  1571.                            (cond ((fixp c) (setq c (ascii c))))
  1572.                        nxt:
  1573.                            (cond ((null a) (return nil)))
  1574.                            (cond ((eq (car a) c) (return n)))
  1575.                            (setq n (1+ n) a (cdr a))
  1576.                            (go nxt:))) 
  1577.              
  1578.              Note  that  the PC-LISP.L file contains a definition of  pp, 
  1579.         the  LISP   general function pretty printer.  It makes use of pp-
  1580.         form to get its work done.  I will not describe it here but it is 
  1581.         fully described in LISPcraft. 
  1582.  
  1583.  
  1584.  
  1585.  
  1586.                                        26
  1587.  
  1588.  
  1589.  
  1590.              FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1591.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1592.              These  functions  will either have an effect on the way  the 
  1593.         system behaves in the future or will give you a result about  the 
  1594.         way  the system has behaved in the past and future calls will not 
  1595.         necessarily give the same results.
  1596.  
  1597.              (def *a1* *l1*)    
  1598.              ~~~~~~~~~~~~~~~    
  1599.              a1  is a function name and l1 is a lambda,nlambda,  lexpr or 
  1600.         macro body.  The body is associated with the atom a1 from now  on 
  1601.         and  can  be  used as a user defined function.  Def  returns  a1.            
  1602.  
  1603.                -->(def first  (lambda(x)(car x)))
  1604.                -->(def llast  (lexpr(n)(last (arg n))))
  1605.                -->(def myadd  (nlambda(l)(eval(cons '+ l))))
  1606.                -->(def firstm (macro(l)(cons 'car (cdr l))))
  1607.  
  1608.              (defun *a1* [*a2*] *s0* *s1* *s2* ....*sN*)
  1609.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1610.              Defun  will  do the same job as "def" except  that  it  will 
  1611.         build  the  expression  body  for you.  a1 is  the  name  of  the 
  1612.         expression  that you are defining,  a2 is an optional  expression 
  1613.         kind  indicator  which  may be either expr,  fexpr or  macro. The 
  1614.         default  is  expr.  These kinds correspond  directly  to  lambda, 
  1615.         nlambda  and macro forms.  s0 specifies the formal parameters  to 
  1616.         the expression.  Usually this is just a list of symbols. If it is 
  1617.         a  single  symbol  it is assumed that the symbol  is  the  single 
  1618.         parameter  to an lexpr form and an lexpr form will be constructed 
  1619.         from the ensuing bodies s1....sn. If it is a list of symbols then 
  1620.         a  lambda,  nlambda  or macro body will be constructed  from  the 
  1621.         bodies  s1...sn according to the kind specified by parameter  a2. 
  1622.         For  example,  these calls to defun do the same job as the  above 
  1623.         calls to def.
  1624.  
  1625.                -->(defun first(x)(car x))
  1626.                -->(defun llast n (last (arg n))) 
  1627.                -->(defun myadd fexpr(l)(eval(cons '+ l)))
  1628.                -->(defun firstm macro(l)(cons 'car (cdr l)))
  1629.  
  1630.              (exit)
  1631.              ~~~~~~
  1632.              The  LISP interpreter will exit to MSDOS.  Depending on  how 
  1633.         big  you set LISP%MEM MSDOS may ask for a system disk  to  reload 
  1634.         COMMAND.COM.  Note that the video mode will be left alone if  you 
  1635.         call exit.  But if you leave via CONTROL-Z the video mode will be 
  1636.         set to 80x25B&W. (Only if you have made a call to (#scrmde#)).
  1637.              
  1638.              (gc)
  1639.              ~~~~
  1640.              Starts garbage collection of alpha and cell space. Returns t 
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.                                        27
  1648.  
  1649.  
  1650.  
  1651.              FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1652.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1653.              CONT'D
  1654.              ~~~~~~
  1655.              (get a1 a2)
  1656.              ~~~~~~~~~~~
  1657.              Will  return  the value associated with property key a2   in 
  1658.         a1's property list.  This value will have been set by a  previous 
  1659.         call to (putprop a1 s1 a2). Example:
  1660.  
  1661.              -->(get 'frank 'lastname)
  1662.  
  1663.              (getd a1)
  1664.              ~~~~~~~~~
  1665.              Will return the lambda,  nlambda or macro expression that is 
  1666.         associated  with  a1 or nil if no such expression  is  associated 
  1667.         with a1.
  1668.  
  1669.              (getenv h1)
  1670.              ~~~~~~~~~~~
  1671.              Will  return  an atom whose print name is the string set  by 
  1672.         environment variable h1. For example we can get the PATH variable 
  1673.         setting by evaluating (getenv 'PATH).  Note that these must be in 
  1674.         upper case because MS-DOS converts the variable names to upper.
  1675.  
  1676.              (hashtabstat)
  1677.              ~~~~~~~~~~~~~
  1678.              Will  return a  list containing 503 fixnums.  Each  of these 
  1679.         represents  the  number of elements in the bucket for  that  hash 
  1680.         location  in  the heap hash table.  503 is the size of  the  hash 
  1681.         table.  This  is not especially useful for you but it gives me  a 
  1682.         way  of  checking  how the hashing function is  distributing  the 
  1683.         heap using cells.  Heap using cells are symbol,  string and hunk. 
  1684.         The  cell  itself  is allocated from the alpha  or  other  memory 
  1685.         blocks  while  its  variable length space is allocated  from  the 
  1686.         heap.  Hence  this  table contains the oblist  plus  strings  and 
  1687.         hunks.  Note  however that unlike symbols,  strings and hunks are 
  1688.         not unique objects.
  1689.  
  1690.              (memstat)      { not present in Franz }
  1691.              ~~~~~~~~~
  1692.              Returns  three fixnums. The first is the percentage of  cell 
  1693.         space that is in use.  The second is the percentage of alpha cell 
  1694.         space and the third is the percentage of heap space in use.  When 
  1695.         any of these reach 100%, garbage collection will occur. Alpha and 
  1696.         cell  space is collected together.  Heap space is only  collected 
  1697.         when  you run out.  After garbage collection you will  see  these 
  1698.         three  percentages  drop.  The alpha and cell percentages  should 
  1699.         drop  to  tell  you how much memory is actually in  use  at  that 
  1700.         moment.  The  heap  space when compacted and  gathered  will  not 
  1701.         necessarily drop to indicate how much you really have left.  This 
  1702.         is  because heap space is gathered in blocks of 16K,  not all  at 
  1703.         once as with atoms and cells.  So, there will almost certainly be 
  1704.         more  than 20% free heap space in other non compacted blocks even 
  1705.         if memstat reports 80% of the heap space is in use.                   
  1706.  
  1707.  
  1708.                                        28
  1709.  
  1710.  
  1711.  
  1712.              FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1713.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1714.              CONT'D
  1715.              ~~~~~~
  1716.              (oblist)
  1717.              ~~~~~~~~
  1718.              Returns  a  list of most known symbols in the system at  the 
  1719.         current  moment.  Note  that if you call oblist  and  assign  the 
  1720.         result  somewhere you will cause every one of those objects to be 
  1721.         kept  by the system.  If there are lots of large alpha atoms  the 
  1722.         heap  and alpha space will be tied up until you set the  assigned 
  1723.         variable to some other value.  Several special internal atoms are 
  1724.         not placed in the returned list to keep them out of user code.
  1725.  
  1726.              (plist a1)
  1727.              ~~~~~~~~~~
  1728.              Will return the property list for atom a1. The property list 
  1729.         is of the form ((ke1 . value1)(key2 . value2)...(keyn . valuen)). 
  1730.         Note  that  plist returns a top level copy of the  property  list 
  1731.         because remprop destroys this lists top level structure. 
  1732.  
  1733.              (putd a1 l1)
  1734.              ~~~~~~~~~~~~
  1735.              Identical  to "def" except that the parameters a1 and l1 are 
  1736.         evaluated.  This  allows  you  to  write  functions  that  create 
  1737.         functions and add them to the LISP interpreter.
  1738.              
  1739.              (putprop a1 s1 a2)
  1740.              ~~~~~~~~~~~~~~~~~~
  1741.              Adds to the property list of a1 the value s1 associated with 
  1742.         the  property  indicator a2.  It returns the  value  of  a1.  For 
  1743.         example: (putprop 'Peter 'AshwoodSmith 'lastname)
  1744.  
  1745.              (remprop a1 a2)
  1746.              ~~~~~~~~~~~~~~~
  1747.              Removes  the  property  associated  with  key  a2  from  the 
  1748.         property list of atom a1. The top level structure of the property 
  1749.         list  is  actually destroyed.  It returns the old  property  list 
  1750.         starting at the point where the deletion was made.
  1751.  
  1752.              (set a1 s1)
  1753.              ~~~~~~~~~~~  
  1754.              Will  bind a1 to s1 at current scope level or globally if no 
  1755.         scope exists for a1 yet. Set returns s1.
  1756.  
  1757.              (setplist a1 l1)
  1758.              ~~~~~~~~~~~~~~~~
  1759.              Will  set the property list of atom a1 to the list l1  where 
  1760.         the  list must be ((keyn.valn)..). It returns this new list l1.
  1761.  
  1762.              (setq *a1* s1 *a2* s2 ..... *an* sn)
  1763.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1764.              Allows an infinite number of variable and value pairs and it 
  1765.         does  not  evaluate the variables a1...an.  So (setq  a  'val1  b 
  1766.         'val2) binds val1 to a and val2 to b. Setq will return sn.
  1767.  
  1768.  
  1769.                                        29
  1770.  
  1771.  
  1772.  
  1773.              FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1774.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1775.              CONT'D
  1776.              ~~~~~~
  1777.              (setsyntax a1 a2 l1)
  1778.              ~~~~~~~~~~~~~~~~~~~~
  1779.                 Is  a  way of defining a read expression macro l1  to  be 
  1780.         associated   with  chracter  a1.   And  invoked  in  'vmacro   or 
  1781.         'vsplicing-macro  mode depending on a2.  This function allows you 
  1782.         to  alter  the way that (read)  works.  Basically  after  calling 
  1783.         setsyntax   the  expression  l1  will  be  invoked  whenever  the 
  1784.         character  a1 is found in the input stream and this character  is 
  1785.         not  escaped or hidden in a comment or delimiters of  some  kind. 
  1786.         For example a macro :  that pretty prints the following  function 
  1787.         name could be defined as follows:
  1788.  
  1789.              -->(setsyntax '|:| 'vmacro '(lambda()(list 'pp (read))))
  1790.              
  1791.              Then  if  I  typed :pp at the input prompt the  character  : 
  1792.         would  be  read causing the expression (list 'pp  (read))  to  be 
  1793.         invoked.  This would then read the pp atom and construct the list 
  1794.         (pp  pp)  which  would then be passed back to the  read  function 
  1795.         which would pass it back to the eval loop which will evaluate  it 
  1796.         and  pretty  print the function pp.  Read macro  expressions  are 
  1797.         lambda  expressions that take no parameters.  Any calls to (read) 
  1798.         must not have any arguments,  (read) will know where to read  the 
  1799.         next expression from because of a global binding performed by the 
  1800.         read macro driver on behalf of the read function. 
  1801.  
  1802.              Splicing macros are also available. Just replace the 'vmacro 
  1803.         parameter  with 'vsplicing-macro.  What will happen is  that  the 
  1804.         returned  list will be spliced into the input expression,  rather 
  1805.         than forming a sublist expression in the current input.  This  is 
  1806.         useful  if  you  want to define your own comment  delimiters  and 
  1807.         return nil.  For example let's define a new comment delimiter say 
  1808.         the < and > characters.
  1809.  
  1810.              -->(defun SkipToEnd()
  1811.                        (cond ((eq (readc) '|>|) nil)
  1812.                              (t (SkipToEnd))))
  1813.              SkipToEnd
  1814.              -->(setsyntax '|<| 'vsplicing-macro '(lambda()(SkipToEnd)))
  1815.              t  
  1816.              -->(and t <junk junk junk> t)
  1817.              t
  1818.  
  1819.              What I have done is first write a comment skipping  function 
  1820.         that  just  reads  input character by character until  the  >  is 
  1821.         found.   I  then  associate  the  character  '<'  with  a  lambda 
  1822.         expression that calls this skipper. The macro is a splicing macro 
  1823.         as  the  last (and t <junk...junk> t) demonstrates.  Think  about 
  1824.         what would have happened if the macro were non splicing and I put 
  1825.         a comment in the (and ....) list.  Try it and see,  then you will 
  1826.         know why splicing macros are needed. 
  1827.  
  1828.  
  1829.  
  1830.                                        30
  1831.  
  1832.  
  1833.  
  1834.              FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1835.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1836.              CONT'D
  1837.              ~~~~~~
  1838.              
  1839.              (trace [*a1* *a2* *a3* ..... *an*])
  1840.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1841.              Will  turn on tracing of the user defined functions a1...an. 
  1842.         Note that you cannot trace built in functions.  If you call trace 
  1843.         with  no  parameters it will return a list of  all  user  defined 
  1844.         functions  that  have been set for tracing by a previous call  to 
  1845.         trace,  otherwise  trace  returns exactly the list  (a1  a2...an) 
  1846.         after  enabling tracing of each of these user defined  functions. 
  1847.         If  any  of the atoms is not a user defined function trace  stops 
  1848.         and returns an error.  All atoms up to the point of error will be 
  1849.         traced.   
  1850.              
  1851.              (untrace [*a1* *a2* *a3* ..... *an*])
  1852.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1853.              Will  disable tracing of the listed functions which must all 
  1854.         be user defined.  If no parameters are given it disables  tracing 
  1855.         of  all functions.  Untrace returns a list of all functions whose 
  1856.         tracing has been disabled. Here is a demonstration of how you can 
  1857.         use  them.  The  -->  is the LISP prompt.  This is  the  sort  of 
  1858.         sequence  that you should see on the console.  The comments  ;... 
  1859.         were added to tell you what is going on.
  1860.  
  1861.           -->(defun factorial(n)                ; define n! = n * (n-1)!
  1862.                     (cond ((zerop n) 1)
  1863.                           (t (* n (factorial (1- n]     
  1864.  
  1865.           factorial
  1866.           -->(trace factorial)                  ; ask LISP to trace n!
  1867.           (factorial)
  1868.           -->(factorial 5)                      ; ask LISP for 5!
  1869.           <enter> factorial( 5 )                ; entered with parm=5
  1870.            <enter> factorial( 4 )               ;    "      "    "  4
  1871.             <enter> factorial( 3 )              ;    "      "    "  3
  1872.              <enter> factorial( 2 )             ;    "      "    "  2
  1873.               <enter> factorial( 1 )            ;    "      "    "  1
  1874.                <enter> factorial( 0 )           ;    "      "    "  0
  1875.                <EXIT>  factorial 1              ; exit 0! = 1
  1876.               <EXIT>  factorial 1               ; exit 1! = 1
  1877.              <EXIT>  factorial 2                ; exit 2! = 1
  1878.             <EXIT>  factorial 6                 ; exit 3! = 6
  1879.            <EXIT>  factorial 24                 ; exit 4! = 24
  1880.           <EXIT>  factorial 120                 ; exit 5! = 120
  1881.           120
  1882.           -->(untrace factorial)                ; ask LISP to shut up
  1883.           (factorial)
  1884.           -->(factorial 5)                      ; now it is quiet again.
  1885.           120
  1886.           -->   
  1887.  
  1888.  
  1889.  
  1890.  
  1891.                                        31
  1892.  
  1893.  
  1894.  
  1895.              FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1896.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1897.              CONT'D
  1898.              ~~~~~~
  1899.  
  1900.              (showstack)
  1901.              ~~~~~~~~~~~
  1902.                   This  function will display a copy of the last 20  eval 
  1903.         and  apply  evaluations from the internal stack.  The top of  the 
  1904.         internal  stack  is copied whenever LISP is about  to  enter  the 
  1905.         break level (prompt 'er>').   This means that if you execute some 
  1906.         function  and  it aborts prematurely you can call showstack  from 
  1907.         the break level and see exactly what lead to the error.  Whenever 
  1908.         a  new  error occurs the old copy of the top 20 elements  on  the 
  1909.         internal  stack  is  lost and a new trace is copied  for  you  to 
  1910.         display  via  (showstack).  This  is unlike  Franz  which  allows 
  1911.         lots of  break levels.  For example consider this example session 
  1912.         with PC-LISP which is similar to an example in LISPcraft.
  1913.                        
  1914.              -->(defun foobar(y)(prog(x)(setq x (cons (car 8) y]
  1915.              foobar
  1916.              -->(foobar '(a b c))
  1917.              --- error evaluating built in function [car] ---
  1918.              er>x
  1919.              ()
  1920.              er>y
  1921.              (a b c)
  1922.              er>(showstack)
  1923.  
  1924.              [] (car 8)
  1925.              [] (car 8)
  1926.              [] (cons <**> y)
  1927.              [] (setq x <**>)
  1928.              [] (prog(x) <**>)
  1929.              [] (foobar '(a b c))
  1930.  
  1931.              t 
  1932.  
  1933.              In  this example I declared a function called 'foobar' which 
  1934.         runs a prog and does a single assignment to x.  When I execute it 
  1935.         with  parameter '(a b c).  PC-LISP correctly tells me that  there 
  1936.         was  an  error  evaluating the built in  function  'car'.  I  can 
  1937.         examine  the values of x and y and see that x is still set to the 
  1938.         empty  list () that the prog call set it to.  y is bound  to  the 
  1939.         parameter passed to foobar as expected. Next I called (showstack) 
  1940.         to see the trace of execution. I see that the top evaluation (car 
  1941.         8)  is the culprit.  The evaluation previous to that is also (car 
  1942.         8)  but  this  evaluation  was  before  the  arguments  had  been 
  1943.         evaluated.  Remember that fixnums eval to  themselves.  The  <**> 
  1944.         symbols  in  the show stack are just a short hand way  of  saying 
  1945.         look  at the entry above to see what the <**> should be  replaced 
  1946.         with.  This  greatly  reduces the amount of information that  you 
  1947.         have to look at when you read a stack dump. It also allows you to 
  1948.         follow the stream of partial evaluations by looking at each  <**> 
  1949.         in turn. Note that infinite recursion leaves a stream of <**>'s.
  1950.  
  1951.  
  1952.                                        32
  1953.  
  1954.  
  1955.  
  1956.              LIST EVALUATION CONTROL FUNCTIONS
  1957.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1958.              These functions are the control flow functions for LISP they 
  1959.         effect  which  lists are evaluated and how.  They operate on  the 
  1960.         basic LISP function types,  descriptions of which follow. 
  1961.  
  1962.              (lambda l1 s1....sn)
  1963.              ~~~~~~~~~~~~~~~~~~~~
  1964.              This  is  not a function but it is a  list  construct  which      
  1965.         can act as a function in any context where a function is legal. A 
  1966.         lambda  expression is a function body.  The S-expressions  s1..sn 
  1967.         are  expressions  that are evaluated in the  order  s1...sn.  The 
  1968.         result  is  the evaluation of sn.  The atoms in the list  l1  are 
  1969.         called  bound variables.  They will be bound to values that occur 
  1970.         on  the right of the lambda expression before  the  S-expressions 
  1971.         s1..sn  are  evaluated  and  unbound after the  value  of  sn  is 
  1972.         returned. 
  1973.  
  1974.              (nlambda l1 s1....sn)
  1975.              ~~~~~~~~~~~~~~~~~~~~~
  1976.              This is a function body construct similar to lambda but with 
  1977.         a few major differences.  The first is that the list l1 must only 
  1978.         specify  one formal parameter.  This will be set to a list of the 
  1979.         UNEVALUATED  parameters  that  fall on the right of  the  nlambda 
  1980.         expression when it is being evaluated.  This function allows  you 
  1981.         to  write  functions with a variable number of parameters and  to 
  1982.         control  the evaluation of these parameters.  For example we  can 
  1983.         write a function called 'ADDEM that behaves the same way as '+ in 
  1984.         nearly all contexts as follows:
  1985.  
  1986.              -->(def ADDEM (nlambda(l)(eval(cons '+ l))))  
  1987.         or   
  1988.              -->(defun ADDEM fexpr(l)(eval(cons '+ l)))
  1989.  
  1990.              Both  of  which create the  same  nlambda  expression.  This 
  1991.         function  will  behave as follows when spotted on the left  of  a 
  1992.         sequence  of parameters 1 2 3 4.  First it will not evaluate  the 
  1993.         sequence of parameters 1 2 3 4. Second it makes these into a list 
  1994.         (1  2  3  4).  It then binds 'l to this list  and  evaluates  the 
  1995.         expression (eval(cons( '+ l))).  This expression results in (eval 
  1996.         (+ 1 2 3 4)). Which is just the desired result 10.
  1997.  
  1998.              (label a1 (lambda|nlambda l1 s1..sn))     {not in Franz}
  1999.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2000.              This acts just like a lambda expression except that the body 
  2001.         is  temporarily  bound to the name a1 for evaluation of the  body 
  2002.         s1.  This allows recursive calls to the same body. The binding of 
  2003.         the  body  to  the  name a1 will be  forgotten  as  soon  as  the 
  2004.         expression s1 terminates the recursion. For example:   
  2005.  
  2006.              (label LastElement (lambda(List)
  2007.                                 (cond ((null (cdr List))(car List))
  2008.                                       (t (LastElement (cdr List))))))
  2009.  
  2010.  
  2011.  
  2012.  
  2013.                                        33
  2014.  
  2015.  
  2016.  
  2017.              LIST EVALUATION CONTROL FUNCTIONS CONT'D
  2018.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2019.              (lexpr (a1) s1 s2 .... sN)
  2020.              ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2021.              This  function  body  form is similar to  the  nlambda  form 
  2022.         except that all of its variable number of arguments are evaluated 
  2023.         and  the  args are accessed in a  different  manner.  The  second 
  2024.         element of the lexpr form must be a list of exactly one atom. The 
  2025.         remaining  elements  of the lexpr form represent bodies that  are 
  2026.         evaluated  one after the other.  The result of evaluating a  list 
  2027.         whose  first element is an lexpr is just the value  that  results 
  2028.         from  evaluating  s1....sN  in order in the context where  a1  is 
  2029.         bound to the number of actual parameters, and the (arg), (setarg) 
  2030.         and (listify) functions behave as follows:
  2031.  
  2032.              (arg [n1])
  2033.              ~~~~~~~~~~
  2034.              When  in the context of an lexprs' evaluation,  will  return 
  2035.         either the number of arguments provided to the nearest  enclosing 
  2036.         lexpr,  or  the nth argument indexed from 1 passed to that  lexpr 
  2037.         depending  on whether n1 is provided or not as  a  parameter.  An 
  2038.         error occurs if n1 is less than 1 or greater than (arg).
  2039.  
  2040.              (setarg n1 s1)
  2041.              ~~~~~~~~~~~~~~
  2042.              When  in the context of an lexprs' evaluation,  will  return 
  2043.         exactly s1.  It has the side effect that future calls to (arg n1) 
  2044.         will  return  the  value  s1  for the  duration  of  the  current 
  2045.         enclosing lexpr evaluation.  An error occurs if n1 is less than 1 
  2046.         or greater than (arg).
  2047.  
  2048.              (listify n1)
  2049.              ~~~~~~~~~~~~
  2050.              When in the context of an lexprs' evaluation,  will return a 
  2051.         tail  of  the list of arguments that were passed to  the  nearest 
  2052.         enclosing lexpr.  The head of this tail is either (arg n1) if  n1 
  2053.         is positive,  or (arg (+ (arg) n1 1)) if n is negative.  An error 
  2054.         occurs  if the value of n1 does not correctly index a head within 
  2055.         the actual argument list of the nearest enclosing lexpr.
  2056.  
  2057.              Here  is  a small lexpr example which just sets some  global 
  2058.         variables  to  allow us to see what went  on  inside.  Again  see 
  2059.         LISPcraft for a much better description.
  2060.  
  2061.              -->((lexpr(n)
  2062.                     (setq a0 n a1 (arg 1) an (arg(arg)))
  2063.                     (listify -3)  
  2064.                  ) 'A 'B 'C 'D 'E 'F 'G )  
  2065.              (E F G)
  2066.              -->a0
  2067.              7
  2068.              -->a1
  2069.              A
  2070.              -->an
  2071.              G
  2072.  
  2073.  
  2074.                                        34
  2075.  
  2076.  
  2077.  
  2078.              LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2079.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2080.              (apply s1 l1)
  2081.              ~~~~~~~~~~~~~
  2082.              The  function s1 is evaluated in the context resulting  from 
  2083.         binding  its formal parameters to the values in l1. The result of 
  2084.         this evaluation is returned. Example:
  2085.  
  2086.              -->(apply '(lambda(x y z)(* (+ x y) z)) '(2 3 4))
  2087.              20
  2088.              
  2089.              (cond l1 l2 ... ln)
  2090.              ~~~~~~~~~~~~~~~~~~~
  2091.              The lists l1 ...  ln  are checked on by one. They are of the 
  2092.         form  (s1 s2 .. sn). Cond  evaluates the s1's one by one until it 
  2093.         finds one that does not eval to nil. It then evaluates the s2..sn 
  2094.         expressions  one by one and returns the result of evaluating  sn. 
  2095.         If  all of the s1's (called guards) evaluate to nil,  it  returns 
  2096.         'nil. For example:
  2097.                   
  2098.               -->(cond ((equal '(a b c) (cdr '(x a b c))) 'yes)
  2099.                        (t 'opps))         
  2100.              yes
  2101.  
  2102.              (eval s1) 
  2103.              ~~~~~~~~~
  2104.              Runs  the LISP interpreter on the S-expression s1.  It  just 
  2105.         removes a quote from the expression s1. For example:
  2106.              
  2107.              -->(eval '(+ 2 4))
  2108.              6
  2109.  
  2110.              (mapcar s1 l1 l2 l3 .... ln)
  2111.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2112.              This  function  will map the function s1 onto the  parameter 
  2113.         list made by taking the car of each of l1...ln.  It forms a  list 
  2114.         of  the  results  of the repeated application of s1 to  the  next 
  2115.         elements in the lists l1...ln. It stops when the list l1 runs out 
  2116.         of  elements.  Note  that each of l1...ln should  have  the  same 
  2117.         number  of elements,  although this condition is not checked  for 
  2118.         and nil will be substituted if a list runs out of elements before 
  2119.         the others. Extra elements in any list are ignored. For example:
  2120.  
  2121.              -->(mapcar '< '(10 20 30) '(11 19 30))
  2122.              (t nil nil)
  2123.  
  2124.              Which  returns the results of (< 10 11) (< 20 19) and (<  30 
  2125.         30) as the list (t nil nil).  Note that s1 could be any built  in 
  2126.         function,   user  defined  function  or  lambda  expression.  For 
  2127.         example:
  2128.  
  2129.              -->(mapcar 'putprop '(John Fred Bill)
  2130.                                  '(Mary Sue Linda)
  2131.                                  '(mother sister daughter))
  2132.              (Mary Sue Linda) 
  2133.  
  2134.  
  2135.                                        35
  2136.  
  2137.  
  2138.  
  2139.              LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2140.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2141.              (defun a1 macro l1 s1 s2 ... sn)
  2142.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     
  2143.              Macro  is a special body,  similar to nlambda except that it 
  2144.         may causes code replacement when it is evaluated. When a macro is 
  2145.         encountered  the  list  (name  arg1  arg2...)  is  bound  to  the 
  2146.         macro parameter. Name is the name of the macro and arg1..argn are 
  2147.         the  arguments that were provided to it.  Then the bodies of  the 
  2148.         macro  are evaluated and the expression returned by the last body 
  2149.         is returned.  Then depending on the value of displace-macros  and 
  2150.         the type of the returned S-expression,  the returned S-expression 
  2151.         may  destructively replace the peice of code that called  it.  If 
  2152.         the  value of displace-macros is nil (its default value)  or  the 
  2153.         type  of  the  returned  S-expression  is not  one  that  can  be 
  2154.         replaced, no destructive substitution will occur. Next regardless 
  2155.         of  whether  the  S-expression was substituted  or  not,  the  S-
  2156.         expression  is evaluated and the value returned.  This all sounds 
  2157.         pretty  compex,  but  in  fact it is quite  simple,  here  is  an 
  2158.         example:
  2159.  
  2160.              -->(defun first-elemet macro(l)(cons 'car (cdr l)))
  2161.              first-element
  2162.              -->(setq x '(first-element '(a b c)))
  2163.              (first-element '(a b c)) 
  2164.              -->(eval x)
  2165.              a
  2166.              -->x
  2167.              (first-element '(a b c))
  2168.              -->(setq displace-macros t)
  2169.              t
  2170.              -->(eval x)
  2171.              a
  2172.              -->x
  2173.              (car '(a b c)) 
  2174.              -->(eval x)
  2175.              a
  2176.  
  2177.              In  the  example above I have first declared a macro  called 
  2178.         'first-element'  which  when run given a  list  parameter  should 
  2179.         return  the  first element in the list.  I could have  done  this 
  2180.         using  a  lambda  expression  but this  would  require  parameter 
  2181.         binding etc every time I execute 'first-element'.  Rather, what I 
  2182.         have chosen to do is to cause (first-element x) to be replaced by 
  2183.         the  code  (car  x) everywhere it  is  encountered.  Then  future 
  2184.         execution of (first-element x) is just as costly as an  execution 
  2185.         of (car x).  Let's examine what I did above.  First I declared  a 
  2186.         macro  which will take the parameter (first-element -stuff-)  and 
  2187.         construct  the  code  (car  -stuff-).  I  then set  x  to  be  an 
  2188.         expression  which when evaluated should give 'a.  I  then  verify 
  2189.         this  by evaluating x,  sure enough it is 'a.  I then look at the 
  2190.         code for x which has not changed.  Now, I set the global variable 
  2191.         displace-macros to be non nil.  What I should now expect is  that 
  2192.         (eval  x) will give the same answer,  but with the side effect of 
  2193.         doing  the  code  substitution  so  that  future  passes  of  the 
  2194.  
  2195.  
  2196.                                        36
  2197.  
  2198.  
  2199.  
  2200.              LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2201.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2202.         expression  bound to x will run much faster.  This is  the  whole 
  2203.         reason  for  macros,  they are not much use if they are  expanded 
  2204.         every  time,  it is more work than a simple user  defined  lambda 
  2205.         expression  call.  Anyway  after  running x and  looking  at  its 
  2206.         definition  we can see that the code has indeed been substituted. 
  2207.         It is worth noting that unless you set displace-macros to be  non 
  2208.         nil  all  your  macros  will  be expanded  every  time  they  are 
  2209.         encountered.  This is probably not what you want.  You should set 
  2210.         displace-macros to be t to cause macros to behave  properly.  The 
  2211.         only  reason I did not set displace-macros to be t by default  is 
  2212.         that Franz does not. 
  2213.  
  2214.              Note,  macros  may  return any type expression however  some 
  2215.         expressions  may  not  result in  code  substitution  because  of 
  2216.         internal  problems with doing the substitution.  In particular  a 
  2217.         macro  that directly returns an atom,  hunk or string will  never 
  2218.         result  in code replacement,  while a macro that returns a  list, 
  2219.         fixnum, flonum or port can result in code replacement. Since code 
  2220.         replacement  is a physical copying of one cell over another  heap 
  2221.         space  owning functions cannot be physically substituted  because 
  2222.         their  cells  are  unique. You  should note  however  that  these 
  2223.         limitations  do not occur much in practice since usually a  macro 
  2224.         will  return a number or a list.  For exampe a quoted atom is  ok 
  2225.         because  it  is really the list (quote x).  In any  case  PC-LISP 
  2226.         macros  will  always  return  the correct  values  regardless  of 
  2227.         these substitution limitations.
  2228.  
  2229.              Macro   bodies can function in all contexts that an  nlambda 
  2230.         body can function, however expansion, if it is to occur will only 
  2231.         happen  when  a macro is referred to by its atom name  which  was 
  2232.         defined by a defun, def or putd call. Using macros in this manner 
  2233.         does not seem to have any real use though.
  2234.  
  2235.              (macroexpand s1)
  2236.              ~~~~~~~~~~~~~~~~     
  2237.              This  function lets you see  what the macro expansion of  s1 
  2238.         looks like prior to evaluation and substitution. This function is 
  2239.         necessary  to help debug macro definitions because otherwise  the 
  2240.         intermediate code is only visible on the showstack and the code 
  2241.         may not be on the showstack when the error occurs. For example:
  2242.  
  2243.              -->(macroexpand '(first-element '(a b c)))
  2244.              (car '(a b c))
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.  
  2252.  
  2253.  
  2254.  
  2255.  
  2256.  
  2257.                                        37
  2258.  
  2259.  
  2260.  
  2261.              LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2262.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2263.  
  2264.              (prog l1 s1.....sn)
  2265.              ~~~~~~~~~~~~~~~~~~~
  2266.              Prog  is  a  way  of  escaping  the  pure  LISP  applicative 
  2267.         programming environment.  It allows you to evaluate a sequence of 
  2268.         S-expressions  one after the other in true imperative  style.  It 
  2269.         allows you to use the functions (go..) and (return ..) to perform 
  2270.         the  goto and return functions that imperative languages  permit. 
  2271.         Prog  operates  as follows:  The list l1 which is a list of  atom 
  2272.         names  is  scanned and each atom is bound to nil  at  this  scope 
  2273.         level.  Next the S-expressions s1..sn are scanned once. If any of 
  2274.         s1..sn  are atoms they are bound to the S-expression that follows 
  2275.         them.  Next we start evaluating lists s1...sn ignoring  the atoms 
  2276.         which  are  assumed  to be labels.  If after  evaluation  an   S-
  2277.         expression  is  of the form ($[|return|]$  Z) we unbind  all  the 
  2278.         atoms  and  labels  and  return  the  S-expression  Z.  If  after 
  2279.         evaluation  a  list  is  of the form ($[|go|]$ Z)  we  alter  our 
  2280.         evaluation to start next at Z.  The functions (go)  and  (return) 
  2281.         will return the above mentioned special forms.  If at any time we 
  2282.         reach sn, and it is not a go or a return, we simply unbind all of 
  2283.         l1  and the labels in s1...sn and return the result of evaluating 
  2284.         sn.  Note  that prog labels must be alpha or literal alpha atoms. 
  2285.         Also note that the (return) and (go) mechanisms are not the  same 
  2286.         as  Franz and will only operate if the special form works its way 
  2287.         back  to the prog.  Because of this you are advised to  keep  the 
  2288.         calls  to go and return within the lexical scope of the prog body 
  2289.         and  to insure that the special form returned is not absorbed  by 
  2290.         some higher level function. 
  2291.              
  2292.              For example:
  2293.  
  2294.                -->(prog (List SumOfAtoms)
  2295.                         (setq List (hashtabstat))
  2296.                         (setq SumOfAtoms 0)
  2297.                    LOOP (cond ((null List) (return SumOfAtoms)))
  2298.                         (setq SumOfAtoms (+ (car List) SumOfAtoms))
  2299.                         (setq List (cdr List))
  2300.                         (go   LOOP)
  2301.                   )
  2302.                306  
  2303.  
  2304.              This peice of code operates as follows. First it creates two 
  2305.         local variables.  Next it binds the variable List to the list  of 
  2306.         hash bucket totals from the alpha hash table.  It then sets a sum 
  2307.         counter  to 0.  Next it checks the List variable to see if it  is 
  2308.         nil. If so it returns the Sum Of all the Atoms. Otherwise it adds 
  2309.         the  first  fixnum in the list List to  the  running  SumOfAtoms, 
  2310.         winds in the list List by one,  and jumps to LOOP. Note also that 
  2311.         we  can accomplish the same thing as the above prog with the much 
  2312.         simpler example which follows:
  2313.  
  2314.              -->(eval (cons '+ (hashtabstat)))
  2315.              306
  2316.  
  2317.  
  2318.                                        38
  2319.  
  2320.  
  2321.  
  2322.              HUNKS 
  2323.              ~~~~~
  2324.              A hunk is just an array of 1 to 126 elements.  The  elements 
  2325.         may be any other type including hunks.  With hunks it is possible 
  2326.         to create self referencial structures (see DANGEROUS  FUNCTIONS). 
  2327.         A  Hunks  element storage space comes from the heap.  Hunks  like 
  2328.         strings   and  alpha  print  names  are  subject  to   compaction 
  2329.         relocation and reclaimation.
  2330.  
  2331.              (hunk s1 s2 .... sN)
  2332.              ~~~~~~~~~~~~~~~~~~~~
  2333.              Returns  a  newly created hunk of size N whose elements  are 
  2334.         s1,  s2  ...  sN in that order.  N must be in the range 1 to  126 
  2335.         inclusive.   Note  that  a  hunk  is  printed  like  a  list  but 
  2336.         surrounded by { }. Ie {s1 s2 ...sN}. 
  2337.  
  2338.              (cxr n1 H)
  2339.              ~~~~~~~~~~
  2340.              Returns the n1'th element of hunk H indexed from 0. Hence n1 
  2341.         must be in the range 0 .. (hunksize H)-1.
  2342.  
  2343.              (hunkp s1)
  2344.              ~~~~~~~~~~
  2345.              Returns  true  if s1 is of type hunk,  otherwise it  returns 
  2346.         nil.  Note  this function has also been mentioned with the  other 
  2347.         predicates.
  2348.  
  2349.              (hunksize H)
  2350.              ~~~~~~~~~~~~
  2351.              Returns a fixnum whose value is the size of the  hunk.  This 
  2352.         value is one larger than the largest index allowed into the  hunk 
  2353.         by  both cxr and rplacx.  The size of a hunk is fixed at the time 
  2354.         of its creation and can never change throughout its life.
  2355.  
  2356.              (makhunk n1) or (makhunk (s1 s2 ...sN))
  2357.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2358.              The  first form returns a nil filled hunk of   n1  elements. 
  2359.         Needless  to say,  n1 must be between 1 and  126  inclusive.  The 
  2360.         second form is just identical to (hunk s1.....sN).
  2361.  
  2362.              (rplacx n1 H s1)
  2363.              ~~~~~~~~~~~~~~~~
  2364.              Returns the hunk H, however as a side effect element n1 of H 
  2365.         has been made (eq) to s1.  In other words H[n1] = s1.  Note  that 
  2366.         this  function  like rplaca and rplacd allows you to create  self 
  2367.         referencial structures.
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.  
  2374.  
  2375.  
  2376.  
  2377.  
  2378.  
  2379.                                        39
  2380.  
  2381.  
  2382.  
  2383.              DANGEROUS FUNCTIONS
  2384.              ~~~~~~~~~~~~~~~~~~~ 
  2385.              The  following  two functions have  potentially  disasterous 
  2386.         results if used by unwary or inexperienced LISP programmers.  The 
  2387.         third function is provided to make their use less dangerous.
  2388.  
  2389.              (rplaca l1 s1)
  2390.              ~~~~~~~~~~~~~~
  2391.              The  cons  cell l1 is physically altered so that its car  is 
  2392.         (eq) to s1.  That is the car pointer of l1 is set to point to s1. 
  2393.         The list l1 is returned. (l1 must not be nil).
  2394.  
  2395.              (rplacd l1 s1)
  2396.              ~~~~~~~~~~~~~~
  2397.              The  cons cell l1 is physically altered so that its  cdr  is 
  2398.         (eq) to s1.  That is the cdr pointer of l1 is set to point to s1. 
  2399.         The list l1 is returned. (l1 must not be nil).
  2400.              
  2401.              (copy s1)
  2402.              ~~~~~~~~~
  2403.              Returns  a  structure (equal) to s1 but made with  new  cons 
  2404.         cells.  Note  that only cons cells are  copied,  strings,  atoms, 
  2405.         hunks etc are not copied.
  2406.  
  2407.              Warning  #1  - altering  a cons cell allows  you  to  create 
  2408.         structures that point (refer) to themselves.  While this does not 
  2409.         cause a problem for the LISP interpreter or garbage collector  it 
  2410.         does  mean  that many built in functions will either loop  around 
  2411.         the structure infinitely or recurse until a stack overflows. 
  2412.  
  2413.              -->(setq x '(a b c d))
  2414.              (a b c d)
  2415.              -->(rplaca x x)
  2416.              ((((((((((((((((((((((((((((((((((((((((...............
  2417.              -- stack overflow --
  2418.              er>
  2419.  
  2420.              Warning #2 - altering a cons cell can cause a million little 
  2421.         side  effects that you did not count on.  Consider carefully  the 
  2422.         following example.
  2423.              
  2424.              -->(defun FooBar(x) (cons x '(b c)))
  2425.              FooBar
  2426.              -->(setq z (FooBar 'a))
  2427.              (a b c)
  2428.              -->(rplaca (cdr z) 'GOTCHA!)
  2429.              (GOTCAH! c)
  2430.              -->(FooBar 'a)      
  2431.              (a GOTCHA! c)      
  2432.              
  2433.              What  happened?  The rplaca has modified the list that is  a 
  2434.         constant  in  FooBar.  Lists are not copied unless necessary  and 
  2435.         building the list (a b c) did not require a copy of the  constant 
  2436.         list (b c) to be made. Ie (cdr z) is eq to (b c) in FooBar.
  2437.  
  2438.  
  2439.  
  2440.                                        40
  2441.  
  2442.  
  2443.  
  2444.              MSDOS BIOS CALLS FOR GRAPHICS OUTPUT
  2445.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2446.              These  functions  are still experimental.  They  do  however 
  2447.         allow  you  to  play  with drawing  recursive  curves  etc.  They      
  2448.         all  result  in  an  INT  10H.   This  means  that  the  graphics      
  2449.         should  be portable to most MSDOS machines and should  run  under 
  2450.         any windowing environment like Topview or MSwindows.  This is why 
  2451.         they are so slow. Note that they all return 't. They do not check 
  2452.         to  see if the INT call was successful or if you have a  graphics 
  2453.         capability.  You  can  crash  your  system  if  you  abuse  these 
  2454.         functions.  
  2455.  
  2456.              (#scrline# n1 n2 n3 n4 n5)
  2457.              ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2458.              Draws a line on the screen connecting (n1,n2) with the point 
  2459.         (n3,n4) using attribute n5.  This function calls the BIOS set dot 
  2460.         function  for each point.  Hence it is not very fast.  
  2461.              
  2462.              (#scrmde# n1)       {ah=0, al=n1, INT 10H}  
  2463.              ~~~~~~~~~~~~~
  2464.              Sets the video mode to n1. Modes are positive numbers 0..... 
  2465.         Where  (8  and  9) are high resolution for the  Tandy2000  and  I 
  2466.         suppose  are high resolution modes on other machines that support  
  2467.         the  (640 x 400) or greater graphics resolutions.  These are  all 
  2468.         listed in your hardware reference manual but basically they  are: 
  2469.         0 = 40x25B&W,  1=40x25COL, 2=80x25B&W 3=80x25COL,  4 =320x200COL,  
  2470.         5=320x200B&W,      6=640x200B&W,     7=reserved,    8=640x400COL, 
  2471.         9=640x400B&W etc...?   This is as of DOS 2.11. Also note that the 
  2472.         AT  EGA Graphics Modes should also work with no problem  however, 
  2473.         resolutions  greater  than 1024x1024 will cause  the  (#scrline#) 
  2474.         function to cease to work correctly.
  2475.  
  2476.              (#scrsap# n1)      {ah=5, al=n1, INT 10H}
  2477.              ~~~~~~~~~~~~~
  2478.              Sets the active video page to n1. n1 should be between 0 and 
  2479.         8.  This  is valid for text modes only.  Versions of MSDOS  other 
  2480.         than 2.11 may not support this call.
  2481.  
  2482.              (#scrspt# bh bl al)      {ah=11,bh=bh,bl=bl,al=al,INT 10H}
  2483.              ~~~~~~~~~~~~~~~~~~~
  2484.              Sets  the color palette according to the value  in  bh.  For 
  2485.         most  BIOS  compatable  machines  these  are:  If  bh=0  it  sets 
  2486.         background  color bl.  If bh=1 it sets the default palette to the 
  2487.         number 0 or 1 in BL. If bh=2 it sets a single palette entry where 
  2488.         bl  is the palette entry number and al is the  color  value.  See 
  2489.         your BIOS reference for the color values and additional info. 
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.                                        41
  2502.  
  2503.  
  2504.  
  2505.              MSDOS BIOS CALLS FOR GRAPHICS OUTPUT  (CONT'D)
  2506.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2507.  
  2508.              (#scrscp# n1 n2 n3)      {ah=2,bh=n1,dh=n2,dl=n3,INT 10H}
  2509.              ~~~~~~~~~~~~~~~~~~~
  2510.              Sets  the cursor position to be in page n1 at row n2 and  in 
  2511.         column n3. Where 0 is the top row and 0 is leftmost col.
  2512.  
  2513.              (#scrsct# n1 n2)         {ah=1,ch=n1,cl=n2,INT 10H}
  2514.              ~~~~~~~~~~~~~~~~
  2515.              Sets  the  cursor  type to agree with the following:  n1 bit 
  2516.         5  (0 = blink 1 = steady),  bit 6 (0 = visible,  1 =  invisible), 
  2517.         bits  4-0 = start line for cursor within character cell.  n2 bits 
  2518.         4-0 = end line for cursor within character cell.
  2519.  
  2520.              (#scrwdot# n1 n2 n3)     {ah=12,cx=n1,dx=n2,al=n3,INT 10H}
  2521.              ~~~~~~~~~~~~~~~~~~~~
  2522.              Write a dot (pixel).  The pixel at row n1 and column n2  has 
  2523.         its  color  value XORed with the color attribute  n3.  Since  the 
  2524.         color  attributes  vary from machine to machine you will have  to 
  2525.         look up the correct values for this parameter in your BIOS guide.
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.  
  2543.  
  2544.  
  2545.  
  2546.  
  2547.  
  2548.  
  2549.  
  2550.  
  2551.  
  2552.  
  2553.  
  2554.  
  2555.  
  2556.  
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.                                        42
  2563.  
  2564.  
  2565.  
  2566.              MSDOS BIOS CALLS FOR DATE AND TIME
  2567.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  2568.              Rather  than try to implement the (sys:time) function or the 
  2569.         (status localtime) call in PC-LISP I have provided access to  the 
  2570.         MS-DOS  get  date  and get time BIOS calls.  These  are  INT  21H 
  2571.         function numbers 2A and 2C hex respectively.  Here is how you get 
  2572.         at them from PC-LISP.
  2573.  
  2574.              (#date#)
  2575.              ~~~~~~~~
  2576.              Returns  a  list of four fixnums. The first element in  this 
  2577.         list represents the year 1980 means 1980 etc.  The second element 
  2578.         is  the  month of the year where 1 means January  etc.  The  next 
  2579.         element in the list represents the day of the month where 1 means 
  2580.         the first day,  etc.  The last element in the list represents the 
  2581.         day of the week where 0 means Sunday etc.
  2582.  
  2583.              (#time#)
  2584.              ~~~~~~~~
  2585.              Returns  a list of four fixnums. The first element  in  this 
  2586.         list  represents  the  hour of the day where 1 means 1AM  and  24 
  2587.         means 12 PM.  The next element represents the minutes these are 0 
  2588.         through  59.  The  next element  represents  the  seconds,  these 
  2589.         represent hundredths of a second, 0-99.
  2590.  
  2591.              For example:
  2592.  
  2593.              -->(append (#date#) (#time#))
  2594.              (1986 4 6 0 20 23 22 15)
  2595.              
  2596.              Means that the date is Sunday April 6th,  1986 and the local 
  2597.         time is 8:23:22 and 15/100 of a second.
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.                                        43
  2624.  
  2625.  
  2626.  
  2627.              MEMORY EXHAUSTION   
  2628.              ~~~~~~~~~~~~~~~~~
  2629.              The  memory  is all used up when you get a message  such  as 
  2630.         "LISP  cons  cells exhausted".  Usually when this happens  it  is 
  2631.         because  you are tying up memory somewhere but do not realize it. 
  2632.         The  most common way to tie up memory is to execute  an  infinite 
  2633.         recursion  such as (defun looper(n)(looper (+ n 1))).  The  stack 
  2634.         will  of course overflow and YOUR BINDINGS WILL BE HELD FOR YOU!! 
  2635.         This  means that ALL bindings are held.  If you execute the above 
  2636.         program  several  times  from  the break  level, 'er>', you  will 
  2637.         eventually run out of CONS cells. They are all in use to hold the 
  2638.         values  n,  n+1,  n+2,......  to  the point of  the  first  stack 
  2639.         overflow.  Then n,  n+1,....  to the point of the second overflow 
  2640.         and  so on and so on.  Eventually there is no more space left  to 
  2641.         evaluate  the function (looper).  The solution is simple:  If you 
  2642.         run an infinite recursion by mistake and are placed in the  break 
  2643.         level,  use  the showstack to figure out where you are.  Then use 
  2644.         the  break level to examine variables etc.  But  before  retrying 
  2645.         anything  return  to  the top level.  This will  cause  the  held 
  2646.         bindings  to  be  dropped and the cells will  become  reclaimable 
  2647.         garbage  (ie free).  Consider the following session with  PC-LISP 
  2648.         V2.11:
  2649.  
  2650.              -->(defun looper(n)(looper (+ n 1)))    ; infinite function
  2651.              looper
  2652.              -->(looper 0)                           ; run it from 0
  2653.              -- Stack Overflow --                    ; all n's saved!
  2654.              er>n                                    ; last value of n
  2655.              588
  2656.              er>(looper 0)                           ; another run will
  2657.              -- Stack Overflow --                    ; save more n's
  2658.              er>(looper 0)
  2659.              -- Stack Overflow --
  2660.              er>(looper 0)                           ; another run will
  2661.              LISP out of cons cells!                 ; save more n's
  2662.              B> 
  2663.  
  2664.              Note  that  in last (looper 0) call we made from  the  break 
  2665.         level  was unable to complete because we ran out of memory.  When 
  2666.         this  happens PC-LISP gives up and returns to DOS,  hence the  B> 
  2667.         prompt.  We  could have avoided this problem if we had entered  a 
  2668.         CONTROL-Z  ENTER sequence at the 'er>' prompt before any  further 
  2669.         calls to (looper 0) were made.  This would have freed up all  the 
  2670.         held intermediate bindings of n. 
  2671.  
  2672.              If you find that you are running out of heap space it may be 
  2673.         because you are keeping too many unused strings,symbols or hunks.
  2674.         The  easiest way to do this by mistake is the following:  (setq x 
  2675.         (oblist)). The variable x is globally set to the oblist contents. 
  2676.         Now,  all objects that were in the oblist at the time of the call 
  2677.         will never be freed.  The heap space associated with their  print 
  2678.         names  will also be unreclaimable.  The solution is to be careful 
  2679.         what you do with copies of the oblist if heap space is in demand. 
  2680.         Usually heap space is not critical and you need not worry.
  2681.  
  2682.  
  2683.  
  2684.                                        44
  2685.  
  2686.  
  2687.  
  2688.              TECHNICAL INFORMATION
  2689.              ~~~~~~~~~~~~~~~~~~~~~
  2690.              The  interpreter  is written using the  Lattice  C  compiler 
  2691.         version  2.03.  It consists of 8 separate modules totaling nearly 
  2692.         10,000 lines of C.  The modules are:  A scanner,  parser,  memory 
  2693.         manager, list evaluator and critical functions module, two  built 
  2694.         in  functions modules, a library of extra Unix libc functions not 
  2695.         provided  by Lattice C consisting of assembly  language  routines 
  2696.         for  setjmp(),  longjmp() and getenv(),  and finally a modified C 
  2697.         start up assembly language module to provide signal trapping  for 
  2698.         stack  overflow  and control-break.  The program is  designed  to 
  2699.         compile  without changing more than 2 #defines under UNIX 4.2 and 
  2700.         sys V. This has been done as has porting to a SUN.
  2701.  
  2702.              Memory is organized as follows.  Alpha cells have fields for 
  2703.         a  shallow  stack of bindings,  a pointer to heap space  for  the 
  2704.         print names, a pointer to any built in or user defined functions, 
  2705.         and a pointer to any property lists.  Alpha cells are the largest 
  2706.         of  all  the cells and have their own fixed  storage  area.  Heap 
  2707.         space  which  is just the space used for the print names  of  the 
  2708.         alpha cells and strings,  and the element array for hunks may  be 
  2709.         variable sized blocks of up to 254 bytes long. This is why a hunk 
  2710.         can have only 126 elements in PC-LISP. The rest of the cells used 
  2711.         by  PC-LISP  are  all considered as one.  This  consists  of  the 
  2712.         flonum,  fixnum,  list,  string,  hunk and port cells.  They have 
  2713.         their  own  contiguous  slice of memory.  This means  that  three 
  2714.         different contiguous types of memory are required.  It is managed 
  2715.         in the following way.  At start up time the percentages of memory 
  2716.         are  read from the default settings or the environment  variables 
  2717.         LISP%HEAP and LISP%ALPH.  Next memory is allocated in 16K  chunks 
  2718.         these  are  the largest contiguous pieces handled by  the  memory 
  2719.         manager.  If  the  environment variable LISP%MEM has  an  integer 
  2720.         value,  this  is  used  as the upper limit on the number  of  16K 
  2721.         chunks to allocate. These are all kept track of in a large vector 
  2722.         of  pointers.  After all chunks have been allocated 8K are  given 
  2723.         back  for use by the I/O functions.  If the environment  variable 
  2724.         LISP%KEEP  is set to an integer value that many bytes  are  given 
  2725.         back  instead  of  8K.  If file I/O seems to stop working  it  is 
  2726.         probably  because  the  standard I/O functions have  run  out  of 
  2727.         memory,  in this case either set LISP%KEEP a bit bigger,  or  set 
  2728.         LISP%MEM  to  a value that does not cause all free memory  to  be 
  2729.         allocated.  Next  groups  of these blocks are primed for  use  by 
  2730.         alpha,cell,   or   heap  managers.   These  managers  handle  the 
  2731.         distribution and reclamation  of memory in their block.  The heap 
  2732.         manager will perform compaction and relocation to get free space. 
  2733.         The alpha and cell managers will perform mark and gather  garbage 
  2734.         collection  to get space.  The heap manager may request mark  and 
  2735.         gather collection if there is a real shortage of heap space.
  2736.  
  2737.              Stack overflow detection is done by intercepting the call to 
  2738.         the  Lattice C stack overflow routine,  temporarily resetting the 
  2739.         stack, and them making a call to my own C stack overflow routine. 
  2740.         This then longjmps out of the error condition.  The Unix  version 
  2741.         handles  the  error  in  the same way except  that  the  overflow 
  2742.         results in a SIGSEGV which then calls the same routine.
  2743.  
  2744.  
  2745.                                        45
  2746.  
  2747.  
  2748.  
  2749.              TECHNICAL INFORMATION (CONT'D)
  2750.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2751.  
  2752.              Control-BREAK detection is done via periodic testing of  the 
  2753.         status in the evaluator main loop, and the read main loop. When a 
  2754.         break  is  detected control is transferred to the  break  handler 
  2755.         which  prints  a message and longjmps back to the mainline  code. 
  2756.         The  Unix  version will have made a signal call asking  that  the 
  2757.         break handler be executed when a user break key is hit. Hence the 
  2758.         results are the same.  CONTROL-C checking is done in the same way 
  2759.         except that a CONTROL-C will only be spotted on I/O so a  looping 
  2760.         non  printing  function can only be stopped  with  CONTROL-BREAK. 
  2761.         Note that CONTROL-BREAK is INT 1BH and CONTROL-C is INT 23H.
  2762.  
  2763.              If  your  machine does not support int 1BH,  you can  easily 
  2764.         patch PC-LISP to trap whatever vector you want.  To do this  just 
  2765.         start  disassembling PC-LISP with DEBUG.  The procedures that set 
  2766.         and  reset  the int 1BH vector are pretty near the start  of  the 
  2767.         program and are very easy to spot.  Note that there are a  couple 
  2768.         of  other set/reset interrupt vector routines here so do not  get 
  2769.         the wrong one.  Look for calls to the MS-DOS set interrupt vector 
  2770.         routine. If you have trouble doing this drop me a line and I will 
  2771.         try  to help you get it done.   There should not be many machines 
  2772.         for  which this patch is necessary because most MS-DOS  machines, 
  2773.         even  partially PC compatible,  seem to generate an interrupt 1BH 
  2774.         when CONTROL BREAK is hit.            
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.  
  2781.  
  2782.  
  2783.  
  2784.  
  2785.  
  2786.  
  2787.  
  2788.  
  2789.  
  2790.  
  2791.  
  2792.  
  2793.  
  2794.  
  2795.  
  2796.  
  2797.  
  2798.  
  2799.  
  2800.  
  2801.  
  2802.  
  2803.  
  2804.  
  2805.  
  2806.                                        46
  2807.  
  2808.  
  2809.  
  2810.              KNOWN BUGS OR LACKING FEATURES OF V2.11
  2811.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2812.  
  2813.             -It  is  possible  to run out of stack  space  while  garbage 
  2814.         collecting.  When  this happens the garbage collection is retried 
  2815.         once but the error is unrecoverable.  You should treat this as  a 
  2816.         stack  overflow caused by your program.  This can be fixed with a 
  2817.         link inversion  marking phase in the next release of PC-LISP. See 
  2818.         also  the  section  MEMORY EXHAUSTION for more  details  on  this 
  2819.         problem.  Note that if the stack overflows on the second  garbage 
  2820.         collection retry it gives up and advises you of a probable memory
  2821.         corruption.
  2822.  
  2823.             -Line drawing is not too quick,  or too clean. The lines take 
  2824.         time to draw because they go through the BIOS,  they are not very 
  2825.         clean at certain slopes due to some bugs.  But the video graphics 
  2826.         routines  are still experimental so do not rely on them too much. 
  2827.         You  will  also  note  that several other  video  INT  calls  are 
  2828.         missing.
  2829.  
  2830.             -If  too  many  (load 'file) calls fail you will run  out  of 
  2831.         available ports. This is because they are left open. PC-LISP does 
  2832.         not  close open load ports if an error occurs while reading  from 
  2833.         them.
  2834.  
  2835.             -Two  special atoms with rather obscure names should never be 
  2836.         directly  returned manipulated in a prog.  These are $[|return|]$ 
  2837.         and $[|go|]$.  If you attempt say print these from within a prog, 
  2838.         the  print  function will return them and this will  confuse  the 
  2839.         heck  out of prog which uses them for internal purposes.  Because 
  2840.         of this the (oblist) call does not return them. Thus the only way 
  2841.         they  can get into your code is for you to enter  them  directly. 
  2842.         Since  this is unlikely and I have warned you the problem  should 
  2843.         not occur.
  2844.  
  2845.             -You are not prevented from altering the binding of t.   This 
  2846.         means  that  if  you  use t as a  parameter  or  set/setq  it  to 
  2847.         something  other  than  t you may cause some  strange  behaviour, 
  2848.         especially if you bind t to nil by accident.
  2849.  
  2850.             -Macros  are slightly restricted in that only lists,  fixnums 
  2851.         , flonums or ports can be substituted. This is a small difference 
  2852.         from  Franz  but one that would require  significant  performance 
  2853.         penalties   to implement.  Since not substituting these types  is 
  2854.         less  expensive than implementing substitution would be,  I  will 
  2855.         not implement this feature of Franz in a PC environment.
  2856.  
  2857.             -Explode and Exploden only work on atoms or strings. In Franz 
  2858.         you can explode anything. For PC-LISP I decided to leave out this 
  2859.         feature  because  it  complicates the print functions  which  are 
  2860.         already pretty messy.    
  2861.  
  2862.  
  2863.  
  2864.  
  2865.  
  2866.  
  2867.                                        47
  2868.  
  2869.  
  2870.  
  2871.              KNOWN BUGS OR LACKING FEATURES OF V2.11 (CONT'D)
  2872.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2873.  
  2874.             -It is possible for the I/O functions to stop working if they 
  2875.         run  out of memory.  Since they get their memory separately  from 
  2876.         the  other  functions in PC-LISP the only solution is to run  PC-
  2877.         LISP  with a little less memory either by setting the environment 
  2878.         variable  LISP%MEM to a value that leaves one or more 16K  blocks 
  2879.         free,  or  to set LISP%KEEP a little larger than 8K so that  more 
  2880.         memory is free for use by the I/O functions.
  2881.  
  2882.             -The  interpreter  is slow.  I am planning on  introducing  a 
  2883.         compiler which should speed things up significantly.  I will also 
  2884.         rewrite a very small portion of the interpreter in assember which 
  2885.         should double or tripple the speed.
  2886.  
  2887.             -Car  and cdr will not access the first and second element of 
  2888.         a hunk as they do in Franz.
  2889.  
  2890.             -Showstack   does   not  print  lists  in   compressed   form 
  2891.         horizontally.  The vertical compression <**> is however done.  It 
  2892.         also  occasionally  gets  confused and does not  print  the  last 
  2893.         evaluation  this sometimes happens on macro expansion.  Showstack 
  2894.         may  also  get  confused and print a list one element at  a  time 
  2895.         rather  than  as a complete list.  This is because  showstack  is 
  2896.         trying  to trace backwards through an internal stack which has  a 
  2897.         lot  of  intermediate  stuff on it and can get  confused  by  the 
  2898.         extra stacked info.
  2899.  
  2900.              RE BUGS OR DESIRED ENHANCMENTS
  2901.              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2902.              I have tried to think of everything that a user could do  to 
  2903.         crash  the  system  and protect him/her from it but I'm  sure  my 
  2904.         imagination  has only covered half of the possibilities.  If  you 
  2905.         find  any other bugs or if you think some features would be  nice 
  2906.         to  add  to  PC-LISP,  I will consider them for  the  next  major 
  2907.         release.  Please  don't  hesitate to let me know what you  think, 
  2908.         good or bad.  I'd appreciate the feed back as I have put a lot of 
  2909.         work into this program and want to know what you people out there 
  2910.         think of it.
  2911.              
  2912.                           Regards,
  2913.  
  2914.              
  2915.                           Peter Ashwood-Smith.
  2916.  
  2917.  
  2918.  
  2919.  
  2920.  
  2921.  
  2922.  
  2923.  
  2924.  
  2925.  
  2926.  
  2927.  
  2928.                                        48
  2929.