home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-08-08 | 138.4 KB | 4,528 lines |
-
-
- Y8888bo .d88oo
- 88[ 88[ d8` ‘8
- 88[ ]8P ]8P ‘[
- 88[ 88` .ooo .oo. d8[ `.oo, oo.oo oo, .o,oo oo.o ooo .oo. .oo.
- 88888o 8[]8[ 88 Y 88[ .8`‘8[’88“Y8P”88 Y8P 8b ‘88P8`d8 8b 88 Y 88 Y
- 88[ ‘88 “ ]8[ 88b‘ 88[ 88 88 88 ]8[ 88 ]8[ 88[ 88 ]8P“”“ 88b‘ 88b’
- 88[ 88[ oP]8[ ‘888 Y8b .88 88`88 ]8[ 88 ]8[ 88[ 88 ]8[ ’888 ‘888
- 88[ ]88`]8[]8[] Y8[‘88, dY8 88 88 ]8[ 88 ]8[ 88` 88 ]8b ] Y88 Y8[
- o888888“ ‘8b/8b,bodP ’Y8boP`‘YbdP`.88,d8b.88,]88o8“ .88, Y8bo‘ bodP bodP
- ]8[
- ]8[
- “”`
-
- v1.69 4th August 1995
-
- Program and documentation by
-
- Cy Booker
- 86 Church View
- Main Road
- Crockenhill
- Swanley
- Kent
- BR8 8JW
- U.K.
-
- Internet: bc@cheepnis.demon.co.uk
- Arcade BBS (Fidonet#2:254/27.0): Cy Booker
-
- Musical entertainment provided by Frank Zappa
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ============================================================ BasCompress ====
-
-
-
-
- [1] Overview . . . . . . . . . . . . . . . . . . . . . 1
- [1.1] Disclaimer . . . . . . . . . . . . . . . . . . . . 1
- [1.2] Synopsis . . . . . . . . . . . . . . . . . . . . . 1
- [1.3] Features . . . . . . . . . . . . . . . . . . . . . 2
- [1.4] Documentation . . . . . . . . . . . . . . . . . . . 3
- [1.5] Compressing your first file . . . . . . . . . . . . 3
- [1.6] Example speed . . . . . . . . . . . . . . . . . . . 3
- [1.7] Example compression . . . . . . . . . . . . . . . . 4
- [2] BasCompress . . . . . . . . . . . . . . . . . . . . 5
- [2.1] Overview . . . . . . . . . . . . . . . . . . . . . 5
- [2.2] Jargon . . . . . . . . . . . . . . . . . . . . . . 5
- [2.3] Basic . . . . . . . . . . . . . . . . . . . . . . . 5
- [2.4] Numbers . . . . . . . . . . . . . . . . . . . . . . 5
- [2.5] SWI’s . . . . . . . . . . . . . . . . . . . . . . . 6
- [2.6] Star commands . . . . . . . . . . . . . . . . . . . 6
- [2.7] Assembler . . . . . . . . . . . . . . . . . . . . . 7
- [2.8] Routines . . . . . . . . . . . . . . . . . . . . . 7
- [2.8.1] Main program . . . . . . . . . . . . . . . . . . . 7
- [2.8.2] Start and end of a routine . . . . . . . . . . . . 8
- [2.8.3] Routine end detection . . . . . . . . . . . . . . . 8
- [2.8.4] END and ERROR . . . . . . . . . . . . . . . . . . . 9
- [2.8.5] LOCAL ERROR . . . . . . . . . . . . . . . . . . . . 9
- [2.9] Multi-line structures . . . . . . . . . . . . . . . 9
- [2.10] Libraries . . . . . . . . . . . . . . . . . . . . . 10
- [2.10.1] Multiply-defined routines in libraries . . . . . . 11
- [2.11] Label reduction . . . . . . . . . . . . . . . . . . 11
- [2.12] Line numbers . . . . . . . . . . . . . . . . . . . 12
- [2.12.1] Output line numbers . . . . . . . . . . . . . . . . 12
- [2.13] Multi-line output . . . . . . . . . . . . . . . . . 13
- [2.14] DATA . . . . . . . . . . . . . . . . . . . . . . . 13
- [2.15] Re-compressing . . . . . . . . . . . . . . . . . . 13
- [2.16] Constant variables . . . . . . . . . . . . . . . . 14
- [2.16.1] Caveat . . . . . . . . . . . . . . . . . . . . . . 15
- [2.17] ASC compression . . . . . . . . . . . . . . . . . . 15
- [2.18] Overlays . . . . . . . . . . . . . . . . . . . . . 16
- [2.18.1] Overlay specification . . . . . . . . . . . . . . . 16
- [2.18.2] Inline comments . . . . . . . . . . . . . . . . . . 16
- [2.18.3] Example of overlays . . . . . . . . . . . . . . . . 17
- [2.18.4] OVERLAYs and re-compressing . . . . . . . . . . . . 17
- [2.19] NEXT compression . . . . . . . . . . . . . . . . . 17
- [2.20] Keeping initial REM statements . . . . . . . . . . 18
- [2.21] TOP handling . . . . . . . . . . . . . . . . . . . 18
- [2.22] Output type . . . . . . . . . . . . . . . . . . . . 19
- [2.22.1] Squeezed output . . . . . . . . . . . . . . . . . . 19
- [2.22.2] Command line parameters . . . . . . . . . . . . . . 19
- [3] Cross-referencing . . . . . . . . . . . . . . . . . 20
- [3.1] Overview . . . . . . . . . . . . . . . . . . . . . 20
- [3.1.1] What’s cross-referenced . . . . . . . . . . . . . . 20
- [3.1.2] What’s output . . . . . . . . . . . . . . . . . . . 20
- [3.1.3] Messages . . . . . . . . . . . . . . . . . . . . . 20
- [3.2] Level of detail . . . . . . . . . . . . . . . . . . 21
- [3.2.1] Routine definition . . . . . . . . . . . . . . . . 21
- [3.2.2] Routine calls . . . . . . . . . . . . . . . . . . . 21
- [3.2.3] Routine called by . . . . . . . . . . . . . . . . . 22
-
-
-
-
-
- ============================================================ BasCompress ====
-
-
-
-
- [3.2.4] Variable declaration . . . . . . . . . . . . . . . 22
- [3.2.5] Variable assignment . . . . . . . . . . . . . . . . 22
- [3.2.6] Variable reference . . . . . . . . . . . . . . . . 22
- [3.3] Order . . . . . . . . . . . . . . . . . . . . . . . 23
- [4] The front end . . . . . . . . . . . . . . . . . . . 24
- [4.1] Installation . . . . . . . . . . . . . . . . . . . 24
- [4.1.1] Installing throwback . . . . . . . . . . . . . . . 24
- [4.2] Starting . . . . . . . . . . . . . . . . . . . . . 24
- [4.3] Overview . . . . . . . . . . . . . . . . . . . . . 25
- [4.3.1] Icon bar icon . . . . . . . . . . . . . . . . . . . 25
- [4.4] Control window . . . . . . . . . . . . . . . . . . 25
- [4.5] Main menu . . . . . . . . . . . . . . . . . . . . . 26
- [4.6] Input . . . . . . . . . . . . . . . . . . . . . . . 26
- [4.7] Output . . . . . . . . . . . . . . . . . . . . . . 27
- [4.8] Log . . . . . . . . . . . . . . . . . . . . . . . . 29
- [4.9] Special files . . . . . . . . . . . . . . . . . . . 30
- [4.10] Cross-reference . . . . . . . . . . . . . . . . . . 31
- [4.11] Choices Dialogue Box . . . . . . . . . . . . . . . 32
- [5.1] Invoking . . . . . . . . . . . . . . . . . . . . . 35
- [5.2] Installing . . . . . . . . . . . . . . . . . . . . 35
- [5.3] Environment variables . . . . . . . . . . . . . . . 36
- [5.3.1] DDEUtils and long command lines . . . . . . . . . . 36
- [5.4] The CLI parameters . . . . . . . . . . . . . . . . 37
- [5.4.1] Input . . . . . . . . . . . . . . . . . . . . . . . 37
- [5.4.2] Output . . . . . . . . . . . . . . . . . . . . . . 38
- [5.4.2.1] Output listing . . . . . . . . . . . . . . . . . . 38
- [5.4.3] Log . . . . . . . . . . . . . . . . . . . . . . . . 39
- [5.4.4] Special . . . . . . . . . . . . . . . . . . . . . . 39
- [5.4.5] Cross-reference . . . . . . . . . . . . . . . . . . 39
- [5.4.5.1] What gets cross-referenced . . . . . . . . . . . . 39
- [5.4.5.2] How much cross-referencing to be done . . . . . . . 40
- [5.4.5.3] Order of cross-referencing . . . . . . . . . . . . 40
- [5.5] Error handling . . . . . . . . . . . . . . . . . . 40
- [5.6] Escape handling . . . . . . . . . . . . . . . . . . 41
- [5.7] Hourglass . . . . . . . . . . . . . . . . . . . . . 41
- [6] Special files . . . . . . . . . . . . . . . . . . . 42
- [6.1] Why need special files? . . . . . . . . . . . . . . 42
- [6.2] The Special file . . . . . . . . . . . . . . . . . 42
- [6.3] Format of a Special file . . . . . . . . . . . . . 43
- [6.3.1] Defining routines . . . . . . . . . . . . . . . . . 43
- [6.3.2] Defining globals . . . . . . . . . . . . . . . . . 43
- [6.3.3] Labels . . . . . . . . . . . . . . . . . . . . . . 44
- [6.3.3.1] Verbatim . . . . . . . . . . . . . . . . . . . . . 44
- [6.3.3.2] Comma separated . . . . . . . . . . . . . . . . . . 45
- [6.3.3.3] Full pathname . . . . . . . . . . . . . . . . . . . 45
- [6.3.3.4] Wimp menu . . . . . . . . . . . . . . . . . . . . . 45
- [6.3.4] Variables as regular expressions . . . . . . . . . 46
- [6.3.4.1] Example patterns . . . . . . . . . . . . . . . . . 46
- [6.3.4.2] Limitations . . . . . . . . . . . . . . . . . . . . 47
- [6.3.5] Libraries . . . . . . . . . . . . . . . . . . . . . 47
- [6.3.6] Overlays . . . . . . . . . . . . . . . . . . . . . 48
- [6.3.7] Include files . . . . . . . . . . . . . . . . . . . 48
- [6.4] Limitations . . . . . . . . . . . . . . . . . . . . 48
- [7] Errors . . . . . . . . . . . . . . . . . . . . . . 49
-
-
-
-
-
- ============================================================ BasCompress ====
-
-
-
-
- [7.1] Overview . . . . . . . . . . . . . . . . . . . . . 49
- [7.2] Warnings . . . . . . . . . . . . . . . . . . . . . 49
- [7.3] Errors . . . . . . . . . . . . . . . . . . . . . . 54
- [7.4] Run-time errors . . . . . . . . . . . . . . . . . . 59
- [7.4.1] Unknown or missing variable . . . . . . . . . . . . 59
- [7.4.2] No such function/procedure . . . . . . . . . . . . 59
- [7.4.3] Missing ENDIF . . . . . . . . . . . . . . . . . . . 59
- [7.4.4] Invalid RETURN actual parameter . . . . . . . . . . 60
- [7.4.5] Syntax error . . . . . . . . . . . . . . . . . . . 60
- [7.4.6] Logical errors . . . . . . . . . . . . . . . . . . 60
- [7.5] Internal errors . . . . . . . . . . . . . . . . . . 61
- [8] Loose ends . . . . . . . . . . . . . . . . . . . . 62
- [8.1] Memory usage . . . . . . . . . . . . . . . . . . . 62
- [8.2] Missing THEN . . . . . . . . . . . . . . . . . . . 63
- [8.3] Cross-reference . . . . . . . . . . . . . . . . . . 64
- [8.4] Statistics . . . . . . . . . . . . . . . . . . . . 64
- [8.5] Uncompressed output . . . . . . . . . . . . . . . . 64
- [8.6] Label reduction . . . . . . . . . . . . . . . . . . 65
- [8.7] Executable . . . . . . . . . . . . . . . . . . . . 65
- [A] Messages . . . . . . . . . . . . . . . . . . . . . 66
- [A.1] Internationalism united . . . . . . . . . . . . . . 66
- [A.2] Format . . . . . . . . . . . . . . . . . . . . . . 66
- [B] Regular expressions . . . . . . . . . . . . . . . . 67
- [B.1] Definition . . . . . . . . . . . . . . . . . . . . 67
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ============================================================ BasCompress ====
-
-
-
- [1] Overview
-
-
- [1.1] Disclaimer
-
- This program is supplied “as is”. No warranty, express or implied,
- of the merchantability of this program or its fitness for any
- particular purpose is given. In no circumstances shall the author,
- or any provider or distributor of this program, be liable for any
- damage, loss of profits, or any indirect or consequential loss
- arising out of the use of this program.
-
-
- [1.2] Synopsis
-
- BasCompress takes as input a tokenised basic file, analyses it on a
- routine-by-routine basis, and outputs a cross-reference and a
- compressed tokenised basic file.
-
- (It was written because none of the currently available Basic
- squashers handled the side effects of EVAL, removed unused routines,
- or discarded the junk inbetween routines, and they were all far too
- slow).
-
- It consists of two programs, a Wimp-based front end, and a CLI-based
- back end. The former is ideal for occasional use, while the later is
- better for scripts, make files, etc..
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 1
-
- ============================================================ BasCompress ====
-
-
-
- [1.3] Features
-
- The main features of BasCompress can be summarised as follows:
-
- • Checks all multi-line IFs have a matching ENDIF
- • Checks all CASE’s have a matching ENDCASE
- • Checks all WHILE’s have a matching ENDWHILE
- • Checks the ellipsis/quotes/brackets on each statement
- • It doesn’t balk at the use of line numbers (too much)
- • Loads in explicit LIBRARY files
- • Checks every routine exits cleanly
- • Checks for multiply-defined routines
- • Produces a full cross-reference on all variables and
- routines, with four levels of detail, and user-definable
- ordering
- • Variable/routine name reduction, targeting the most used to
- be the shortest
- • Remove all redundant spaces and REMarks
- • Remove all between-routine junk
- • Concatenation of output lines
- • Remove unused code
- • Reduces numbers to their shortest form
- • Converts SYS and SWI strings to numbers
- • Converts ASC(“s”) to the equivalent number
- • Compresses/removes constant variables
- • Handles DIM x!24 32
- • Optional “special” file to handle EVALuated variables and
- functions, and implicitly loaded library files
- • “special” file allows variables to be defined as regular
- expressions
- • It is fast
-
- In other words it does all you would expect, a bit more, and all at a
- very respectable speed.
-
- All those syntax checks may seem superfluous until you realise that
- most error handling code isn’t always as fully debugged as it should
- be.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 2
-
- ============================================================ BasCompress ====
-
-
-
- [1.4] Documentation
-
- This document is split into several sections. First a full
- description of exactly what this program does to, and expects of, the
- input. This is followed by §3, a chapter on the powerful cross-
- referencing available. Not until §4 is the program itself described,
- the Wimp front end application. The back end application, accessible
- from the CLI is §5. Special files, their format and use are detailed
- in §6. §7 is what this author wishes every program documentation
- had, a complete list of errors and reasons why they occurred, and
- more importantly --- some hints on how to get rid of them. Finally,
- §8 contains miscellanea, the junk that doesn’t categorise too easily.
-
-
- [1.5] Compressing your first file
-
- Run the application. This will install the Wimp front end onto the
- icon bar icon and open the control window to the center of the screen.
-
- First of all drag the Log file icon to a directory display (not
- another application, sorry). This file will contain information
- about the actions of the compression process. Now drag a Basic file
- onto the control window, to compress it.
-
- With the default options this Basic file will be analysed, the log
- file created and then automatically loaded into your resident text
- editor. If this is Edit, then don’t close the Log window for now.
-
- Even if the Basic file was analysed without error, no output file was
- produced because none was defined. Just drag the output file icon
- from the control window onto a directory display and start again.
-
- Now, because Edit still had a view of the Log file, this was
- automatically updated, using the current window size. This gives an
- extremely usable environment!
-
- Voila, a compressed basic file has been produced.
-
- If the log file reports any EVAL or DATA statements were found, it is
- possible that the program may not run. See the chapter on Special
- files for a way to handle this. (The quick way is to disable all
- variable and routine label reduction).
-
- Now read §2.
-
-
- [1.6] Example speed
-
- It takes BasCompress less than 20s to compress itself. This needs 4
- special files, contains 40-odd source files (including libraries)
- totalling just over 450K, and compresses it down to 100K. And all
- this on an Arm2 off of the standard 440 hard-disc, with all the I/O
- overhead that that involves.
-
-
-
-
-
- Page 3
-
- ============================================================ BasCompress ====
-
-
-
- [1.7] Example compression
-
- Here’s how well BasCompress handles compressing an early version of
- the Wimp front end application:
-
- 192742 Total input size
- 29659 Maximum compression
- 29706 No decimal number analysis
- 31129 No SWI name analysis
- 35103 No concatenation of output lines
- 47421 No removal of unused code
- 51950 No reduction of labels
-
- The later ones are not accumulative, the non-reduction of labels
- (only) really does add on 57% to the output program size!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 4
-
- ============================================================ BasCompress ====
-
-
-
- [2] BasCompress
-
-
- [2.1] Overview
-
- This chapter concerns itself with Basic, and what BasCompress expects
- (and does) to it.
-
-
- [2.2] Jargon
-
- The following terms will be used quite frequently, so I’ll explain
- what is meant by them:
-
- routine a procedure or function
- variable an (integer | real | string)[array]
- label the name of a routine or variable
- name a label with its (pre | post)fix
-
- E.g. the following table might help
-
- name label
- PROC_Zappa _Zappa
- Frank% Frank
- Cy$() Cy
-
-
- [2.3] Basic
-
- BasCompress will only except fully tokenised basic files, it does not
- accept text files. This program only knows about the tokens present
- in Basic V, v1.04. The behaviour of this program on Basic files on a
- version greater than this is undefined.
-
- Only one Basic file is parsed (but see §2.10).
-
-
- [2.4] Numbers
-
- BasCompress will interpret all numbers and try to output them in as
- compact a form as possible. This is most effective on long binary
- numbers, but can shorten many large decimal values as well.
-
- The analysis and output of (decimal) numbers requires the floating
- point emulator. For this reason this can be turned off, just in case
- you are very short on memory.
-
- Analysis of hexadecimal and binary numbers is always done, as this
- does not require any floating point math.
-
- Note that BasCompress tries to output numbers in the hexadecimal
- format whenever possible. One artifact of this is assembler source
- where the registers get converted to &e, etc.
-
-
-
-
-
- Page 5
-
- ============================================================ BasCompress ====
-
-
-
- [2.5] SWI’s
-
- Acorn’s interface to the operating system, the SWI is an elegant self-
- documenting system. However, for interpreted languages like Basic,
- the translation of a SWI name to a SWI number is relatively time-
- consuming.
-
- BasCompress will try to do this translation, leaving just a number.
- This provides both large space and large execution savings,
- particularly for Wimp programs that use SWI’s during screen redraw
- (that’s all of them!)
-
- In order for BasCompress to translate the SWI name, it must be a
- simple constant string expression. If it isn’t, or it can’t
- translate it, then it is left as it is --- thus providing an (almost)
- fool-proof conversion. (A possible case of a complex string constant
- would be SYS “X”+ “OS_ReadC”).
-
- Both SYS calls (in Basic) and SWI calls (in assembler) are converted.
-
- Note also that the any modules used by the program should be resident
- at the time of compression, otherwise the SWI’s will be unknown and
- thus BasCompress will leave them as strings. This is an easy mistake
- to make, and results in slower and longer compacted files being
- produced. This cases ud detected, and generates a suitable warning.
-
-
- [2.6] Star commands
-
- A backward compatibility feature of Basic V is it’s allowance of
- *Commands anywhere in Basic. Modern programs should really put this
- in an OSCLI(“...”), or better yet a SYS “OS_CLI”, “...”.
-
- However, since this is allowed, some programmers use it to introduce
- comments in programs by using the *| comment construct. BasCompress
- will remove these lines completely. It will also remove all
- unnecessary *’s and spaces.
-
- If this results in a complete removal of the statement, BasCompress
- may produce incorrect code if (and only if) this *command was just
- after an (explicit) THEN. Since this is extremely bad programming
- practised, this author felt the benefits gained far outweigh the
- possible side-effects.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 6
-
- ============================================================ BasCompress ====
-
-
-
- [2.7] Assembler
-
- BasCompress fully understands and compacts assembler statements. As
- part of this process, BasCompress also checks that the square bracket
- “[]” count on each statement is valid --- which may be useful for
- detecting bugs in conditionally assembled code.
-
- All R0..R15 registers get translated to 0..15, this saves a lot of
- space. Also the integer EQU’s can be renamed to DC’s.
-
- Note that the single space left after some mnemonics is necessary,
- without it the Basic assembler will refuse to work.
-
- BasCompress also recognises (and compresses to) the ‘&’ derivative
- of DCW and the ‘=’ derivative of EQUS and DCB.
-
-
- [2.8] Routines
-
- It is important to understand that BasCompress treats a program as a
- group of routines. Because of this it can remove any junk inbetween
- routines, i.e. comments not explicitly starting with a REM, that
- other squashers leave behind (and even try to analyse --- producing
- many, many errors).
-
- Note that this behaviour, removing junk between routines, can be
- disabled in cases where BasCompress is unable to detect the end of
- a routine. See below for details of why BasCompress can get
- confused.
-
- Because a record is kept of what happens inside a routine, it is
- possible to conclude that a routine isn’t actually needed in the
- output file --- and so none of the routines that it calls are needed
- that bit less as well. Thus BasCompress can remove ALL unused
- routines from the output file. This is a very powerful feature.
-
-
- [2.8.1] Main program
-
- BasicV does not provide a clearly defined method for distinguishing
- the end of the main program, and the start of the subroutines.
- BasCompress treats everything from the start of the first file to the
- first routine definition (DEF PROC or DEF FN) to be the main
- program. This isn’t ideal, as many main programs consists of an
- infinite loop followed by junk --- however there is no easy way of
- recognising the true end of the main program, so you have to live
- with it as it is.
-
- If you wish to compress library files separately, i.e. files that do
- not contain a main routine at the start of a file, then this is
- easily accommodated. There is a menu item
- ‘Input->Process as a library file’ which toggles this feature.
-
-
-
-
-
-
- Page 7
-
- ============================================================ BasCompress ====
-
-
-
- [2.8.2] Start and end of a routine
-
- The start of a Basic routine is very easily detected, it is a line
- that starts with DEF FN or DEF PROC.
-
- However, the end of a routine isn’t so easy to detect. In the ideal
- world, every routine will have one, and only one exit that is a
- simple ENDPROC, or = <expr> on a line of its’ own. However, we all
- live in the real world, and things are more complicated than that.
-
-
- [2.8.3] Routine end detection
-
- For example, consider the following function:
-
- DEF FNmin(a, b)
- IF a>b THEN =b ELSE =a
-
- Now, the only way for BasCompress to recognise this construct is if
- it kept track of all branches of a conditional. This would involve a
- major upgrade, and would make the program just a code-generation pass
- away from a true compiler.
-
- BasCompress has two separate ways of dealing with this, a ‘smart’ way
- and a ‘dumb’ way. The dumb method is to ignore routine ends all
- together. The smart method is to ignore exits from a routine that
- occur:
-
- • on the same line as an IF
- • an the same line as an ON ERROR
- • inside a multi-line construct
-
- By default BasCompress is ‘smart’. To disable this use the CLI
- switch -Dumb, or tick menu item
- ‘Input->Ignore exits from a routine (‘dumb’)’.
-
- Each method has its’ own merits. The smart method means that
- because BasCompress knows when the routine has ended, it can skip any
- inter-routine junk. The dumb method is extremely useful for coping
- with legacy code that confuses BasCompress ‘smart’ algorithms.
-
- When in ‘smart’ mode BasCompress will think that the next line, in
- the above example will be inside the function min. This usually
- results in a cascade of warning/error messages being generated. The
- only long-time cure for this is to amend the offending function. The
- simplest way is to just put a dummy terminator in, e.g.
-
- DEF FNmin(a, b)
- IF a>b THEN =b ELSE =a
- = 0
-
-
-
-
-
-
-
-
- Page 8
-
- ============================================================ BasCompress ====
-
-
-
- Better yet, would be to code it “properly”:
-
- DEF FNmin(a, b)
- IF a>b THEN a=b
- = a
-
- There is also the problem of programs that prematurely terminate
- routines inside, say, a case structure. This happens quite often,
- because it makes for much shorter code, and so BasCompress recognises
- this, see §2.9.
-
-
- [2.8.4] END and ERROR
-
- Currently BasCompress does not recognise the fact that a routine may
- end with the END command, nor an unconditional ERROR. Since these
- are examples of bad-programming anyway, these are easily worked
- around by just adding a redundant ENDPROC or =0 after the last line.
-
-
- [2.8.5] LOCAL ERROR
-
- BasCompress fully recognises local error handlers, and will force the
- next input line to start a new output line accordingly.
-
-
- [2.9] Multi-line structures
-
- When in ‘smart’ mode (see §2.8.3) BasCompress keeps track of the
- current nesting level of all multi-line structures:
-
- • CASE ... ENDCASE
- • IF THEN ... ENDIF
- • REPEAT ... UNTIL
- • WHILE ... ENDWHILE
-
- It does this primarily to detect conditional exiting from a routine.
- For example, if an ENDPROC or = <expr> is detected inside such a
- structure, then BasCompress knows it isn’t the true end of the
- routine, and so will ignore it. A very useful side-effect of this is
- that BasCompress detects programming errors in the use of these
- constructs, errors that the run time Basic interpreter allows
- through. These very often are genuine program mistakes, usually
- inside error-handling code that is not fully debugged.
-
- However, there are two caveats to this. Firstly, in order for
- BasCompress to do this it must assume that the start of any multi-
- line structure is not inside a one-line IF construct. Unfortunately,
- some programmers put a quick WHILE ... ENDWHILE loop in a one-line
- IF. BasCompress does not handle this correctly and this line needs
- to be split into a true multi-line IF.
-
-
-
-
-
-
-
- Page 9
-
- ============================================================ BasCompress ====
-
-
-
- Secondly, and just as less seriously, BasicV is rather lax in it’s
- attitude towards multi-line structures. For example:
-
- REPEAT
- i += 1
- CASE x(i) OF
- WHEN 1:
- IF do_it THEN
- UNTIL FALSE:ENDPROC
- ENDIF
- ...
- ...
- ENDCASE
- UNTIL i>max_i
-
- Here, BasicV will rather carelessly execute the UNTIL, even though it
- isn’t at the same nesting level as the matching REPEAT. BasCompress
- is not so lenient and it will refuse point blank to handle such
- code. It is another example of bad programming being used, and
- should be re-coded in another way.
-
- If you need to compress such code then put BasCompress in it’s ‘dumb’
- mode.
-
-
-
- [2.10] Libraries
-
- The use of the LIBRARY call is recognised. It causes the appropriate
- file to be appended to the queue of files to be parsed, and the
- entire LIBRARY statement to be removed from the output.
-
- For this to work, BasCompress assumes a simple string constant
- follows the LIBRARY. If this is not the case and it uses a
- variable/routine parameter then you will need to set up a Special
- file. This will tell BasCompress what to expect the variable to be
- so it can load the correct file. Please refer to the §6.
-
- All LIBRARY files are only ever scanned once, even if it is included
- many times.
-
- Of course, the loading of libraries will mean that the current
- directory and/or some system variables (e.g. App$Dir) may need to be
- set up --- otherwise BasCompress will not be able to locate the
- library file.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 10
-
- ============================================================ BasCompress ====
-
-
-
- [2.10.1] Multiply-defined routines in libraries
-
- Note that the loading of libraries, as performed by BasCompress is
- not exactly the same as the order that BasicV would have loaded them
- in. This could only cause a problem if multiply-defined routines
- exist, and further more these multiple definitions are themselves in
- library files, not the main file. If this situation does arise, then
- the kludge is: include the library containing the preferred
- definition twice, once before and once after the LIBRARY containing
- the unwanted definition. This will work because BasCompress will use
- the first loaded, and the uncompressed program would use the second!
-
-
- [2.11] Label reduction
-
- A lot of the time that BasicV takes to interpret a program is spent
- looking up variable names. BasCompress will attempt to reduce the
- long labels down to size, often producing dramatic space and speed
- improvements. The algorithm used ensures that the most used
- variables are chosen for the shortest variable names, and the names
- themselves are chosen so as to spread evenly across the name-space.
-
- Did you note the word attempt in the above paragraph? This is
- because basic is an interpreted language and provides the powerful
- commands EVAL and DATA, allowing expressions to be evaluated in the
- current context. For instance EVAL(“zappa%”) would yield the value
- of the variable zappa%. But, if BasCompress had reduced this
- variable down to, say, A% in the rest of the program (because it
- analysed the program in a different context) then what happens at run-
- time is you get a variable not found error.
-
- There are two solutions to this very common problem. The first is to
- disable label reduction on all variables of the type that are used in
- EVAL or DATA statements. This is extremely wasteful, but the only
- option available in other squashers. With BasCompress there is a
- much more elegant solution --- you can specify all the labels that
- must not be reduced. Further more, these variables can be implied
- from the parameters passed to a routine!
-
- For example, many Wimp-based programs will have a menu-construction
- suite of routines. These will be passed a string that describes the
- menu. Inside this string will be references to variables that at run-
- time will point to more information (sub-menus or windows usually).
- With BasCompress, you can get it to analyse all these strings,
- extract the variables, and then reduce all other variables apart from
- those. This is a very powerful feature. See the §6 for more info.
-
- Note that BasCompress goes to the trouble of making sure that it
- never produces one of the “built-in” register labels used by the
- assembler (R0-R15, pc). On other basic squashers this can lead to
- VERY obscure bugs.
-
-
-
-
-
-
-
- Page 11
-
- ============================================================ BasCompress ====
-
-
-
- Also worth mentioning is that any labels accessed inside deleted
- routines are automatically removed from the list of labels to
- reduce. This produces better results than just reducing all labels
- found.
-
- BasCompress can handle any number of labels, well as many as could
- fit into available memory!
-
-
- [2.12] Line numbers
-
- Normally line numbers are an anathema but there does exist a valid
- reason for using them in BasicV, and so line number handling has been
- included in BasCompress. The reason why line numbers may be needed
- is if a program claims more memory though the use of the END=<expr>
- construct. This has the unfortunate side-effect of removing all
- routine level info, so you have to GOTO the main program loop).
-
- Obviously, line numbers found in any library files are faulted as
- there is no valid reason for them being there.
-
- Note that in short programs it is just possible that there will be a
- GOTO to a destination outside both the main program and all other
- routines. Currently BasCompress does not handle this (rather rare)
- case. As a kludge, surround the offending code in a dummy routine.
-
-
- [2.12.1] Output line numbers
-
- If no line numbers were found then line numbering is easy. For
- single-file programs the line numbers keep to their original values,
- even if multi-line compaction is enabled. For multi-file programs
- the output file starts from 1 and increases in steps of 1.
-
- If line numbers were found then the line numbers in the original
- program are used for the original program part, and thereafter line
- numbers increment in steps of one for any further libraries.
-
- Unfortunately BasicV only allows line numbers up to around 65000
- odd. This could possibly be a problem if the original program has
- line numbers up to, say, 64000, and includes quite a few library
- files. This is one of the few possible errors that are not checked
- for, as the possibility of it occurring are just so remote.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 12
-
- ============================================================ BasCompress ====
-
-
-
- [2.13] Multi-line output
-
- Normally as many statements are compressed onto one output line as
- will fit. This produces the smallest files as the overhead that
- Basic imposes on each line is reduced by quite a bit.
-
- However, it can produce code that runs slower. This is because it
- appears BasicV only notes the statement number of an implicit jump
- (e.g. after a FOR, WHILE, or REPEAT). And so if this is on statement
- 56 of a line, say, then it has to scan all along the line to find
- where to continue execution. This situation may be recognised in a
- future upgrade by forcing the statement after one of these cases to
- start on a new line.
-
-
- [2.14] DATA
-
- BasCompress recognises the possibility that DATA may not reside
- inside a routine. All “unlinked” DATA statements will still be
- included in the output file, but only if there is some code left that
- will READ it.
-
- Please note that variables used as DATA will require the use of
- Special files.
-
-
- [2.15] Re-compressing
-
- Although at first sight the notion of compressing an already
- compressed file may seem a waste of time, in actual fact it is not.
-
- This is because BasCompress compresses a whole line at a time, and
- then merges together two or more lines. This isn’t done quite as
- optimally as possible, and sometimes extra colons are inserted.
-
- If the output is fed back into BasCompress these extra colons will be
- removed, as it will be obvious that they are truly redundant.
-
- If constant variable substitution is enabled (§2.16) then quite often
- a second pass reveals more constant variables!
-
- The best way to double-compress is to first compress with reduction
- of function and procedure names only (thus ensuring ‘special’
- routines only parsed once), and then a second time with full
- reduction of variable names.
-
- If you are using BasCompress to generate a distributable file (for
- instance your latest commercial/shareware executable) then you
- should give serious consideration to using this re-compression
- technique. It only takes a little while to set up a script (Obey)
- file to perform this at a (double) click of a file.
-
-
-
-
-
-
-
- Page 13
-
- ============================================================ BasCompress ====
-
-
-
- [2.16] Constant variables
-
- New to version 1.50 of BasCompress is the handling of ‘constant’
- variables. By this it is meant a string/real/integer variable (not
- an array) that is:
-
- • only ever assigned once
- • never declared (ie LOCAL, or routine parameter)
- • the assignment is ‘simple’
-
- By simple it is meant very simple! Currently the only types that are
- recognised are:
-
- • integer number, base 10
- • real number
- • hexadecimal number
- • string
-
- Although nowhere near the full types of basic expressions, the above
- list does cover the most common case in libraries where one generally
- has a lot of variables used to give ‘names’ to constants.
-
- When BasCompress finds such a variable it does two things:
-
- • Remove the definition
- • Replace all occurrences of the variable name with its’
- definition.
-
- This has the advantage that it leaves more room in the symbol table
- for variables that are actually used as variables. It should also
- speed up the programs’ execution.
-
- Note that variables that have been compressed is this way are listed
- as ‘unused’ in the log file.
-
- If you have enabled ‘Process as a library’ then BasCompress will
- silently disable constant variable analysis.
-
- Note that for this feature to work BasCompress needs to recognise
- all types of variable assignment, including SWAP, MOUSE TO, and
- RETURN parameters in routines. This used to be a problem, but
- BasCompress has been updated to account for all of these cases.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 14
-
- ============================================================ BasCompress ====
-
-
-
- [2.16.1] Caveat
-
- There is one important caveat with constant variable handling. This
- occurs if the definition of the constant variable is longer than the
- variable name itself. This most often happens with long string
- constants, although can happen with some integer values.
-
- The problem occurs when BasCompress comes to ‘remove’ the variable
- and substitute the longer definition. In rare circumstances (most
- noticably on already compressed source) this can cause a line longer
- than 256 bytes (a BasicV limitation) to be generated.
-
- The solution to such cases is to defined the variable in the special
- file (see §6.) See also §3.2.5.
-
-
- [2.17] ASC compression
-
- In many programs that deal with text you will see expressions of the
- form:
-
- IF (c%>=ASC(“0”) AND c%<=ASC(“9”)) THEN
- ...
- ENDIF
-
- This looks very nice, but executes relatively slowly. BasCompress
- now understands constructs of this form and will compress this down
- to:
-
- IF(A%>=48ANDA%<=57) THEN
- ...
- ENDIF
-
- Which is both textually shorter and is much faster to execute.
-
- To be more exact BasCompress understands the following:
-
- ASC [(]* string [)]*
-
- where spaces are swallowed and the string is a Basic format string.
- Also the brackets must match!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 15
-
- ============================================================ BasCompress ====
-
-
-
- [2.18] Overlays
-
- Overlays are a way of ‘dynamically’ loading groups of orthogonal
- routines that BASIC supports. The main advantage is that their use
- can, with careful program design, significantly reduce the memory
- requirements of an application.
-
- One oft cited example is in a ‘document’ handler, you only ever
- need to load, save, or print at one time. Therefore these
- separate functions (which could be quite complex) could each be
- handled in different source files, and all three specified in an
- OVERLAY command. The net result is that the application will
- only require as much memory as the largest overlay, rather than
- the total size of all overlays.
-
-
- [2.18.1] Overlay specification
-
- The OVERLAY command is not understood by BasCompress. However,
- overlays are supported, through the use of special files (see §6),
- or through inline comments (see below).
-
- When specifying an overlay file, if no directory separator is given
- (‘.’) then the directory of the input file is used. This is usually
- sufficient, unless you store overlays in a subdirectory.
-
- When output, each overlay file is output to the same directory as
- the main program (and all its’ libraries). There is no support for
- placing the overlays in sub-directories of the output directory.
-
- Note that this means you MUST ensure that the output directory is
- different from the input directory, otherwise the overlay files
- will become (silently) overwritten with their compressed version.
-
- For every overlay file an output file is always generated, even if
- BasCompress has removed all the routines inside it.
-
-
- [2.18.2] Inline comments
-
- BasCompress ‘understands’ comments of the form:
-
- REM BasCompress:Overlay: <overlay file>
-
- Note that case IS significant. This tells BasCompress to parse the
- specified file as an overlay, always. There is no condition
- attached to this (such as only parsing the overlay if this routine
- is actually used).
-
- If you require more control of which overlay files are parsed you
- will need to use a special file.
-
-
-
-
-
-
-
- Page 16
-
- ============================================================ BasCompress ====
-
-
-
- [2.18.3] Example of overlays
-
- Imagine an application has overlay files called “Load”, “Save”, and
- “Print”. These are all in the ‘application’ directory <App$Dir>.
-
- REM >App
- DIM lib$(3)
- lib$() = “<App$Dir>.Load”, “<App$Dir>.Save”, “<App$Dir>.Print”
- OVERLAY lib$()
- REM BasCompress:Overlay: Load
- REM BasCompress:Overlay: SCSI::HardDrive4.$.AppSource.Save
- REM BasCompress:Overlay: Print
- ...
- PROC_Load_Document(doc%)
- PROC_Save_Document(doc%)
- PROC_Print_Document(doc%)
-
- Then, with the system variable App$Dir set up appropriately the
- source and the BasCompress’ed files will execute as expected.
-
-
- [2.18.4] OVERLAYs and re-compressing
-
- If you wish to compress a program that uses overlays more than once
- (see §2.15), and it contains inline comments then you need to take
- care.
-
- There are two solutions. One involves the use of an environment
- variable in the inline comment:
-
- REM BasCompress:OverLay <App$Dir>.overlay
-
- which needs to change between compressions. The other depends on
- the comments being in the ‘main program’ (see §2.20). Here you can
- force BasCompress to keep initial REMs on the first pass, and remove
- them on the second pass!
-
-
- [2.19] NEXT compression
-
- Basic supports a shorthand method of terminating FOR loops, by
- omitting the variable name after the NEXT statement. While
- developing programs this is of dubious value, as it stops the
- interpreter from spotting possible mismatched FOR/NEXT’s.
-
- However, for compressed programs it is a good idea to remove the
- variable, as it (obviously) reduces the program size. It also
- speeds the program up, as the Basic interpreter no longer has to
- check that the correct variable has been placed after the NEXT.
-
-
-
-
-
-
-
-
-
- Page 17
-
- ============================================================ BasCompress ====
-
-
-
- BasCompress will ‘swallow’ real and integer loop variables. It will
- also concatenate adjacent NEXT’s to use a comma, eg.
-
- NEXT a%:NEXT b%:PRINT ASC(“A”)
-
- will be compressed down to
-
- NEXT,:PRINT65
-
- This only works if the NEXT’s are on the same line, however. If you
- want as much compression as possible, you should process the file
- twice (see §2.15), as on the second pass most NEXT’s will be on the
- same line.
-
-
- [2.20] Keeping initial REM statements
-
- The file that BasCompress is usually the file that gets distributed
- to third parties (ie an applications’ !RunImage file). It would be
- nice if you could incorporate into this some copyright message.
-
- One way to achieve this is to tell BasCompress to retain all
- ‘initial’ REM statements. These are comments that are
-
- • before the first routine definition
- • on a line by themselves
- • begin with REM (not *|, or ;)
-
-
- [2.21] TOP handling
-
- Basic supports a pseudo-variable called ‘TOP’. When read, it returns
- the topmost byte of memory. Unfortunately Basic does not use a token
- to encode this variable, but uses the token for ‘TO’ and the letter
- ‘P’.
-
- Basic has no problem with this, as it knows when to expect a proper
- ‘TO’ (after a FOR <var>=<expr>, or after a SYS). Unfortunately
- BasCompress does not know this, and so can not distinguish between a
- true ‘TOP’ and a ‘TO P’ without a space.
-
- This does matter if constant variable deletion is enabled, because
- BasCompress will not ‘see’ the P after the TO and if the P is other-
- wise constant, will be substituted everywhere else.
-
- Unfortunately there is no solution, other than to ensure that your
- source code never contains the sequence ‘TOP’, which can be done by
- ensuring that you have spaces after the TO. (Note that ‘TOPizza’ is
- OK, as is ‘TOP%’).
-
- As far as BasCompress output is concerned, this is not a problem, as
- the Basic interpreter knows how to handle these cases anyway.
-
-
-
-
-
-
- Page 18
-
- ============================================================ BasCompress ====
-
-
-
- [2.22] Output type
-
- Ordinarily BasCompress will produce a standard tokenised Basic file.
- However, it is a common requirement to further “protect” the
- program, and this can be done by making the file an “absolute”
- program.
-
- An “absolute” program consists of some machine code stuck onto the
- front of the tokenised basic. When executed the code “enters” BBC
- Basic and starts executing the program.
-
- Thus, for all intents and purposes they are identical --- you can
- double click either from a directory display, and your original
- Basic code will be executed the same.
-
-
- [2.22.1] Squeezed output
-
- Going one stage further in trying to “protect” your code,
- BasCompress now supports squeeze'ing the absolute file. This
- has the added benefit of making the file smaller on disc, and hence
- quicker to load (especially from a floppy).
-
- However, the actual program that squeeze’s the absolute file is
- copyright Acorn. But do not despair --- you already own a copy of
- it!
-
- The squeeze program can be found in your copy of the Patch
- application, in the directory “!Patch.Library”. Copy the “squeeze”
- file in this directory into the directory “$.Library”. (Or
- anywhere in your Run$Path).
-
-
- [2.22.2] Command line parameters
-
- There is a problem with using an absolute program in place of a
- tokenised file --- the command line is different.
-
- The details are pretty horrible --- it is necessary for the
- machine code stub to ‘remember’ the command line, then invoke
- Basic. The backend compressor will have inserted a single line
- of basic that picks up this command line (in the system variable
- BasCompress$CLI) and updates the CLI with it.
-
- Thus by the time the first line of *your* Basic executes, then
- a call to SYS "OS_GetEnv" will return the correct value.
-
- Note that if the absolute code was envoked with an extended
- command line (ie using DDEUtils) then this will NOT be handled.
- If you require this feature then please contact the author.
-
-
-
-
-
-
-
-
- Page 19
-
- ============================================================ BasCompress ====
-
-
-
- [3] Cross-referencing
-
-
- [3.1] Overview
-
- The cross-referencing of a large program can provide many useful
- insights, providing you can organise the output so as not to swamp
- you with “useless” information. To this end you can control what
- gets include, the level of detail, and the ordering (with many types
- of ordering available).
-
- Note that the cross-referencing of variables and routines is
- completely independent.
-
-
- [3.1.1] What’s cross-referenced
-
- The cross-reference contains only the routines and variables that
- will be included in the output file. Since dead code is usually
- removed, you have to tell BasCompress to keep in all would-be deleted
- stuff if you need a complete cross-reference.
-
- You can also control exactly what types of labels are included.
- Usually you’d keep the default (everything), but sometimes you don’t
- care about all the real variables, say, and this is easily catered
- for.
-
-
- [3.1.2] What’s output
-
- The result of the cross-referencing is sent to the cross-reference
- file, or the screen if none is specified. Since this is a lot of
- data, you will almost certainly want to use a file. The front end
- application has the ability to automatically load this into the
- resident text editor.
-
-
- [3.1.3] Messages
-
- The formatting of the cross-reference is defined using the external
- Messages file. By altering the following messages you can tailor the
- output of the program dramatically (see appendix A for description of
- format of messages) :-
-
- Name Show label and its’ qualifying string (“%s%s”)
- Comma Separates distinct references (“, ”)
- SemiColon Separates similar references (“; ”)
-
-
-
-
-
-
-
-
-
-
-
- Page 20
-
- ============================================================ BasCompress ====
-
-
-
- They are currently set up to produce “one-line-per entry”. However,
- it is possible to change these three so that every distinct reference
- appears on each separate line, vis-a-vis:
-
- Name: \n\t%s%s
- Comma: \n\t
- SemiColon: ,%
-
- But note, you will probably need to alter all the titles used so that
- they start rather than end with a newline. (The \t expands to a tab
- character, this is usually better than many spaces, since cross-
- reference files are large enough as it is)
-
-
- [3.2] Level of detail
-
- There are four levels of detail supported by BasCompress:
-
- None suppresses output, obvious really
- Existence useful to just list the name of all the
- labels used
- Global gives the additional information of a count
- of the label usage
- Routine reports only each separate routine where a
- reference was made, this is probably the most
- useful option
- Line details the exact statement for every
- reference
-
- For the last two, each label has separate lists. For routines there
- is: defined, calls, called by; and for variables there is: declared,
- assigned, and referenced.
-
- Note that the main program itself is treated internally as a
- procedure, and so appears in the routine cross-reference.
-
-
- [3.2.1] Routine definition
-
- This gives the file and line numbers of the start and end of the
- routine.
-
-
- [3.2.2] Routine calls
-
- Lists the names of the routines called by this routine, and the line
- number of the call.
-
-
-
-
-
-
-
-
-
-
-
- Page 21
-
- ============================================================ BasCompress ====
-
-
-
- [3.2.3] Routine called by
-
- Lists the names of the routines that calls this routine, and the line
- number of the call.
-
- If the list is empty then BasCompress knows that this routine is not
- needed in the output program, and so will not include it.
-
-
- [3.2.4] Variable declaration
-
- Where a label was “declared”. By this BasCompress means it is a
- formal parameter of a routine, or explicitly declared as LOCAL.
-
-
- [3.2.5] Variable assignment
-
- When ever a variable appears at the start of a statement. This
- includes assembler statements.
- Note that BasCompress sometimes thinks variable assignments are
- references. This happens in the following cases:
-
- • variable is passed to a routine with RETURN parameters
- • assignment after a one-line IF that is without a THEN
-
- Here’s an example of the later:
-
- IF x<y x=y
-
- Because Bascompress doesn’t try to understand the conditional, it
- doesn’t know that a new statement has started and so can’t categorise
- the second reference to x as an assignment. See §8.2.
-
-
- [3.2.6] Variable reference
-
- Any other instance of a variable other than the above two is taken to
- be a reference.
-
- BasCompress will not recognise the fact that x += 1 is actually both
- an assignment and a reference.
-
- BasCompress will also fail to recognise that var!0 = 1 only
- references var and does not assign to it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 22
-
- ============================================================ BasCompress ====
-
-
-
- [3.3] Order
-
- There are many uses you can put to a list of labels, provided you can
- order them in the way you need. BasCompress allows you to specify as
- many levels of sorting as you would need, with all the types of
- ordering that are relevant to the labels!
-
- You can sort in either direction --- top to bottom, or the more usual
- bottom to top.
-
- These are the following sort types currently supported:
-
- Name in Ascii order
- Type for routines: function, procedure
- for variables: integer, real, string, integer
- array, real array, string array
- Dictionary by name, but as it would appear in a
- dictionary
- Location the location of the reference
- Usage for routines: number of times it is called
- for variables: sum of the assignments and the
- references
-
- Note the needed for multi-level sorting. You would normally sort
- labels by name, and type; and references by name, type, and location.
-
- Trying to sort labels by location has no meaning, and will result in
- a seemingly random order. So it is not possible to list routines in
- the order they were defined in.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 23
-
- ============================================================ BasCompress ====
-
-
-
- [4] The front end
-
- This describes the Wimp front end application. This allows the user
- to set up the parameters for the back end program in a friendly way.
-
-
- [4.1] Installation
-
- By default the front end enables throwback. This is a technique
- where a command line utility (eg the BasCompress back end engine)
- can communicate errors to a wimp application, such as SrcEdit, Zap,
- or StrongED.
-
- This causes the wimp application to display the errors in a window,
- where the user chooses an error/warning and the editor displays the
- appropriate source line, ready for editing.
-
-
- [4.1.1] Installing throwback
-
- For throwback to work, you require a support module called DDEUtils.
- This is an Acorn module that acts between the command line utility
- and the wimp application throwback server.
-
- Unfortunately, in order to distribute DDEUtils requires a Binary
- Distribution License from Acorn. Therefore only developers may
- distribute this module.
-
- Luckily, BasCompress comes with a (partial) functional replacement,
- called DDEUtilsCy. This supports all of the DDEUtils API, but has
- no functionality for any Prefix code (if you don’t understand this
- then it doesn’t concern you). It also requires the use of an Obey
- script to initialise some system variables.
-
- Because DDEUtilsCy only contains a subset of the real DDEUtils’
- functionality, the !BC.!Run file goes to great lengths to ensure
- that if the user has the real DDEUtils module, then this is used in
- stead of the replacement.
-
-
- [4.2] Starting
-
- A standard Archimedes application, just double-click the application
- icon in the directory display to install it onto the icon bar.
-
- For foreign users, see the appendix A describing the Message file.
-
-
-
-
-
-
-
-
-
-
-
-
- Page 24
-
- ============================================================ BasCompress ====
-
-
-
- [4.3] Overview
-
- Because the back end works on, and produces, a number of whole files
- the format of this application is slightly unorthodox.
-
- Basically you use the standard RISC OS method of dragging file icons
- to directory displays (to define the output files), and then drag a
- BASIC file onto the front end to invoke the back end application to
- compress it. This generates the new log, cross-reference, and output
- files.
-
- Not all of the types of output files need to be generated. Usually
- there is no need for a cross-reference. But, you will almost
- certainly want the log file defined, as otherwise you would not know
- what errors occurred, or anything else.
-
- It is almost a pre-requisite to have Edit running alongside this
- front end in order for you to view the log that the back end
- application produces. The loading of this log will normally be
- automatic.
-
-
- [4.3.1] Icon bar icon
-
- The icon bar icon shows some messages while the back end is active.
- This gives a visual reference to what is going on.
-
- Clicking SELECT on the icon bar icon brings the control window to the
- front of the window stack.
-
- Clicking ADJUST in the icon bar icon re-loads the last input file,
- using the new options. This is extremely handy for trying out new
- options on a file that generated an error.
-
-
- [4.4] Control window
-
- This is automatically opened to the center of the screen when the
- application starts. It allows you to quickly set up all the files to
- be used, and as a side effect it gives you the chance to open a menu
- somewhere other than in the bottom right of the screen!. The left-
- most three icon groups act just like the save as dialogue boxes to be
- found on the menu.
-
- The special file is defined by dragging a Text file onto this
- window. More special files can be defined by editing the text field,
- appending a comma separated list of file names.
-
-
-
-
-
-
-
-
-
-
-
- Page 25
-
- ============================================================ BasCompress ====
-
-
-
- [4.5] Main menu
-
- There is only one menu.
-
- Because the sub-menus are rather on the large side, it is recommended
- that you bring the menu up over the control window. This was the
- main reason for having a control window, as a convenient anchor for
- the menu.
-
-
- [4.6] Input
-
- This sub-menu defines various parameters affecting BasCompress’s
- analysis of the input file.
-
-
- Ignore exits from a routine (‘dumb’)
-
- BasCompress has two strategies for detecting the end of a routine, a
- ‘smart’ method (the default) and a ‘dumb’ method. The smart method
- will keep track of multi-line statements to detect an actual end of
- routine, the dumb method just parses until the next DEF FN/PROC.
-
- When enabled BasCompress will use the ‘dumb’ method. See §2.16.
-
-
- Allow multiply-defined routines
-
- It is better to leave this option un-ticked, so that if a routine is
- defined more than once an error is generated. This is the default.
-
- Ticking this option allows a routine to be defined more than once,
- with only warnings being given. See §2.10.1.
-
-
- Force malformed SWI’s to generate error
-
- Malformed SWI’s are those that aren’t simple strings, e.g. “X”+
- “Wimp_Poll”. With this enabled these generate an error, otherwise
- just a warning. See §2.5.
-
- This item will be disabled if ‘Convert SWIs to numbers’ item in the
- output sub-menu is turned on.
-
-
- Process as a library file
-
- This option allows the input file to be treated as a library file.
- This means that no main program is expected, and any undefined
- variables and routines do not generate an error. Of course, using
- this option is usually pointless without also disabling all label
- reductions.
-
- When turned on this item disables the item ‘Compress constant
- variables’ in the output sub-menu, as it is usually not very useful
- to have both these items enabled!
-
-
- Page 26
-
- ============================================================ BasCompress ====
-
-
-
- [4.7] Output
-
- This sub-menu allows you to tailor how much compression is applied to
- the output programs. Redundant spaces and comments are always
- removed, since there seems little point in using BasCompress without
- doing this.
-
- By default all compression is on.
-
-
- Save as
-
- This leads to a standard dialogue box, used to define the basic file
- that will be produced if the input is analysed without error.
-
- Note that currently the only way to determine whether a Basic,
- Absolute, or Squeezed file is produced is from the main control
- window.
-
-
- Keep initial REMs
-
- This feature is useful for retaining copyright messages in the
- BasCompressed file. By ‘inital’ it is meant everything up to the
- first routine definition. See §2.20.
-
-
- Concatenate lines
-
- Forces as many statements as possible onto each output line. This is
- usually very desirable as it produces quite substantially shorter
- code, but at the possible loss of a bit of execution speed. See §2.
- 13.
-
-
- Remove unused routines
-
- Because BasCompress can work out exactly which routines are, and are
- not needed in the final program, then it can remove unused routines.
- This is the default, and there is little point in disabling it, other
- than creating a full cross-reference.
-
-
- Remove constant variables
-
- BasCompress can recognise ‘constant’ variables, those that are only
- assigned once and have a very simple definition. This helps to
- reduce symbol table overloading. See §2.16.
-
- This item will be disabled if ‘Process as a library file’ in the
- Input sub-menu is turned on.
-
-
-
-
-
-
-
- Page 27
-
- ============================================================ BasCompress ====
-
-
-
- Remove constant ASC()
-
- When enabled this feature will recognise constructs of the form
- ASC(“string”) and ASC“s” and compress them down to the appropriate
- numbers. See §2.17.
-
-
- Remove NEXT variables
-
- BasCompress supports BasicV’s use of unnamed NEXT statement in a
- FOR/NEXT loop. It can remove any variables it finds after a NEXT
- statement, and cocatenate adjacent NEXT statements. See §2.19.
-
-
- Convert SWIs to numbers
-
- There doesn’t appear to be any reason to disable this. See §2.5.
-
- When turned off this will cause the following two items to be
- disabled.
-
-
- Parse numbers
-
- This toggles whether BasCompress will try to reduce a string of
- decimal digits. Hexadecimal and binary numbers are always
- compressed. See §2.4.
-
- List
-
- This leads to a simple sub-menu where you can specify the screen mode
- to use. When enabled, as BasCompress produces the output file it
- will switch to that screen mode and scroll the source and output in
- two separate columns. Although “pretty”, it is also pretty useless,
- as this takes at least an order of magnitude longer to do, what with
- all that screen scrolling and printing.
-
- Note that if throwback is enabled (as it is by default) then the back
- end is actually run in a TaskWindow. Thus the ‘listing’ is actually
- output to a task window. Thus showing the complete uselessness of
- this feature!
-
-
- Reduce variable names
-
- By default, all variable types are reduced. The only conceivable use
- for disabling the reduction of these would be to circumvent the use
- of EVAL or DATA variables, although BasCompress provides a much
- better method, via the use of Special files. See §2.11.
-
- The final option, ‘E’ suppression is used to stop BasCompress
- shortening any variables to a name beginning with an ‘E’. For the
- reason why this might be desirable, see §8.2.
-
-
-
-
-
- Page 28
-
- ============================================================ BasCompress ====
-
-
-
- Reduce routine names
-
- By default, all procedure and function names are reduced. The only
- reason for disabling the reduction of these would be to circumvent
- the use of function names used inside an EVAL construct, although
- BasCompress provides a much better method to handle this, via the use
- of Special files.
-
-
- [4.8] Log
-
- The log sub-menu controls what additional information may be inserted
- into the log file, along with the name of all files scanned and any
- warnings and errors.
-
-
- Save as
-
- This leads to a standard save as dialogue box, used to define the
- file to which the log will be dumped. This will be a standard Text
- file.
-
-
- Report multiple exits
-
- BasCompress needs to know when each and every routine ends. If it
- finds more than one exit it will report it. For large programs this
- can produce many warnings, and so these warnings can be disabled.
- See §2.8.3.
-
- This item will be disabled if you have selected ‘Ignore exits from a
- routine (‘dumb’)’, in the input menu.
-
-
- Report unknown SWI’s
-
- In order for BasCompress to convert a SWI string to a number the
- Module must be resident at the time of compression. If the module is
- not resident, then this warning will be given. This toggles the
- appearance of such warnings, and is usually left enabled. See §2.5.
-
- This item will be disabled if ‘Convert SWIs to numbers’ in the output
- menu is turned on.
-
-
- Report OVERLAY usage
-
- Because the parameter to an OVERLAY statement is a string array, it
- is not possible for BasCompress to know which files should be
- OVERLAY’ed. Therefore BasCompress emits a warning when it sees the
- token.
-
- If your program uses overlays then please read §2.18.
-
-
-
-
-
- Page 29
-
- ============================================================ BasCompress ====
-
-
-
- Report TOP usage
-
- BasCompress is unable to distinguish between the pseudo-variable
- ‘TOP’ and a possible sequence ‘TO P’ (without the space) which can
- occur in a FOR loop. See §2.21.
-
-
- Statistics
-
- This shows how many of each type of variable and routine there is
- altogether in the program. This includes all deleted labels.
-
-
- EVAL keyword, DATA keyword, READ keyword
-
- These will list out every line that contains such a keyword,
- indicating where BasCompress may introduce errors because of its’
- reduction of labels. Note that only the use of these keywords
- outside special routines is reported, as it is assumed the use of the
- keyword was fully handled by the Special file. Further note that
- DATA found outside any routine is just reported as unlinked.
-
-
- List input
-
- With this option ticked, the input basic is also listed inside the
- log file. This produces humongous files, as this is plain text Basic
- not tokenised Basic.
-
-
-
- [4.9] Special files
-
- Special files are used to help BasCompress to handle the EVALuation
- of variables. A special file consisting of a list of routines that
- are expected to contain this keyword, and/or a secondary list of any
- particular labels that must not be reduced.
-
- The writable menu item allows you to type in a full pathname. It is
- easier just to drag the file onto the control window, though.
-
-
- Warn undefined
-
- Normally it wouldn’t matter that you have told BasCompress about
- special routines that aren’t used in the input file. However there
- is still this option that will report superfluous definitions found
- in Special files.
-
-
-
-
-
-
-
-
-
-
- Page 30
-
- ============================================================ BasCompress ====
-
-
-
- Show expansion
-
- With this item ticked, every special label constructed will generate
- a warning message into the log file. This can be useful for showing
- what you think should appear, and what BasCompress thinks should
- appear.
-
-
-
- [4.10] Cross-reference
-
- From here you define all aspects of the (rather large) cross-
- referencing sub-system.
-
-
- Save as
-
- This leads to a standard save as dialogue box, used to define the
- file to which the cross-reference will be dumped. This will be a
- standard Text file.
-
-
- Include deleted
-
- When ticked, this will force all the superfluous routines and
- variables to be included in the cross-reference. This is usually not
- such a good idea, as the process of deletion removes all the
- reference information. For a full cross-reference, also disable the
- removal of unused routines (see Output), which leaves this
- information in tact.
-
-
- Reference order
-
- This leads to an order dialogue box (see below) used to set the
- sorting criteria for the references. This is probably best left as
- the default: Name, Type, Location.
-
-
- Variables, Routines
-
- These two items lead into identical sub-menus. They allow the cross-
- referencing to be defined for both independently.
-
-
- Verbosity
-
- This leads to a sub-menu where you can define the level of detail of
- the cross-referencing information. See §3.2.
-
-
-
-
-
-
-
-
-
- Page 31
-
- ============================================================ BasCompress ====
-
-
-
- Types
-
- Used to define what types of variables or routines are included in
- the cross-reference. Usually this would be all types, but sometimes
- you might only want to know about the integers, say. Just de-tick
- all the others.
-
-
- Order
-
- This dialogue box is quite complicated. Basically, you are trying to
- define several layers of ordering. First of all everything is sorted
- according to the left hand column. Now BasCompress goes through
- these sorted items looking for a sequence of items that are the same,
- according to this ordering. Now, for each sequence found it will
- sort them again using whatever you have defined in column two. This
- recurse on each smaller and smaller sub-sequences to the columns on
- the right.
-
- Obviously, it isn’t much use having two columns sorting by the same
- criteria, so BasCompress will not allow you to select it.
-
- You can delete a column by ADJUST clicking on the ordering already
- used. This will cause all columns to the right to shuffle one column
- to the left (this is quite a pleasing graphical effect!)
-
- It isn’t possible to have a “blank” column. If you attempt to create
- a blank column then your new column will be shifted to the left (yet
- another pleasing graphical effect!)
-
- It is possible to delete all columns. This will cause the output to
- appear in a seemingly random order. Not much use, apart from seeing
- how good the hashing function is!
-
- Ordering by location is only meaningful for references. Using this
- option for variables or routines will result in a (seemingly) random
- order.
-
- The Dict. standards for dictionary, and is similar to Name, except
- instead of ordering by ASCII, order as it would appear in a...
- (guess).
-
-
- [4.11] Choices Dialogue Box
-
- This dialogue box controls aspects of the front end application
- itself, not the back end. It grabs the input focus so that some
- keyboard short cuts can be used, must notably RETURN and ESCAPE.
- Also the bottom row of buttons can be pressed using F2, F3, etc..
-
-
- Set
-
- This accepts the above values for the current session of
- BasCompress. For the effects to be permanent use either Save or Save
- full. Also see the note below about using outline fonts in dialogue
- boxes.
-
- Page 32
-
- ============================================================ BasCompress ====
-
-
-
- Cancel
-
- This disregards any edits you have made to the above options.
-
-
- Save full
-
- Along with all the expected switches and sort ordering, also saved
- with the choices are the default names of the log, cross-reference
- and output files. This option saves the full pathname of each of
- these files, and would be used while developing a project, to save
- dragging the log and output files each session.
-
-
- Save
-
- As Save full but only the leaf names of the log, cross-reference and
- output files are saved. This is handy for more generic
- environments. For instance, if you always call your Wimp programs
- Wimp, then to make a standard application from this, the output file
- would be !RunImage, and this would be a better default to have than
- Output.
-
-
- Default
-
- This sets up everything to a default state, for when you’ve made a
- complete mess of the options. This default state can also be
- achieved by deleting the Choices file inside !BC.!fe, and restarting
- the application.
-
-
- Run BasCompress’ed file
-
- With this option ticked whenever an output file is specified it is
- immediately executed after being generated. This is useful while
- constructing a Special file, so the program can proceed and report
- the missing variables found!)
-
-
- Load log file
-
- If a log file was specified then this is “opened” immediately after
- it is generated. On a properly set up system this would cause Edit
- to be loaded up automatically if necessary, and replace any version
- currently held if Edit is already resident. Multi-tasking at its
- best. Note that if you edit the “old” log file, then this smoothness
- is ruined, because Edit will open up a new window containing the new
- version. C’est la vie.
-
-
- Load cross-reference file
-
- Same as the above option, but loads the cross-reference file
- generated, if any.
-
-
-
- Page 33
-
- ============================================================ BasCompress ====
-
-
-
- Name output as <Main>
-
- This is a kludge to reduce the size of both cross-reference and log
- files. As any Wimp application must use the full pathname of every
- file, this is what is passed to the back end application. However
- this causes the full pathname to be printed in every error message
- and reference. As a stop gap, this front end can be told to set the
- environment variable <Main> to the full pathname, and pass this to
- the back end application. It does mean you don’t see the actual name
- of the file being processed, but that usually isn’t a problem as you
- know that anyway.
-
-
- Output file leaf name same as input
-
- This option is useful when compressing lots of files from one
- directory to another, for example having compressed versions of all
- your library files. Having defined the output directory, the full
- pathname is constructed from this directory and the leaf name of the
- input file, saving quite a bit of typing.
-
-
- Use outline fonts in dialogue boxes
-
- BasCompress comes with two versions of all its’ windows − with and
- without outline fonts. Users of low-resolution monitors may prefer
- to use the system font versions. Also, RiscPC users may have to use
- the “System font” windows for two reasons: first because the
- fontified windows use fonts at a different size (slightly larger for
- low resolution users) which looks ugly but more importantly because
- of a bug in the Window Manager that causes clicks on (genuine) font
- icons to cause the Wimp to “forget” the text font :(
-
- Note that for historical reasons changes to this option are not
- updated immediately but only take effect the next time BasCompress is
- run.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 34
-
- ============================================================ BasCompress ====
-
-
-
- 5 The back end
-
-
- This chapter describes the underlying CLI program, and how to use it
- effectively.
-
- By default all text output is to the screen. This can be redirected
- to separate log and cross-reference files, as required.
-
-
- [5.1] Invoking
-
- Double-clicking on the application directory from a directory display
- will automatically start up the Wimp front end application. This is
- because no parameters were passed to the !Run file.
-
- If any parameters are passed to the application, i.e. you activated
- it from a command shell then the back end application is called
- direct.
-
- This application requires the floating point emulator module to be
- resident. This is automatically loaded from the current system
- resources. (Floating point arithmetic is only used to analyse and
- output decimal numbers, this can be disabled and so there will be no
- need to load the floating point emulator --- this is not a
- recommended procedure, though).
-
- Also required to be resident is the authors’ own library module:
- CAssembler.
-
- These modules are automatically loaded if not resident.
-
-
- [5.2] Installing
-
- There are two methods of installing BasCompress for easy use from a
- shell. One is to just install the application onto your Run$Path,
- and use it by *!BC file.
-
- This has the disadvantage in that you must remember the !. The much
- better alternative is to use the Alias$BasCompress that is set up for
- you in the !Boot file. Thus it is only required to run this !Boot
- file in your boot-up sequence, and then call BasCompress by
- *BasCompress file.
-
- In both the above it is essential that the !Run file gets executed,
- as this ensures auxiliary modules are resident and checks that there
- will be enough memory to start the application.
-
-
-
-
-
-
-
-
-
-
- Page 35
-
- ============================================================ BasCompress ====
-
-
-
- [5.3] Environment variables
-
- Because the CLI limits command lines to (a paltry) 256 bytes, several
- tricks were used in order to make the front end application work
- effectively with the back end program (with full pathnames). These
- can be put to great advantage for CLI users. In all cases an unset,
- or empty variable is ignored.
-
- BasCompress$Options
- This should be a string of the same format as a
- normal parameter set, except missing the name of the
- input file (of course). With this you can override
- any of the built-in default values with your own
- preferred set.
-
- BasCompress$Out
- The name of the tokenised basic file produced.
-
- BasCompress$Log
- The name of the log file produced.
-
- BasCompress$XRef
- The name of the cross-reference file produced.
-
- BasCompress$Special
- The name of the special file(s) input (a comma
- separated list).
-
- BasCompress$Path
- A comma separated list of directories used to find
- Special files
-
- It should be noted that the front end application resets all of these
- variables (except the Path), so keep this in mind.
-
-
- [5.3.1] DDEUtils and long command lines
-
- BasCompress knows about the long command lines supported by the
- DDEUtils module. This is a method of passing a command line larger
- than 256 bytes to a child process.
-
- This provides a much more elegant solution than the use of
- environment variables. The Wimp front end application now uses this
- feature if throwback is enabled, but uses the environment variables
- otherwise.
-
-
-
-
-
-
-
-
-
-
-
-
- Page 36
-
- ============================================================ BasCompress ====
-
-
-
- [5.4] The CLI parameters
-
- The ordering of the parameters has been carefully set up so there is
- usually no need to name any parameters.
-
- BasCompress [-In] <file>
- [[-Out <file>]
- [[-Special] <files>]
- [[-Log] <file>]
- [[-XRefFile] <file>]
- [[-XRef] <n>]
- ...
-
- So for normal work you would have set up BasCompress$Options and
- you’d just do BasCompress @.MyProg @.Result @.Special @.Log “” 0.
- There is a -Help option to display a brief description of the
- available options.
-
- As with all all native Archimedes applications, switches toggle the
- previous state (OS_ReadArgs does not allow -f and +f).
-
-
- [5.4.1] Input
-
- -Dumb ignore ENDPROCs (OFF) §2.8.3
- -In <file> this must always be given
- -Library ignore undefined routines & main program
- (OFF) §2.8.1
- -MultiDEF allow multiple definitions of the same
- routine (OFF) §2.10.1
- -SWIBad fault malformed SWI names (OFF) §2.5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 37
-
- ============================================================ BasCompress ====
-
-
-
- [5.4.2] Output
-
- -ASC decompose ASC(“X”) to number (ON) §2.16
- -CLI prefix code to write env with
- BasCompress$CLI (OFF) §2.22
- -CVar constant variables are compressed (ON) §2.17
- -InitialREM keep REMs before first routine def (OFF)
- §2.20
- -ListOut <n> echo output in screen mode <n> (OFF) §4.6
- -NEXTs remove NEXT variables (ON) §2.19
- -Number analyse decimal numbers (needs FPEmulator)
- (ON) §2.4
- -Out <file> output file (see BasCompress$Output)
- -ReduceVar <type>
- -ReduceRtn <type>
- -Reduce <type> reduce these types of labels (irsIRSpf) §2.11
- -Single no concatenation of output lines (OFF) §2.13
- -SWI convert SWI strings to numbers (ON) §2.5
- -Unused delete unused routines and variables (ON)
- §2.8
-
- <type> is a string of these letters:
- p procedure
- f function
- r real variable
- i integer variable
- s string variable
- R real array variable
- I integer array variable
- S string array variable
-
-
- [5.4.2.1] Output listing
-
- First the mode is selected (-1 would select the current mode), and an
- appropriate warning or error generated if that mode is not
- available. Next a blue-on-white colour scheme is selected. Then the
- display is split into two columns, with the left column about 61% of
- the screen wide (80 columns in mode 16). The source listing is
- scrolled here. On the right column the output is scrolled.
-
- The source listing does not include any deleted routines, but does
- include all inter-routine junk. The output listing is as per the
- output file, in its’ entirety. The right column is only updated each
- time a whole line has been amassed, which could take a while if
- maximum compression is selected.
-
- There isn’t really much use for this option, as the time taken to
- scroll the screen takes far too long.
-
-
-
-
-
-
-
-
-
- Page 38
-
- ============================================================ BasCompress ====
-
-
-
- [5.4.3] Log
-
- -DATA log lines containing DATA (ON)
- -EVAL log lines containing EVAL (ON)
- -Goto log lines containing line numbers (ON)
- -List echo input to log (OFF)
- -Log <file> output file (see BasCompress$Log)
- -OVERLAY suppress warnings if see ‘OVERLAY’ (OFF)
- §2.18
- -READ log lines containing READ (ON)
- -Stats log program statistics (ON)
- -SWIExist report unknown SWI strings (ON) §2.5
- -TOP suppress warnings if see ‘TOP’ (OFF) §2.21
- -WEndRtn report conditional exits (ON) §2.8.3
-
-
- [5.4.4] Special
-
- -Special <files> use comma list of <file> to resolve implicit
- usages (see BasCompress$Special and
- BasCompress$Path)
- -UnusedS report undefined special routines (OFF)
- -WSpLabel report label expansion results (OFF)
-
-
- [5.4.5] Cross-reference
-
- -XRefFile <file> output file (see BasCompress$XRef)
-
-
- [5.4.5.1] What gets cross-referenced
-
- -Deleted xref includes deleted variables and routines
- (OFF)
- -XIncVar <type>
- -XIncRtn <type>
- -XInc <type> xref these types of labels (irsIRSpf) §3.1.1
-
- <type> is a string of these letters:
- p procedure
- f function
- r real variable
- i integer variable
- s string variable
- R real array variable
- I integer array variable
- S string array variable
-
-
-
-
-
-
-
-
-
-
-
- Page 39
-
- ============================================================ BasCompress ====
-
-
-
- [5.4.5.2] How much cross-referencing to be done
-
- -XRef <n> level of xref detail for both routines and variables
- §3.2
- -XRtn <n> level of xref detail for routines (0)
- -XVar <n> level of xref detail for variables (0)
-
- <n> evaluates to a number from 0 to 4:
- 0 None
- 1 Existence --- name
- 2 Global --- name / count
- 3 Routine --- reference to routine level
- 4 Line --- reference to line level
-
-
- [5.4.5.3] Order of cross-referencing
-
- -Sort <sort> order of all variable, routine, and reference sorting
- §3.3
- -SRef <sort> order of cross–references (NTP)
- -SRtn <sort> order of routines (TN)
- -SVar <sort> order of variables (TN)
-
- <sort> is a string of these letters:
- N sort by name
- T sort by type
- D sort by name (in dictionary sense)
- P sort by position in source
- U sort by usage
-
- e.g. to sort by usage, name, then type = “UNT”.
-
- Lower case letters order top to bottom.
-
-
-
- [5.5] Error handling
-
- By errors, it is meant system errors (i.e. those generated by calls
- to the operating system).
-
- Admittedly, error handling is quite primitive in BasCompress. All
- calls to the operating system are tested for error condition, and if
- set this is immediately propagated all the way back to the user, with
- an appropriate message dumped in the log file.
-
- Errors occurring before the log file is opened are reported to the
- screen.
-
- In any case, an error safely closes all files opened by this
- application.
-
-
-
-
-
-
-
- Page 40
-
- ============================================================ BasCompress ====
-
-
-
- [5.6] Escape handling
-
- As with error handling, this is fairly primitive.
-
- BasCompress can be aborted at any time, terminating immediately after
- closing all open files.
-
- Note that during the middle of program output the Basic file will be
- Type’d to Data, as a safeguard against loading it into BasicV. (This
- does not handle zero-length files very well --- it hangs the
- machine).
-
-
- [5.7] Hourglass
-
- The hourglass is used to indicate BasCompress’s progress.
-
- During parsing, the percentage shows how much has already been
- analysed. Note that because BasCompress can not know the total
- length of input beforehand, the percentage may actually go backwards
- as LIBRARY statements are parsed.
-
- During cross referencing, there is no percentage, but the bottom
- L.E.D. is on.
-
- Finally, during program output an accurate percentage is displayed,
- with the top L.E.D. on.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 41
-
- ============================================================ BasCompress ====
-
-
-
- [6] Special files
-
-
- This chapter explains the format of the Special files. These are
- auxiliary Text files used to give BasCompress some more information
- to help it compress better. See also the examples supplied on disc.
-
-
- [6.1] Why need special files?
-
- Special files are used to tell BasCompress how to cope with the
- following types of situation:
-
- • EVAL(“Variable”)
- • DATA Variable
- • LIBRARY “%.”+ RoutineParameter$
- • EVAL(“FN_”+ RoutineParameter$)
- • definitions from RETURN parameters
- • OVERLAYs
-
- Because BasCompress reduces labels (see §2.11) using a global
- context, at run-time when BasicV tries to find these labels in the
- current context, it fails. Special files tell BasCompress which
- labels not to compress, either explicitly as in the first two cases
- or above, or implicitly (from routine parameters) as in the later two.
-
- You may also need to tell BasCompress about variables that it thinks
- are constant, but actually get assigned as a result of a RETURN
- parameter in a routine.
-
-
- [6.2] The Special file
-
- Special files are just plain Text files, in the format specified
- below. BasCompress allows more than one Special file to be defined
- (using a comma separated list), but it is far easier to use the
- #include directive inside a Special file, as shown below.
-
- Special files are found using the environment variable
- BasCompress$Path. By default this is not set up, but you may like to
- create a sub-directory BasCompress in your library and set this
- variable to “,%.BasCompress.” in your boot-up sequence (note the
- trailing dot, as with all path variables). Here you would keep the
- one or two special files that handle your particular set of library
- files, and BasCompress will find them for you without you having to
- type in a full pathname every time.
-
-
-
-
-
-
-
-
-
-
-
-
- Page 42
-
- ============================================================ BasCompress ====
-
-
-
- [6.3] Format of a Special file
-
- The format of a Special file is fairly simple.
-
- Basically, (for variables) all you’re trying to tell BasCompress is:
-
- • routine X has a string in parameter Y
- • inside routine X there is an EVAL
- • this constructs a new label Z from Y
- • don’t reduce this label Z
-
- So all you do is give the name and expected parameters of a routine
- and tell BasCompress how to construct label Z.
-
-
- [6.3.1] Defining routines
-
- You give the name of a routine by:
-
- procedure foo(1)
-
- or,
-
- function bar(,1)
-
- The brackets are necessary if a routine doesn’t have any parameters.
-
- The procedure definition above tells BasCompress to expect a (simple)
- string expression to be passed to the procedure foo at every call, as
- the sole parameter. The function definition says the first parameter
- is not important, but the second parameter will be a simple string.
-
- These prototypes are checked against what is actually found in the
- program proper, and an appropriate error generated if they don’t
- match.
-
- There can be up to ten distinct string parameters [0-9], but you’ll
- probably only ever need just one.
-
-
- [6.3.2] Defining globals
-
- Sometimes the EVAL isn’t in any particular routine (or is used inside
- a nested routine structure not amenable to the above simplification),
- so you’d like to give the name of the labels not to reduce just
- once. This is easy because at the start of each Special file,
- BasCompress puts an implicit declaration of the main program as a
- routine, with no parameters. So you’d just start defining the global
- labels as normal routine labels.
-
-
-
-
-
-
-
-
-
- Page 43
-
- ============================================================ BasCompress ====
-
-
-
- [6.3.3] Labels
-
- First of all an example:
-
- PROC_List(a, “Zappa”, “Good”)
- ...
- :
- DEF PROC_List(RETURN x, y$, z$)
- IF EVAL(“Frank_”+ y$)<>0 THEN
- x += EVAL(“FN_”+ z$+ “_Name(Cy%)”)
- ENDIF
- ENDPROC
-
- this would be implemented as:
-
- procedure _List(, 1, 2)
- real Frank_\1
- function _\2_Name
- integer Cy%
-
- Note the spaces to the left of the implicit declarations, and the
- case of the keywords as both of these are important. Also note the
- need to declare Cy% as another variable that must not be shortened.
-
- There is no attempt to verify that the <n> used was declared in the
- parameter list, but all undeclared <n> are reset to the empty
- string. Also there is only rudimentary checking done on the
- expansion template, so be sensible.
-
- The following table shows the exact words to use --- note they must
- be lower case:
-
- real a real variable e.g. pi_by_2
- integer an integer variable, e.g. count%
- string a string variable, e.g name$
- real_array a real array variable, e.g. times()
- integer_array an integer variable, e.g. books%()
- string_array a string variable, e.g. titles$()
- procedure a procedure, e.g. PROC_total
- function a function, e.g. FNmin
- library load library file, e.g. %.Wimp
-
- BasCompress can currently interpret the simple string in a number of
- ways. These template expansion types are:
-
-
- [6.3.3.1] Verbatim
-
- \<n> causes the formal parameter <n> to be substituted verbatim.
-
-
-
-
-
-
-
-
-
- Page 44
-
- ============================================================ BasCompress ====
-
-
-
- [6.3.3.2] Comma separated
-
- ,<n> treats parameter <n> as a comma separated list of strings to
- substitute, with optional spaces after each comma.
-
- Each value is extracted from the string in turn. Note that the
- string is expected to contain real variables only, i.e. no %, $, or (.
-
- For example:
-
- PROC_Music(“Zappa,Varese,Stravinsky,Belew)
- ...
- :
- DEF PROC_Music(p$)
- LOCAL i, dummy
- i = INSTR(p$, “,”)
- WHILE i>0
- dummy = EVAL(“FN_”+ LEFT$(p$, i-1))
- p$ = MID$(p$, i+1)
- i = INSTR(p$, “,”)
- ENDWHILE
- ENDPROC
-
- could get coded as:
-
- procedure _Music(1)
- function _,1
-
-
- [6.3.3.3] Full pathname
-
- @<n> parameter <n> is considered as a full pathname, and just the
- leaf name is substituted.
-
- For an example see §6.3.4 below.
-
-
- [6.3.3.4] Wimp menu
-
- [note this uses the guillemotright glyph (character 187), but will be
- represented here as ‘>>’.]
-
- >><n> <n> is taken to be a Wimp menu string. This means that after
- “>” and “:” a variable name is expected, terminated by a
- comma or the EOS.
-
- It is assumed that the implicit variables are all of the same type.
- If not just define several rules, one for each type.
- For example
-
- PROC_menu(“Prog,Info>Info%,dSave as>SaveAs,Quit”)
-
- may get coded as follows:
-
- procedure _menu(1)
- integer >>1
- real >>1
-
- Page 45
-
- ============================================================ BasCompress ====
-
-
-
- [6.3.4] Variables as regular expressions
-
- As well as the above special meta-characters BasCompress will now
- allow you to specify special variables (not routines or libraries) as
- a regular expression (a fancy wildcard expression). This means that
- instead of specifying one variable, you specify any variables that
- match a pattern.
-
- Special variables so specified can not contain any parameter
- substitution commands. They also behave in a slightly different
- manner.
-
- To process special variables defined as regular expressions
- BasCompress must use a separate pass, between parsing and output.
- This scans every variable (of the particular type) to see if it
- matches the specified pattern. If so, then the variable is flagged
- as being un-renamable − as expected.
-
- So what is a regular expression, and why would you want to use it?
- For a full description of regular expressions please see Appendix B,
- but all the useful features (two of them!) will be shown in the
- examples below.
-
- You would want to use regular expressions to specify a range of
- variables with the same sort of name − instead of specifying every
- single one individually. Eg say you have defined many constants such
- as ‘Wimp_Initialise’, ‘Wimp_CloseDown’, ‘Wimp_GetRectangle’, etc. and
- then used these constants in some DATA statements. Instead of having
- a (long) list of these variable names in the special file you would
- recognise that all of the variables begin with the pattern ‘Wimp_’
- and tell BasCompress to mark all such variables as unrenamable.
-
-
- [6.3.4.1] Example patterns
-
- Here’s how you would write the above example in a special file:
-
- procedure dummy()
- real Wimp_.*
-
- the important bit being the “.*”. This should be read as “any
- character“, ”repeated 0 or more times“. Ie as long as a variable
- starts with the five characters “Wimp_” the pattern is matched.
-
- Another frequent case is when variables have the same postfix --- eg
- the pattern:
-
- integer .*CMOS\>
-
- would match all integers that end (“\>” means “match end of
- variable“) in the letters CMOS, ie MosROMFrugalCMOS%, FontMaxCMOS%,
- etc... The specification that CMOS be at the end stops, say,
- MyCMOSvar% being matched by the pattern, as it otherwise would if
- this were not included.
-
-
-
-
- Page 46
-
- ============================================================ BasCompress ====
-
-
-
- [6.3.4.2] Limitations
-
- Although a regular expression may be defined dependent on a special
- routine being called, this fact is currently ignored − all special
- variables specified using a regular expression are used during the
- pass. For this reason it is probably worthwhile to place all wild-
- card specifications as global − ie in the main program section of the
- special file. This limitation will not last long.
-
- Currently a variable that is recognised as matching a pattern is
- flagged as being referenced from the main program (in the cross
- reference) and not inside the special routine that specified the
- wildcard − but this will change in a later version.
-
-
- [6.3.5] Libraries
-
- As well as labels, libraries may be implicit. For example, here’s a
- simple library handler:
-
- PROC_Load_Library(“<Basic$Lib>.Wimp”, 2)
- ...
- :
- DEF PROC_Load_Library(f$, v)
- LOCAL x
- LIBRARY file$
- x = EVAL(“FN_Init_”+ FNleaf(f$))
- IF EVAL(“Version_”+ FNleaf(f$))<v THEN
- ERROR 1, “Library too old”
- ENDIF
- ENDPROC
-
- Well, in real life you’d set up error handlers and note which
- libraries have already been loaded, but you get the idea. This could
- be coded as follows:
-
- procedure _Load_Overlay(1,)
- library \1
- function _Init_@1
- real Version_@1
-
- Note the use of @<n> to extract the leaf name.
-
- In the output program the entire statement containing the LIBRARY is
- removed.
-
- Note that because BasCompress analyses the program in a linear
- fashion, the order of library routines may well be different from
- that used in the uncompressed program, (see §2.10).
-
-
-
-
-
-
-
-
-
- Page 47
-
- ============================================================ BasCompress ====
-
-
-
- [6.3.6] Overlays
-
- Overlays may be specified as inline comments (§2.18.2) or in the
- special file.
-
- For most common purposes inline comments will suffice, but for complex
- programs that possibly use routines to specify members of the string
- array passed to OVERLAY, then you may use the special file keyword
- ‘overlay’ to handle such cases.
-
- For example:
-
- procedure _Load_Library(1,)
- overlay scsi::cheepnis.$.source.code.app.\1
-
- would be a typical use.
-
-
- [6.3.7] Include files
-
- It is possible for special files to include other special files.
- Thus you will probably set up BasCompress$Path and a special file to
- handle your own set of standard libraries, and then...
-
- #include mylibs
-
- somewhere in the special file for each particular program. (Note
- that there are no spaces to the left of the #include, and don’t put
- any quotes on the name either).
-
- Nesting level is not limited, and you can recurse. This will result
- in an infinite loop, with the only resort being to press escape to
- quit, and then examine the log file.
-
-
- [6.4] Limitations
-
- There can only be 250 odd total Special routines defined. If any one
- actually reaches this limit, then contact the author, it’s easy to
- alter --- at the expense of a slight increase in memory usage.
-
- There is of course one major limitation in that you have to specify
- the name of all the special files before processing the program. It
- would be nice to set up a system whereby if the program (maybe
- implicitly) loads in library X, then load up special file Y. However
- this would require re-finding all calls to the (new) Special
- routines --- something that seems quite hard to do, sigh.
-
- Finally, you’d like to be able to take into account the scope of the
- variables so only the use of variables in scope are not reduced. But
- since BasicV only has one scope, this is not possible to implement
- safely, without some explicit help from the programmer by marking the
- scope of variables in some way.
-
-
-
-
-
- Page 48
-
- ============================================================ BasCompress ====
-
-
-
- [7] Errors
-
-
- [7.1] Overview
-
- Errors and warnings can be generated at various stages of the game.
- They all look the same and are all sent to the current log (file /
- screen). The format is:
-
- file 1234 warning 3: message
-
- If there is no filename, then it indicates the error is global in
- scope, for example the “undefined routine” error generated when all
- files have been parsed.
-
- Warnings report non-fatal deficiencies. Errors report a major
- problem, and will stop any output file being generated.
-
- As with all text used by BasCompress, these error texts are held in
- the Messages file.
-
- It is worth pointing out that many warnings and errors may be
- generated after the seemingly innocent warnings 9 and 10. This means
- that BasCompress may have lost touch with what routine is being
- defined, and starts interpreting the junk inbetween routines as
- genuine code. So do check the log file from the start.
-
-
- [7.2] Warnings
-
- Most of the warnings are self explanatory.
-
-
- 1:Expecting PROC or FN after DEF
-
- In standard Basic, these are the only valid things after a DEF. This
- warning has never been encountered in debugged source!
-
-
- 2:DEF inside a routine
-
- This is generated because an earlier routine did not exit cleanly,
- and the program believes you are still in this routine. You need to
- fix the errant routine by terminating it properly, or simply
- appending a dummy routine end (ENDPROC or = <expr>).
-
- Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 3:Unexpected period ‘.’
-
- A period on it’s own is treated as the start of a number (e.g. “.
- 7”). This warning is generated if a statement starts with a period
- and it is not in the assembler.
-
-
-
-
- Page 49
-
- ============================================================ BasCompress ====
-
-
-
- 4:Mismatched quotes ‘“’
-
- Every line should have matching quotes.
-
-
- 5:Malformed hexadecimal number
-
- It is expected that a digit or a letter [0-9a-fA-F] comes after an &.
-
-
- 6:Malformed binary number
-
- It is expected that a 0 or 1 comes after a %.
-
-
- 7:Line number reference found
-
- This is given if line numbers are found in any libraries, since there
- is no valid reason for them being there.
-
-
- 8:Expecting routine name after PROC or FN
-
- A non-label character was found after one of these tokens. This very
- unlikely.
-
- 9:ENDPROC not at end of procedure
-
- This is generated if ENDPROC is found on a line containing an IF, i.
- e. it is ambiguous as to whether this is the genuine end of the
- procedure. Most of the time this causes no problems, but for short
- routines where this is the only way it exits then BasCompress will
- get confused as to the exact end of the routine. In this case you
- must either re-code the routine (recommended) or insert a dummy
- routine terminator (ENDPROC or = <expr>).
-
- Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 10:= not at end of function
-
- This is generated if an “= <expr>” is found on a line containing an
- IF, i.e. it is ambiguous as to whether this is the genuine end of the
- function. Most of the time this causes no problems, but for short
- routines where this is the only way it exits then BasCompress will
- get confused as to the exact end of the routine. In this case you
- must either re-code the routine (recommended) or insert a dummy
- routine terminator (ENDPROC or = <expr>).
-
- Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
-
-
-
-
-
-
- Page 50
-
- ============================================================ BasCompress ====
-
-
-
- 11:Code found on last line of function
-
- There were more statements on the same line as the terminating “=
- <expr>” statement. Since these will never be executed by Basic then
- they should be removed. This warning could well turn up quite often
- if BasCompress is fed the output of other squashers.
-
-
- 12:Expecting a string after LIBRARY/INSTALL
-
- In order to be able to load in libraries BasCompress expects a simple
- constant string expression to follow these keywords. If this is not
- the case then you will need to set up a Special file to handle this
- situation. This warning is suppressed if inside a Special routine.
-
-
- 13:OVERLAY not parsed, use special file or inline comment
-
- The OVERLAY keyword can not be parsed by BasCompress and needs
- some help. See §2.18.
-
-
- 14:Unexpected ‘[’
-
- A running total of square brackets is kept. This indicates that
- something like “LDR R0, [[R1...]” was found.
-
-
- 15:Unexpected ‘]’
-
- A running total of square brackets is kept. This indicates that
- something like “LDR R0, [R1...]]” was found.
-
-
- 16:ENDPROC inside a %s structure
-
- Found a conditional exit from a procedure --- this indicates a bad
- programming style.
-
- Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 17:= inside a %s structure
-
- Found a conditional exit from a function --- this indicates a bad
- programming style.
-
- Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
-
-
-
-
-
-
-
-
- Page 51
-
- ============================================================ BasCompress ====
-
-
-
- 18:Conditional %s
-
- Found a conditional termination of a multi-line structure --- this
- indicates a bad programming style.
-
- This may occur on lines like the following:
-
- IF x>0 THEN WHILE x>0:y+=FNy(x):x-=1:ENDWHILE
-
- Unfortunately BasCompress does not like this because it expects all
- multi-line constructs to start unconditionally. To cure this split
- the one-line IF into a multi-line IF.
-
- Alternatively put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 19:Too many ‘(’ found
-
- A running total of ellipsis is kept. This indicates something like
- “(1+2)(” was found.
-
-
- 20:Unexpected ‘)’ found
-
- A running total of ellipsis is kept. This indicates something like
- “(1+2))” was found.
-
-
- 21:Routine %s already defined at %s
-
- This warns about multiply-defined routines. Since there are
- sometimes very good reasons for doing this this warning can be
- suppressed.
-
-
- 22:Malformed decimal number
-
- A bad decimal number was found. A decimal number is something
- beginning with a digit or a period and continuing as expected. The
- form of the number is always checked, but the compression may be
- turned off.
-
-
- 23:The (global) special routine %s is not defined
-
- anywhere
- This speaks for itself. It is only generated if the user has asked
- for it, as it is not usually relevant.
-
-
- 24:SWI name missing, or not simple
-
- It is normal to just have a string, variable, or number immediately
- after a SYS (SWI). This indicates that found something else ---
- which may indicate a syntax error.
-
-
-
- Page 52
-
- ============================================================ BasCompress ====
-
-
-
- 25:SWI ‘%s’ is unknown
-
- The operating system has no record of what this SWI means. This
- indicates that either the module is not loaded at the time of
- compression, or it is misspelt. BasCompress will leave it as it is,
- producing longer and slower code.
-
-
- 26:Can’t change to screen mode %d
-
- If the listing Mode could not be found, but a suitable alternative
- was possible.
-
- 27:Special variable %s has been used
- 28:Special routine %s has been used
- 29:Special library %s has been used
- 30:Special overlay %s has been used
-
- These warnings are generated if the user has turned them on. They
- show the results of label expansion done at the instance of a call to
- a Special routine.
-
- 31:Found TOP, treated as ‘TOP’ and not ‘TO P’
-
- BasCompress may fail to remove a constant variable ‘P’ if this
- warning occurs. See §2.21.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 53
-
- ============================================================ BasCompress ====
-
-
-
- [7.3] Errors
-
- Any errors encountered will stop the final output phase, but the
- program will soldier on parsing, so you can rectify all the errors in
- one hit.
-
-
- 2:ENDPROC found in a function
-
- This invariably follows warning 2, about DEF found inside a routine,
- which itself follows a warning 10, because the previous function did
- not terminate cleanly.
-
- A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 3:= found in a procedure
-
- This invariably follows warning 2, about DEF found inside a routine,
- which itself follows a warning 9, because the previous procedure did
- not terminate cleanly.
-
- A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 4:Routine %s already defined at %s
-
- It’s either an error or a warning (21), and this is the error.
-
-
- 5:File error: %s
-
- Since there is minimal file accessing done (files are loaded in one
- hit), this usually just reports not being able to find a particular
- file/invalid file name --- it is dependent on the underlying filing
- system.
-
-
- 6:End of file in middle of routine
-
- It is invalid for a routine to span across a file boundary.
-
-
- 7:Too many files (>254)
-
- I can’t foresee anyone getting this error message! It is unlikely
- that this limitation would be lifted, either.
-
-
- 8:Undefined routine: %s (used %s)
-
- Generated after all files have been parsed, it warns of routines used
- but never defined. These are usually obscure routines only called in
- error handlers. If you know for sure that this routine will never be
- called, just put an empty version in your main file to suppress this
- error.
-
-
- Page 54
-
- ============================================================ BasCompress ====
-
-
-
- 9:Undefined variable: %s (used %s)
-
- Not generated.
-
-
- 10:FOR not at start of statement
-
- This may be of some use --- not much, but what the hey? (Maybe be on
- a one-line IF)?
-
-
- 11:Escape pressed, parsing aborted
-
- Not generated. Escapes just terminate program immediately in the
- current version.
-
-
- 12:File %s does not have a Basic file type
-
- This program only accepts tokenised Basic files --- maybe the file is
- just not Type’d correctly. (Could be that it was saved under the CFS
- or some such, and you only gave the SCSIFS?)
-
-
- 13:File %s is too small to be a Basic type
-
- A rudimentary check on each Basic file is done --- this is generated
- if it fails.
-
-
- 14:File is corrupted/not basic
-
- Each line of tokenised Basic has a header. As the file is parsed
- each header is checked and if invalid this error is generated and
- parsing of the file is aborted.
-
-
- 15:Escape pressed, xref aborted
-
- Not generated. Escapes just terminate program immediately in the
- current version.
-
-
- 16:Escape pressed, compression aborted
-
- Not generated. Escapes just terminate program immediately in the
- current version.
-
-
-
-
-
-
-
-
-
-
-
- Page 55
-
- ============================================================ BasCompress ====
-
-
-
- 17:Unexpected %s in a %s structure
-
- This detects any foul-ups in multi-lined structures. The Basic
- interpreter allows some of these through without reporting an error.
- These errors allow you to fix the (very probably) mistakes. See
- warning 18.
-
- A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 18:Unexpected %s
-
- As error 17 above, but obviously outside any surrounding structure.
-
-
- 19:End of file in middle of assembler
-
- A special case of error 6, i.e. a routine did not end before the end
- of a file was found.
-
-
- 20:OTHERWISE not at start of line
-
- A simple error for a simple mistake.
-
-
- 21:WHEN not at start of line
-
- A simple error for a simple mistake.
-
-
- 22:Computed GOTO/GOSUB found
-
- Now, I ask you, is this how to program? BasCompress will refuse to
- work with such things, and who can blame it?
-
-
- 23:INSTALL/LIBRARY not at start of line
-
- This indicates a syntax error, probably. Or maybe an IF without a
- THEN, who knows?
-
-
- 24:INSTALL/LIBRARY can not be on a conditional line
-
- If you must, then split into a multi-line IF and try again.
-
-
- 25:The special routine ‘%s’ was declared as having different parameters
- from those found here
-
- The number of parameters do not match --- probably a wrong number of
- commas in the Special file.
-
-
-
-
-
- Page 56
-
- ============================================================ BasCompress ====
-
-
-
- 26:The special routine ‘%s’ wants a string constant for one of its’
- parameters
-
- This program only handles very simple constant string expressions,
- and this error indicates that the expression was not simple enough.
-
-
- 27:Line too long (max 256)
-
- This seems a reasonable upper limit on the line length of a Special
- file.
-
-
- 28:Line ‘%s’ is not of a recognised form
-
- Syntax error for the Special file line. Note that if you specified a
- Text file full of control codes and such, then you may only get to
- read the last few words of this message.
-
-
- 29:Label ‘%s’ is invalid
-
- In Special files, the label probably starts with a digit, or some
- such.
-
-
- 30:Parameter list ‘%s’ is invalid
-
- In Special files: what more needs to be said?
-
-
- 31:Parameter list ‘%s’ contains a duplicate
-
- In Special files: it is not exactly meaningful to have two or more
- parameters assigned to the same expansion number is it?
-
-
- 32:Implicit label substitution overflowed
-
- When a call to a Special routine is found, the label templates get
- expanded using the actual parameters passed. This error shows
- BasCompress checks for overflow in its’ internal buffers!
-
-
- 33:Too many special routines (max 255)
-
- A perfectly reasonable limit it seems. This could easily be
- extended, though.
-
-
- 34:Unable to load special file (not Text?)
-
- Or maybe it wasn’t found. Only Text files are accepted.
-
-
-
-
-
- Page 57
-
- ============================================================ BasCompress ====
-
-
-
- 35:SWI name missing, or not simple
-
- It is normal to just have a string, variable, or number immediately
- after a SYS (SWI). This indicates that found something else ---
- which may indicate an error.
-
-
- 36:Illegal screen mode
-
- If the listing mode could not be found, and no suitable alternative
- was possible, then this error is generated.
-
-
- 37:Bad main program, unterminated %s structure
-
- This is a special case, if the first routine found (DEF PROC, or
- DEF FN) was inside a multi-line structure. This indicates an error
- in the main program.
-
- A quick fix is to put BasCompress into ‘dumb’ mode --- see §2.8.3.
-
-
- 38:Can’t find closing ellipsis in special routine parameter
-
- During label expansion, BasCompress found a label ending in (, which
- it took to mean the start of an array index. No closing ) was found
- before the end of the string.
-
-
- 39:Bad char ‘%c’ following > or : in special routine parameter
-
- During label expansion, BasCompress expects the label to be
- terminated by a comma or the EOS. This indicates that this condition
- was not satisfied.
-
-
- 40:Called routine ‘%s’ with wrong number of parameters
-
- BasCompress keeps note of the number of parameters a routine is
- defined with, and can detect when an attempt is made to use the
- routine with the wrong number of parameters.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 58
-
- ============================================================ BasCompress ====
-
-
-
- [7.4] Run-time errors
-
- Here is some help with possible errors that BasCompress may introduce
- to the compressed Basic output.
-
-
- [7.4.1] Unknown or missing variable
-
- The quick and easy method to solve this problem is to turn off all
- label reduction. This is not recommend, as it makes the use of
- BasCompress almost worthless.
-
- This error has been generated because you have not told BasCompress
- about the side effects of an EVAL or DATA statements. See §2.11 for
- why this produces the error, and §6 for how to cure it.
- In essence you have to go through the program, locate the EVAL’s and
- possibly the DATA statements as well, (look in the log file for
- exactly where to find these), and then build a Special file to tell
- BasCompress how to handle these.
-
- Usually this entails defining some “global” labels that will never be
- reduced, although sometimes it is possible to build a more
- sophisticated parameter-based rule.
-
- It may just be possible that this error is generated inside
- assembler. If so, then this indicates an error on BasCompress’
- part. Examples of such should be sent to the author for inclusion in
- upgrades. This possibility is extremely remote as BasCompress has
- been tested with a wide range of sources, but most cases where it has
- failed in the past has been in this area.
-
-
-
- [7.4.2] No such function/procedure
-
- This occurs for exactly the same reasons as detailed in §7.4.1 above.
-
-
- [7.4.3] Missing ENDIF
-
- These errors are generated very rarely, but they are just possible.
- Consider the following code:
-
- IF FN_SaveFile THEN :::REM comment
-
- What BasCompress could produce, although it does tries not to, is:
-
- IFFNxTHEN
-
- Obviously this is wrong, wrong, wrong. From a simple one-line
- conditional (that does nothing), BasCompress has produced a multi-
- line conditional construct where there shouldn’t be any, and without
- the ENDIF.
-
-
-
-
-
- Page 59
-
- ============================================================ BasCompress ====
-
-
-
- Since this situation is fairly rare, and BasCompress does handle it
- most of the time, it is not likely to be remedied --- unless enough
- people request it.
-
- The work around is to not to ignore the return value from the
- function, which is probably an error status (indicating a very lazy
- programmer!), but to assign it to a variable, and then act on it
- accordingly.
-
-
- [7.4.4] Invalid RETURN actual parameter
-
- If the program compresses OK but when run comes up with an error:
-
- ‘Invalid RETURN actual parameter’
-
- then ensure that menu item ‘Input->Remove constant variables’ is
- disabled. The proper way to deal with this is to use a special file
- on the variable, see the manual. See §2.8.3.
-
-
- [7.4.5] Syntax error
-
- If this occurs then ensure that menu item
- ‘Output->Reduce variable names->‘E’ suppression’ is ticked. See §8.2.
-
-
- [7.4.6] Logical errors
-
- By this it is meant that a program doesn’t generate any overt errors,
- it’s just that it doesn’t do the same as it did before compression.
-
- BasCompress has been tested quite thoroughly with a wide source of
- Basic programs, and it is hoped that all of these exceptional cases
- have been noted and duly handled. However if you do get this type of
- error, it is still probably because of EVAL and DATA being used with
- undeclared (and probably short, e.g. A%, x, etc.) variables. These
- variables may have been “renamed” by BasCompress, or even re-mapped
- to different variables, and hence contain an invalid value.
-
- If it is not because of this, then the author would appreciate it if
- an example of the incorrectly compressed source was sent in, so
- BasCompress could be updated to handle that case.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 60
-
- ============================================================ BasCompress ====
-
-
-
- [7.5] Internal errors
-
- These are “system” errors generated by BasCompress itself. These
- messages are hard-coded into the executable, and use the error number
- chunk &DCBC0 to &DCBFF:
-
- Error(s) during parsing
-
- This should never appear, as it is an internal error used to indicate
- an erroneous parsing stage.
- Invalid sort character ‘%c’
- Sort string too long
- Invalid type character ‘%c’
-
- These indicate rudimentary errors on the parameters passed on the CLI.
-
- Invalid option in system variable BasCompress$Options
-
- Indicates an invalid system variable. Unfortunately it is not
- possible to show exactly what was wrong with it, just that some part
- of it was wrong.
-
- 1.1
- ...
- 10.1
-
- These errors should never be generated. They indicate where
- BasCompress has found some inconsistencies in its’ own internal data
- structures. Any occurrences of such should be sent, along with the
- source that produced them, to the author for correcting in future
- upgrades.
-
- This can be sent by Email to bascompress@cheepnis.demon.co.uk.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 61
-
- ============================================================ BasCompress ====
-
-
-
- [8] Loose ends
-
- The fact that this chapter exists shows that I’m no good at
- documentation! It mainly describes features that may (or may not)
- get implemented in future upgrades.
-
-
- [8.1] Memory usage
-
- Let’s face it boys and girls, this program eats RAM like nobody’s
- business. It’s really just a fact of life for 32-bit/RISC machines.
-
- This is compounded by the need for some oomph (technical term) in the
- program execution stakes. To this end most things are kept on two
- separate lists --- e.g. if a routine X calls Y then this is recorded
- both in X’s calls list, and Y’s called by list. This bit of
- redundancy probably doubles the speed of cross referencing, so it was
- felt worth it.
-
- Also all the source is kept in RAM, and all the output.
-
- There is some consideration to low-memory users in that the hash
- table sizes grow on request, but then again they start pretty big
- anyway!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 62
-
- ============================================================ BasCompress ====
-
-
-
- [8.2] Missing THEN
-
- Basic allows the programmer to omit a THEN statement when used on a
- single-line IF compound. However, this can cause problems. Because
- BasCompress removes all spaces, if the condition ended with a digit,
- and the statement after the (missing) THEN starts with an ‘E’ then
- Basic gets confused – thinking a real number (in exponent format) has
- been given. Eg the BasCompress produced line:
-
- IF x<>0E%=1
-
- is wrong. There should be a space after the 0. This is very rare.
- A temporary cure is to stop BasCompress shortening any variables to
- names starting with an ‘E’. Although this will solve most problems,
- there is still the unresolved problem of the un-shortened variables.
- The only cure is to make sure the THEN is always used.
-
- A similar problem is the following BasCompress produced line:
-
- WHILE x<>0E%=2
-
- The cure for this is to always separate the expression from the first
- statement of a WHILE compound by a colon.
-
- While testing this program, it became evident that the missing THEN
- was part of a general problem --- skipping a Basic expression. This
- is harder than at first seems, because there is no point at where you
- can say “yes, here is the end”, as you can in a procedural call, say
- (e.g. you’ve found a comma, close ellipse and the bracket and quote
- count is zero). E.g. how would you handle this:
-
- IF a=b=c THEN P.“hello”
-
- Intuition get’s it wrong. Basic treats this as:
-
- IF (a=b) THEN =c ...
-
- Which means you have to build a tree/stack. But, once you can do
- this then this program could become quite interesting. It could
- evaluate constant sub-expressions. This could produce some very
- compact stuff, as you’d also be able to substitute constant variables
- with their values, and even eliminate dead code. I.e. debugging
- stuff that would never be executed because it is known that, say,
- Debug is always FALSE.
-
- But, tie that in with a bit more knowledge of the structure of the
- Basic, and it is almost easy to generate not tokenised Basic, but
- code. Well, I’m sure if enough people register, it will give this
- author the incentive to develop BasCompress into the fastest (and
- cheapest) Basic compiler.
-
-
-
-
-
-
-
-
- Page 63
-
- ============================================================ BasCompress ====
-
-
-
- [8.3] Cross-reference
-
- It would be nice to have a toggle between multi-line and single-line
- (the current) output. This is fairly easy to do, but it’ll require
- some experimentation!
-
- Also handy could be some ordering based on label length, or even the
- (approximate) size of a routine.
-
- Some rationalisation of the messages used is in order, too.
- Currently the program outputs some line feeds of its’ own accord,
- which is decidedly against the grain.
-
- How about not listing the file that a routine is in? Or just the
- leaf of the filename. This would reduce the size of the output by
- quite a lot. The former would require the user to cross-reference
- (the cross-reference!) to find the file of the reference, though.
-
-
- [8.4] Statistics
-
- There are loads more statistics that could be done;
-
- • libraries that aren’t needed
- • variables only ever declared (e.g. LOCALised but
- never used)
- • variables only ever assigned to once (constants)
- • lines where the memory indirection operators ?, | and
- ! are used
- • don’t log all the deleted routines and variables,
- just count them
- • give a percentage of the code that is unused
- • percentage compression achieved on the used code
- • lines containing any user-defined basic token (e.g.
- PRINT)
- • time taken to load, parse, cross-reference, compress,
- write
-
-
- [8.5] Uncompressed output
-
- It would have been nice if there was an option to just remove the
- unused routines and merge all the libraries into one big file. This
- would give a nice listable program containing only the routines
- used. However this is currently unpossible, as BasCompress was never
- intended to produce anything but compressed code. (There are many
- places where “skip until hit non-space” is hard-coded, and it would
- take a rather long time to rationalise these so you could toggle it
- on/off.) Oh well.
-
-
-
-
-
-
-
-
-
- Page 64
-
- ============================================================ BasCompress ====
-
-
-
- [8.6] Label reduction
-
- The reduction of labels isn’t always as good as it could be.
- Currently BasCompress only judges the fitness of a label to be
- reduced on its’ global usage. A better algorithm would take into
- consideration the nesting level of each usage, and use this to bias
- the reduction of labels towards those used inside loops.
-
-
- [8.7] Executable
-
- The current situation, with two separate applications is far from
- ideal. A better situation would be to have the back end program
- inside a module. This would have the added bonus of not needing to
- load in the Messages file every time it is run.
-
- Better yet would be to have the whole thing as one big Wimp
- application. Here many extras are possible because there would be
- direct access to the cross-reference database. For example it could
- create graphs of variable name distribution, provide the cross-
- reference in it’s own window, where you could filter it given user
- criteria (such as name matching a regexp AND usage>3). But I don’t
- think so, do you?
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 65
-
- ============================================================ BasCompress ====
-
-
-
- [A] Messages
-
- [A.1] Internationalism united
-
- For users of a foreign extractment, the Messages directory contains
- the country-specific text files. Copy Default, to (say) Iceland and
- edit the messages, and if that is the configured country of the
- machine, then those messages will be loaded. Note it is sensible to
- keep a Default file as this will be loaded if no file of the
- configured country could be found.
-
- If you do make a translated messages file, the author would
- appreciate it greatly if you could send it in so every one can
- benefit.
-
-
- [A.2] Format
-
- The message format is fairly obvious --- just look at them to see
- what can and can’t be done, but here’s a quick summary.
-
- • Comments start with a #
- • Messages names start on a new line, and end in a
- colon
- • Messages start at the first non-space after the
- colon, and finish at the end of the line
- • Spaces can be done as “% ”
- • Percents can be included using “%%”
- • The “parameter”s %s and %d are supplied by
- BasCompress, these are standard C printf() strings
- • The standard C escape sequences \b, \t, \n, \r, \xXX,
- \000, etc. can be used to insert those characters
- inside the messages
- • A message may be a selection: starts with a “%?” and
- consists of a comma separated list of alternatives
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 66
-
- ============================================================ BasCompress ====
-
-
-
-
- [B] Regular expressions
-
-
- [B.1] Definition
-
- A regular expression (RE) is a fancy wild-carding system – i.e. you
- don’t need exact matches. A regular expression is really a
- mini–programming language with the following “commands”:
-
- . any character
- ^ start of line
- $ end of line
- [...] set of characters(*)
-
- Any other character matches itself
-
- There are also modifiers:
-
- | or, “re1|re2” match either RE1 or RE2
- ~ not, “~c” matches anything but the next character
- + many, “re+” matches RE repeated one or more times
- * repeat, “re+” matches RE repeated zero or more times
- ? optional, “re?” matches RE repeated zero or one times
-
- Parenthesis () can be used to group REs
-
- Finally, there are memories:
-
- \{ begin recording
- \} end recording, and place in next memory (starts with 1)
- \<n> \1, ... \9 will then match the corresponding memory
-
-
- (*) character sets:
-
- Character sets are used to match one of a group of characters. All
- characters are taken literally except “–”, “]”, and “\”. The “–”
- indicates a range, unless it is the first or last character, or the
- first character after a previous range. The “\” can be used to
- include a “]” or a “–” in the set.
-
-