                                  
                           REVTRAN Manual
                                  
                       Version 2.5, April 1994


Introduction

   Revtran is a program for the Psion Series 3, which reverse-
   translates translated programs back into moderately intelligible
   OPL source code.  It is written in OPL, and will run on the
   Series 3, in compatibility mode on the Series 3a, or on Psion's
   highly useful "EHWIM" Series 3 emulator (available on CIX) which
   runs on a PC.  Revtran processes both Series 3 and Series 3a OPL
   programs.


Uses

   You might use Revtran on your own programs, e.g. if you have
   lost the source code, or you want to regress to an earlier
   version of a program where you have deleted the earlier source
   code.
   
   You might use Revtran on someone else's programs, for a variety
   of reasons, for example:
   
   - to do minor bugfixes, and to make adjustments and improvements
     to a user interface for your own use.
   - to remove features that you don't use, and which are taking up
     space.
   - to understand the data file formats used, so you can read or
     write them from another program.
   - to convert a .OPO to a .OPA or vice versa.
   - to extract, remove, replace or add an icon picture in a .OPA.
   - to convert a Series 3a application to Series 3 (by removing
     Series 3a-specific keywords etc).
   - to learn from others' experience.
   - NOT to hack into authorisation mechanisms etc.! (A note here to
     OPL authors: the translation of OPL into .OPA or .OPO is not
     very secure; the process is direct and easily reversible.
     Writing in 'C' or some other compiled language will give much
     better security, if that is what you want.)
   
   NOTE: whatever your reason for using Revtran, please DO NOT
   distribute any modified programs without the original author's
   approval.  See the 'Ethics' section below.


What's new in V2.5

   Prior to V2.5, the IOOPEN variant for unique file 
   creation, and the Series 3a SEND function, were not 
   handled, being reported as "unknown q-code" values $25 
   and $48.  The rare q-codes $7e and $7f are now also 
   handled.  An option to write 'GOTO' in place of 'ELSE' 
   clauses has been added, to reduce structure nesting 
   depth if necessary.  A bug to do with negative
   single-byte integers is fixed.
   From V2.4, Application TYPE codes of $8000 and above are
   no longer misinterpreted as negative.
   Prior to V2.3, procedure parameter and local variable
   names were only procedure-unique; they are now
   file-unique, making global changes easier.
   Prior to version 2.2, translated VECTOR commands were 
   not handled properly, usually causing Revtran to crash.
   Version 2.2 improved the control-structure inference 
   algorithm to cope with a rare special case where a GOTO 
   jumps into an IF..ENDIF construct.
   Prior to V2.0, programs translated for the Series 3a 
   could not be handled.  Also there was a bug whereby only 
   seven of the eight allowable structure nesting levels 
   were accepted.
   There was a bug prior to V1.2 whereby 'BREAK' or 'CONTINUE'
   could (very rarely) be decoded erroneously inside a DO..UNTIL
   loop when nested within a WHILE..ENDWH loop.
   There was another bug prior to V1.2 which resulted in "String
   too long" on some occurrences of 'percentage' operators.


Installation

   You should have unzipped from RVTRN25.ZIP the following files:
   
   REVTRAN.TXT  This file.
   
   REVTRAN.OPO  The program.
   
   REVTRAN.TBL  A look-up table used by Revtran.
   
   Copy or move the two files REVTRAN.OPO and REVTRAN.TBL to a \OPO
   directory, or to two \OPO directories on different disks.


Memory requirements

   You will need about 27k bytes to store the two program files.
   
   In addition, at run-time Revtran needs up to roughly 30-35k,
   depending on the most complex source-code line being
   reconstructed.
   
   Also, don't forget you need space for the output file(s).


Running the program

   Use the Series 3/3a RunOPL application to run REVTRAN.OPO, then
   choose appropriate items from the menus presented.
   
   The default directory for input files is \OPO, but normal Psion
   dialogs are used when selecting input and output files, so you
   can use Tab or Control-Tab to change directory, e.g. to \OPA.
   
   If the input file is an OPA and contains an icon picture, you
   should write the picture out to a bitmap file if you wish to
   reconstruct an identical .OPA later, because the reverse-
   translated OPL source will need to make a reference to the
   bitmap file.
   
   When you write out reverse-translated OPL, you're given the
   option of adding or discarding an APP..ENDA section, by choosing
   an OPA or OPO module type.  If you keep or add an APP..ENDA
   section, you'll be prompted for the parameters to insert
   (although as many as possible are copied from the original by
   default).  If you put a blank entry in the dialog for PATH, EXT
   or ICON, then that line will be omitted from the APP..ENDA
   section.
   
   If you choose to alter the 'Text features', you can adjust
   several things.  You can change how new local variable and
   procedure parameter names are invented, but bear in mind that
   you may cause name clashes with global variables.  You can
   choose 'Verbose' comments, so that 'REM' statements will be
   added to the OPL output to record some numerical details which
   may help in debugging a Revtran problem.  You can choose
   Hexadecimal output for all integer literals, although some
   integer literals will be output in hex even if Decimal is
   selected, to ensure that data types are unchanged.  If 
   you find that reverse-translated OPL has too many nested 
   levels of structure, you can flatten out the 'ELSE' 
   clauses by choosing 'Use GOTO' for the 'Control 
   Structure' item.

   Revtran does not run particularly quickly, even for an OPL
   program, partly because dynamic storage allocation is achieved
   by doing recursive calls to a procedure with a large local
   storage area.  On a Series 3, with all files on the internal
   disk, Revtran processes roughly 400 bytes of input file per
   minute.  On the emulator (EHWIM) running on a reasonably fast
   PC, it achieves about 4k per minute.


