home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsa / bc / Manual < prev    next >
Encoding:
Text File  |  1995-08-08  |  138.4 KB  |  4,528 lines

  1.  
  2.      
  3.  Y8888bo                .d88oo                                                
  4.   88[ 88[              d8`  ‘8                                                
  5.   88[ ]8P             ]8P    ‘[                                               
  6.   88[ 88`  .ooo  .oo. d8[     `.oo,  oo.oo oo, .o,oo   oo.o  ooo  .oo. .oo.
  7.   88888o   8[]8[ 88 Y 88[     .8`‘8[’88“Y8P”88 Y8P 8b ‘88P8`d8 8b 88 Y 88 Y
  8.   88[ ‘88  “ ]8[ 88b‘ 88[     88  88 88 ]8[ 88 ]8[ 88[ 88  ]8P“”“ 88b‘ 88b’
  9.   88[  88[ oP]8[ ‘888 Y8b    .88  88`88 ]8[ 88 ]8[ 88[ 88  ]8[    ’888 ‘888
  10.   88[ ]88`]8[]8[]  Y8[‘88,   dY8  88 88 ]8[ 88 ]8[ 88` 88  ]8b   ]  Y88  Y8[
  11.  o888888“ ‘8b/8b,bodP  ’Y8boP`‘YbdP`.88,d8b.88,]88o8“ .88,  Y8bo‘ bodP bodP
  12.                                                ]8[
  13.                                                ]8[
  14.                                                “”`
  15.  
  16.                            v1.69 4th August 1995
  17.                 
  18.                         Program and documentation by
  19.                 
  20.                                  Cy Booker
  21.                               86 Church View
  22.                                  Main Road
  23.                                 Crockenhill
  24.                                   Swanley
  25.                                    Kent
  26.                                   BR8 8JW
  27.                                    U.K.
  28.                 
  29.                     Internet: bc@cheepnis.demon.co.uk
  30.                 Arcade BBS (Fidonet#2:254/27.0): Cy Booker
  31.                 
  32.               Musical entertainment provided by Frank Zappa
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  ============================================================ BasCompress ==== 
  67.  
  68.  
  69.  
  70.  
  71.      [1]        Overview  . . . . . . . . . . . . . . . . . . . . .  1
  72.      [1.1]      Disclaimer  . . . . . . . . . . . . . . . . . . . .  1
  73.      [1.2]      Synopsis  . . . . . . . . . . . . . . . . . . . . .  1
  74.      [1.3]      Features  . . . . . . . . . . . . . . . . . . . . .  2
  75.      [1.4]      Documentation . . . . . . . . . . . . . . . . . . .  3
  76.      [1.5]      Compressing your first file . . . . . . . . . . . .  3
  77.      [1.6]      Example speed . . . . . . . . . . . . . . . . . . .  3
  78.      [1.7]      Example compression . . . . . . . . . . . . . . . .  4
  79.      [2]        BasCompress . . . . . . . . . . . . . . . . . . . .  5
  80.      [2.1]      Overview  . . . . . . . . . . . . . . . . . . . . .  5
  81.      [2.2]      Jargon  . . . . . . . . . . . . . . . . . . . . . .  5
  82.      [2.3]      Basic . . . . . . . . . . . . . . . . . . . . . . .  5
  83.      [2.4]      Numbers . . . . . . . . . . . . . . . . . . . . . .  5
  84.      [2.5]      SWI’s . . . . . . . . . . . . . . . . . . . . . . .  6
  85.      [2.6]      Star commands . . . . . . . . . . . . . . . . . . .  6
  86.      [2.7]      Assembler . . . . . . . . . . . . . . . . . . . . .  7
  87.      [2.8]      Routines  . . . . . . . . . . . . . . . . . . . . .  7
  88.      [2.8.1]    Main program  . . . . . . . . . . . . . . . . . . .  7
  89.      [2.8.2]    Start and end of a routine  . . . . . . . . . . . .  8
  90.      [2.8.3]    Routine end detection . . . . . . . . . . . . . . .  8
  91.      [2.8.4]    END and ERROR . . . . . . . . . . . . . . . . . . .  9
  92.      [2.8.5]    LOCAL ERROR . . . . . . . . . . . . . . . . . . . .  9
  93.      [2.9]      Multi-line structures . . . . . . . . . . . . . . .  9
  94.      [2.10]     Libraries . . . . . . . . . . . . . . . . . . . . . 10
  95.      [2.10.1]   Multiply-defined routines in libraries  . . . . . . 11
  96.      [2.11]     Label reduction . . . . . . . . . . . . . . . . . . 11
  97.      [2.12]     Line numbers  . . . . . . . . . . . . . . . . . . . 12
  98.      [2.12.1]   Output line numbers . . . . . . . . . . . . . . . . 12
  99.      [2.13]     Multi-line output . . . . . . . . . . . . . . . . . 13
  100.      [2.14]     DATA  . . . . . . . . . . . . . . . . . . . . . . . 13
  101.      [2.15]     Re-compressing  . . . . . . . . . . . . . . . . . . 13
  102.      [2.16]     Constant variables  . . . . . . . . . . . . . . . . 14
  103.      [2.16.1]   Caveat  . . . . . . . . . . . . . . . . . . . . . . 15
  104.      [2.17]     ASC compression . . . . . . . . . . . . . . . . . . 15
  105.      [2.18]     Overlays  . . . . . . . . . . . . . . . . . . . . . 16
  106.      [2.18.1]   Overlay specification . . . . . . . . . . . . . . . 16
  107.      [2.18.2]   Inline comments . . . . . . . . . . . . . . . . . . 16
  108.      [2.18.3]   Example of overlays . . . . . . . . . . . . . . . . 17
  109.      [2.18.4]   OVERLAYs and re-compressing . . . . . . . . . . . . 17
  110.      [2.19]     NEXT compression  . . . . . . . . . . . . . . . . . 17
  111.      [2.20]     Keeping initial REM statements  . . . . . . . . . . 18
  112.      [2.21]     TOP handling  . . . . . . . . . . . . . . . . . . . 18
  113.      [2.22]     Output type . . . . . . . . . . . . . . . . . . . . 19
  114.      [2.22.1]   Squeezed output . . . . . . . . . . . . . . . . . . 19
  115.      [2.22.2]   Command line parameters . . . . . . . . . . . . . . 19
  116.      [3]        Cross-referencing . . . . . . . . . . . . . . . . . 20
  117.      [3.1]      Overview  . . . . . . . . . . . . . . . . . . . . . 20
  118.      [3.1.1]    What’s cross-referenced . . . . . . . . . . . . . . 20
  119.      [3.1.2]    What’s output . . . . . . . . . . . . . . . . . . . 20
  120.      [3.1.3]    Messages  . . . . . . . . . . . . . . . . . . . . . 20
  121.      [3.2]      Level of detail . . . . . . . . . . . . . . . . . . 21
  122.      [3.2.1]    Routine definition  . . . . . . . . . . . . . . . . 21
  123.      [3.2.2]    Routine calls . . . . . . . . . . . . . . . . . . . 21
  124.      [3.2.3]    Routine called by . . . . . . . . . . . . . . . . . 22
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  ============================================================ BasCompress ==== 
  131.  
  132.  
  133.  
  134.  
  135.      [3.2.4]    Variable declaration  . . . . . . . . . . . . . . . 22
  136.      [3.2.5]    Variable assignment . . . . . . . . . . . . . . . . 22
  137.      [3.2.6]    Variable reference  . . . . . . . . . . . . . . . . 22
  138.      [3.3]      Order . . . . . . . . . . . . . . . . . . . . . . . 23
  139.      [4]        The front end . . . . . . . . . . . . . . . . . . . 24
  140.      [4.1]      Installation  . . . . . . . . . . . . . . . . . . . 24
  141.      [4.1.1]    Installing throwback  . . . . . . . . . . . . . . . 24
  142.      [4.2]      Starting  . . . . . . . . . . . . . . . . . . . . . 24
  143.      [4.3]      Overview  . . . . . . . . . . . . . . . . . . . . . 25
  144.      [4.3.1]    Icon bar icon . . . . . . . . . . . . . . . . . . . 25
  145.      [4.4]      Control window  . . . . . . . . . . . . . . . . . . 25
  146.      [4.5]      Main menu . . . . . . . . . . . . . . . . . . . . . 26
  147.      [4.6]      Input . . . . . . . . . . . . . . . . . . . . . . . 26
  148.      [4.7]      Output  . . . . . . . . . . . . . . . . . . . . . . 27
  149.      [4.8]      Log . . . . . . . . . . . . . . . . . . . . . . . . 29
  150.      [4.9]      Special files . . . . . . . . . . . . . . . . . . . 30
  151.      [4.10]     Cross-reference . . . . . . . . . . . . . . . . . . 31
  152.      [4.11]     Choices Dialogue Box  . . . . . . . . . . . . . . . 32
  153.      [5.1]      Invoking  . . . . . . . . . . . . . . . . . . . . . 35
  154.      [5.2]      Installing  . . . . . . . . . . . . . . . . . . . . 35
  155.      [5.3]      Environment variables . . . . . . . . . . . . . . . 36
  156.      [5.3.1]    DDEUtils and long command lines . . . . . . . . . . 36
  157.      [5.4]      The CLI parameters  . . . . . . . . . . . . . . . . 37
  158.      [5.4.1]    Input . . . . . . . . . . . . . . . . . . . . . . . 37
  159.      [5.4.2]    Output  . . . . . . . . . . . . . . . . . . . . . . 38
  160.      [5.4.2.1]  Output listing  . . . . . . . . . . . . . . . . . . 38
  161.      [5.4.3]    Log . . . . . . . . . . . . . . . . . . . . . . . . 39
  162.      [5.4.4]    Special . . . . . . . . . . . . . . . . . . . . . . 39
  163.      [5.4.5]    Cross-reference . . . . . . . . . . . . . . . . . . 39
  164.      [5.4.5.1]  What gets cross-referenced  . . . . . . . . . . . . 39
  165.      [5.4.5.2]  How much cross-referencing to be done . . . . . . . 40
  166.      [5.4.5.3]  Order of cross-referencing  . . . . . . . . . . . . 40
  167.      [5.5]      Error handling  . . . . . . . . . . . . . . . . . . 40
  168.      [5.6]      Escape handling . . . . . . . . . . . . . . . . . . 41
  169.      [5.7]      Hourglass . . . . . . . . . . . . . . . . . . . . . 41
  170.      [6]        Special files . . . . . . . . . . . . . . . . . . . 42
  171.      [6.1]      Why need special files? . . . . . . . . . . . . . . 42
  172.      [6.2]      The Special file  . . . . . . . . . . . . . . . . . 42
  173.      [6.3]      Format of a Special file  . . . . . . . . . . . . . 43
  174.      [6.3.1]    Defining routines . . . . . . . . . . . . . . . . . 43
  175.      [6.3.2]    Defining globals  . . . . . . . . . . . . . . . . . 43
  176.      [6.3.3]    Labels  . . . . . . . . . . . . . . . . . . . . . . 44
  177.      [6.3.3.1]  Verbatim  . . . . . . . . . . . . . . . . . . . . . 44
  178.      [6.3.3.2]  Comma separated . . . . . . . . . . . . . . . . . . 45
  179.      [6.3.3.3]  Full pathname . . . . . . . . . . . . . . . . . . . 45
  180.      [6.3.3.4]  Wimp menu . . . . . . . . . . . . . . . . . . . . . 45
  181.      [6.3.4]    Variables as regular expressions  . . . . . . . . . 46
  182.      [6.3.4.1]  Example patterns  . . . . . . . . . . . . . . . . . 46
  183.      [6.3.4.2]  Limitations . . . . . . . . . . . . . . . . . . . . 47
  184.      [6.3.5]    Libraries . . . . . . . . . . . . . . . . . . . . . 47
  185.      [6.3.6]    Overlays  . . . . . . . . . . . . . . . . . . . . . 48
  186.      [6.3.7]    Include files . . . . . . . . . . . . . . . . . . . 48
  187.      [6.4]      Limitations . . . . . . . . . . . . . . . . . . . . 48
  188.      [7]        Errors  . . . . . . . . . . . . . . . . . . . . . . 49
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  ============================================================ BasCompress ==== 
  195.  
  196.  
  197.  
  198.  
  199.      [7.1]      Overview  . . . . . . . . . . . . . . . . . . . . . 49
  200.      [7.2]      Warnings  . . . . . . . . . . . . . . . . . . . . . 49
  201.      [7.3]      Errors  . . . . . . . . . . . . . . . . . . . . . . 54
  202.      [7.4]      Run-time errors . . . . . . . . . . . . . . . . . . 59
  203.      [7.4.1]    Unknown or missing variable . . . . . . . . . . . . 59
  204.      [7.4.2]    No such function/procedure  . . . . . . . . . . . . 59
  205.      [7.4.3]    Missing ENDIF . . . . . . . . . . . . . . . . . . . 59
  206.      [7.4.4]    Invalid RETURN actual parameter . . . . . . . . . . 60
  207.      [7.4.5]    Syntax error  . . . . . . . . . . . . . . . . . . . 60
  208.      [7.4.6]    Logical errors  . . . . . . . . . . . . . . . . . . 60
  209.      [7.5]      Internal errors . . . . . . . . . . . . . . . . . . 61
  210.      [8]        Loose ends  . . . . . . . . . . . . . . . . . . . . 62
  211.      [8.1]      Memory usage  . . . . . . . . . . . . . . . . . . . 62
  212.      [8.2]      Missing THEN  . . . . . . . . . . . . . . . . . . . 63
  213.      [8.3]      Cross-reference . . . . . . . . . . . . . . . . . . 64
  214.      [8.4]      Statistics  . . . . . . . . . . . . . . . . . . . . 64
  215.      [8.5]      Uncompressed output . . . . . . . . . . . . . . . . 64
  216.      [8.6]      Label reduction . . . . . . . . . . . . . . . . . . 65
  217.      [8.7]      Executable  . . . . . . . . . . . . . . . . . . . . 65
  218.      [A]        Messages  . . . . . . . . . . . . . . . . . . . . . 66
  219.      [A.1]      Internationalism united . . . . . . . . . . . . . . 66
  220.      [A.2]      Format  . . . . . . . . . . . . . . . . . . . . . . 66
  221.      [B]        Regular expressions . . . . . . . . . . . . . . . . 67
  222.      [B.1]      Definition  . . . . . . . . . . . . . . . . . . . . 67
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  ============================================================ BasCompress ====
  259.  
  260.  
  261.  
  262.  [1] Overview
  263.      
  264.      
  265.  [1.1] Disclaimer
  266.      
  267.      This program is supplied “as is”.  No warranty, express or implied,
  268.      of the  merchantability of this program or its fitness for any
  269.      particular purpose is given.  In no circumstances shall the author,
  270.      or any provider or distributor of this program, be liable for any
  271.      damage, loss of profits, or any indirect or consequential loss
  272.      arising out of the use of this program.
  273.      
  274.      
  275.  [1.2] Synopsis
  276.      
  277.      BasCompress takes as input a tokenised basic file, analyses it on a
  278.      routine-by-routine basis, and outputs a cross-reference and a
  279.      compressed tokenised basic file.
  280.      
  281.      (It was written because none of the currently available Basic
  282.      squashers handled the side effects of EVAL, removed unused routines,
  283.      or discarded the junk inbetween routines, and they were all far too
  284.      slow).
  285.      
  286.      It consists of two programs, a Wimp-based front end, and a CLI-based
  287.      back end.  The former is ideal for occasional use, while the later is
  288.      better for scripts, make files, etc..
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.                                   Page   1
  321.  
  322.  ============================================================ BasCompress ====
  323.  
  324.  
  325.  
  326.  [1.3] Features
  327.      
  328.      The main features of BasCompress can be summarised as follows:
  329.  
  330.          •   Checks all multi-line IFs have a matching ENDIF
  331.          •   Checks all CASE’s have a matching ENDCASE
  332.          •   Checks all WHILE’s have a matching ENDWHILE
  333.          •   Checks the ellipsis/quotes/brackets on each statement
  334.          •   It doesn’t balk at the use of line numbers (too much)
  335.          •   Loads in explicit LIBRARY files
  336.          •   Checks every routine exits cleanly
  337.          •   Checks for multiply-defined routines
  338.          •   Produces a full cross-reference on all variables and
  339.              routines, with four levels of detail, and user-definable
  340.              ordering
  341.          •   Variable/routine name reduction, targeting the most used to
  342.              be the shortest
  343.          •   Remove all redundant spaces and REMarks
  344.          •   Remove all between-routine junk
  345.          •   Concatenation of output lines
  346.          •   Remove unused code
  347.          •   Reduces numbers to their shortest form
  348.          •   Converts SYS and SWI strings to numbers
  349.          •   Converts ASC(“s”) to the equivalent number
  350.          •   Compresses/removes constant variables
  351.          •   Handles DIM x!24 32
  352.          •   Optional “special” file to handle EVALuated variables and
  353.              functions, and implicitly loaded library files
  354.          •   “special” file allows variables to be defined as regular
  355.              expressions
  356.          •   It is fast
  357.      
  358.      In other words it does all you would expect, a bit more, and all at a
  359.      very respectable speed.
  360.      
  361.      All those syntax checks may seem superfluous until you realise that
  362.      most error handling code isn’t always as fully debugged as it should
  363.      be.
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.                                   Page   2
  385.  
  386.  ============================================================ BasCompress ====
  387.  
  388.  
  389.  
  390.  [1.4] Documentation
  391.      
  392.      This document is split into several sections.  First a full
  393.      description of exactly what this program does to, and expects of, the
  394.      input.  This is followed by §3, a chapter on the powerful cross-
  395.      referencing available.  Not until §4 is the program itself described,
  396.      the Wimp front end application.  The back end application, accessible
  397.      from the CLI is §5.  Special files, their format and use are detailed
  398.      in §6.  §7 is what this author wishes every program documentation
  399.      had, a complete list of errors and reasons why they occurred, and
  400.      more importantly --- some hints on how to get rid of them.  Finally,
  401.      §8 contains miscellanea, the junk that doesn’t categorise too easily.
  402.      
  403.      
  404.  [1.5] Compressing your first file
  405.      
  406.      Run the application.  This will install the Wimp front end onto the
  407.      icon bar icon and open the control window to the center of the screen.
  408.      
  409.      First of all drag the Log file icon to a directory display (not
  410.      another application, sorry).  This file will contain information
  411.      about the actions of the compression process.  Now drag a Basic file
  412.      onto the control window, to compress it.
  413.      
  414.      With the default options this Basic file will be analysed, the log
  415.      file created and then automatically loaded into your resident text
  416.      editor.  If this is Edit, then don’t close the Log window for now.
  417.      
  418.      Even if the Basic file was analysed without error, no output file was
  419.      produced because none was defined.  Just drag the output file icon
  420.      from the control window onto a directory display and start again.
  421.      
  422.      Now, because Edit still had a view of the Log file, this was
  423.      automatically updated, using the current window size.  This gives an
  424.      extremely usable environment!
  425.      
  426.      Voila, a compressed basic file has been produced.
  427.      
  428.      If the log file reports any EVAL or DATA statements were found, it is
  429.      possible that the program may not run.  See the chapter on Special
  430.      files for a way to handle this.  (The quick way is to disable all
  431.      variable and routine label reduction).
  432.      
  433.      Now read §2.
  434.      
  435.      
  436.  [1.6] Example speed
  437.      
  438.      It takes BasCompress less than 20s to compress itself.  This needs 4
  439.      special files, contains 40-odd source files (including libraries)
  440.      totalling just over 450K, and compresses it down to 100K.  And all
  441.      this on an Arm2 off of the standard 440 hard-disc, with all the I/O
  442.      overhead that that involves.
  443.  
  444.  
  445.  
  446.  
  447.  
  448.                                   Page   3
  449.  
  450.  ============================================================ BasCompress ====
  451.  
  452.  
  453.  
  454.  [1.7] Example compression
  455.      
  456.      Here’s how well BasCompress handles compressing an early version of
  457.      the Wimp front end application:
  458.      
  459.              192742  Total input size
  460.              29659   Maximum compression
  461.              29706   No decimal number analysis
  462.              31129   No SWI name analysis
  463.              35103   No concatenation of output lines
  464.              47421   No removal of unused code
  465.              51950   No reduction of labels
  466.      
  467.      The later ones are not accumulative, the non-reduction of labels
  468.      (only) really does add on 57% to the output program size!
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.                                   Page   4
  513.  
  514.  ============================================================ BasCompress ====
  515.  
  516.  
  517.  
  518.  [2] BasCompress
  519.      
  520.      
  521.  [2.1] Overview
  522.      
  523.      This chapter concerns itself with Basic, and what BasCompress expects
  524.      (and does) to it.
  525.      
  526.      
  527.  [2.2] Jargon
  528.      
  529.      The following terms will be used quite frequently, so I’ll explain
  530.      what is meant by them:
  531.      
  532.              routine         a procedure or function
  533.              variable        an (integer | real | string)[array]
  534.              label           the name of a routine or variable
  535.              name            a label with its (pre | post)fix
  536.      
  537.      E.g. the following table might help
  538.      
  539.              name            label
  540.              PROC_Zappa      _Zappa
  541.              Frank%          Frank
  542.              Cy$()           Cy
  543.      
  544.      
  545.  [2.3] Basic
  546.      
  547.      BasCompress will only except fully tokenised basic files, it does not
  548.      accept text files.  This program only knows about the tokens present
  549.      in Basic V, v1.04.  The behaviour of this program on Basic files on a
  550.      version greater than this is undefined.
  551.      
  552.      Only one Basic file is parsed (but see §2.10).
  553.      
  554.      
  555.  [2.4] Numbers
  556.      
  557.      BasCompress will interpret all numbers and try to output them in as
  558.      compact a form as possible.  This is most effective on long binary
  559.      numbers, but can shorten many large decimal values as well.
  560.      
  561.      The analysis and output of (decimal) numbers requires the floating
  562.      point emulator.  For this reason this can be turned off, just in case
  563.      you are very short on memory.
  564.      
  565.      Analysis of hexadecimal and binary numbers is always done, as this
  566.      does not require any floating point math.
  567.  
  568.      Note that BasCompress tries to output numbers in the hexadecimal
  569.      format whenever possible.  One artifact of this is assembler source
  570.      where the registers get converted to &e, etc.
  571.  
  572.  
  573.  
  574.  
  575.  
  576.                                   Page   5
  577.  
  578.  ============================================================ BasCompress ====
  579.  
  580.  
  581.  
  582.  [2.5] SWI’s
  583.      
  584.      Acorn’s interface to the operating system, the SWI is an elegant self-
  585.      documenting system.  However, for interpreted languages like Basic,
  586.      the translation of a SWI name to a SWI number is relatively time-
  587.      consuming.
  588.      
  589.      BasCompress will try to do this translation, leaving just a number.
  590.      This provides both large space and large execution savings,
  591.      particularly for Wimp programs that use SWI’s during screen redraw
  592.      (that’s all of them!)
  593.      
  594.      In order for BasCompress to translate the SWI name, it must be a
  595.      simple constant string expression.  If it isn’t, or it can’t
  596.      translate it, then it is left as it is --- thus providing an (almost)
  597.      fool-proof conversion.  (A possible case of a complex string constant
  598.      would be SYS “X”+ “OS_ReadC”).
  599.      
  600.      Both SYS calls (in Basic) and SWI calls (in assembler) are converted.
  601.      
  602.      Note also that the any modules used by the program should be resident
  603.      at the time of compression, otherwise the SWI’s will be unknown and
  604.      thus BasCompress will leave them as strings.  This is an easy mistake
  605.      to make, and results in slower and longer compacted files being
  606.      produced.  This cases ud detected, and generates a suitable warning.
  607.      
  608.      
  609.  [2.6] Star commands
  610.      
  611.      A backward compatibility feature of Basic V is it’s allowance of
  612.      *Commands anywhere in Basic.  Modern programs should really put this
  613.      in an OSCLI(“...”), or better yet a SYS “OS_CLI”, “...”.
  614.      
  615.      However, since this is allowed, some programmers use it to introduce
  616.      comments in programs by using the *| comment construct.  BasCompress
  617.      will remove these lines completely.  It will also remove all
  618.      unnecessary *’s and spaces.
  619.      
  620.      If this results in a complete removal of the statement, BasCompress
  621.      may produce incorrect code if (and only if) this *command was just
  622.      after an (explicit) THEN.  Since this is extremely bad programming
  623.      practised, this author felt the benefits gained far outweigh the
  624.      possible side-effects.
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.                                   Page   6
  641.  
  642.  ============================================================ BasCompress ====
  643.  
  644.  
  645.  
  646.  [2.7] Assembler
  647.      
  648.      BasCompress fully understands and compacts assembler statements.  As
  649.      part of this process, BasCompress also checks that the square bracket
  650.      “[]” count on each statement is valid --- which may be useful for
  651.      detecting bugs in conditionally assembled code.
  652.      
  653.      All R0..R15 registers get translated to 0..15, this saves a lot of
  654.      space.  Also the integer EQU’s can be renamed to DC’s.
  655.      
  656.      Note that the single space left after some mnemonics is necessary,
  657.      without it the Basic assembler will refuse to work.
  658.  
  659.      BasCompress also recognises (and compresses to) the ‘&’ derivative
  660.      of DCW and the ‘=’ derivative of EQUS and DCB.
  661.      
  662.      
  663.  [2.8] Routines
  664.      
  665.      It is important to understand that BasCompress treats a program as a
  666.      group of routines.  Because of this it can remove any junk inbetween
  667.      routines, i.e. comments not explicitly starting with a REM, that
  668.      other squashers leave behind (and even try to analyse --- producing
  669.      many, many errors).
  670.      
  671.      Note that this behaviour, removing junk between routines, can be
  672.      disabled in cases where BasCompress is unable to detect the end of
  673.      a routine.  See below for details of why BasCompress can get
  674.      confused.
  675.  
  676.      Because a record is kept of what happens inside a routine, it is
  677.      possible to conclude that a routine isn’t actually needed in the
  678.      output file --- and so none of the routines that it calls are needed
  679.      that bit less as well.  Thus BasCompress can remove ALL unused
  680.      routines from the output file.  This is a very powerful feature.
  681.  
  682.  
  683.  [2.8.1] Main program
  684.      
  685.      BasicV does not provide a clearly defined method for distinguishing
  686.      the end of the main program, and the start of the subroutines.
  687.      BasCompress treats everything from the start of the first file to the
  688.      first routine definition (DEF PROC or DEF FN) to be the main
  689.      program.  This isn’t ideal, as many main programs consists of an
  690.      infinite loop followed by junk --- however there is no easy way of
  691.      recognising the true end of the main program, so you have to live
  692.      with it as it is.
  693.      
  694.      If you wish to compress library files separately, i.e. files that do
  695.      not contain a main routine at the start of a file, then this is
  696.      easily accommodated.  There is a menu item
  697.      ‘Input->Process as a library file’ which toggles this feature.
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.                                   Page   7
  705.  
  706.  ============================================================ BasCompress ====
  707.  
  708.  
  709.  
  710.  [2.8.2] Start and end of a routine
  711.      
  712.      The start of a Basic routine is very easily detected, it is a line
  713.      that starts with DEF FN or DEF PROC.
  714.      
  715.      However, the end of a routine isn’t so easy to detect.  In the ideal
  716.      world, every routine will have one, and only one exit that is a
  717.      simple ENDPROC, or = <expr> on a line of its’ own.  However, we all
  718.      live in the real world, and things are more complicated than that.
  719.      
  720.      
  721.  [2.8.3] Routine end detection
  722.      
  723.      For example, consider the following function:
  724.      
  725.              DEF FNmin(a, b)
  726.                IF a>b THEN =b ELSE =a
  727.      
  728.      Now, the only way for BasCompress to recognise this construct is if
  729.      it kept track of all branches of a conditional.  This would involve a
  730.      major upgrade, and would make the program just a code-generation pass
  731.      away from a true compiler.
  732.      
  733.      BasCompress has two separate ways of dealing with this, a ‘smart’ way
  734.      and a ‘dumb’ way.   The dumb method is to ignore routine ends all
  735.      together.  The smart method is to ignore exits from a routine that
  736.      occur:
  737.  
  738.                 •       on the same line as an IF
  739.                 •       an the same line as an ON ERROR
  740.                 •       inside a multi-line construct
  741.  
  742.      By default BasCompress is ‘smart’.  To disable this use the CLI
  743.      switch -Dumb, or tick menu item
  744.      ‘Input->Ignore exits from a routine (‘dumb’)’.
  745.  
  746.      Each method has its’ own merits.  The smart method means that
  747.      because BasCompress knows when the routine has ended, it can skip any
  748.      inter-routine junk.  The dumb method is extremely useful for coping
  749.      with legacy code that confuses BasCompress ‘smart’ algorithms.
  750.  
  751.      When in ‘smart’ mode BasCompress will think that the next line, in
  752.      the above example will be inside the function min.  This usually
  753.      results in a cascade of warning/error messages being generated.  The
  754.      only long-time cure for this is to amend the offending function.  The
  755.      simplest way is to just put a dummy terminator in, e.g.
  756.      
  757.              DEF FNmin(a, b)
  758.                IF a>b THEN =b ELSE =a
  759.              = 0
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.                                   Page   8
  769.  
  770.  ============================================================ BasCompress ====
  771.  
  772.  
  773.  
  774.      Better yet, would be to code it “properly”:
  775.      
  776.              DEF FNmin(a, b)
  777.                IF a>b THEN a=b
  778.              = a
  779.      
  780.      There is also the problem of programs that prematurely terminate
  781.      routines inside, say, a case structure.  This happens quite often,
  782.      because it makes for much shorter code, and so BasCompress recognises
  783.      this, see §2.9.
  784.      
  785.      
  786.  [2.8.4] END and ERROR
  787.      
  788.      Currently BasCompress does not recognise the fact that a routine may
  789.      end with the END command, nor an unconditional ERROR.  Since these
  790.      are examples of bad-programming anyway, these are easily worked
  791.      around by just adding a redundant ENDPROC or =0 after the last line.
  792.      
  793.      
  794.  [2.8.5] LOCAL ERROR
  795.      
  796.      BasCompress fully recognises local error handlers, and will force the
  797.      next input line to start a new output line accordingly.
  798.      
  799.      
  800.  [2.9] Multi-line structures
  801.      
  802.      When in ‘smart’ mode (see §2.8.3) BasCompress keeps track of the
  803.      current nesting level of all multi-line structures:
  804.      
  805.              •       CASE ... ENDCASE
  806.              •       IF THEN ... ENDIF
  807.              •       REPEAT ... UNTIL
  808.              •       WHILE ... ENDWHILE
  809.      
  810.      It does this primarily to detect conditional exiting from a routine.
  811.      For example, if an ENDPROC or = <expr> is detected inside such a
  812.      structure, then BasCompress knows it isn’t the true end of the
  813.      routine, and so will ignore it.  A very useful side-effect of this is
  814.      that BasCompress detects programming errors in the use of these
  815.      constructs, errors that the run time Basic interpreter allows
  816.      through.  These very often are genuine program mistakes, usually
  817.      inside error-handling code that is not fully debugged.
  818.      
  819.      However, there are two caveats to this.  Firstly, in order for
  820.      BasCompress to do this it must assume that the start of any multi-
  821.      line structure is not inside a one-line IF construct.  Unfortunately,
  822.      some programmers put a quick WHILE ... ENDWHILE loop in a one-line
  823.      IF.  BasCompress does not handle this correctly and this line needs
  824.      to be split into a true multi-line IF.
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.                                   Page   9
  833.  
  834.  ============================================================ BasCompress ====
  835.  
  836.  
  837.  
  838.      Secondly, and just as less seriously, BasicV is rather lax in it’s
  839.      attitude towards multi-line structures.  For example:
  840.      
  841.              REPEAT
  842.                i += 1
  843.                CASE x(i) OF
  844.                WHEN 1:
  845.                  IF do_it THEN
  846.                    UNTIL FALSE:ENDPROC
  847.                  ENDIF
  848.                  ...
  849.                ...
  850.                ENDCASE
  851.              UNTIL i>max_i
  852.      
  853.      Here, BasicV will rather carelessly execute the UNTIL, even though it
  854.      isn’t at the same nesting level as the matching REPEAT.  BasCompress
  855.      is not so lenient and it will refuse point blank to handle such
  856.      code.  It is another example of bad programming being used, and
  857.      should be re-coded in another way.
  858.  
  859.      If you need to compress such code then put BasCompress in it’s ‘dumb’
  860.      mode.
  861.  
  862.      
  863.      
  864.  [2.10] Libraries
  865.      
  866.      The use of the LIBRARY call is recognised.  It causes the appropriate
  867.      file to be appended to the queue of files to be parsed, and the
  868.      entire LIBRARY statement to be removed from the output.
  869.      
  870.      For this to work, BasCompress assumes a simple string constant
  871.      follows the LIBRARY.  If this is not the case and it uses a
  872.      variable/routine parameter then you will need to set up a Special
  873.      file.  This will tell BasCompress what to expect the variable to be
  874.      so it can load the correct file.  Please refer to the §6.
  875.      
  876.      All LIBRARY files are only ever scanned once, even if it is included
  877.      many times.
  878.      
  879.      Of course, the loading of libraries will mean that the current
  880.      directory and/or some system variables (e.g. App$Dir) may need to be
  881.      set up --- otherwise BasCompress will not be able to locate the 
  882.      library file.
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.                                   Page  10
  897.  
  898.  ============================================================ BasCompress ====
  899.  
  900.  
  901.  
  902.  [2.10.1] Multiply-defined routines in libraries
  903.      
  904.      Note that the loading of libraries, as performed by BasCompress is
  905.      not exactly the same as the order that BasicV would have loaded them
  906.      in.  This could only cause a problem if multiply-defined routines
  907.      exist, and further more these multiple definitions are themselves in
  908.      library files, not the main file.  If this situation does arise, then
  909.      the kludge is: include the library containing the preferred
  910.      definition twice, once before and once after the LIBRARY containing
  911.      the unwanted definition.  This will work because BasCompress will use
  912.      the first loaded, and the uncompressed program would use the second!
  913.      
  914.      
  915.  [2.11] Label reduction
  916.      
  917.      A lot of the time that BasicV takes to interpret a program is spent
  918.      looking up variable names.  BasCompress will attempt to reduce the
  919.      long labels down to size, often producing dramatic space and speed
  920.      improvements.  The algorithm used ensures that the most used
  921.      variables are chosen for the shortest variable names, and the names
  922.      themselves are chosen so as to spread evenly across the name-space.
  923.      
  924.      Did you note the word attempt in the above paragraph?  This is
  925.      because basic is an interpreted language and provides the powerful
  926.      commands EVAL and DATA, allowing expressions to be evaluated in the
  927.      current context.  For instance EVAL(“zappa%”) would yield the value
  928.      of the variable zappa%.  But, if BasCompress had reduced this
  929.      variable down to, say, A% in the rest of the program (because  it
  930.      analysed the program in a different context) then what happens at run-
  931.      time is you get a variable not found error.
  932.      
  933.      There are two solutions to this very common problem.  The first is to
  934.      disable label reduction on all variables of the type that are used in
  935.      EVAL or DATA statements.  This is extremely wasteful, but the only
  936.      option available in other squashers.  With BasCompress there is a
  937.      much more elegant solution --- you can specify all the labels that
  938.      must not be reduced.  Further more, these variables can be implied
  939.      from the parameters passed to a routine!
  940.      
  941.      For example, many Wimp-based programs will have a menu-construction
  942.      suite of routines.  These will be passed a string that describes the
  943.      menu.  Inside this string will be references to variables that at run-
  944.      time will point to more information (sub-menus or windows usually).
  945.      With BasCompress, you can get it to analyse all these strings,
  946.      extract the variables, and then reduce all other variables apart from
  947.      those.  This is a very powerful feature.  See the §6 for more info.
  948.      
  949.      Note that BasCompress goes to the trouble of making sure that it
  950.      never produces one of the “built-in” register labels used by the
  951.      assembler (R0-R15, pc).  On other basic squashers this can lead to
  952.      VERY obscure bugs.
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.                                   Page  11
  961.  
  962.  ============================================================ BasCompress ====
  963.  
  964.  
  965.  
  966.      Also worth mentioning is that any labels accessed inside deleted
  967.      routines are automatically removed from the list of labels to
  968.      reduce.  This produces better results than just reducing all labels
  969.      found.
  970.      
  971.      BasCompress can handle any number of labels, well as many as could
  972.      fit into available memory!
  973.  
  974.      
  975.  [2.12] Line numbers
  976.      
  977.      Normally line numbers are an anathema but there does exist a valid
  978.      reason for using them in BasicV, and so line number handling has been
  979.      included in BasCompress.  The reason why line numbers may be needed
  980.      is if a program claims more memory though the use of the END=<expr>
  981.      construct.  This has the unfortunate side-effect of removing all
  982.      routine level info, so you have to GOTO the main program loop).
  983.      
  984.      Obviously, line numbers found in any library files are faulted as
  985.      there is no valid reason for them being there.
  986.      
  987.      Note that in short programs it is just possible that there will be a
  988.      GOTO to a destination outside both the main program and all other
  989.      routines.  Currently BasCompress does not handle this (rather rare)
  990.      case.  As a kludge, surround the offending code in a dummy routine.
  991.      
  992.      
  993.  [2.12.1] Output line numbers
  994.      
  995.      If no line numbers were found then line numbering is easy.  For
  996.      single-file programs the line numbers keep to their original values,
  997.      even if multi-line compaction is enabled.  For multi-file programs
  998.      the output file starts from 1 and increases in steps of 1.
  999.      
  1000.      If line numbers were found then the line numbers in the original
  1001.      program are used for the original program part, and thereafter line
  1002.      numbers increment in steps of one for any further libraries.
  1003.      
  1004.      Unfortunately BasicV only allows line numbers up to around 65000
  1005.      odd.  This could possibly be a problem if the original program has
  1006.      line numbers up to, say, 64000, and includes quite a few library
  1007.      files.  This is one of the few possible errors that are not checked
  1008.      for, as the possibility of it occurring are just so remote.
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.                                   Page  12
  1025.  
  1026.  ============================================================ BasCompress ====
  1027.  
  1028.  
  1029.  
  1030.  [2.13] Multi-line output
  1031.      
  1032.      Normally as many statements are compressed onto one output line as
  1033.      will fit.  This produces the smallest files as the overhead that
  1034.      Basic imposes on each line is reduced by quite a bit.
  1035.      
  1036.      However, it can produce code that runs slower.  This is because it
  1037.      appears BasicV only notes the statement number of an implicit jump
  1038.      (e.g. after a FOR, WHILE, or REPEAT).  And so if this is on statement
  1039.      56 of a line, say, then it has to scan all along the line to find
  1040.      where to continue execution.  This situation may be recognised in a
  1041.      future upgrade by forcing the statement after one of these cases to
  1042.      start on a new line.
  1043.      
  1044.      
  1045.  [2.14] DATA
  1046.      
  1047.      BasCompress recognises the possibility that DATA may not reside
  1048.      inside a routine.  All “unlinked” DATA statements will still be
  1049.      included in the output file, but only if there is some code left that
  1050.      will READ it.
  1051.      
  1052.      Please note that variables used as DATA will require the use of
  1053.      Special files.
  1054.      
  1055.      
  1056.  [2.15] Re-compressing
  1057.      
  1058.      Although at first sight the notion of compressing an already
  1059.      compressed file may seem a waste of time, in actual fact it is not.
  1060.      
  1061.      This is because BasCompress compresses a whole line at a time, and
  1062.      then merges together two or more lines.  This isn’t done quite as
  1063.      optimally as possible, and sometimes extra colons are inserted.
  1064.      
  1065.      If the output is fed back into BasCompress these extra colons will be
  1066.      removed, as it will be obvious that they are truly redundant.
  1067.      
  1068.      If constant variable substitution is enabled (§2.16) then quite often
  1069.      a second pass reveals more constant variables!
  1070.      
  1071.      The best way to double-compress is to first compress with reduction
  1072.      of function and procedure names only (thus ensuring ‘special’
  1073.      routines only parsed once), and then a second time with full
  1074.      reduction of variable names.
  1075.  
  1076.      If you are using BasCompress to generate a distributable file (for
  1077.      instance your latest commercial/shareware executable) then you
  1078.      should give serious consideration to using this re-compression
  1079.      technique.  It only takes a little while to set up a script (Obey)
  1080.      file to perform this at a (double) click of a file.
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.                                   Page  13
  1089.  
  1090.  ============================================================ BasCompress ====
  1091.  
  1092.  
  1093.  
  1094.  [2.16] Constant variables
  1095.      
  1096.      New to version 1.50 of BasCompress is the handling of ‘constant’
  1097.      variables.  By this it is meant a string/real/integer variable (not
  1098.      an array) that is:
  1099.      
  1100.              •       only ever assigned once
  1101.              •       never declared (ie LOCAL, or routine parameter)
  1102.              •       the assignment is ‘simple’
  1103.      
  1104.      By simple it is meant very simple!  Currently the only types that are
  1105.      recognised are:
  1106.      
  1107.              •       integer number, base 10
  1108.              •       real number
  1109.              •       hexadecimal number
  1110.              •       string
  1111.      
  1112.      Although nowhere near the full types of basic expressions, the above
  1113.      list does cover the most common case in libraries where one generally
  1114.      has a lot of variables used to give ‘names’ to constants.
  1115.      
  1116.      When BasCompress finds such a variable it does two things:
  1117.      
  1118.              •       Remove the definition
  1119.              •       Replace all occurrences of the variable name with its’
  1120.                      definition.
  1121.      
  1122.      This has the advantage that it leaves more room in the symbol table
  1123.      for variables that are actually used as variables.  It should also
  1124.      speed up the programs’ execution.
  1125.      
  1126.      Note that variables that have been compressed is this way are listed
  1127.      as ‘unused’ in the log file.
  1128.      
  1129.      If you have enabled ‘Process as a library’ then BasCompress will
  1130.      silently disable constant variable analysis.
  1131.  
  1132.      Note that for this feature to work BasCompress needs to recognise
  1133.      all types of variable assignment, including SWAP, MOUSE TO, and
  1134.      RETURN parameters in routines.  This used to be a problem, but
  1135.      BasCompress has been updated to account for all of these cases.
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.                                   Page  14
  1153.  
  1154.  ============================================================ BasCompress ====
  1155.  
  1156.  
  1157.  
  1158.  [2.16.1] Caveat
  1159.  
  1160.      There is one important caveat with constant variable handling.  This
  1161.      occurs if the definition of the constant variable is longer than the
  1162.      variable name itself.  This most often happens with long string
  1163.      constants, although can happen with some integer values.
  1164.  
  1165.      The problem occurs when BasCompress comes to ‘remove’ the variable
  1166.      and substitute the longer definition.  In rare circumstances (most
  1167.      noticably on already compressed source) this can cause a line longer
  1168.      than 256 bytes (a BasicV limitation) to be generated.
  1169.  
  1170.      The solution to such cases is to defined the variable in the special
  1171.      file (see §6.)  See also §3.2.5.
  1172.  
  1173.  
  1174.  [2.17] ASC compression
  1175.      
  1176.      In many programs that deal with text you will see expressions of the
  1177.      form:
  1178.      
  1179.              IF (c%>=ASC(“0”) AND c%<=ASC(“9”)) THEN
  1180.               ...
  1181.              ENDIF
  1182.      
  1183.      This looks very nice, but executes relatively slowly.  BasCompress
  1184.      now understands constructs of this form and will compress this down
  1185.      to:
  1186.      
  1187.              IF(A%>=48ANDA%<=57) THEN
  1188.               ...
  1189.              ENDIF
  1190.      
  1191.      Which is both textually shorter and is much faster to execute.
  1192.      
  1193.      To be more exact BasCompress understands the following:
  1194.      
  1195.              ASC [(]* string [)]*
  1196.      
  1197.      where spaces are swallowed and the string is a Basic format string.
  1198.      Also the brackets must match!
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.                                   Page  15
  1217.  
  1218.  ============================================================ BasCompress ====
  1219.  
  1220.  
  1221.  
  1222.  [2.18] Overlays
  1223.  
  1224.      Overlays are a way of ‘dynamically’ loading groups of orthogonal
  1225.      routines that BASIC supports.  The main advantage is that their use
  1226.      can, with careful program design, significantly reduce the memory
  1227.      requirements of an application.
  1228.      
  1229.      One oft cited example is in a ‘document’ handler, you only ever
  1230.      need to load, save, or print at one time.  Therefore these
  1231.      separate functions (which could be quite complex) could each be
  1232.      handled in different source files, and all three specified in an
  1233.      OVERLAY command.  The net result is that the application will
  1234.      only require as much memory as the largest overlay, rather than
  1235.      the total size of all overlays.
  1236.      
  1237.  
  1238.  [2.18.1] Overlay specification
  1239.  
  1240.      The OVERLAY command is not understood by BasCompress.  However,
  1241.      overlays are supported, through the use of special files (see §6),
  1242.      or through inline comments (see below).
  1243.      
  1244.      When specifying an overlay file, if no directory separator is given
  1245.      (‘.’) then the directory of the input file is used.  This is usually
  1246.      sufficient, unless you store overlays in a subdirectory.
  1247.  
  1248.      When output, each overlay file is output to the same directory as
  1249.      the main program (and all its’ libraries).  There is no support for
  1250.      placing the overlays in sub-directories of the output directory.
  1251.  
  1252.      Note that this means you MUST ensure that the output directory is
  1253.      different from the input directory, otherwise the overlay files
  1254.      will become (silently) overwritten with their compressed version.
  1255.  
  1256.      For every overlay file an output file is always generated, even if
  1257.      BasCompress has removed all the routines inside it.
  1258.  
  1259.  
  1260.  [2.18.2] Inline comments
  1261.  
  1262.      BasCompress ‘understands’ comments of the form:
  1263.      
  1264.                 REM BasCompress:Overlay: <overlay file>
  1265.  
  1266.      Note that case IS significant.  This tells BasCompress to parse the
  1267.      specified file as an overlay, always.  There is no condition
  1268.      attached to this (such as only parsing the overlay if this routine
  1269.      is actually used).
  1270.  
  1271.      If you require more control of which overlay files are parsed you
  1272.      will need to use a special file.
  1273.  
  1274.  
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.                                   Page  16
  1281.  
  1282.  ============================================================ BasCompress ====
  1283.  
  1284.  
  1285.  
  1286.  [2.18.3] Example of overlays
  1287.  
  1288.      Imagine an application has overlay files called “Load”, “Save”, and
  1289.      “Print”.  These are all in the ‘application’ directory <App$Dir>.
  1290.  
  1291.          REM >App
  1292.          DIM lib$(3)
  1293.          lib$() = “<App$Dir>.Load”, “<App$Dir>.Save”, “<App$Dir>.Print”
  1294.          OVERLAY lib$()
  1295.          REM BasCompress:Overlay: Load
  1296.          REM BasCompress:Overlay: SCSI::HardDrive4.$.AppSource.Save
  1297.          REM BasCompress:Overlay: Print
  1298.          ...
  1299.          PROC_Load_Document(doc%)
  1300.          PROC_Save_Document(doc%)
  1301.          PROC_Print_Document(doc%)
  1302.  
  1303.      Then, with the system variable App$Dir set up appropriately the
  1304.      source and the BasCompress’ed files will execute as expected.
  1305.  
  1306.  
  1307.  [2.18.4] OVERLAYs and re-compressing
  1308.  
  1309.      If you wish to compress a program that uses overlays more than once
  1310.      (see §2.15), and it contains inline comments then you need to take
  1311.      care.
  1312.  
  1313.      There are two solutions.  One involves the use of an environment
  1314.      variable in the inline comment:
  1315.  
  1316.                 REM BasCompress:OverLay <App$Dir>.overlay
  1317.  
  1318.      which needs to change between compressions.  The other depends on
  1319.      the comments being in the ‘main program’ (see §2.20).  Here you can
  1320.      force BasCompress to keep initial REMs on the first pass, and remove
  1321.      them on the second pass!
  1322.  
  1323.  
  1324.  [2.19] NEXT compression
  1325.  
  1326.      Basic supports a shorthand method of terminating FOR loops, by
  1327.      omitting the variable name after the NEXT statement.  While
  1328.      developing programs this is of dubious value, as it stops the
  1329.      interpreter from spotting possible mismatched FOR/NEXT’s.
  1330.  
  1331.      However, for compressed programs it is a good idea to remove the
  1332.      variable, as it (obviously) reduces the program size.  It also
  1333.      speeds the program up, as the Basic interpreter no longer has to
  1334.      check that the correct variable has been placed after the NEXT.
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.                                   Page  17
  1345.  
  1346.  ============================================================ BasCompress ====
  1347.  
  1348.  
  1349.  
  1350.      BasCompress will ‘swallow’ real and integer loop variables.  It will
  1351.      also concatenate adjacent NEXT’s to use a comma, eg.
  1352.  
  1353.                 NEXT a%:NEXT b%:PRINT ASC(“A”)
  1354.  
  1355.      will be compressed down to
  1356.  
  1357.                 NEXT,:PRINT65
  1358.  
  1359.      This only works if the NEXT’s are on the same line, however.  If you
  1360.      want as much compression as possible, you should process the file
  1361.      twice (see §2.15), as on the second pass most NEXT’s will be on the
  1362.      same line.
  1363.  
  1364.  
  1365.  [2.20] Keeping initial REM statements
  1366.  
  1367.      The file that BasCompress is usually the file that gets distributed
  1368.      to third parties (ie an applications’ !RunImage file).  It would be
  1369.      nice if you could incorporate into this some copyright message.
  1370.  
  1371.      One way to achieve this is to tell BasCompress to retain all 
  1372.      ‘initial’ REM statements.  These are comments that are
  1373.  
  1374.         •       before the first routine definition
  1375.         •       on a line by themselves
  1376.         •       begin with REM (not *|, or ;)
  1377.  
  1378.  
  1379.  [2.21] TOP handling
  1380.  
  1381.      Basic supports a pseudo-variable called ‘TOP’.  When read, it returns
  1382.      the topmost byte of memory.  Unfortunately Basic does not use a token
  1383.      to encode this variable, but uses the token for ‘TO’ and the letter
  1384.      ‘P’.
  1385.  
  1386.      Basic has no problem with this, as it knows when to expect a proper
  1387.      ‘TO’ (after a FOR <var>=<expr>, or after a SYS).  Unfortunately
  1388.      BasCompress does not know this, and so can not distinguish between a
  1389.      true ‘TOP’ and a ‘TO P’ without a space.
  1390.  
  1391.      This does matter if constant variable deletion is enabled, because
  1392.      BasCompress will not ‘see’ the P after the TO and if the P is other-
  1393.      wise constant, will be substituted everywhere else.
  1394.  
  1395.      Unfortunately there is no solution, other than to ensure that your
  1396.      source code never contains the sequence ‘TOP’, which can be done by
  1397.      ensuring that you have spaces after the TO.  (Note that ‘TOPizza’ is
  1398.      OK, as is ‘TOP%’).
  1399.  
  1400.      As far as BasCompress output is concerned, this is not a problem, as
  1401.      the Basic interpreter knows how to handle these cases anyway.
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.  
  1408.                                   Page  18
  1409.  
  1410.  ============================================================ BasCompress ====
  1411.  
  1412.  
  1413.  
  1414.  [2.22] Output type
  1415.  
  1416.      Ordinarily BasCompress will produce a standard tokenised Basic file.
  1417.      However, it is a common requirement to further “protect” the
  1418.      program, and this can be done by making the file an “absolute”
  1419.      program.
  1420.  
  1421.      An “absolute” program consists of some machine code stuck onto the
  1422.      front of the tokenised basic.  When executed the code “enters” BBC
  1423.      Basic and starts executing the program.
  1424.  
  1425.      Thus, for all intents and purposes they are identical --- you can
  1426.      double click either from a directory display, and your original
  1427.      Basic code will be executed the same.
  1428.  
  1429.  
  1430.  [2.22.1] Squeezed output
  1431.  
  1432.      Going one stage further in trying to “protect” your code,
  1433.      BasCompress now supports squeeze'ing the absolute file.  This
  1434.      has the added benefit of making the file smaller on disc, and hence
  1435.      quicker to load (especially from a floppy).
  1436.  
  1437.      However, the actual program that squeeze’s the absolute file is
  1438.      copyright Acorn.  But do not despair --- you already own a copy of
  1439.      it!
  1440.  
  1441.      The squeeze program can be found in your copy of the Patch
  1442.      application, in the directory “!Patch.Library”.  Copy the “squeeze”
  1443.      file in this directory into the directory “$.Library”.  (Or
  1444.      anywhere in your Run$Path).
  1445.  
  1446.  
  1447.  [2.22.2] Command line parameters
  1448.  
  1449.      There is a problem with using an absolute program in place of a
  1450.      tokenised file --- the command line is different.
  1451.  
  1452.      The details are pretty horrible --- it is necessary for the
  1453.      machine code stub to ‘remember’ the command line, then invoke
  1454.      Basic.  The backend compressor will have inserted a single line
  1455.      of basic that picks up this command line (in the system variable
  1456.      BasCompress$CLI) and updates the CLI with it.
  1457.  
  1458.      Thus by the time the first line of *your* Basic executes, then
  1459.      a call to SYS "OS_GetEnv" will return the correct value.
  1460.  
  1461.      Note that if the absolute code was envoked with an extended
  1462.      command line (ie using DDEUtils) then this will NOT be handled.
  1463.      If you require this feature then please contact the author.
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.                                   Page  19
  1473.  
  1474.  ============================================================ BasCompress ====
  1475.  
  1476.  
  1477.  
  1478.  [3] Cross-referencing
  1479.      
  1480.      
  1481.  [3.1] Overview
  1482.      
  1483.      The cross-referencing of a large program can provide many useful
  1484.      insights, providing you can organise the output so as not to swamp
  1485.      you with “useless” information.  To this end you can control what
  1486.      gets include, the level of detail, and the ordering (with many types
  1487.      of ordering available).
  1488.      
  1489.      Note that the cross-referencing of variables and routines is
  1490.      completely independent.
  1491.      
  1492.      
  1493.  [3.1.1] What’s cross-referenced
  1494.      
  1495.      The cross-reference contains only the routines and variables that
  1496.      will be included in the output file.  Since dead code is usually
  1497.      removed, you have to tell BasCompress to keep in all would-be deleted
  1498.      stuff if you need a complete cross-reference.
  1499.      
  1500.      You can also control exactly what types of labels are included.
  1501.      Usually you’d keep the default (everything), but sometimes you don’t
  1502.      care about all the real variables, say, and this is easily catered
  1503.      for.
  1504.      
  1505.      
  1506.  [3.1.2] What’s output
  1507.      
  1508.      The result of the cross-referencing is sent to the cross-reference
  1509.      file, or the screen if none is specified.  Since this is a lot of
  1510.      data, you will almost certainly want to use a file.  The front end
  1511.      application has the ability to automatically load this into the
  1512.      resident text editor.
  1513.      
  1514.      
  1515.  [3.1.3] Messages
  1516.      
  1517.      The formatting of the cross-reference is defined using the external
  1518.      Messages file.  By altering the following messages you can tailor the
  1519.      output of the program dramatically (see appendix A for description of
  1520.      format of messages) :-
  1521.      
  1522.              Name            Show label and its’ qualifying string (“%s%s”)
  1523.              Comma           Separates distinct references (“, ”)
  1524.              SemiColon       Separates similar references (“; ”)
  1525.      
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.                                   Page  20
  1537.  
  1538.  ============================================================ BasCompress ====
  1539.  
  1540.  
  1541.  
  1542.      They are currently set up to produce “one-line-per entry”.  However,
  1543.      it is possible to change these three so that every distinct reference
  1544.      appears on each separate line, vis-a-vis:
  1545.      
  1546.              Name:           \n\t%s%s
  1547.              Comma:          \n\t
  1548.              SemiColon:      ,% 
  1549.      
  1550.      But note, you will probably need to alter all the titles used so that
  1551.      they start rather than end with a newline.  (The \t expands to a tab
  1552.      character, this is usually better than many spaces, since cross-
  1553.      reference files are large enough as it is)
  1554.      
  1555.      
  1556.  [3.2] Level of detail
  1557.      
  1558.      There are four levels of detail supported by BasCompress:
  1559.      
  1560.              None            suppresses output, obvious really
  1561.              Existence       useful to just list the name of all the
  1562.                              labels used
  1563.              Global          gives the additional information of a count
  1564.                              of the label usage
  1565.              Routine         reports only each separate routine where a
  1566.                              reference was made, this is probably the most
  1567.                              useful option
  1568.              Line            details the exact statement for every
  1569.                              reference
  1570.      
  1571.      For the last two, each label has separate lists.  For routines there
  1572.      is: defined, calls, called by; and for variables there is: declared,
  1573.      assigned, and referenced.
  1574.      
  1575.      Note that the main program itself is treated internally as a
  1576.      procedure, and so appears in the routine cross-reference.
  1577.      
  1578.      
  1579.  [3.2.1] Routine definition
  1580.      
  1581.      This gives the file and line numbers of the start and end of the
  1582.      routine.
  1583.      
  1584.      
  1585.  [3.2.2] Routine calls
  1586.      
  1587.      Lists the names of the routines called by this routine, and the line
  1588.      number of the call.
  1589.  
  1590.  
  1591.  
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.                                   Page  21
  1601.  
  1602.  ============================================================ BasCompress ====
  1603.  
  1604.  
  1605.  
  1606.  [3.2.3] Routine called by
  1607.      
  1608.      Lists the names of the routines that calls this routine, and the line
  1609.      number of the call.
  1610.      
  1611.      If the list is empty then BasCompress knows that this routine is not
  1612.      needed in the output program, and so will not include it.
  1613.      
  1614.      
  1615.  [3.2.4] Variable declaration
  1616.      
  1617.      Where a label was “declared”.  By this BasCompress means it is a
  1618.      formal parameter of a routine, or explicitly declared as LOCAL.
  1619.      
  1620.      
  1621.  [3.2.5] Variable assignment
  1622.      
  1623.      When ever a variable appears at the start of a statement.  This
  1624.      includes assembler statements.
  1625.      Note that BasCompress sometimes thinks variable assignments are
  1626.      references.  This happens in the following cases:
  1627.      
  1628.              •       variable is passed to a routine with RETURN parameters
  1629.              •       assignment after a one-line IF that is without a THEN
  1630.      
  1631.      Here’s an example of the later:
  1632.      
  1633.              IF x<y x=y
  1634.      
  1635.      Because Bascompress doesn’t try to understand the conditional, it
  1636.      doesn’t know that a new statement has started and so can’t categorise
  1637.      the second reference to x as an assignment.  See §8.2.
  1638.      
  1639.      
  1640.  [3.2.6] Variable reference
  1641.      
  1642.      Any other instance of a variable other than the above two is taken to
  1643.      be a reference.
  1644.      
  1645.      BasCompress will not recognise the fact that x += 1 is actually both
  1646.      an assignment and a reference.
  1647.      
  1648.      BasCompress will also fail to recognise that var!0 = 1 only
  1649.      references var and does not assign to it.
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661.  
  1662.  
  1663.  
  1664.                                   Page  22
  1665.  
  1666.  ============================================================ BasCompress ====
  1667.  
  1668.  
  1669.  
  1670.  [3.3] Order
  1671.      
  1672.      There are many uses you can put to a list of labels, provided you can
  1673.      order them in the way you need.  BasCompress allows you to specify as
  1674.      many levels of sorting as you would need, with all the types of
  1675.      ordering that are relevant to the labels!
  1676.      
  1677.      You can sort in either direction --- top to bottom, or the more usual
  1678.      bottom to top.
  1679.      
  1680.      These are the following sort types currently supported:
  1681.      
  1682.              Name            in Ascii order
  1683.              Type            for routines: function, procedure
  1684.                              for variables: integer, real, string, integer
  1685.                              array, real array, string array
  1686.              Dictionary      by name, but as it would appear in a
  1687.                              dictionary
  1688.              Location        the location of the reference
  1689.              Usage           for routines: number of times it is called
  1690.                              for variables: sum of the assignments and the
  1691.                              references
  1692.      
  1693.      Note the needed for multi-level sorting.  You would normally sort
  1694.      labels by name, and type; and references by name, type, and location.
  1695.      
  1696.      Trying to sort labels by location has no meaning, and will result in
  1697.      a seemingly random order.  So it is not possible to list routines in
  1698.      the order they were defined in.
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.  
  1725.  
  1726.  
  1727.  
  1728.                                   Page  23
  1729.  
  1730.  ============================================================ BasCompress ====
  1731.  
  1732.  
  1733.  
  1734.  [4] The front end
  1735.      
  1736.      This describes the Wimp front end application.  This allows the user
  1737.      to set up the parameters for the back end program in a friendly way.
  1738.      
  1739.  
  1740.  [4.1] Installation
  1741.  
  1742.      By default the front end enables throwback.  This is a technique
  1743.      where a command line utility (eg the BasCompress back end engine)
  1744.      can communicate errors to a wimp application, such as SrcEdit, Zap,
  1745.      or StrongED.
  1746.  
  1747.      This causes the wimp application to display the errors in a window,
  1748.      where the user chooses an error/warning and the editor displays the
  1749.      appropriate source line, ready for editing.
  1750.  
  1751.  
  1752.  [4.1.1] Installing throwback
  1753.  
  1754.      For throwback to work, you require a support module called DDEUtils.
  1755.      This is an Acorn module that acts between the command line utility
  1756.      and the wimp application throwback server.
  1757.  
  1758.      Unfortunately, in order to distribute DDEUtils requires a Binary
  1759.      Distribution License from Acorn.  Therefore only developers may
  1760.      distribute this module.
  1761.  
  1762.      Luckily, BasCompress comes with a (partial) functional replacement,
  1763.      called DDEUtilsCy.  This supports all of the DDEUtils API, but has
  1764.      no functionality for any Prefix code (if you don’t understand this
  1765.      then it doesn’t concern you).  It also requires the use of an Obey
  1766.      script to initialise some system variables.
  1767.  
  1768.      Because DDEUtilsCy only contains a subset of the real DDEUtils’
  1769.      functionality, the !BC.!Run file goes to great lengths to ensure
  1770.      that if the user has the real DDEUtils module, then this is used in
  1771.      stead of the replacement.
  1772.  
  1773.  
  1774.  [4.2] Starting
  1775.      
  1776.      A standard Archimedes application, just double-click the application
  1777.      icon in the directory display to install it onto the icon bar.
  1778.      
  1779.      For foreign users, see the appendix A describing the Message file.
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792.                                   Page  24
  1793.  
  1794.  ============================================================ BasCompress ====
  1795.  
  1796.  
  1797.  
  1798.  [4.3] Overview
  1799.      
  1800.      Because the back end works on, and produces, a number of whole files
  1801.      the format of this application is slightly unorthodox.
  1802.      
  1803.      Basically you use the standard RISC OS method of dragging file icons
  1804.      to directory displays (to define the output files), and then drag a
  1805.      BASIC file onto the front end to invoke the back end application to
  1806.      compress it.  This generates the new log, cross-reference, and output
  1807.      files.
  1808.      
  1809.      Not all of the types of output files need to be generated.  Usually
  1810.      there is no need for a cross-reference.  But, you will almost
  1811.      certainly want the log file defined, as otherwise you would not know
  1812.      what errors occurred, or anything else.
  1813.      
  1814.      It is almost a pre-requisite to have Edit running alongside this
  1815.      front end in order for you to view the log that the back end
  1816.      application produces.  The loading of this log will normally be
  1817.      automatic.
  1818.      
  1819.      
  1820.  [4.3.1] Icon bar icon
  1821.      
  1822.      The icon bar icon shows some messages while the back end is active.
  1823.      This gives a visual reference to what is going on.
  1824.      
  1825.      Clicking SELECT on the icon bar icon brings the control window to the
  1826.      front of the window stack.
  1827.      
  1828.      Clicking ADJUST in the icon bar icon re-loads the last input file,
  1829.      using the new options.  This is extremely handy for trying out new
  1830.      options on a file that generated an error.
  1831.      
  1832.      
  1833.  [4.4] Control window
  1834.      
  1835.      This is automatically opened to the center of the screen when the
  1836.      application starts.  It allows you to quickly set up all the files to
  1837.      be used, and as a side effect it gives you the chance to open a menu
  1838.      somewhere other than in the bottom right of the screen!.  The left-
  1839.      most three icon groups act just like the save as dialogue boxes to be
  1840.      found on the menu.
  1841.      
  1842.      The special file is defined by dragging a Text file onto this
  1843.      window.  More special files can be defined by editing the text field,
  1844.      appending a comma separated list of file names.
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.                                   Page  25
  1857.  
  1858.  ============================================================ BasCompress ====
  1859.  
  1860.  
  1861.  
  1862.  [4.5] Main menu
  1863.      
  1864.      There is only one menu.
  1865.      
  1866.      Because the sub-menus are rather on the large side, it is recommended
  1867.      that you bring the menu up over the control window.  This was the
  1868.      main reason for having a control window, as a convenient anchor for
  1869.      the menu.
  1870.      
  1871.      
  1872.  [4.6] Input
  1873.      
  1874.      This sub-menu defines various parameters affecting BasCompress’s
  1875.      analysis of the input file.
  1876.      
  1877.      
  1878.   Ignore exits from a routine (‘dumb’)
  1879.  
  1880.      BasCompress has two strategies for detecting the end of a routine, a
  1881.      ‘smart’ method (the default) and a ‘dumb’ method.  The smart method
  1882.      will keep track of multi-line statements to detect an actual end of
  1883.      routine, the dumb method just parses until the next DEF FN/PROC.
  1884.  
  1885.      When enabled BasCompress will use the ‘dumb’ method.  See §2.16.
  1886.  
  1887.  
  1888.   Allow multiply-defined routines
  1889.  
  1890.      It is better to leave this option un-ticked, so that if a routine is
  1891.      defined more than once an error is generated.  This is the default.
  1892.      
  1893.      Ticking this option allows a routine to be defined more than once,
  1894.      with only warnings being given.  See §2.10.1.
  1895.      
  1896.  
  1897.   Force malformed SWI’s to generate error
  1898.  
  1899.      Malformed SWI’s are those that aren’t simple strings, e.g. “X”+
  1900.      “Wimp_Poll”.  With this enabled these generate an error, otherwise
  1901.      just a warning.  See §2.5.
  1902.      
  1903.      This item will be disabled if ‘Convert SWIs to numbers’ item in the
  1904.      output sub-menu is turned on.
  1905.      
  1906.      
  1907.   Process as a library file
  1908.  
  1909.      This option allows the input file to be treated as a library file.
  1910.      This means that no main program is expected, and any undefined
  1911.      variables and routines do not generate an error.  Of course, using
  1912.      this option is usually pointless without also disabling all label
  1913.      reductions.
  1914.      
  1915.      When turned on this item disables the item ‘Compress constant
  1916.      variables’ in the output sub-menu, as it is usually not very useful
  1917.      to have both these items enabled!
  1918.  
  1919.  
  1920.                                   Page  26
  1921.  
  1922.  ============================================================ BasCompress ====
  1923.  
  1924.  
  1925.  
  1926.  [4.7] Output
  1927.      
  1928.      This sub-menu allows you to tailor how much compression is applied to
  1929.      the output programs.  Redundant spaces and comments are always
  1930.      removed, since there seems little point in using BasCompress without
  1931.      doing this.
  1932.      
  1933.      By default all compression is on.
  1934.      
  1935.      
  1936.   Save as
  1937.  
  1938.      This leads to a standard dialogue box, used to define the basic file
  1939.      that will be produced if the input is analysed without error.
  1940.  
  1941.      Note that currently the only way to determine whether a Basic,
  1942.      Absolute, or Squeezed file is produced is from the main control
  1943.      window.
  1944.      
  1945.  
  1946.   Keep initial REMs
  1947.  
  1948.      This feature is useful for retaining copyright messages in the
  1949.      BasCompressed file.  By ‘inital’ it is meant everything up to the
  1950.      first routine definition.  See §2.20.
  1951.  
  1952.  
  1953.   Concatenate lines
  1954.  
  1955.      Forces as many statements as possible onto each output line.  This is
  1956.      usually very desirable as it produces quite substantially shorter
  1957.      code, but at the possible loss of a bit of execution speed.  See §2.
  1958.      13.
  1959.      
  1960.      
  1961.   Remove unused routines
  1962.  
  1963.      Because BasCompress can work out exactly which routines are, and are
  1964.      not needed in the final program, then it can remove unused routines.
  1965.      This is the default, and there is little point in disabling it, other
  1966.      than creating a full cross-reference.
  1967.      
  1968.      
  1969.   Remove constant variables
  1970.  
  1971.      BasCompress can recognise ‘constant’ variables, those that are only
  1972.      assigned once and have a very simple definition.  This helps to
  1973.      reduce symbol table overloading.  See §2.16.
  1974.      
  1975.      This item will be disabled if ‘Process as a library file’ in the
  1976.      Input sub-menu is turned on.
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.                                   Page  27
  1985.  
  1986.  ============================================================ BasCompress ====
  1987.  
  1988.      
  1989.      
  1990.   Remove constant ASC()
  1991.  
  1992.      When enabled this feature will recognise constructs of the form
  1993.      ASC(“string”) and ASC“s” and compress them down to the appropriate
  1994.      numbers.  See §2.17.
  1995.  
  1996.  
  1997.   Remove NEXT variables
  1998.  
  1999.      BasCompress supports BasicV’s use of unnamed NEXT statement in a
  2000.      FOR/NEXT loop.  It can remove any variables it finds after a NEXT
  2001.      statement, and cocatenate adjacent NEXT statements.  See §2.19.
  2002.  
  2003.  
  2004.   Convert SWIs to numbers
  2005.  
  2006.      There doesn’t appear to be any reason to disable this.  See §2.5.
  2007.      
  2008.      When turned off this will cause the following two items to be
  2009.      disabled.
  2010.      
  2011.      
  2012.   Parse numbers
  2013.  
  2014.      This toggles whether BasCompress will try to reduce a string of
  2015.      decimal digits.  Hexadecimal and binary numbers are always
  2016.      compressed.  See §2.4.
  2017.  
  2018.   List
  2019.  
  2020.      This leads to a simple sub-menu where you can specify the screen mode
  2021.      to use.  When enabled, as BasCompress produces the output file it
  2022.      will switch to that screen mode and scroll the source and output in
  2023.      two separate columns.  Although “pretty”, it is also pretty useless,
  2024.      as this takes at least an order of magnitude longer to do, what with
  2025.      all that screen scrolling and printing.
  2026.  
  2027.      Note that if throwback is enabled (as it is by default) then the back
  2028.      end is actually run in a TaskWindow.  Thus the ‘listing’ is actually
  2029.      output to a task window.  Thus showing the complete uselessness of
  2030.      this feature!
  2031.      
  2032.      
  2033.   Reduce variable names
  2034.  
  2035.      By default, all variable types are reduced.  The only conceivable use
  2036.      for disabling the reduction of these would be to circumvent the use
  2037.      of EVAL or DATA variables, although BasCompress provides a much
  2038.      better method, via the use of Special files.  See §2.11.
  2039.      
  2040.      The final option, ‘E’ suppression is used to stop BasCompress
  2041.      shortening any variables to a name beginning with an ‘E’.  For the
  2042.      reason why this might be desirable, see §8.2.
  2043.  
  2044.  
  2045.  
  2046.  
  2047.  
  2048.                                   Page  28
  2049.  
  2050.  ============================================================ BasCompress ====
  2051.  
  2052.  
  2053.  
  2054.   Reduce routine names
  2055.  
  2056.      By default, all procedure and function names are reduced.  The only
  2057.      reason for disabling the reduction of these would be to circumvent
  2058.      the use of function names used inside an EVAL construct, although
  2059.      BasCompress provides a much better method to handle this, via the use
  2060.      of Special files.
  2061.      
  2062.      
  2063.  [4.8] Log
  2064.      
  2065.      The log sub-menu controls what additional information may be inserted
  2066.      into the log file, along with the name of all files scanned and any
  2067.      warnings and errors.
  2068.      
  2069.      
  2070.   Save as
  2071.  
  2072.      This leads to a standard save as dialogue box, used to define the
  2073.      file to which the log will be dumped.  This will be a standard Text
  2074.      file.
  2075.      
  2076.      
  2077.   Report multiple exits
  2078.  
  2079.      BasCompress needs to know when each and every routine ends.  If it
  2080.      finds more than one exit it will report it.  For large programs this
  2081.      can produce many warnings, and so these warnings can be disabled.
  2082.      See §2.8.3.
  2083.  
  2084.      This item will be disabled if you have selected ‘Ignore exits from a
  2085.      routine (‘dumb’)’, in the input menu.
  2086.      
  2087.  
  2088.   Report unknown SWI’s
  2089.  
  2090.      In order for BasCompress to convert a SWI string to a number the
  2091.      Module must be resident at the time of compression.  If the module is
  2092.      not resident, then this warning will be given.  This toggles the
  2093.      appearance of such warnings, and is usually left enabled.  See §2.5.
  2094.      
  2095.      This item will be disabled if ‘Convert SWIs to numbers’ in the output
  2096.      menu is turned on.
  2097.      
  2098.  
  2099.   Report OVERLAY usage
  2100.  
  2101.      Because the parameter to an OVERLAY statement is a string array, it
  2102.      is not possible for BasCompress to know which files should be
  2103.      OVERLAY’ed.  Therefore BasCompress emits a warning when it sees the
  2104.      token.
  2105.  
  2106.      If your program uses overlays then please read §2.18.
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.                                   Page  29
  2113.  
  2114.  ============================================================ BasCompress ====
  2115.  
  2116.  
  2117.  
  2118.   Report TOP usage
  2119.  
  2120.      BasCompress is unable to distinguish between the pseudo-variable
  2121.      ‘TOP’ and a possible sequence ‘TO P’ (without the space) which can
  2122.      occur in a FOR loop.  See §2.21.
  2123.  
  2124.  
  2125.   Statistics
  2126.  
  2127.      This shows how many of each type of variable and routine there is
  2128.      altogether in the program.  This includes all deleted labels.
  2129.      
  2130.      
  2131.   EVAL keyword, DATA keyword, READ keyword
  2132.  
  2133.      These will list out every line that contains such a keyword,
  2134.      indicating where BasCompress may introduce errors because of its’
  2135.      reduction of labels.  Note that only the use of these keywords
  2136.      outside special routines is reported, as it is assumed the use of the
  2137.      keyword was fully handled by the Special file.  Further note that
  2138.      DATA found outside any routine is just reported as unlinked.
  2139.      
  2140.      
  2141.   List input
  2142.  
  2143.      With this option ticked, the input basic is also listed inside the
  2144.      log file.  This produces humongous files, as this is plain text Basic
  2145.      not tokenised Basic.
  2146.  
  2147.  
  2148.  
  2149.  [4.9] Special files
  2150.      
  2151.      Special files are used to help BasCompress to handle the EVALuation
  2152.      of variables.  A special file consisting of a list of routines that
  2153.      are expected to contain this keyword, and/or a secondary list of any
  2154.      particular labels that must not be reduced.
  2155.      
  2156.      The writable menu item allows you to type in a full pathname.  It is
  2157.      easier just to drag the file onto the control window, though.
  2158.      
  2159.      
  2160.   Warn undefined
  2161.  
  2162.      Normally it wouldn’t matter that you have told BasCompress about
  2163.      special routines that aren’t used in the input file.  However there
  2164.      is still this option that will report superfluous definitions found
  2165.      in Special files.
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.                                   Page  30
  2177.  
  2178.  ============================================================ BasCompress ====
  2179.  
  2180.  
  2181.  
  2182.   Show expansion
  2183.  
  2184.      With this item ticked, every special label constructed will generate
  2185.      a warning message into the log file.  This can be useful for showing
  2186.      what you think should appear, and what BasCompress thinks should
  2187.      appear.
  2188.  
  2189.      
  2190.  
  2191.  [4.10] Cross-reference
  2192.      
  2193.      From here you define all aspects of the (rather large) cross-
  2194.      referencing sub-system.
  2195.      
  2196.      
  2197.   Save as
  2198.  
  2199.      This leads to a standard save as dialogue box, used to define the
  2200.      file to which the cross-reference will be dumped.  This will be a
  2201.      standard Text file.
  2202.      
  2203.      
  2204.   Include deleted
  2205.  
  2206.      When ticked, this will force all the superfluous routines and
  2207.      variables to be included in the cross-reference.  This is usually not
  2208.      such a good idea, as the process of deletion removes all the
  2209.      reference information.  For a full cross-reference, also disable the
  2210.      removal of unused routines (see Output), which leaves this
  2211.      information in tact.
  2212.  
  2213.  
  2214.   Reference order
  2215.  
  2216.      This leads to an order dialogue box (see below) used to set the
  2217.      sorting criteria for the references.  This is probably best left as
  2218.      the default: Name, Type, Location.
  2219.      
  2220.      
  2221.   Variables, Routines
  2222.  
  2223.      These two items lead into identical sub-menus.  They allow the cross-
  2224.      referencing to be defined for both independently.
  2225.      
  2226.      
  2227.   Verbosity
  2228.  
  2229.      This leads to a sub-menu where you can define the level of detail of
  2230.      the cross-referencing information.  See §3.2.
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.                                   Page  31
  2241.  
  2242.  ============================================================ BasCompress ====
  2243.  
  2244.  
  2245.  
  2246.   Types
  2247.  
  2248.      Used to define what types of variables or routines are included in
  2249.      the cross-reference.  Usually this would be all types, but sometimes
  2250.      you might only want to know about the integers, say.  Just de-tick
  2251.      all the others.
  2252.  
  2253.      
  2254.   Order
  2255.  
  2256.      This dialogue box is quite complicated.  Basically, you are trying to
  2257.      define several layers of ordering.  First of all everything is sorted
  2258.      according to the left hand column.  Now BasCompress goes through
  2259.      these sorted items looking for a sequence of items that are the same,
  2260.      according to this ordering.  Now, for each sequence found it will
  2261.      sort them again using whatever you have defined in column two.  This
  2262.      recurse on each smaller and smaller sub-sequences to the columns on
  2263.      the right.
  2264.      
  2265.      Obviously, it isn’t much use having two columns sorting by the same
  2266.      criteria, so BasCompress will not allow you to select it.
  2267.      
  2268.      You can delete a column by ADJUST clicking on the ordering already
  2269.      used.  This will cause all columns to the right to shuffle one column
  2270.      to the left (this is quite a pleasing graphical effect!)
  2271.      
  2272.      It isn’t possible to have a “blank” column.  If you attempt to create
  2273.      a blank column then your new column will be shifted to the left (yet
  2274.      another pleasing graphical effect!)
  2275.      
  2276.      It is possible to delete all columns.  This will cause the output to
  2277.      appear in a seemingly random order.  Not much use, apart from seeing
  2278.      how good the hashing function is!
  2279.  
  2280.      Ordering by location is only meaningful for references.  Using this
  2281.      option for variables or routines will result in a (seemingly) random
  2282.      order.
  2283.      
  2284.      The Dict. standards for dictionary, and is similar to Name, except
  2285.      instead of ordering by ASCII, order as it would appear in a...
  2286.      (guess).
  2287.      
  2288.      
  2289.  [4.11] Choices Dialogue Box
  2290.      
  2291.      This dialogue box controls aspects of the front end application
  2292.      itself, not the back end.  It grabs the input focus so that some
  2293.      keyboard short cuts can be used, must notably RETURN and ESCAPE.
  2294.      Also the bottom row of buttons can be pressed using F2, F3, etc..
  2295.      
  2296.      
  2297.   Set
  2298.  
  2299.      This accepts the above values for the current session of
  2300.      BasCompress.  For the effects to be permanent use either Save or Save
  2301.      full.  Also see the note below about using outline fonts in dialogue
  2302.      boxes.
  2303.  
  2304.                                   Page  32
  2305.  
  2306.  ============================================================ BasCompress ====
  2307.  
  2308.  
  2309.  
  2310.   Cancel
  2311.  
  2312.      This disregards any edits you have made to the above options.
  2313.  
  2314.      
  2315.   Save full
  2316.  
  2317.      Along with all the expected switches and sort ordering, also saved
  2318.      with the choices are the default names of the log, cross-reference
  2319.      and output files.  This option saves the full pathname of each of
  2320.      these files, and would be used while developing a project, to save
  2321.      dragging the log and output files each session.
  2322.      
  2323.      
  2324.   Save
  2325.  
  2326.      As Save full but only the leaf names of the log, cross-reference and
  2327.      output files are saved.  This is handy for more generic
  2328.      environments.  For instance, if you always call your Wimp programs
  2329.      Wimp, then to make a standard application from this, the output file
  2330.      would be !RunImage, and this would be a better default to have than
  2331.      Output.
  2332.      
  2333.      
  2334.   Default
  2335.  
  2336.      This sets up everything to a default state, for when you’ve made a
  2337.      complete mess of the options.  This default state can also be
  2338.      achieved by deleting the Choices file inside !BC.!fe, and restarting
  2339.      the application.
  2340.  
  2341.      
  2342.   Run BasCompress’ed file
  2343.  
  2344.      With this option ticked whenever an output file is specified it is
  2345.      immediately executed after being generated.  This is useful while
  2346.      constructing a Special file, so the program can proceed and report
  2347.      the missing variables found!)
  2348.  
  2349.  
  2350.   Load log file
  2351.  
  2352.      If a log file was specified then this is “opened” immediately after
  2353.      it is generated.  On a properly set up system this would cause Edit
  2354.      to be loaded up automatically if necessary, and replace any version
  2355.      currently held if Edit is already resident.  Multi-tasking at its
  2356.      best.  Note that if you edit the “old” log file, then this smoothness
  2357.      is ruined, because Edit will open up a new window containing the new
  2358.      version.  C’est la vie.
  2359.      
  2360.      
  2361.   Load cross-reference file
  2362.  
  2363.      Same as the above option, but loads the cross-reference file
  2364.      generated, if any.
  2365.  
  2366.  
  2367.  
  2368.                                   Page  33
  2369.  
  2370.  ============================================================ BasCompress ====
  2371.  
  2372.  
  2373.  
  2374.   Name output as <Main>
  2375.  
  2376.      This is a kludge to reduce the size of both cross-reference and log
  2377.      files.  As any Wimp application must use the full pathname of every
  2378.      file, this is what is passed to the back end application.  However
  2379.      this causes the full pathname to be printed in every error message
  2380.      and reference.  As a stop gap, this front end can be told to set the
  2381.      environment variable <Main> to the full pathname, and pass this to
  2382.      the back end application.  It does mean you don’t see the actual name
  2383.      of the file being processed, but that usually isn’t a problem as you
  2384.      know that anyway.
  2385.      
  2386.      
  2387.   Output file leaf name same as input
  2388.  
  2389.      This option is useful when compressing lots of files from one
  2390.      directory to another, for example having compressed versions of all
  2391.      your library files.  Having defined the output directory, the full
  2392.      pathname is constructed from this directory and the leaf name of the
  2393.      input file, saving quite a bit of typing.
  2394.  
  2395.  
  2396.   Use outline fonts in dialogue boxes
  2397.  
  2398.      BasCompress comes with two versions of all its’ windows − with and
  2399.      without outline fonts.  Users of low-resolution monitors may prefer
  2400.      to use the system font versions.  Also, RiscPC users may have to use
  2401.      the “System font” windows for two reasons: first because the
  2402.      fontified windows use fonts at a different size (slightly larger for
  2403.      low resolution users) which looks ugly but more importantly because
  2404.      of a bug in the Window Manager that causes clicks on (genuine) font
  2405.      icons to cause the Wimp to “forget” the text font :(
  2406.      
  2407.      Note that for historical reasons changes to this option are not
  2408.      updated immediately but only take effect the next time BasCompress is
  2409.      run.
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419.  
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.                                   Page  34
  2433.  
  2434.  ============================================================ BasCompress ====
  2435.  
  2436.  
  2437.  
  2438. 5 The back end
  2439.      
  2440.      
  2441.      This chapter describes the underlying CLI program, and how to use it
  2442.      effectively.
  2443.      
  2444.      By default all text output is to the screen.  This can be redirected
  2445.      to separate log and cross-reference files, as required.
  2446.      
  2447.      
  2448.  [5.1] Invoking
  2449.      
  2450.      Double-clicking on the application directory from a directory display
  2451.      will automatically start up the Wimp front end application.  This is
  2452.      because no parameters were passed to the !Run file.
  2453.      
  2454.      If any parameters are passed to the application, i.e. you activated
  2455.      it from a command shell then the back end application is called
  2456.      direct.
  2457.      
  2458.      This application requires the floating point emulator module to be
  2459.      resident.  This is automatically loaded from the current system
  2460.      resources.  (Floating point arithmetic is only used to analyse and
  2461.      output decimal numbers, this can be disabled and so there will be no
  2462.      need to load the floating point emulator --- this is not a
  2463.      recommended procedure, though).
  2464.      
  2465.      Also required to be resident is the authors’ own library module:
  2466.      CAssembler.
  2467.      
  2468.      These modules are automatically loaded if not resident.
  2469.      
  2470.  
  2471.  [5.2] Installing
  2472.      
  2473.      There are two methods of installing BasCompress for easy use from a
  2474.      shell.  One is to just install the application onto your Run$Path,
  2475.      and use it by *!BC file.
  2476.      
  2477.      This has the disadvantage in that you must remember the !.  The much
  2478.      better alternative is to use the Alias$BasCompress that is set up for
  2479.      you in the !Boot file.  Thus it is only required to run this !Boot
  2480.      file in your boot-up sequence, and then call BasCompress by
  2481.      *BasCompress file.
  2482.      
  2483.      In both the above it is essential that the !Run file gets executed,
  2484.      as this ensures auxiliary modules are resident and checks that there
  2485.      will be enough memory to start the application.
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.                                   Page  35
  2497.  
  2498.  ============================================================ BasCompress ====
  2499.  
  2500.  
  2501.  
  2502.  [5.3] Environment variables
  2503.      
  2504.      Because the CLI limits command lines to (a paltry) 256 bytes, several
  2505.      tricks were used in order to make the front end application work
  2506.      effectively with the back end program (with full pathnames).  These
  2507.      can be put to great advantage for CLI users.  In all cases an unset,
  2508.      or empty variable is ignored.
  2509.      
  2510.      BasCompress$Options
  2511.                      This should be a string of the same format as a
  2512.                      normal parameter set, except missing the name of the
  2513.                      input file (of course).  With this you can override
  2514.                      any of the built-in default values with your own
  2515.                      preferred set.
  2516.      
  2517.      BasCompress$Out
  2518.                      The name of the tokenised basic file produced.
  2519.      
  2520.      BasCompress$Log
  2521.                      The name of the log file produced.
  2522.      
  2523.      BasCompress$XRef
  2524.                      The name of the cross-reference file produced.
  2525.      
  2526.      BasCompress$Special
  2527.                      The name of the special file(s) input (a comma
  2528.                      separated list).
  2529.      
  2530.      BasCompress$Path
  2531.                      A comma separated list of directories used to find
  2532.                      Special files
  2533.      
  2534.      It should be noted that the front end application resets all of these
  2535.      variables (except the Path), so keep this in mind.
  2536.      
  2537.      
  2538.  [5.3.1] DDEUtils and long command lines
  2539.  
  2540.      BasCompress knows about the long command lines supported by the
  2541.      DDEUtils module.  This is a method of passing a command line larger
  2542.      than 256 bytes to a child process.
  2543.  
  2544.      This provides a much more elegant solution than the use of
  2545.      environment variables.  The Wimp front end application now uses this
  2546.      feature if throwback is enabled, but uses the environment variables
  2547.      otherwise.
  2548.  
  2549.  
  2550.  
  2551.  
  2552.  
  2553.  
  2554.  
  2555.  
  2556.  
  2557.  
  2558.  
  2559.  
  2560.                                   Page  36
  2561.  
  2562.  ============================================================ BasCompress ====
  2563.  
  2564.  
  2565.  
  2566.  [5.4] The CLI parameters
  2567.      
  2568.      The ordering of the parameters has been carefully set up so there is
  2569.      usually no need to name any parameters.
  2570.      
  2571.              BasCompress [-In] <file>
  2572.                       [[-Out <file>]
  2573.                       [[-Special] <files>]
  2574.                       [[-Log] <file>]
  2575.                       [[-XRefFile] <file>]
  2576.                       [[-XRef] <n>]
  2577.                       ...
  2578.      
  2579.      So for normal work you would have set up BasCompress$Options and
  2580.      you’d just do BasCompress @.MyProg @.Result @.Special @.Log “” 0.
  2581.      There is a -Help option to display a brief description of the
  2582.      available options.
  2583.      
  2584.      As with all all native Archimedes applications, switches toggle the
  2585.      previous state (OS_ReadArgs does not allow -f and +f).
  2586.      
  2587.      
  2588.  [5.4.1] Input
  2589.  
  2590.      -Dumb                   ignore ENDPROCs (OFF) §2.8.3
  2591.      -In <file>              this must always be given
  2592.      -Library                ignore undefined routines & main program
  2593.                              (OFF) §2.8.1
  2594.      -MultiDEF               allow multiple definitions of the same
  2595.                              routine (OFF) §2.10.1
  2596.      -SWIBad                 fault malformed SWI names (OFF) §2.5
  2597.  
  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.  
  2624.                                   Page  37
  2625.  
  2626.  ============================================================ BasCompress ====
  2627.  
  2628.  
  2629.  
  2630.  [5.4.2] Output
  2631.      
  2632.      -ASC                    decompose ASC(“X”) to number (ON) §2.16
  2633.      -CLI                    prefix code to write env with
  2634.                              BasCompress$CLI (OFF) §2.22
  2635.      -CVar                   constant variables are compressed (ON) §2.17
  2636.      -InitialREM             keep REMs before first routine def (OFF)
  2637.                              §2.20
  2638.      -ListOut <n>            echo output in screen mode <n> (OFF) §4.6
  2639.      -NEXTs                  remove NEXT variables (ON) §2.19 
  2640.      -Number                 analyse decimal numbers (needs FPEmulator)
  2641.                              (ON) §2.4
  2642.      -Out <file>             output file (see BasCompress$Output)
  2643.      -ReduceVar <type>
  2644.      -ReduceRtn <type>
  2645.      -Reduce <type>          reduce these types of labels (irsIRSpf) §2.11
  2646.      -Single                 no concatenation of output lines (OFF) §2.13
  2647.      -SWI                    convert SWI strings to numbers (ON) §2.5
  2648.      -Unused                 delete unused routines and variables (ON)
  2649.                              §2.8
  2650.      
  2651.      <type> is a string of these letters:
  2652.              p       procedure
  2653.              f       function
  2654.              r       real variable
  2655.              i       integer variable
  2656.              s       string variable
  2657.              R       real array variable
  2658.              I       integer array variable
  2659.              S       string array variable
  2660.  
  2661.  
  2662.  [5.4.2.1] Output listing
  2663.      
  2664.      First the mode is selected (-1 would select the current mode), and an
  2665.      appropriate warning or error generated if that mode is not
  2666.      available.  Next a blue-on-white colour scheme is selected.  Then the
  2667.      display is split into two columns, with the left column about 61% of
  2668.      the screen wide (80 columns in mode 16).  The source listing is
  2669.      scrolled here.  On the right column the output is scrolled.
  2670.      
  2671.      The source listing does not include any deleted routines, but does
  2672.      include all inter-routine junk.  The output listing is as per the
  2673.      output file, in its’ entirety.  The right column is only updated each
  2674.      time a whole line has been amassed, which could take a while if
  2675.      maximum compression is selected.
  2676.      
  2677.      There isn’t really much use for this option, as the time taken to
  2678.      scroll the screen takes far too long.
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.                                   Page  38
  2689.  
  2690.  ============================================================ BasCompress ====
  2691.  
  2692.  
  2693.  
  2694.  [5.4.3] Log
  2695.      
  2696.      -DATA                   log lines containing DATA (ON)
  2697.      -EVAL                   log lines containing EVAL (ON)
  2698.      -Goto                   log lines containing line numbers (ON)
  2699.      -List                   echo input to log (OFF)
  2700.      -Log <file>             output file (see BasCompress$Log)
  2701.      -OVERLAY                suppress warnings if see ‘OVERLAY’ (OFF)
  2702.                              §2.18
  2703.      -READ                   log lines containing READ (ON)
  2704.      -Stats                  log program statistics (ON)
  2705.      -SWIExist               report unknown SWI strings (ON) §2.5
  2706.      -TOP                    suppress warnings if see ‘TOP’ (OFF) §2.21
  2707.      -WEndRtn                report conditional exits (ON) §2.8.3
  2708.  
  2709.      
  2710.  [5.4.4] Special
  2711.      
  2712.      -Special <files>        use comma list of <file> to resolve implicit
  2713.                              usages (see BasCompress$Special and
  2714.                              BasCompress$Path)
  2715.      -UnusedS                report undefined special routines (OFF)
  2716.      -WSpLabel               report label expansion results (OFF)
  2717.  
  2718.  
  2719.  [5.4.5] Cross-reference
  2720.      
  2721.      -XRefFile <file>        output file (see BasCompress$XRef)
  2722.  
  2723.      
  2724.  [5.4.5.1] What gets cross-referenced
  2725.      
  2726.      -Deleted                xref includes deleted variables and routines
  2727.                              (OFF)
  2728.      -XIncVar <type>
  2729.      -XIncRtn <type>
  2730.      -XInc <type>            xref these types of labels (irsIRSpf) §3.1.1
  2731.      
  2732.      <type> is a string of these letters:
  2733.              p       procedure
  2734.              f       function
  2735.              r       real variable
  2736.              i       integer variable
  2737.              s       string variable
  2738.              R       real array variable
  2739.              I       integer array variable
  2740.              S       string array variable
  2741.  
  2742.  
  2743.  
  2744.  
  2745.  
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751.  
  2752.                                   Page  39
  2753.  
  2754.  ============================================================ BasCompress ====
  2755.  
  2756.  
  2757.  
  2758.  [5.4.5.2] How much cross-referencing to be done
  2759.      
  2760.      -XRef <n>       level of xref detail for both routines and variables
  2761.                      §3.2
  2762.      -XRtn <n>       level of xref detail for routines (0)
  2763.      -XVar <n>       level of xref detail for variables (0)
  2764.      
  2765.      <n> evaluates to a number from 0 to 4:
  2766.              0       None
  2767.              1       Existence --- name
  2768.              2       Global --- name / count
  2769.              3       Routine --- reference to routine level
  2770.              4       Line --- reference to line level
  2771.      
  2772.      
  2773.  [5.4.5.3] Order of cross-referencing
  2774.      
  2775.      -Sort <sort>    order of all variable, routine, and reference sorting
  2776.                      §3.3
  2777.      -SRef <sort>    order of cross–references (NTP)
  2778.      -SRtn <sort>    order of routines (TN)
  2779.      -SVar <sort>    order of variables (TN)
  2780.      
  2781.      <sort> is a string of these letters:
  2782.              N       sort by name
  2783.              T       sort by type
  2784.              D       sort by name (in dictionary sense)
  2785.              P       sort by position in source
  2786.              U       sort by usage
  2787.      
  2788.      e.g. to sort by usage, name, then type = “UNT”.
  2789.      
  2790.      Lower case letters order top to bottom.
  2791.  
  2792.  
  2793.  
  2794.  [5.5] Error handling
  2795.      
  2796.      By errors, it is meant system errors (i.e. those generated by calls
  2797.      to the operating system).
  2798.      
  2799.      Admittedly, error handling is quite primitive in BasCompress.  All
  2800.      calls to the operating system are tested for error condition, and if
  2801.      set this is immediately propagated all the way back to the user, with
  2802.      an appropriate message dumped in the log file.
  2803.      
  2804.      Errors occurring before the log file is opened are reported to the
  2805.      screen.
  2806.      
  2807.      In any case, an error safely closes all files opened by this
  2808.      application.
  2809.  
  2810.  
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.                                   Page  40
  2817.  
  2818.  ============================================================ BasCompress ====
  2819.  
  2820.  
  2821.  
  2822.  [5.6] Escape handling
  2823.      
  2824.      As with error handling, this is fairly primitive.
  2825.      
  2826.      BasCompress can be aborted at any time, terminating immediately after
  2827.      closing all open files.
  2828.      
  2829.      Note that during the middle of program output the Basic file will be
  2830.      Type’d to Data, as a safeguard against loading it into BasicV.  (This
  2831.      does not handle zero-length files very well --- it hangs the
  2832.      machine).
  2833.      
  2834.      
  2835.  [5.7] Hourglass
  2836.      
  2837.      The hourglass is used to indicate BasCompress’s progress.
  2838.      
  2839.      During parsing, the percentage shows how much has already been
  2840.      analysed.  Note that because BasCompress can not know the total
  2841.      length of input beforehand, the percentage may actually go backwards
  2842.      as LIBRARY statements are parsed.
  2843.      
  2844.      During cross referencing, there is no percentage, but the bottom
  2845.      L.E.D. is on.
  2846.      
  2847.      Finally, during program output an accurate percentage is displayed,
  2848.      with the top L.E.D. on.
  2849.  
  2850.  
  2851.  
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.  
  2858.  
  2859.  
  2860.  
  2861.  
  2862.  
  2863.  
  2864.  
  2865.  
  2866.  
  2867.  
  2868.  
  2869.  
  2870.  
  2871.  
  2872.  
  2873.  
  2874.  
  2875.  
  2876.  
  2877.  
  2878.  
  2879.  
  2880.                                   Page  41
  2881.  
  2882.  ============================================================ BasCompress ====
  2883.  
  2884.  
  2885.  
  2886.  [6] Special files
  2887.      
  2888.      
  2889.      This chapter explains the format of the Special files.  These are
  2890.      auxiliary Text files used to give BasCompress some more information
  2891.      to help it compress better.  See also the examples supplied on disc.
  2892.      
  2893.      
  2894.  [6.1] Why need special files?
  2895.      
  2896.      Special files are used to tell BasCompress how to cope with the
  2897.      following types of situation:
  2898.      
  2899.              •       EVAL(“Variable”)
  2900.              •       DATA Variable
  2901.              •       LIBRARY “%.”+ RoutineParameter$
  2902.              •       EVAL(“FN_”+ RoutineParameter$)
  2903.              •       definitions from RETURN parameters
  2904.              •       OVERLAYs
  2905.  
  2906.      Because BasCompress reduces labels (see §2.11) using a global
  2907.      context, at run-time when BasicV tries to find these labels in the
  2908.      current context, it fails.  Special files tell BasCompress which
  2909.      labels not to compress, either explicitly as in the first two cases
  2910.      or above, or implicitly (from routine parameters) as in the later two.
  2911.  
  2912.      You may also need to tell BasCompress about variables that it thinks
  2913.      are constant, but actually get assigned as a result of a RETURN
  2914.      parameter in a routine.
  2915.      
  2916.      
  2917.  [6.2] The Special file
  2918.      
  2919.      Special files are just plain Text files, in the format specified
  2920.      below.  BasCompress allows more than one Special file to be defined
  2921.      (using a comma separated list), but it is far easier to use the
  2922.      #include directive inside a Special file, as shown below.
  2923.      
  2924.      Special files are found using the environment variable
  2925.      BasCompress$Path.  By default this is not set up, but you may like to
  2926.      create a sub-directory BasCompress in your library and set this
  2927.      variable to “,%.BasCompress.” in your boot-up sequence (note the
  2928.      trailing dot, as with all path variables).  Here you would keep the
  2929.      one or two special files that handle your particular set of library
  2930.      files, and BasCompress will find them for you without you having to
  2931.      type in a full pathname every time.
  2932.  
  2933.  
  2934.  
  2935.  
  2936.  
  2937.  
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.  
  2944.                                   Page  42
  2945.  
  2946.  ============================================================ BasCompress ====
  2947.  
  2948.  
  2949.  
  2950.  [6.3] Format of a Special file
  2951.      
  2952.      The format of a Special file is fairly simple.
  2953.      
  2954.      Basically, (for variables) all you’re trying to tell BasCompress is:
  2955.      
  2956.              •       routine X has a string in parameter Y
  2957.              •       inside routine X there is an EVAL
  2958.              •       this constructs a new label Z from Y
  2959.              •       don’t reduce this label Z
  2960.      
  2961.      So all you do is give the name and expected parameters of a routine
  2962.      and tell BasCompress how to construct label Z.
  2963.      
  2964.      
  2965.  [6.3.1] Defining routines
  2966.      
  2967.      You give the name of a routine by:
  2968.      
  2969.              procedure foo(1)
  2970.      
  2971.      or,
  2972.      
  2973.              function bar(,1)
  2974.      
  2975.      The brackets are necessary if a routine doesn’t have any parameters.
  2976.      
  2977.      The procedure definition above tells BasCompress to expect a (simple)
  2978.      string expression to be passed to the procedure foo at every call, as
  2979.      the sole parameter.  The function definition says the first parameter
  2980.      is not important, but the second parameter will be a simple string.
  2981.      
  2982.      These prototypes are checked against what is actually found in the
  2983.      program proper, and an appropriate error generated if they don’t
  2984.      match.
  2985.      
  2986.      There can be up to ten distinct string parameters [0-9], but you’ll
  2987.      probably only ever need just one.
  2988.      
  2989.      
  2990.  [6.3.2] Defining globals
  2991.      
  2992.      Sometimes the EVAL isn’t in any particular routine (or is used inside
  2993.      a nested routine structure not amenable to the above simplification),
  2994.      so you’d like to give the name of the labels not to reduce just
  2995.      once.  This is easy because at the start of each Special file,
  2996.      BasCompress puts an implicit declaration of the main program as a
  2997.      routine, with no parameters.  So you’d just start defining the global
  2998.      labels as normal routine labels.
  2999.  
  3000.  
  3001.  
  3002.  
  3003.  
  3004.  
  3005.  
  3006.  
  3007.  
  3008.                                   Page  43
  3009.  
  3010.  ============================================================ BasCompress ====
  3011.  
  3012.  
  3013.  
  3014.  [6.3.3] Labels
  3015.      
  3016.      First of all an example:
  3017.      
  3018.              PROC_List(a, “Zappa”, “Good”)
  3019.              ...
  3020.              :
  3021.              DEF PROC_List(RETURN x, y$, z$)
  3022.                IF EVAL(“Frank_”+ y$)<>0 THEN
  3023.                        x += EVAL(“FN_”+ z$+ “_Name(Cy%)”)
  3024.                ENDIF
  3025.              ENDPROC
  3026.      
  3027.      this would be implemented as:
  3028.      
  3029.              procedure _List(, 1, 2)
  3030.                real Frank_\1
  3031.                function _\2_Name
  3032.                integer Cy%
  3033.      
  3034.      Note the spaces to the left of the implicit declarations, and the
  3035.      case of the keywords as both of these are important.  Also note the
  3036.      need to declare Cy% as another variable that must not be shortened.
  3037.      
  3038.      There is no attempt to verify that the <n> used was declared in the
  3039.      parameter list, but all undeclared <n> are reset to the empty
  3040.      string.  Also there is only rudimentary checking done on the
  3041.      expansion template, so be sensible.
  3042.      
  3043.      The following table shows the exact words to use --- note they must
  3044.      be lower case:
  3045.      
  3046.              real            a real variable e.g. pi_by_2
  3047.              integer         an integer variable, e.g. count%
  3048.              string          a string variable, e.g name$
  3049.              real_array      a real array variable, e.g. times()
  3050.              integer_array   an integer variable, e.g. books%()
  3051.              string_array    a string variable, e.g. titles$()
  3052.              procedure       a procedure, e.g. PROC_total
  3053.              function        a function, e.g. FNmin
  3054.              library         load library file, e.g. %.Wimp
  3055.      
  3056.      BasCompress can currently interpret the simple string in a number of
  3057.      ways.  These template expansion types are:
  3058.      
  3059.      
  3060.  [6.3.3.1] Verbatim
  3061.      
  3062.      \<n>    causes the formal parameter <n> to be substituted verbatim.
  3063.  
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072.                                   Page  44
  3073.  
  3074.  ============================================================ BasCompress ====
  3075.  
  3076.  
  3077.  
  3078.  [6.3.3.2] Comma separated
  3079.      
  3080.      ,<n>    treats parameter <n> as a comma separated list of strings to
  3081.              substitute, with optional spaces after each comma.
  3082.      
  3083.      Each value is extracted from the string in turn.  Note that the
  3084.      string is expected to contain real variables only, i.e. no %, $, or (.
  3085.      
  3086.      For example:
  3087.      
  3088.              PROC_Music(“Zappa,Varese,Stravinsky,Belew)
  3089.              ...
  3090.              :
  3091.              DEF PROC_Music(p$)
  3092.              LOCAL i, dummy
  3093.                i = INSTR(p$, “,”)
  3094.                WHILE i>0
  3095.                  dummy = EVAL(“FN_”+ LEFT$(p$, i-1))
  3096.                  p$ = MID$(p$, i+1)
  3097.                  i = INSTR(p$, “,”)
  3098.                ENDWHILE
  3099.              ENDPROC
  3100.      
  3101.      could get coded as:
  3102.      
  3103.              procedure _Music(1)
  3104.                function _,1
  3105.      
  3106.      
  3107.  [6.3.3.3] Full pathname
  3108.      
  3109.      @<n>    parameter <n> is considered as a full pathname, and just the
  3110.              leaf name is substituted.
  3111.      
  3112.      For an example see §6.3.4 below.
  3113.      
  3114.      
  3115.  [6.3.3.4] Wimp menu
  3116.  
  3117.     [note this uses the guillemotright glyph (character 187), but will be
  3118.     represented here as ‘>>’.]
  3119.  
  3120.      >><n>   <n> is taken to be a Wimp menu string.  This means that after
  3121.              “>” and “:” a variable name is expected, terminated by a
  3122.              comma or the EOS.
  3123.      
  3124.      It is assumed that the implicit variables are all of the same type.
  3125.      If not just define several rules, one for each type.
  3126.      For example
  3127.      
  3128.              PROC_menu(“Prog,Info>Info%,dSave as>SaveAs,Quit”)
  3129.      
  3130.      may get coded as follows:
  3131.      
  3132.              procedure _menu(1)
  3133.                integer >>1
  3134.                real >>1
  3135.  
  3136.                                   Page  45
  3137.  
  3138.  ============================================================ BasCompress ====
  3139.  
  3140.  
  3141.  
  3142.  [6.3.4] Variables as regular expressions
  3143.      
  3144.      As well as the above special meta-characters BasCompress will now
  3145.      allow you to specify special variables (not routines or libraries) as
  3146.      a regular expression (a fancy wildcard expression).  This means that
  3147.      instead of specifying one variable, you specify any variables that
  3148.      match a pattern.
  3149.      
  3150.      Special variables so specified can not contain any parameter
  3151.      substitution commands.  They also behave in a slightly different
  3152.      manner.
  3153.      
  3154.      To process special variables defined as regular expressions
  3155.      BasCompress must use a separate pass, between parsing and output.
  3156.      This scans every variable (of the particular type) to see if it
  3157.      matches the specified pattern.  If so, then the variable is flagged
  3158.      as being un-renamable − as expected.
  3159.      
  3160.      So what is a regular expression, and why would you want to use it?
  3161.      For a full description of regular expressions please see Appendix B,
  3162.      but all the useful features (two of them!) will be shown in the
  3163.      examples below.
  3164.      
  3165.      You would want to use regular expressions to specify a range of
  3166.      variables with the same sort of name − instead of specifying every
  3167.      single one individually.  Eg say you have defined many constants such
  3168.      as ‘Wimp_Initialise’, ‘Wimp_CloseDown’, ‘Wimp_GetRectangle’, etc. and
  3169.      then used these constants in some DATA statements.  Instead of having
  3170.      a (long) list of these variable names in the special file you would
  3171.      recognise that all of the variables begin with the pattern ‘Wimp_’
  3172.      and tell BasCompress to mark all such variables as unrenamable.
  3173.      
  3174.      
  3175.  [6.3.4.1] Example patterns
  3176.      
  3177.      Here’s how you would write the above example in a special file:
  3178.      
  3179.          procedure dummy()
  3180.              real Wimp_.*
  3181.      
  3182.      the important bit being the “.*”.  This should be read as “any
  3183.      character“, ”repeated 0 or more times“.  Ie as long as a variable
  3184.      starts with the five characters “Wimp_” the pattern is matched.
  3185.      
  3186.      Another frequent case is when variables have the same postfix --- eg
  3187.      the pattern:
  3188.      
  3189.              integer .*CMOS\>
  3190.      
  3191.      would match all integers that end (“\>” means “match end of
  3192.      variable“) in the letters CMOS, ie MosROMFrugalCMOS%, FontMaxCMOS%,
  3193.      etc...  The specification that CMOS be at the end stops, say,
  3194.      MyCMOSvar% being matched by the pattern, as it otherwise would if
  3195.      this were not included.
  3196.  
  3197.  
  3198.  
  3199.  
  3200.                                   Page  46
  3201.  
  3202.  ============================================================ BasCompress ====
  3203.  
  3204.  
  3205.  
  3206.  [6.3.4.2] Limitations
  3207.      
  3208.      Although a regular expression may be defined dependent on a special
  3209.      routine being called, this fact is currently ignored − all special
  3210.      variables specified using a regular expression are used during the
  3211.      pass.  For this reason it is probably worthwhile to place all wild-
  3212.      card specifications as global − ie in the main program section of the
  3213.      special file.  This limitation will not last long.
  3214.      
  3215.      Currently a variable that is recognised as matching a pattern is
  3216.      flagged as being referenced from the main program (in the cross
  3217.      reference) and not inside the special routine that specified the
  3218.      wildcard − but this will change in a later version.
  3219.      
  3220.      
  3221.  [6.3.5] Libraries
  3222.  
  3223.      As well as labels, libraries may be implicit.  For example, here’s a
  3224.      simple library handler:
  3225.      
  3226.              PROC_Load_Library(“<Basic$Lib>.Wimp”, 2)
  3227.              ...
  3228.              :
  3229.              DEF PROC_Load_Library(f$, v)
  3230.              LOCAL x
  3231.                LIBRARY file$
  3232.                x = EVAL(“FN_Init_”+ FNleaf(f$))
  3233.                IF EVAL(“Version_”+ FNleaf(f$))<v THEN
  3234.                  ERROR 1, “Library too old”
  3235.                ENDIF
  3236.              ENDPROC
  3237.      
  3238.      Well, in real life you’d set up error handlers and note which
  3239.      libraries have already been loaded, but you get the idea.  This could
  3240.      be coded as follows:
  3241.      
  3242.              procedure _Load_Overlay(1,)
  3243.                library \1
  3244.                function _Init_@1
  3245.                real Version_@1
  3246.      
  3247.      Note the use of @<n> to extract the leaf name.
  3248.      
  3249.      In the output program the entire statement containing the LIBRARY is
  3250.      removed.
  3251.      
  3252.      Note that because BasCompress analyses the program in a linear
  3253.      fashion, the order of library routines may well be different from
  3254.      that used in the uncompressed program, (see §2.10).
  3255.  
  3256.  
  3257.  
  3258.  
  3259.  
  3260.  
  3261.  
  3262.  
  3263.  
  3264.                                   Page  47
  3265.  
  3266.  ============================================================ BasCompress ====
  3267.  
  3268.  
  3269.  
  3270.  [6.3.6] Overlays
  3271.  
  3272.      Overlays may be specified as inline comments (§2.18.2) or in the
  3273.      special file.
  3274.  
  3275.      For most common purposes inline comments will suffice, but for complex
  3276.      programs that possibly use routines to specify members of the string
  3277.      array passed to OVERLAY, then you may use the special file keyword
  3278.      ‘overlay’ to handle such cases.
  3279.  
  3280.      For example:
  3281.  
  3282.              procedure _Load_Library(1,)
  3283.                overlay scsi::cheepnis.$.source.code.app.\1
  3284.  
  3285.      would be a typical use.
  3286.  
  3287.  
  3288.  [6.3.7] Include files
  3289.      
  3290.      It is possible for special files to include other special files.
  3291.      Thus you will probably set up BasCompress$Path and a special file to
  3292.      handle your own set of standard libraries, and then...
  3293.      
  3294.              #include mylibs
  3295.      
  3296.      somewhere in the special file for each particular program.  (Note
  3297.      that there are no spaces to the left of the #include, and don’t put
  3298.      any quotes on the name either).
  3299.      
  3300.      Nesting level is not limited, and you can recurse.  This will result
  3301.      in an infinite loop, with the only resort being to press escape to
  3302.      quit, and then examine the log file.
  3303.      
  3304.      
  3305.  [6.4] Limitations
  3306.      
  3307.      There can only be 250 odd total Special routines defined.  If any one
  3308.      actually reaches this limit, then contact the author, it’s easy to
  3309.      alter --- at the expense of a slight increase in memory usage.
  3310.      
  3311.      There is of course one major limitation in that you have to specify
  3312.      the name of all the special files before processing the program.  It
  3313.      would be nice to set up a system whereby if the program (maybe
  3314.      implicitly) loads in library X, then load up special file Y.  However
  3315.      this would require re-finding all calls to the (new) Special
  3316.      routines --- something that seems quite hard to do, sigh.
  3317.      
  3318.      Finally, you’d like to be able to take into account the scope of the
  3319.      variables so only the use of variables in scope are not reduced.  But
  3320.      since BasicV only has one scope, this is not possible to implement
  3321.      safely, without some explicit help from the programmer by marking the
  3322.      scope of variables in some way.
  3323.  
  3324.  
  3325.  
  3326.  
  3327.  
  3328.                                   Page  48
  3329.  
  3330.  ============================================================ BasCompress ====
  3331.  
  3332.  
  3333.  
  3334.  [7] Errors
  3335.      
  3336.      
  3337.  [7.1] Overview
  3338.      
  3339.      Errors and warnings can be generated at various stages of the game.
  3340.      They all look the same and are all sent to the current log (file /
  3341.      screen).  The format is:
  3342.      
  3343.              file 1234 warning 3: message
  3344.      
  3345.      If there is no filename, then it indicates the error is global  in
  3346.      scope, for example the “undefined routine” error generated when all
  3347.      files have been parsed.
  3348.      
  3349.      Warnings report non-fatal deficiencies.  Errors report a major
  3350.      problem, and will stop any output file being generated.
  3351.      
  3352.      As with all text used by BasCompress, these error texts are held in
  3353.      the Messages file.
  3354.      
  3355.      It is worth pointing out that many warnings and errors may be
  3356.      generated after the seemingly innocent warnings 9 and 10.  This means
  3357.      that BasCompress may have lost touch with what routine is being
  3358.      defined, and starts interpreting the junk inbetween routines as
  3359.      genuine code.  So do check the log file from the start.
  3360.      
  3361.      
  3362.  [7.2] Warnings
  3363.      
  3364.      Most of the warnings are self explanatory.
  3365.      
  3366.  
  3367.   1:Expecting PROC or FN after DEF
  3368.  
  3369.      In standard Basic, these are the only valid things after a DEF.  This
  3370.      warning has never been encountered in debugged source!
  3371.      
  3372.  
  3373.   2:DEF inside a routine
  3374.  
  3375.      This is generated because an earlier routine did not exit cleanly,
  3376.      and the program believes you are still in this routine.  You need to
  3377.      fix the errant routine by terminating it properly, or simply
  3378.      appending a dummy routine end (ENDPROC or = <expr>).
  3379.  
  3380.      Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3381.  
  3382.  
  3383.   3:Unexpected period ‘.’
  3384.  
  3385.      A period on it’s own is treated as the start of a number (e.g. “.
  3386.      7”).  This warning is generated if a statement starts with a period
  3387.      and it is not in the assembler.
  3388.  
  3389.  
  3390.  
  3391.  
  3392.                                   Page  49
  3393.  
  3394.  ============================================================ BasCompress ====
  3395.  
  3396.  
  3397.  
  3398.   4:Mismatched quotes ‘“’
  3399.  
  3400.      Every line should have matching quotes.
  3401.      
  3402.  
  3403.   5:Malformed hexadecimal number
  3404.  
  3405.      It is expected that a digit or a letter [0-9a-fA-F] comes after an &.
  3406.      
  3407.  
  3408.   6:Malformed binary number
  3409.  
  3410.      It is expected that a 0 or 1 comes after a %.
  3411.      
  3412.  
  3413.   7:Line number reference found
  3414.  
  3415.      This is given if line numbers are found in any libraries, since there
  3416.      is no valid reason for them being there.
  3417.      
  3418.  
  3419.   8:Expecting routine name after PROC or FN
  3420.  
  3421.      A non-label character was found after one of these tokens.  This very
  3422.      unlikely.
  3423.      
  3424.   9:ENDPROC not at end of procedure
  3425.  
  3426.      This is generated if ENDPROC is found on a line containing an IF, i.
  3427.      e. it is ambiguous as to whether this is the genuine end of the
  3428.      procedure.  Most of the time this causes no problems, but for short
  3429.      routines where this is the only way it exits then BasCompress will
  3430.      get confused as to the exact end of the routine.  In this case you
  3431.      must either re-code the routine (recommended) or insert a dummy
  3432.      routine terminator (ENDPROC or = <expr>).
  3433.  
  3434.      Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3435.  
  3436.  
  3437.   10:= not at end of function
  3438.  
  3439.      This is generated if an “= <expr>” is found on a line containing an
  3440.      IF, i.e. it is ambiguous as to whether this is the genuine end of the
  3441.      function.  Most of the time this causes no problems, but for short
  3442.      routines where this is the only way it exits then BasCompress will
  3443.      get confused as to the exact end of the routine.  In this case you
  3444.      must either re-code the routine (recommended) or insert a dummy
  3445.      routine terminator (ENDPROC or = <expr>).
  3446.  
  3447.      Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3448.  
  3449.  
  3450.  
  3451.  
  3452.  
  3453.  
  3454.  
  3455.  
  3456.                                   Page  50
  3457.  
  3458.  ============================================================ BasCompress ====
  3459.  
  3460.  
  3461.  
  3462.   11:Code found on last line of function
  3463.  
  3464.      There were more statements on the same line as the terminating “=
  3465.      <expr>” statement.  Since these will never be executed by Basic then
  3466.      they should be removed.  This warning could well turn up quite often
  3467.      if BasCompress is fed the output of other squashers.
  3468.      
  3469.  
  3470.   12:Expecting a string after LIBRARY/INSTALL
  3471.  
  3472.      In order to be able to load in libraries BasCompress expects a simple
  3473.      constant string expression to follow these keywords.  If this is not
  3474.      the case then you will need to set up a Special file to handle this
  3475.      situation.  This warning is suppressed if inside a Special routine.
  3476.      
  3477.  
  3478.   13:OVERLAY not parsed, use special file or inline comment
  3479.  
  3480.      The OVERLAY keyword can not be parsed by BasCompress and needs
  3481.      some help.  See §2.18.
  3482.      
  3483.  
  3484.   14:Unexpected ‘[’
  3485.  
  3486.      A running total of square brackets is kept.  This indicates that
  3487.      something like “LDR R0, [[R1...]” was found.
  3488.      
  3489.  
  3490.   15:Unexpected ‘]’
  3491.  
  3492.      A running total of square brackets is kept.  This indicates that
  3493.      something like “LDR R0, [R1...]]” was found.
  3494.      
  3495.  
  3496.   16:ENDPROC inside a %s structure
  3497.  
  3498.      Found a conditional exit from a procedure --- this indicates a bad
  3499.      programming style.
  3500.  
  3501.      Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3502.  
  3503.  
  3504.   17:= inside a %s structure
  3505.  
  3506.      Found a conditional exit from a function --- this indicates a bad
  3507.      programming style.
  3508.  
  3509.      Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3510.  
  3511.  
  3512.  
  3513.  
  3514.  
  3515.  
  3516.  
  3517.  
  3518.  
  3519.  
  3520.                                   Page  51
  3521.  
  3522.  ============================================================ BasCompress ====
  3523.  
  3524.  
  3525.  
  3526.   18:Conditional %s
  3527.  
  3528.      Found a conditional termination of a multi-line structure --- this
  3529.      indicates a bad programming style.
  3530.  
  3531.      This may occur on lines like the following:
  3532.      
  3533.              IF x>0 THEN WHILE x>0:y+=FNy(x):x-=1:ENDWHILE
  3534.      
  3535.      Unfortunately BasCompress does not like this because it expects all
  3536.      multi-line constructs to start unconditionally.  To cure this split
  3537.      the one-line IF into a multi-line IF.
  3538.  
  3539.      Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3540.  
  3541.  
  3542.   19:Too many ‘(’ found
  3543.  
  3544.      A running total of ellipsis is kept.  This indicates something like
  3545.      “(1+2)(” was found.
  3546.      
  3547.  
  3548.   20:Unexpected ‘)’ found
  3549.  
  3550.      A running total of ellipsis is kept.  This indicates something like
  3551.      “(1+2))” was found.
  3552.      
  3553.  
  3554.   21:Routine %s already defined at %s
  3555.  
  3556.      This warns about multiply-defined routines.  Since there are
  3557.      sometimes very good reasons for doing this this warning can be
  3558.      suppressed.
  3559.      
  3560.  
  3561.   22:Malformed decimal number
  3562.  
  3563.      A bad decimal number was found.  A decimal number is something
  3564.      beginning with a digit or a period and continuing as expected.  The
  3565.      form of the number is always checked, but the compression may be
  3566.      turned off.
  3567.      
  3568.  
  3569.   23:The (global) special routine %s is not defined
  3570.  
  3571.      anywhere
  3572.      This speaks for itself.  It is only generated if the user has asked
  3573.      for it, as it is not usually relevant.
  3574.      
  3575.  
  3576.   24:SWI name missing, or not simple
  3577.  
  3578.      It is normal to just have a string, variable, or number immediately
  3579.      after a SYS (SWI).  This indicates that found something else ---
  3580.      which may indicate a syntax error.
  3581.  
  3582.  
  3583.  
  3584.                                   Page  52
  3585.  
  3586.  ============================================================ BasCompress ====
  3587.  
  3588.  
  3589.  
  3590.   25:SWI ‘%s’ is unknown
  3591.  
  3592.      The operating system has no record of what this SWI means.  This
  3593.      indicates that either the module is not loaded at the time of
  3594.      compression, or it is misspelt.  BasCompress will leave it as it is,
  3595.      producing longer and slower code.
  3596.      
  3597.  
  3598.   26:Can’t change to screen mode %d
  3599.  
  3600.      If the listing Mode could not be found, but a suitable alternative
  3601.      was possible.
  3602.      
  3603.   27:Special variable %s has been used
  3604.   28:Special routine %s has been used
  3605.   29:Special library %s has been used
  3606.   30:Special overlay %s has been used
  3607.  
  3608.      These warnings are generated if the user has turned them on.  They
  3609.      show the results of label expansion done at the instance of a call to
  3610.      a Special routine.
  3611.  
  3612.   31:Found TOP, treated as ‘TOP’ and not ‘TO P’
  3613.  
  3614.      BasCompress may fail to remove a constant variable ‘P’ if this
  3615.      warning occurs.  See §2.21.
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.  
  3639.  
  3640.  
  3641.  
  3642.  
  3643.  
  3644.  
  3645.  
  3646.  
  3647.  
  3648.                                   Page  53
  3649.  
  3650.  ============================================================ BasCompress ====
  3651.  
  3652.  
  3653.  
  3654.  [7.3] Errors
  3655.      
  3656.      Any errors encountered will stop the final output phase, but the
  3657.      program will soldier on parsing, so you can rectify all the errors in
  3658.      one hit.
  3659.      
  3660.  
  3661.   2:ENDPROC found in a function
  3662.  
  3663.      This invariably follows warning 2, about DEF found inside a routine,
  3664.      which itself follows a warning 10, because the previous function did
  3665.      not terminate cleanly.
  3666.      
  3667.      A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3668.  
  3669.  
  3670.   3:= found in a procedure
  3671.  
  3672.      This invariably follows  warning 2, about DEF found inside a routine,
  3673.      which itself follows a warning 9, because the previous procedure did
  3674.      not terminate cleanly.
  3675.      
  3676.      A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3677.  
  3678.  
  3679.   4:Routine %s already defined at %s
  3680.  
  3681.      It’s either an error or a warning (21), and this is the error.
  3682.  
  3683.  
  3684.   5:File error: %s
  3685.  
  3686.      Since there is minimal file accessing done (files are loaded in one
  3687.      hit), this usually just reports not being able to find a particular
  3688.      file/invalid file name --- it is dependent on the underlying filing
  3689.      system.
  3690.      
  3691.  
  3692.   6:End of file in middle of routine
  3693.  
  3694.      It is invalid for a routine to span across a file boundary.
  3695.      
  3696.  
  3697.   7:Too many files (>254)
  3698.  
  3699.      I can’t foresee anyone getting this error message!  It is unlikely
  3700.      that this limitation would be lifted, either.
  3701.  
  3702.  
  3703.   8:Undefined routine: %s (used %s)
  3704.  
  3705.      Generated after all files have been parsed, it warns of routines used
  3706.      but never defined.  These are usually obscure routines only called in
  3707.      error handlers.  If you know for sure that this routine will never be
  3708.      called, just put an empty version in your main file to suppress this
  3709.      error.
  3710.  
  3711.  
  3712.                                   Page  54
  3713.  
  3714.  ============================================================ BasCompress ====
  3715.  
  3716.  
  3717.  
  3718.   9:Undefined variable: %s (used %s)
  3719.  
  3720.      Not generated.
  3721.      
  3722.  
  3723.   10:FOR not at start of statement
  3724.  
  3725.      This may be of some use --- not much, but what the hey?  (Maybe be on
  3726.      a one-line IF)?
  3727.      
  3728.  
  3729.   11:Escape pressed, parsing aborted
  3730.  
  3731.      Not generated.  Escapes just terminate program immediately in the
  3732.      current version.
  3733.      
  3734.  
  3735.   12:File %s does not have a Basic file type
  3736.  
  3737.      This program only accepts tokenised Basic files --- maybe the file is
  3738.      just not Type’d correctly.  (Could be that it was saved under the CFS
  3739.      or some such, and you only gave the SCSIFS?)
  3740.      
  3741.  
  3742.   13:File %s is too small to be a Basic type
  3743.  
  3744.      A rudimentary check on each Basic file is done --- this is generated
  3745.      if it fails.
  3746.      
  3747.  
  3748.   14:File is corrupted/not basic
  3749.  
  3750.      Each line of tokenised Basic has a header.  As the file is parsed
  3751.      each header is checked and if invalid this error is generated and
  3752.      parsing of the file is aborted.
  3753.      
  3754.  
  3755.   15:Escape pressed, xref aborted
  3756.  
  3757.      Not generated.  Escapes just terminate program immediately in the
  3758.      current version.
  3759.      
  3760.  
  3761.   16:Escape pressed, compression aborted
  3762.  
  3763.      Not generated.  Escapes just terminate program immediately in the
  3764.      current version.
  3765.  
  3766.  
  3767.  
  3768.  
  3769.  
  3770.  
  3771.  
  3772.  
  3773.  
  3774.  
  3775.  
  3776.                                   Page  55
  3777.  
  3778.  ============================================================ BasCompress ====
  3779.  
  3780.  
  3781.  
  3782.   17:Unexpected %s in a %s structure
  3783.  
  3784.      This detects any foul-ups in multi-lined structures.  The Basic
  3785.      interpreter allows some of these through without reporting an error.
  3786.      These errors allow you to fix the (very probably) mistakes.  See
  3787.      warning 18.
  3788.  
  3789.      A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3790.  
  3791.  
  3792.   18:Unexpected %s
  3793.  
  3794.      As error 17 above, but obviously outside any surrounding structure.
  3795.      
  3796.  
  3797.   19:End of file in middle of assembler
  3798.  
  3799.      A special case of error 6, i.e. a routine did not end before the end
  3800.      of a file was found.
  3801.      
  3802.  
  3803.   20:OTHERWISE not at start of line
  3804.  
  3805.      A simple error for a simple mistake.
  3806.      
  3807.  
  3808.   21:WHEN not at start of line
  3809.  
  3810.      A simple error for a simple mistake.
  3811.      
  3812.  
  3813.   22:Computed GOTO/GOSUB found
  3814.  
  3815.      Now, I ask you, is this how to program?  BasCompress will refuse to
  3816.      work with such things, and who can blame it?
  3817.      
  3818.  
  3819.   23:INSTALL/LIBRARY not at start of line
  3820.  
  3821.      This indicates a syntax error, probably.  Or maybe an IF without a
  3822.      THEN, who knows?
  3823.      
  3824.  
  3825.   24:INSTALL/LIBRARY can not be on a conditional line
  3826.  
  3827.      If you must, then split into a multi-line IF and try again.
  3828.      
  3829.  
  3830.   25:The special routine ‘%s’ was declared as having different parameters
  3831.      from those found here
  3832.  
  3833.      The number of parameters do not match --- probably a wrong number of
  3834.      commas in the Special file.
  3835.  
  3836.  
  3837.  
  3838.  
  3839.  
  3840.                                   Page  56
  3841.  
  3842.  ============================================================ BasCompress ====
  3843.  
  3844.  
  3845.  
  3846.   26:The special routine ‘%s’ wants a string constant for one of its’
  3847.      parameters
  3848.  
  3849.      This program only handles very simple constant string expressions,
  3850.      and this error indicates that the expression was not simple enough.
  3851.      
  3852.  
  3853.   27:Line too long (max 256)
  3854.  
  3855.      This seems a reasonable upper limit on the line length of a Special
  3856.      file.
  3857.      
  3858.  
  3859.   28:Line ‘%s’ is not of a recognised form
  3860.  
  3861.      Syntax error for the Special file line.  Note that if you specified a
  3862.      Text file full of control codes and such, then you may only get to
  3863.      read the last few words of this message.
  3864.      
  3865.  
  3866.   29:Label ‘%s’ is invalid
  3867.  
  3868.      In Special files, the label probably starts with a digit, or some
  3869.      such.
  3870.      
  3871.  
  3872.   30:Parameter list ‘%s’ is invalid
  3873.  
  3874.      In Special files: what more needs to be said?
  3875.      
  3876.  
  3877.   31:Parameter list ‘%s’ contains a duplicate
  3878.  
  3879.      In Special files: it is not exactly meaningful to have two or more
  3880.      parameters assigned to the same expansion number is it?
  3881.      
  3882.  
  3883.   32:Implicit label substitution overflowed
  3884.  
  3885.      When a call to a Special routine is found, the label templates get
  3886.      expanded using the actual parameters passed.  This error shows
  3887.      BasCompress checks for overflow in its’ internal buffers!
  3888.      
  3889.  
  3890.   33:Too many special routines (max 255)
  3891.  
  3892.      A perfectly reasonable limit it seems.  This could easily be
  3893.      extended, though.
  3894.      
  3895.  
  3896.   34:Unable to load special file (not Text?)
  3897.  
  3898.      Or maybe it wasn’t found.  Only Text files are accepted.
  3899.  
  3900.  
  3901.  
  3902.  
  3903.  
  3904.                                   Page  57
  3905.  
  3906.  ============================================================ BasCompress ====
  3907.  
  3908.  
  3909.  
  3910.   35:SWI name missing, or not simple
  3911.  
  3912.      It is normal to just have a string, variable, or number immediately
  3913.      after a SYS (SWI).  This indicates that found something else ---
  3914.      which may indicate an error.
  3915.      
  3916.  
  3917.   36:Illegal screen mode
  3918.  
  3919.      If the listing mode could not be found, and no suitable alternative
  3920.      was possible, then this error is generated.
  3921.      
  3922.  
  3923.   37:Bad main program, unterminated %s structure
  3924.  
  3925.      This is a special case, if the first routine found (DEF PROC, or
  3926.      DEF FN) was inside a multi-line structure.  This indicates an error
  3927.      in the main program.
  3928.      
  3929.      A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
  3930.  
  3931.  
  3932.   38:Can’t find closing ellipsis in special routine parameter
  3933.  
  3934.      During label expansion, BasCompress found a label ending in (, which
  3935.      it took to mean the start of an array index.  No closing ) was found
  3936.      before the end of the string.
  3937.      
  3938.  
  3939.   39:Bad char ‘%c’ following > or : in special routine parameter
  3940.  
  3941.      During label expansion, BasCompress expects the label to be
  3942.      terminated by a comma or the EOS.  This indicates that this condition
  3943.      was not satisfied.
  3944.      
  3945.  
  3946.   40:Called routine ‘%s’ with wrong number of parameters
  3947.  
  3948.      BasCompress keeps note of the number of parameters a routine is
  3949.      defined with, and can detect when an attempt is made to use the
  3950.      routine with the wrong number of parameters.
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.  
  3957.  
  3958.  
  3959.  
  3960.  
  3961.  
  3962.  
  3963.  
  3964.  
  3965.  
  3966.  
  3967.  
  3968.                                   Page  58
  3969.  
  3970.  ============================================================ BasCompress ====
  3971.  
  3972.  
  3973.  
  3974.  [7.4] Run-time errors
  3975.      
  3976.      Here is some help with possible errors that BasCompress may introduce
  3977.      to the compressed Basic output.
  3978.      
  3979.      
  3980.  [7.4.1] Unknown or missing variable
  3981.      
  3982.      The quick and easy method to solve this problem is to turn off all
  3983.      label reduction.  This is not recommend, as it makes the use of
  3984.      BasCompress almost worthless.
  3985.      
  3986.      This error has been generated because you have not told BasCompress
  3987.      about the side effects of an EVAL or DATA statements.  See §2.11 for
  3988.      why this produces the error, and §6 for how to cure it.
  3989.      In essence you have to go through the program, locate the EVAL’s and
  3990.      possibly the DATA statements as well, (look in the log file for
  3991.      exactly where to find these), and then build a Special file to tell
  3992.      BasCompress how to handle these.
  3993.      
  3994.      Usually this entails defining some “global” labels that will never be
  3995.      reduced, although sometimes it is possible to build a more
  3996.      sophisticated parameter-based rule.
  3997.      
  3998.      It may just be possible that this error is generated inside
  3999.      assembler.  If so, then this indicates an error on BasCompress’
  4000.      part.  Examples of such should be sent to the author for inclusion in
  4001.      upgrades.  This possibility is extremely remote as BasCompress has
  4002.      been tested with a wide range of sources, but most cases where it has
  4003.      failed in the past has been in this area.
  4004.      
  4005.      
  4006.  
  4007.  [7.4.2] No such function/procedure
  4008.      
  4009.      This occurs for exactly the same reasons as detailed in §7.4.1 above.
  4010.  
  4011.  
  4012.  [7.4.3] Missing ENDIF
  4013.      
  4014.      These errors are generated very rarely, but they are just possible.
  4015.      Consider the following code:
  4016.      
  4017.              IF FN_SaveFile THEN :::REM comment
  4018.      
  4019.      What BasCompress could produce, although it does tries not to, is:
  4020.      
  4021.              IFFNxTHEN
  4022.      
  4023.      Obviously this is wrong, wrong, wrong.  From a simple one-line
  4024.      conditional (that does nothing), BasCompress has produced a multi-
  4025.      line conditional construct where there shouldn’t be any, and without
  4026.      the ENDIF.
  4027.  
  4028.  
  4029.  
  4030.  
  4031.  
  4032.                                   Page  59
  4033.  
  4034.  ============================================================ BasCompress ====
  4035.  
  4036.  
  4037.  
  4038.      Since this situation is fairly rare, and BasCompress does handle it
  4039.      most of the time, it is not likely to be remedied --- unless enough
  4040.      people request it.
  4041.      
  4042.      The work around is to not to ignore the return value from the
  4043.      function, which is probably an error status (indicating a very lazy
  4044.      programmer!), but to assign it to a variable, and then act on it
  4045.      accordingly.
  4046.  
  4047.  
  4048.  [7.4.4] Invalid RETURN actual parameter
  4049.  
  4050.     If the program compresses OK but when run comes up with an error:
  4051.     
  4052.                     ‘Invalid RETURN actual parameter’
  4053.     
  4054.     then ensure that menu item ‘Input->Remove constant variables’ is
  4055.     disabled.  The proper way to deal with this is to use a special file
  4056.     on the variable, see the manual.  See §2.8.3.
  4057.  
  4058.  
  4059.  [7.4.5] Syntax error
  4060.  
  4061.     If this occurs then ensure that menu item
  4062.     ‘Output->Reduce variable names->‘E’ suppression’ is ticked. See §8.2.
  4063.  
  4064.  
  4065.  [7.4.6] Logical errors
  4066.      
  4067.      By this it is meant that a program doesn’t generate any overt errors,
  4068.      it’s just that it doesn’t do the same as it did before compression.
  4069.      
  4070.      BasCompress has been tested quite thoroughly with a wide source of
  4071.      Basic programs, and it is hoped that all of these exceptional cases
  4072.      have been noted and duly handled.  However if you do get this type of
  4073.      error, it is still probably because of EVAL and DATA being used with
  4074.      undeclared (and probably short, e.g. A%, x, etc.) variables.  These
  4075.      variables may have been “renamed” by BasCompress, or even re-mapped
  4076.      to different variables, and hence contain an invalid value.
  4077.      
  4078.      If it is not because of this, then the author would appreciate it if
  4079.      an example of the incorrectly compressed source was sent in, so
  4080.      BasCompress could be updated to handle that case.
  4081.  
  4082.  
  4083.  
  4084.  
  4085.  
  4086.  
  4087.  
  4088.  
  4089.  
  4090.  
  4091.  
  4092.  
  4093.  
  4094.  
  4095.  
  4096.                                   Page  60
  4097.  
  4098.  ============================================================ BasCompress ====
  4099.  
  4100.  
  4101.  
  4102.  [7.5] Internal errors
  4103.      
  4104.      These are “system” errors generated by BasCompress itself.  These
  4105.      messages are hard-coded into the executable, and use the error number
  4106.      chunk &DCBC0 to &DCBFF:
  4107.      
  4108.                      Error(s) during parsing
  4109.      
  4110.      This should never appear, as it is an internal error used to indicate
  4111.      an erroneous parsing stage.
  4112.                      Invalid sort character ‘%c’
  4113.                      Sort string too long
  4114.                      Invalid type character ‘%c’
  4115.      
  4116.      These indicate rudimentary errors on the parameters passed on the CLI.
  4117.      
  4118.                      Invalid option in system variable BasCompress$Options
  4119.      
  4120.      Indicates an invalid system variable.  Unfortunately it is not
  4121.      possible to show exactly what was wrong with it, just that some part
  4122.      of it was wrong.
  4123.      
  4124.                      1.1
  4125.                      ...
  4126.                      10.1
  4127.      
  4128.      These errors should never be generated.  They indicate where
  4129.      BasCompress has found some inconsistencies in its’ own internal data
  4130.      structures.  Any occurrences of such should be sent, along with the
  4131.      source that produced them, to the author for correcting in future
  4132.      upgrades.
  4133.  
  4134.      This can be sent by Email to bascompress@cheepnis.demon.co.uk.
  4135.  
  4136.  
  4137.  
  4138.  
  4139.  
  4140.  
  4141.  
  4142.  
  4143.  
  4144.  
  4145.  
  4146.  
  4147.  
  4148.  
  4149.  
  4150.  
  4151.  
  4152.  
  4153.  
  4154.  
  4155.  
  4156.  
  4157.  
  4158.  
  4159.  
  4160.                                   Page  61
  4161.  
  4162.  ============================================================ BasCompress ====
  4163.  
  4164.  
  4165.  
  4166.  [8] Loose ends
  4167.      
  4168.      The fact that this chapter exists shows that I’m no good at
  4169.      documentation!  It mainly describes features that may (or may not)
  4170.      get implemented in future upgrades.
  4171.      
  4172.      
  4173.  [8.1] Memory usage
  4174.      
  4175.      Let’s face it boys and girls, this program eats RAM like nobody’s
  4176.      business.  It’s really just a fact of life for 32-bit/RISC machines.
  4177.      
  4178.      This is compounded by the need for some oomph (technical term) in the
  4179.      program execution stakes.  To this end most things are kept on two
  4180.      separate lists --- e.g. if a routine X calls Y then this is recorded
  4181.      both in X’s calls list, and Y’s called by list.  This bit of
  4182.      redundancy probably doubles the speed of cross referencing, so it was
  4183.      felt worth it.
  4184.      
  4185.      Also all the source is kept in RAM, and all the output.
  4186.      
  4187.      There is some consideration to low-memory users in that the hash
  4188.      table sizes grow on request, but then again they start pretty big
  4189.      anyway!
  4190.  
  4191.  
  4192.  
  4193.  
  4194.  
  4195.  
  4196.  
  4197.  
  4198.  
  4199.  
  4200.  
  4201.  
  4202.  
  4203.  
  4204.  
  4205.  
  4206.  
  4207.  
  4208.  
  4209.  
  4210.  
  4211.  
  4212.  
  4213.  
  4214.  
  4215.  
  4216.  
  4217.  
  4218.  
  4219.  
  4220.  
  4221.  
  4222.  
  4223.  
  4224.                                   Page  62
  4225.  
  4226.  ============================================================ BasCompress ====
  4227.  
  4228.  
  4229.  
  4230.  [8.2] Missing THEN
  4231.      
  4232.      Basic allows the programmer to omit a THEN statement when used on a
  4233.      single-line IF compound.  However, this can cause problems.  Because
  4234.      BasCompress removes all spaces, if the condition ended with a digit,
  4235.      and the statement after the (missing) THEN starts with an ‘E’ then
  4236.      Basic gets confused – thinking a real number (in exponent format) has
  4237.      been given.  Eg the BasCompress produced line:
  4238.      
  4239.              IF x<>0E%=1
  4240.      
  4241.      is wrong.  There should be a space after the 0.  This is very rare.
  4242.      A temporary cure is to stop BasCompress shortening any variables to
  4243.      names starting with an ‘E’.  Although this will solve most problems,
  4244.      there is still the unresolved problem of the un-shortened variables.
  4245.      The only cure is to make sure the THEN is always used.
  4246.      
  4247.      A similar problem is the following BasCompress produced line:
  4248.      
  4249.              WHILE x<>0E%=2
  4250.      
  4251.      The cure for this is to always separate the expression from the first
  4252.      statement of a WHILE compound by a colon.
  4253.      
  4254.      While testing this program, it became evident that the missing THEN
  4255.      was part of a general problem --- skipping a Basic expression.  This
  4256.      is harder than at first seems, because there is no point at where you
  4257.      can say “yes, here is the end”, as you can in a procedural call, say
  4258.      (e.g. you’ve found a comma, close ellipse and the bracket and quote
  4259.      count is zero).  E.g. how would you handle this:
  4260.      
  4261.              IF a=b=c THEN P.“hello”
  4262.      
  4263.      Intuition get’s it wrong.  Basic treats this as:
  4264.      
  4265.              IF (a=b) THEN =c ...
  4266.      
  4267.      Which means you have to build a tree/stack.  But, once you can do
  4268.      this then this program could become quite interesting.  It could
  4269.      evaluate constant sub-expressions.  This could produce some very
  4270.      compact stuff, as you’d also be able to substitute constant variables
  4271.      with their values, and even eliminate dead code.  I.e. debugging
  4272.      stuff that would never be executed because it is known that, say,
  4273.      Debug is always FALSE.
  4274.      
  4275.      But, tie that in with a bit more knowledge of the structure of the
  4276.      Basic, and it is almost easy to generate not tokenised Basic, but
  4277.      code.  Well, I’m sure if enough people register, it will give this
  4278.      author the incentive to develop BasCompress into the fastest (and
  4279.      cheapest) Basic compiler.
  4280.  
  4281.  
  4282.  
  4283.  
  4284.  
  4285.  
  4286.  
  4287.  
  4288.                                   Page  63
  4289.  
  4290.  ============================================================ BasCompress ====
  4291.  
  4292.  
  4293.  
  4294.  [8.3] Cross-reference
  4295.      
  4296.      It would be nice to have a toggle between multi-line and single-line
  4297.      (the current) output.  This is fairly easy to do, but it’ll require
  4298.      some experimentation!
  4299.      
  4300.      Also handy could be some ordering based on label length, or even the
  4301.      (approximate) size of a routine.
  4302.      
  4303.      Some rationalisation of the messages used is in order, too.
  4304.      Currently the program outputs some line feeds of its’ own accord,
  4305.      which is decidedly against the grain.
  4306.      
  4307.      How about not listing the file that a routine is in?  Or just the
  4308.      leaf of the filename.  This would reduce the size of the output by
  4309.      quite a lot.  The former would require the user to cross-reference
  4310.      (the cross-reference!) to find the file of the reference, though.
  4311.      
  4312.      
  4313.  [8.4] Statistics
  4314.      
  4315.      There are loads more statistics that could be done;
  4316.      
  4317.              •       libraries that aren’t needed
  4318.              •       variables only ever declared (e.g. LOCALised but
  4319.                      never used)
  4320.              •       variables only ever assigned to once (constants)
  4321.              •       lines where the memory indirection operators ?, | and
  4322.                      ! are used
  4323.              •       don’t log all the deleted routines and variables,
  4324.                      just count them
  4325.              •       give a percentage of the code that is unused
  4326.              •       percentage compression achieved on the used code
  4327.              •       lines containing any user-defined basic token (e.g.
  4328.                      PRINT)
  4329.              •       time taken to load, parse, cross-reference, compress,
  4330.                      write
  4331.      
  4332.      
  4333.  [8.5] Uncompressed output
  4334.      
  4335.      It would have been nice if there was an option to just remove the
  4336.      unused routines and merge all the libraries into one big file.  This
  4337.      would give a nice listable program containing only the routines
  4338.      used.  However this is currently unpossible, as BasCompress was never
  4339.      intended to produce anything but compressed code.  (There are many
  4340.      places where “skip until hit non-space” is hard-coded, and it would
  4341.      take a rather long time to rationalise these so you could toggle it
  4342.      on/off.)  Oh well.
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.  
  4352.                                   Page  64
  4353.  
  4354.  ============================================================ BasCompress ====
  4355.  
  4356.  
  4357.  
  4358.  [8.6] Label reduction
  4359.      
  4360.      The reduction of labels isn’t always as good as it could be.
  4361.      Currently BasCompress only judges the fitness of a label to be
  4362.      reduced on its’ global usage.  A better algorithm would take into
  4363.      consideration the nesting level of each usage, and use this to bias
  4364.      the reduction of labels towards those used inside loops.
  4365.      
  4366.      
  4367.  [8.7] Executable
  4368.      
  4369.      The current situation, with two separate applications is far from
  4370.      ideal.  A better situation would be to have the back end program
  4371.      inside a module.  This would have the added bonus of not needing to
  4372.      load in the Messages file every time it is run.
  4373.      
  4374.      Better yet would be to have the whole thing as one big Wimp
  4375.      application.  Here many extras are possible because there would be
  4376.      direct access to the cross-reference database.  For example it could
  4377.      create graphs of variable name distribution, provide the cross-
  4378.      reference in it’s own window, where you could filter it given user
  4379.      criteria (such as name matching a regexp AND usage>3).  But I don’t
  4380.      think so, do you?
  4381.  
  4382.  
  4383.  
  4384.  
  4385.  
  4386.  
  4387.  
  4388.  
  4389.  
  4390.  
  4391.  
  4392.  
  4393.  
  4394.  
  4395.  
  4396.  
  4397.  
  4398.  
  4399.  
  4400.  
  4401.  
  4402.  
  4403.  
  4404.  
  4405.  
  4406.  
  4407.  
  4408.  
  4409.  
  4410.  
  4411.  
  4412.  
  4413.  
  4414.  
  4415.  
  4416.                                   Page  65
  4417.  
  4418.  ============================================================ BasCompress ====
  4419.  
  4420.  
  4421.  
  4422.  [A] Messages
  4423.      
  4424.  [A.1] Internationalism united
  4425.      
  4426.      For users of a foreign extractment, the Messages directory contains
  4427.      the country-specific text files.  Copy Default, to (say) Iceland and
  4428.      edit the messages, and if that is the configured country of the
  4429.      machine, then those messages will be loaded.  Note it is sensible to
  4430.      keep a Default file as this will be loaded if no file of the
  4431.      configured country could be found.
  4432.      
  4433.      If you do make a translated messages file, the author would
  4434.      appreciate it greatly if you could send it in so every one can
  4435.      benefit.
  4436.      
  4437.      
  4438.  [A.2] Format
  4439.      
  4440.      The message format is fairly obvious --- just look at them to see
  4441.      what can and can’t be done, but here’s a quick summary.
  4442.  
  4443.              •       Comments start with a #
  4444.              •       Messages names start on a new line, and end in a
  4445.                      colon
  4446.              •       Messages start at the first non-space after the
  4447.                      colon, and finish at the end of the line
  4448.              •       Spaces can be done as “% ”
  4449.              •       Percents can be included using “%%”
  4450.              •       The “parameter”s %s and %d are supplied by
  4451.                      BasCompress, these are standard C printf() strings
  4452.              •       The standard C escape sequences \b, \t, \n, \r, \xXX,
  4453.                      \000, etc. can be used to insert those characters
  4454.                      inside the messages
  4455.              •       A message may be a selection: starts with a “%?” and
  4456.                      consists of a comma separated list of alternatives
  4457.  
  4458.  
  4459.  
  4460.  
  4461.  
  4462.  
  4463.  
  4464.  
  4465.  
  4466.  
  4467.  
  4468.  
  4469.  
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.  
  4477.  
  4478.  
  4479.  
  4480.                                   Page  66
  4481.  
  4482.  ============================================================ BasCompress ====
  4483.  
  4484.  
  4485.  
  4486.  
  4487.  [B] Regular expressions
  4488.      
  4489.      
  4490.  [B.1] Definition
  4491.      
  4492.      A regular expression (RE) is a fancy wild-carding system – i.e.  you
  4493.      don’t need exact matches.  A regular expression is really a
  4494.      mini–programming language with the following “commands”:
  4495.      
  4496.              .     any character
  4497.              ^     start of line
  4498.              $     end of line
  4499.              [...] set of characters(*)
  4500.      
  4501.      Any other character matches itself
  4502.      
  4503.      There are also modifiers:
  4504.      
  4505.              |    or, “re1|re2” match either RE1 or RE2
  4506.              ~    not, “~c” matches anything but the next character
  4507.              +    many, “re+” matches RE repeated one or more times
  4508.              *    repeat, “re+” matches RE repeated zero or more times
  4509.              ?    optional, “re?” matches RE repeated zero or one times
  4510.      
  4511.      Parenthesis () can be used to group REs
  4512.      
  4513.      Finally, there are memories:
  4514.      
  4515.              \{   begin recording
  4516.              \}   end recording, and place in next memory (starts with 1)
  4517.              \<n> \1, ... \9 will then match the corresponding memory
  4518.      
  4519.  
  4520.  (*) character sets:
  4521.      
  4522.      Character sets are used to match one of a group of characters.  All
  4523.      characters are taken literally except “–”, “]”, and “\”.  The “–”
  4524.      indicates a range, unless it is the first or last character, or the
  4525.      first character after a previous range.  The “\” can be used to
  4526.      include a “]” or a “–” in the set.
  4527.  
  4528.