home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 146_01 / notes.doc < prev    next >
Text File  |  1985-03-10  |  22KB  |  730 lines

  1. /*
  2. HEADER:        CUG146.10;
  3. TITLE:        A letter from Serge Stepanoff;
  4. KEYWORDS:    Serge Stepanoff, Small-C, Ron Cain;
  5. SYSTEM:        FLEX;
  6. FILENAME:    NOTES.DOC;
  7. AUTHORS:    Serge Stepanoff, Ron Cain;
  8. COMPILERS:    Small-C;
  9. */
  10.  
  11.                                Serge Stepanoff
  12.                                5469 Arlene Way
  13.                              Livermore, CA 94550
  14.  
  15. INTRODUCTION:
  16.  
  17. Small-C  is  exactly  what  the  name  implies  --  a subset of the language C
  18. developed at Bell Labs and best described in the de-facto language  definition
  19. "The C Programming Language", by Brian Kernighan and Dennis Ritchie, published
  20. by Prentice-Hall, Inc.  1978.
  21.  
  22. The   original  Small-C  compiler  was  written  by  Ron  Cain  for  the  8080
  23. microcomputer on a North Star system.  He was kind and  farsighted  enough  to
  24. place  it  in  the  public domain via articles in "Dr.  Dobbs Journal".  Since
  25. then, this  compiler  has  been  adapted  to  several  operating  systems  and
  26. microcomputers,  including  the 6809.  To this author's knowledge, this is the
  27. first adaptation for the 6800 micro under TSC's FLEX  operating  system.   The
  28. project  required  approximately  one  year's  worth  of calendar time, mainly
  29. because the work on it was carried out in a sporadic and aperiodic basis.
  30.  
  31. Initial  conversion  attempts  involved compilation directly to assembly level
  32. code, but this approach was  quickly  dropped  due  to  lack  of  any  16  bit
  33. arithmetic   in  the  6800  instruction  set  and  general  paucity  of  stack
  34. operations.  Resultant code was lengthy to say the least -- no wonder the 6809
  35. came about.  However, in the tradition of PASCAL's P-code and FORTH's threaded
  36. code,  a  solution  was  found  in  translating  to  a  pseudo-code  and  then
  37. interpreting this code on a virtual machine.  The penalty in execution time is
  38. much less than for  a  straight  interpreter  ala  BASIC  --  the  pseudo-code
  39. interpreter  and  the  run-time  library  occupy less than 2K bytes, and as an
  40. interesting side note, to execute this pseudo-code on  a  different  operating
  41. system  or  a  different  micro-  computer  requires  only  the rewrite of the
  42. interpreter and the run-time library for the target machine.
  43.  
  44. As  a  historical  note, the initial conversion was not done on a UNIX system,
  45. but rather on a PDP 11 running RSX-11 operating system and the  DECUS  version
  46. of  a  C  compiler (another public-domain User Group product) with the Small-C
  47. code supplied by DECUS (Digital Equipment  Corporation  Users  Society).   The
  48. ongoing  development of this version of the Small-C compiler is  being carried
  49. out on a SWTPC 6800 system with dual 8 inch single density floppy drives,  and
  50. 32K of RAM memory.
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.                               - 1 -                              
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73. SMALL-C USER NOTES.                                       Page  2
  74.  
  75.  
  76. OPERATION:
  77.  
  78. The Small-C compiler is invoked by typing CC on the keyboard.  No command line
  79. arguments are necessary.  A series of questions are then  asked.   After  each
  80. question, Small-C prints (in paretheses) what the possible responses are.  The
  81. capitalized response is the one that Small-C will default to if you just press
  82. RETURN.  The first question is:
  83.  
  84.      Do you want the c-text to appear (y,N) ?
  85.  
  86. This  gives  you  the  option  of interleaving the source code into the output
  87. file.  Response is Y or N (y or n  will  also  serve).   If  Y  is  given,  an
  88. asterisk will be placed at the start of each input line (to force a comment to
  89. the 6800 assembler) and the input lines will be interleaved with the  compiler
  90. generated  pseudo-code output.  If the answer is N (or just RETURN, since N is
  91. capitalized, and is the default),  only  the  generated  pseudo-code  will  be
  92. output.   NOTE:  the  TSC  assembler accepts any length labels, both lower and
  93. upper case, but only the first 6 characters are used and saved in  the  symbol
  94. table.   Therefore, if you have either functions or labels of the type MODULE1
  95. and MODULE2, the assembler will generate a multiply defined label error.   So,
  96. make sure that the first 6 characters are unique.  C'est la vie.....
  97.  
  98.      Are you compiling the whole program at once (Y,n) ?
  99.  
  100. This is a convenience (or annoyance) question.  If you type Y (or RETURN), you
  101. will be able to avoid three more technical questions, which are only needed if
  102. your  C  program  will  be  fed into Small-C in several separate compilations.
  103. (Best not to do it.)
  104.  
  105. If you answer N to the all-at-once question, you'll also be asked:
  106.  
  107.           Do you want the globals to be defined (y,N) ?
  108.  
  109.      This  question is primarily a developmental aid between machines.  If the
  110.      answer is Y, all static symbols will allocate storage within  the  module
  111.      being compiled.  This is the normal method.  If N (or RETURN), no storage
  112.      will be allocated, but symbol references will still be made in the normal
  113.      way.   Essentially,  this question allows the user to specify all or none
  114.      of the static symbols 'external'.
  115.  
  116.           Is the output file the first one the assembler will see (y,N) ?
  117.  
  118.      If it is, Small-C will put out a short prologue that parses  the  command
  119.      line parameters (if any), sets up the stack, and calls the C program as a
  120.      subroutine, so that a return to  FLEX  may  be  made  properly  when  the
  121.      routine is finished.
  122.  
  123.           Starting number for labels (0) ?
  124.  
  125.      This lets you supply the first label number generated by the compiler for
  126.      its internal labels (which will typically be "ccNNN", where  "NNN"  is  a
  127.      decimal  number).   This  option allows modules to be compiled separately
  128.      and later appended on the source level without  generating  multi-defined
  129.  
  130.  
  131.  
  132.                               - 2 -                              
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. SMALL-C USER NOTES.                                       Page  3
  140.  
  141.  
  142.      labels.  If you just press RETURN, labels will start at "cc000".
  143.  
  144. Now a question that requires some consideration:
  145.  
  146.      Should I pause after an error (y,N) ?
  147.  
  148. If your are doing a long compilation, the sort that you go  off  and  mow  the
  149. lawn during, you run the risk of having an error message scroll off the screen
  150. while you're away.  If you answer Y to this question, Small-C  will,  when  it
  151. finds an error, stop everything it's doing until you tell it to proceed.  That
  152. way, you are assurred of knowing about ALL the errors that the compiler found.
  153. FLEX  users  have a third choice -- set the TTYSET screen full Pause parameter
  154. to YES.  This will stop any tendency to scroll off important messages  at  the
  155. expense  of  having  to  hit  ESCAPE  every time the screen prints the maximum
  156. number of lines.
  157.  
  158.      Output filename ?
  159.  
  160. This question gets the name of the file to be created.  If you press   RETURN,
  161. the  output  of the compiler will go to the screen.  Doing this, especially in
  162. conjunction with having the C source code interleaved with the normal  output,
  163. is one way of learning what the compiler does with your source.
  164.  
  165. CAUTION !!!!  If the output file already exists, the compiler will  delete  it
  166. with  NO warning to you -- which makes for frustration at least when you meant
  167. to type in FILE.A and instead typed FILE.C.... If this worries you, modify the
  168. run-time routine "fopen" in the interpreter.
  169.  
  170.      Input filename ?
  171.  
  172. This  question  gets  the  name  of  the C source module to use as input.  The
  173. question will be repeated each time a name is supplied, allowing the  user  to
  174. create  an  output  file consisting of many separate files.  (It behaves as if
  175. you had appended them together and submitted only the one file.)  Press RETURN
  176. to  end  the  compilation  process.  Again CAUTION!!!, if you mistype the file
  177. name and the file  is  not  found,  the  compiler  will  exit  to  FLEX  after
  178. appropriate message.  If this  annoys you go fix "fopen".
  179.  
  180. Here is how you would compile the sample program "WC.C":
  181.  
  182. +++CC          [invoke the compiler]
  183.  
  184. * * *  greetings and
  185.  
  186.               salutations  with a note
  187.  
  188.                   for the sponsor         * * *
  189.  
  190. Do you want the C-text to appear (y,N) ?  Y   [Why not ?}
  191.  
  192. Are you compiling the whole program at once (Y,n) ?  Y  [You bet!]
  193.  
  194. Should I pause after an error (y,N) ?  N    [Live dangerously !]
  195.  
  196.  
  197.  
  198.                               - 3 -                              
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205. SMALL-C USER NOTES.                                       Page  4
  206.  
  207.  
  208.  
  209. Output filename: WC.A           [Assembler will get this file]
  210.  
  211. Input filename: WC.C            [This is the C source file]
  212. ====== main()                   [reports the function being compiled]
  213. ====== nl()
  214. ====== putnum()
  215.  
  216. Input filename: (press RETURN)  [Tell the compiler we're done]
  217.  
  218. The compiler will report the number of errors encountered.  If there are  any,
  219. they  will  also  be  displayed  in  the output pseudo-assembly file where the
  220. offending line of C will be shown as a comment, with an  error  message  below
  221. it.
  222.  
  223. If there were no errors, we may proceed with assembly.
  224.  
  225. +++ASMB WC.A +SY    [Assemble suppressing Symbol table listing]
  226.  
  227. Note the final assembly address at this point.  If the assembly listing output
  228. was  supressed  (as  is  quite  often the case for longer assemblies), use the
  229. supplied utility FSIZE to get the range of addresses occupied  by  the  binary
  230. file.
  231.  
  232. +++FSIZE WC.BIN
  233.  
  234. Write down the last address displayed.
  235.  
  236. +++GET CCINT        [Load the interpreter and run-time library]
  237. +++GET WC           [Load the compiled and assembled object code]
  238. +++SAVE WC.CMD 0 XXX 0
  239.  
  240. The  last  line saves the complete file as an executable command.  Notice that
  241. the only things that vary are the file name and the final address XXX  (gotten
  242. from the assembly listing or by using FSIZE).
  243.  
  244. The program WC (which by the way is a standard Word Count utility) may now  be
  245. executed by typing:
  246.  
  247. +++WC Filename.Ext
  248.  
  249. The above program requires a command line parameter (in this case a file name)
  250. in order to execute.  If this was not the case, then  for  debugging  purposes
  251. the  SAVE  command  could  have  been  skipped,  and  the C program under test
  252. executed by typing (in response to system prompt):
  253.  
  254. +++JUMP 0
  255.  
  256. However, after successfull debug session  the  SAVE  utility  would  still  be
  257. invoked.
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.                               - 4 -                              
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271. SMALL-C USER NOTES.                                       Page  5
  272.  
  273.  
  274. ERROR REPORTING:
  275.  
  276. When  Small-C  detects  an  error  in your program, it prints a message on the
  277. screen.  For example:
  278.  
  279.      Line 47, main + 3: missing semicolon
  280.       int a,b,c     char x
  281.                     ^
  282.  
  283. As you can see, you are given a count of how many lines from the beginning  of
  284. the CURRENT file the error happened, (line 47 in this example).  Next it tells
  285. you what the most recent function name was ("main" in this example), and  then
  286. how  many  lines into the function (+ 3) the error occurred.  Once the message
  287. has been printed, the compiler continues its work.  If you answered "Y" to the
  288. Should-I-pause  question,  the  compiler will come to a stop after each error,
  289. and wait until you tell it to proceed.  When it stops, it will ask you
  290.  
  291.      Continue (Y,n,g) ?
  292.  
  293. If you answer Y (or just press RETURN), Small-C  will  resume  compiling  your
  294. program.   If  you  answer  N,  Small-C will drop everything and return you to
  295. FLEX.  If you answer G (for  "go!"),  Small-C  will  continue  compiling  your
  296. program, but will no longer stop after each error.  (it will report errors and
  297. keep compiling.)
  298.  
  299. It should be noted that an error on one line may cause a whole series of error
  300. messages for the same and subsequent lines of code.  The moral is
  301.  -- examine the first error carefully, and use the "go" option if warranted.
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.                               - 5 -                              
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337. SMALL-C USER NOTES.                                       Page  6
  338.  
  339.  
  340. THE RUN-TIME LIBRARY AND ITS FUNCTIONS:
  341.  
  342. The  following  is a brief description of the standard functions provided with
  343. this version of the Small-C compiler.  They are  found  (along  with  run-time
  344. interpreter) in the file CCINT.  Here's what they are supposed to do:
  345.  
  346.  
  347.    c = getchar(c);
  348.  
  349. Reads  a  character  from  the  console keyboard, echoes it to the screen, and
  350. returns it.  If the character  is  a  carriage-return,  a  line-feed  is  also
  351. printed.   TTYSET  parameter  settings  are  honored.   If  the  character  is
  352. control-Z, -1 (end-of-file) is returned instead.
  353.  
  354.  
  355.    c = putchar(c);
  356.  
  357. Writes  the  passed  character  to  the  console.   If  the  character  is   a
  358. carriage-return,  a  line-feed is also written.  Putchar returns the character
  359. passed to it.
  360.  
  361.  
  362.    gets(buff);
  363.        char *buff;
  364.  
  365. Reads one line from the console into the supplied character array buffer.  The
  366. usual FLEX character/line  editing  features  are  supported.   A  null  ('0')
  367. character  is  appended  to  the  end  of the string.  The supplied buffer had
  368. better be long enough to hold the input string.
  369.  
  370.  
  371.    puts(string);
  372.        char *string;
  373.  
  374. Writes  a  string  to  the  console.   Stops writing when it encounters a null
  375. character, which is assumed to terminate  the  string.   (The  null  character
  376. itself  is  not  written.)  No cariage-return or line-feed is written unless a
  377. new-line character is found.  A limited subset of backslash character sequence
  378. is  supported,  including:  b,  f,  n,  \, xDD (DD=hex digits), OOO (OOO=octal
  379. digits) -- a sort of poor man's "printf" function.  Yes it is  interpreted  at
  380. run-time.
  381.  
  382.  
  383.    ptr = fopen(name, mode);
  384.        int ptr;
  385.  
  386. Opens the named file for reading or writing.   Both  name  and  mode  must  be
  387. strings,  or  pointers  to  characters.   If the mode is "r", name is open for
  388. reading, otherwise if "w" it is open for writing  and  previous  contents  are
  389. overwritten  (no  warning of file's existance is given).  Both "r" and "w" may
  390. be appended with "u", the "Uncompress" flag, to facilitate reading  binary  or
  391. any  other  non-text  files.   A pointer to FCB is returned for later use with
  392. getc, putc, and fclose.  If the open fails, an exit to FLEX  is  made  and  an
  393.  
  394.  
  395.  
  396.                               - 6 -                              
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403. SMALL-C USER NOTES.                                       Page  7
  404.  
  405.  
  406. appropriate message issued.  Currently, no more than four files may be open at
  407. one time;  if this is not enough for  you,  modify  the  parameter  NFILES  in
  408. CCINT.TXT and reassemble it.
  409.  
  410.  
  411.    fclose(ptr);
  412.  
  413. Flushes  any unwritten output to disk, and closes file.  It returns to FLEX if
  414. the close fails.  Please note that you should explicitly close each file  that
  415. was opened.
  416.  
  417.  
  418.    c = getc(ptr);
  419.  
  420. Reads  and  returns  the next character from the file.  Ptr is the FCB pointer
  421. returned from fopen().  When the physical end-of-file is reached getc  returns
  422. a -1.  A read error returns control to FLEX.
  423.  
  424.  
  425.    putc(c, ptr);
  426.  
  427. Writes  a  character to file.  If a write error occurs, control is returned to
  428. FLEX.
  429.  
  430.  
  431.    isalpha(c);
  432.        char c;
  433.  
  434. Returns  TRUE  if character passed to it is an alpha (i.e.  a-z, A-Z, or '_'),
  435. FALSE if it isn't.
  436.  
  437.  
  438.    isdigit(c);
  439.        char c;
  440.  
  441. Returns  TRUE  if  the  character passed to it is a numeric digit (0-9), FALSE
  442. otherwise.
  443.  
  444.  
  445.    isalnum(c);
  446.  
  447. Returns TRUE if the character is alpha or digit (numeric), else FALSE.
  448.  
  449.  
  450.    islower(c);
  451.  
  452. TRUE if lower case alpha (a-z), FALSE otherwise.
  453.  
  454.  
  455.    isupper(c);
  456.  
  457. TRUE if upper case alpha (A-Z), FALSE otherwise.
  458.  
  459.  
  460.  
  461.  
  462.                               - 7 -                              
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469. SMALL-C USER NOTES.                                       Page  8
  470.  
  471.  
  472.    isspace(c);
  473.  
  474. TRUE if c is a  "white"  space  character  (space,  tab,  carriage-return,  or
  475. line-feed), FALSE otherwise.
  476.  
  477.  
  478.    toupper(c);
  479.  
  480. Returns upper case of c if c is lower case alpha, otherwise returns c.
  481.  
  482.  
  483.    tolower(c);
  484.  
  485. Returns lower case of c if c is upper case alpha, otherwise returns c.
  486.  
  487.  
  488.    strclr(s,n);
  489.        char *s;   int n;
  490.  
  491. Clears the string of n bytes in length pointed to by s to all NULL's.
  492.  
  493.  
  494.    strlen(s);
  495.        char *s;
  496.  
  497. Returns the length of the string pointed to by s.
  498.  
  499.  
  500.    strcpy(s1, s2);
  501.  
  502. Copies  string s2 into s1.  No check for whether s1 is large enough to hold s2
  503. is made.
  504.  
  505.  
  506.    strcat(s1, s2);
  507.  
  508. Concatenates s2 (adds onto tail of) to s1.
  509.  
  510.  
  511.    strcmp(s1, s2);
  512.  
  513. Compares string s1 with string s2 until there is a difference between the two,
  514. or either string runs out.  The difference between the last two characters (s1
  515. - s2) is then returned.  Case is not ignored so "foo" and "Foo" are not equal.
  516. Also string "aaaaa" is smaller than the string "bb".
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.                               - 8 -                              
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535. SMALL-C USER NOTES.                                       Page  9
  536.  
  537.  
  538. ASSEMBLY LANGUAGE INTERFACE:
  539.  
  540. Interfacing  to  assembly  language  is  quite easy.  The "#asm" and "#endasm"
  541. constructs allow assembly language to be placed inside C programs.   Since  it
  542. is  considered by the compiler to be a single statement, it may appear in such
  543. forms as:
  544.  
  545.  
  546.        while(1) #asm .....  #endasm
  547.                  or
  548.        if(expression)  #asm .....  #endasm    else .....
  549.  
  550. Due to the workings of the preprocessor (which  must  be  suppressed  by  this
  551. construct),   the   pseudo-op   "#asm"  must  be  the  last  item  before  the
  552. carriage-return on the end of the line (since the text between  #asm  and  the
  553. <CR>  is  thrown  away),  and  the  #endasm pseudo-op must appear on a line by
  554. itself (since everything after #endasm is thrown away).  Since the  parser  is
  555. completely  free-format outside of these exceptions, the expected format is as
  556. follows:
  557.  
  558.        if (expression) #asm
  559.              ......
  560.              ......
  561.              #endasm
  562.        else statement;
  563.  
  564. Note that a semicolon is not required after the  #endasm,  since  the  end  of
  565. context is obvious to the compiler.
  566.  
  567. Unlike the rest of Small-C compilers, the assembly language user of  this  one
  568. must  also switch in and out of interpreted mode, before writing pure assembly
  569. code.  This is accomplished as follows:
  570.  
  571.   .....  #asm
  572.     FCB  86      [Switch to assembly code]
  573.       ....
  574.       ....
  575.       ....
  576.  
  577.     JSR RTSC     [If simply in line sequence of assembly language
  578.                    statements]
  579.  
  580.       or
  581.  
  582.     JMP RTSC     [If return from an assembly language function]
  583.  
  584.     #endasm
  585.  
  586. The  label  RTSC  is  a special global symbol for the routine that returns the
  587. control to the interpreter.
  588.  
  589. Assembly  language  code  within the "#asm .... #endasm" context has access to
  590. all global symbols and functions by name (watch the  lower  case  convention).
  591.  
  592.  
  593.  
  594.                               - 9 -                              
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601. SMALL-C USER NOTES.                                      Page  10
  602.  
  603.  
  604. It is up to the programmer to know the data type of the symbol (whether "char"
  605. or "int" -- implies a byte acess or a word access).
  606.  
  607. External assembly language routines (functions) invoked by function calls from
  608. the C code have access to all registers and do not have to restore them  prior
  609. to exit.  They may push items on the stack as well but must remove (pull) them
  610. off before exit.  It is the responsibility of the calling  program  to  remove
  611. arguments  from the stack after a function call.  This must not be done by the
  612. function itself.  There is no limit to the number of items  the  function  may
  613. push  on  the  stack,  providing  it   removes  them  prior to exiting.  Since
  614. parameters are passed by value, the called function may modify them.   If  the
  615. function  is  to  return a value, it must do so by loading it into the A and B
  616. registers (MSB and LSB respectively) prior to exiting.
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.                              - 10 -                              
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667. SMALL-C USER NOTES.                                      Page  11
  668.  
  669.  
  670. STACK USAGE:
  671.  
  672. The stack is used extensively by the compiler.  Function arguments are  pushed
  673. on  the  stack  as  they  are encountered between the parentheses (or in other
  674. words left to right) which is the opposite of standard C.  This means routines
  675. using  a  variable number of arguments -- beware !!.  It is worth pointing out
  676. that the local declarations allocate only as much room  on  the  stack  as  is
  677. necessary,  including  an  odd number of bytes for char variables, whereas the
  678. function call arguments always use two  bytes  a  piece.   In  the  event  the
  679. argument  was type "char" (8 bits).  the most significant byte of the two-byte
  680. value is a sign extension of the lower byte.
  681.  
  682.  
  683.  
  684.  
  685.  
  686. A PARTING NOTE:
  687.  
  688. This is the first version of 6800 Small-C compiler released to the public.  It
  689. is highly likely that some insidious bugs are present.  Some useful utilities,
  690. notably "printf" and "fprintf" are not yet implemented.  The distribution disk
  691. contains   some  C  programs  from  the  BDS  c  Users  Group  and  the  DECUS
  692. distribution.  If you convert them to the Small-C  subset,  send  the  listing
  693. (preferably  on an 8 inch diskette) back to the author and it will be included
  694. in the future distributions, with due credits of course.   A user group  would
  695. be a nice idea......
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.                              - 11 -                              
  727.  
  728.  
  729.  
  730. self.  There is no limit to the number of items  the  fun