Input/Output Files

   When the program runs, it accesses up to three files which you
   specify:
   
   <your file>.OPO/.OPA (Read, mandatory) The .OPO or .OPA file to
                        reverse-translate, from the \OPO directory
                        by default.
   
   <revtran output>.OPL (Write, optional) The new OPL source code
                        extracted from the .OPO/.OPA file, to go in
                        the \OPL directory by default.
   
   <original icon>.PIC  (Write, optional) The extracted icon
                        picture, if one is present inside a .OPA
                        file, to go in the \OPL directory by
                        default.
   
   When writing OPL source code for a .OPA, Revtran will also
   prompt you for a filename to go in the ICON command, but Revtran
   will not access that file.


Capabilities and limitations

   Revtran is intended to cope with all the OPL language constructs
   described in the Series 3a Programming Manual (Version 1.0).  It
   will only take as input OPO and OPA files, i.e. those created as
   a result of translating OPL source code.  It cannot process the
   compiled version of 'C' source code etc., e.g. .IMG files.
   
   If you translate something from, say, English to Japanese, then
   reverse-translate back to English, you'll lose something in both
   directions.  Unfortunately, the situation with Revtran is
   similar.  Most of the information loss is in the 'translate'
   direction; see the 'differences' sections below.
   
   There are a few arbitrary limits hard-coded into Revtran.  In
   each procedure to be reverse-translated, there can be no more
   than 40 parameters, 200 global declarations, 100 local
   declarations, 100 string declarations (local and global
   combined), 100 different references to other procedures, 100
   different references to external globals, and 1000 commands.  In
   this context, an unconditional jump (whether a 'GOTO' or as a
   translated part of an 'IF..ENDIF' construct etc.) counts as a
   'command'.  Also, any single command, when reverse-translated,
   is limited to 255 characters in length; whether or not this
   limit is breached will be affected by the choice of invented
   names for locals and parameters.


Error handling

   Revtran will check the input file header and refuse to proceed
   if the signature is not "OPLObjectFile**".  After that, if
   Revtran encounters something it isn't prepared for in the file,
   it is likely to raise an error message, but not recover very
   well; please let me know if this happens and you can't fix it.


Technical description

   Translation
   
   After you write an OPL module, you 'translate' it to produce a
   .OPO or .OPA file.  There is no form of security encryption
   involved; the purpose of translation is mainly to create a
   syntax-checked, semi-interpreted, compact version of the source
   code.  The resulting file is mainly a list of procedures encoded
   in 'Q-code', which is executed by a software 'virtual machine',
   the Runtime Interpreter, in the Series 3/3a when you run the
   program.  The Q-code uses stack-based reverse-Polish logic, i.e.
   postfix operators etc.  Each OPL function or command is
   translated to a specific code (one or two bytes usually).  OPL
   control structure keywords (e.g. GOTO, IF..ENDIF, CONTINUE) are
   translated into jumps and conditional jumps.  OPL global
   variable names and procedure names are stored unchanged (in
   upper case).  OPL local variable names and procedure parameters
   are converted to numbered storage locations, and their names are
   lost.  'REM' comments are discarded.  Any ICON picture is
   incorporated in-line.
   
   Reverse-translation
   
   To regenerate OPL from a Q-code file, Revtran first decodes the
   file header, extracting any APP details (perhaps including an
   icon picture).  Then it deals with each procedure, after
   extracting global variables etc., in three passes:
   
   Pass 1:  All the commands, variable assignments and jumps are
            identified (each command potentially invoking functions
            in its parameters), and local variables are found.
   
   Pass 2:  In three sub-passes, by analysing the jumps, the
            original control structure is inferred (this is one of
            the more tricky bits, but it runs quickly).
   
   Pass 3:  Each command is turned into text, with the addition of
            control structure keywords and indentation.  PRINT,
            LPRINT and GPRINT commands, which were translated
            piecemeal, are reconstructed.
   
   During Pass 1 and Pass 3, Revtran needs to know how to decode
   particular Q-code values into the original OPL keywords.  Some
   of this information is included in the Revtran program itself,
   but most of the run-of-the-mill Function and Command keywords
   are decoded by reference to the external table REVTRAN.TBL,
   which was previously generated by MKTABLE.OPO (not included in
   this package of files).  Revtran behaves a bit like a Q-code
   interpreter in these phases, tracking the way that values are
   placed on a stack, and then are replaced by functions and
   removed by commands.
   The heuristics that Revtran uses in Pass 2 are unlikely to be
   foolproof, but have worked on all the test cases I have tried.
   If you find an example which causes 'unexpected UNTIL',
   'structure fault' etc., please let me know.


Differences between original and reverse-translated OPL source code

   Any comments in the original OPL are lost.
   Any pre-processor directives (e.g. for HHTRAN) are lost.
   Indentation and spacing will be different, and there will only
   be one command per line (no use of ":").
   Global and local declarations are made in a different order (all
   the globals then all the locals), but the translated effect
   should be the same.  Storage space for originally declared but
   unreferenced locals will be reserved by new dummy declarations
   which may be of different data types (integers and strings
   only).
   Local variables, procedure parameters and labels all lose their
   original names, and are given invented ones.
   All global variables and procedure names are shown with an 
   initial capital letter, and remaining letters in lower case.
   Data file record field names are shown in upper-case.  Names of
   arrays for use in ADDR or var-parameters are always like
   "arr()", where the original might have used the "arr(1)" form.
   Literal integers may be represented differently, e.g. "$0020"
   would be reverse-translated as "32" (although, if you wish, you
   can turn on Hex output for literals).   
   Literal floating-point numbers may be represented differently,
   e.g. "20.0E6" would be reverse-translated as "2.00000E+07"
   Unnecessary brackets in expressions are generally not included;
   operator precedence rules are applied.  The main exception to
   this is that a pair of brackets is always inserted when the "#"
   feature is used for var-parameters.
   Lists of expressions and commas in PRINT, LPRINT and GPRINT
   commands, may be split into a different number of commands, but
   the effect should be the same.
   Any labels which are not jumped to will vanish, and some
   original GOTO commands may be replaced by functionally
   equivalent BREAK, CONTINUE or ELSE/ELSEIF constructs.


Differences between original and re-translated .OPO/.OPA

   If you re-translate Revtran output and compare the result
   against the original .OPO/.OPA, then functionally there should
   be no difference when the program runs, but some of the bytes
   may be different, as follows:
   
   Encoded source line numbers may be different.
   The source file pathname may be different.
   You may have changed, removed or added an icon picture.
   There may be other differences if a different translator version
   is used.


Bugs

   I know of no bugs at present, but no doubt there are some!  My
   understanding of .OPA/.OPO file content is based mostly on
   guesswork, not hard fact, so I've probably got some
   misconceptions, which will account for some of the bugs.


Ethics

   Revtran is intended for private use, and must not be used to
   create OPL source code which is subsequently transferred to
   anyone else (whether modified or not, and whether re-translated
   or not).  European law allows reverse-engineering in certain
   reasonable circumstances, but anything sold as a result of
   reverse-engineering is likely to be a breach of copyright.
   Regardless of the law, if a software author clearly does not
   want you to see the structure of his program, then it would be
   unethical for you to use Revtran on it.  See also the lengthy
   discussion on the CIX psion/2_series3 topic, starting at
   messages #858 and #903.


Distribution

   I'm distributing Revtran as Smileware - if you use it and like
   it, then smile :-)  I wrote Revtran largely out of curiosity and
   to get myself familiar with OPL, rather than to make money.
   Even so, you're welcome to send tokens of appreciation!
   I do not promise any user support (try me anyway), but would
   welcome bug reports and constructive criticism.  Why not drop me
   a line anyway as a sort of informal registration; I'd like to
   know if anyone actually finds the program useful!  Revtran is
   all my own work, and if you use any of the better bits of my
   source code, please credit me as author.  You are welcome to use
   Revtran on itself (but don't distribute any changed version),
   and if you need access to the original source code I will give
   it and other notes to you for a small or zero fee.
   
   You may freely give Revtran to your friends, but if you wish to
   make it any more public (on a BBS for example), then first check
   carefully with the people who run and use the BBS, and let me
   know so that I have a chance of keeping it up-to-date.
   
   If you want the latest version of Revtran in a hurry, send me a
   cheque for 5 pounds and I'll send you it on an IBM-PC-compatible
   3.5" DD Diskette, or other IBM PC formats if you really prefer.
   If you need it on SSD, write to me and we'll discuss content,
   delivery etc.


Copyright etc.

   Revtran is copyright of the author.
   
   You must not use Revtran (source code or executable) for
   financial gain or to infringe other authors' copyright.  It is
   your responsibility to use Revtran within the law.
   
   No warranty is given on this program.  No liability for any
   damage or loss to equipment, data or software will be assumed.
   You use this program at your own risk.
   
   Revtran must not be sold, and may be freely distributed (see
   above) provided that this copyright notice always accompanies it
   unaltered.  Revtran must not be used commercially, but otherwise
   permission is granted for free use of the program and its source
   code in any legal way which does not involve financial gain.
   
   Psion is a registered trademark, and Psion Series 3, Series 3a
   and SSD are trademarks of Psion PLC.  IBM PC is a trademark of
   International Business Machines Corp.


Author

   Mike Rudin
   9, Highfield Rd,
   Coventry
   ENGLAND
   CV2 4GU
   
   Or email me on CIX:
   mrudin@cix.compulink.co.uk


[End of Revtran manual]
