qb2c:      Microsoft's (R) QuickBASIC (C) to ANSI C translator
 
 QB2C is a package which enables execution of BASIC programs under UNIX
provided that a C compiler is available on the system. It is built
around the QuickBASIC-to-C translator (qb2c) which translates BASIC
code into C code. Intrinsically qb2c understands only programs written
in strict QuickBASIC syntax, but 'bcpp' syntax preprocessor can translate
a variety of BASIC styles into QB format thus making the whole thing
much more flexible. 
 Scripts 'brun' (to run directly BASIC programs) and 'bcc' (to compile 
BASIC program and produce an executable) are also provided in order to make
life easier. User may change them to suit his/her needs or system specifics.

 BASIC is an easy-to-learn and user friendly programming language which 
is in principle known by everybody. One of ideas behind this project was
to be able to use scripts made in BASIC as all-around tool for building 
user-made commands and interfaces to existing UNIX commands, rather than 
using awkward script tools that have been developed lately (I have no 
intention to mention their names here). It is true though that BASIC has
a rather limited access to UNIX system, but QB2C allows to circumvent this
problem by mixing BASIC and C text in a single program/file. (See the example
at the end of the manual.) 

QB2C packet consists of:

qb2c         qb2c translator;
bcpp         BASIC -> C syntax preprocessor. One needs that when the
             input BASIC text is not exactly in QuickBASIC format;
calib        Tool used to 'calibrate' key(board) codes of your UNIX
             system to match QB standard (see the DIFFERENCES section);
brun         A script to run BASIC programs in UNIX;
bcc          A BASIC compiler.


QB2C MAIN FEATURES: 

* Recognizes MAIN and SUBroutines

* Declares variables (int, real, char) inside MAIN and inside every SUB.
  All arguments are passed to user-defined SUBroutines as pointers, so
  that SUBroutines can affect their values, as in QuickBASIC.
  Arguments of a SUB are therefore not declared in the SUB.

* Takes care of SHARED variables. 
  If a variable is SHARED it is not formatted inside the respective SUB. 
  A complete list of shared variables appears in preamble of the translated C 
  program.

* Treats UNIX formatted ASCII (text) files as QB would treat
  DOS formatted ASCII files. 

* Translates logical expressions from QB form to C form

* Brakes up multiple lines (:) into single lines in C

* Keeps all original REMarks and places them intelligently. 
  Does add a few of its own REMarks (about shared variables in SUBs)

* Writes out C text neatly

* Recognizes and translates over 70 BASIC keywords: 

 ... the following QB commands and keywords:
 o SUB ... END SUB
 o EXIT SUB
 o FUNCTION ... END FUNCTION
 o STATIC  (as a qualifier of SUB or FUNCTION)
 o SHARED
 o CONST
 o DECLARE
 o DIM
 o IF ... THEN ... ELSE ... END IF
 o FOR ... TO ... STEP ... NEXT
 o DO WHILE ... LOOP
 o WHILE ... WEND
 o GOTO
 o GOSUB
 o RETURN
 o Labels
 o CALL
 o OPEN .. FOR mode AS #n  
   where 'mode' is INPUT, OUTPUT, APPEND
 o CLOSE #n
 o EOF
 o PRINT #n
 o PRINT
 o LINE INPUT #n
 o INPUT #n
 o INPUT
 o COMMAND$
 o INKEY$()
 o DATE$
 o TIME$
 o TIMER
 o SHELL
 o REM
 o LET
 o END 
 
 ... basic string processing functions: 
 o SPACE$, MID$, LEFT$, RIGHT$, STR$, CHR$, ASC, VAL, LEN

 ... and mathematical functions:  
 o LOG, SIN, COS, TAN, ATN, SQR, ABS, EXP, SGN, RND, INT, CINT and power ^


* If a line cannot be translated a WARNING or ERROR are issued, the  
  line and its number dumped at the screen and the translating 
  process stopped.

* There are few syntax or other errors which can be detected  
  during translation. Translation assumes that the input QuickBASIC
  program is itself debugged. Preprocessor bcpp does some additional
  simple checks like brackets and double quotes balance etc.

* The translator changes names of variables in such a way that suffix
  "$" becomes "_S", "%" becomes "_int", "&" becomes "_long" and "#" becomes
  "_double". An open file identified in BASIC with number 'n', becomes 
  identified with a pointer of name 'fp_n'. This may be important in case 
  of direct insertion of C lines into a BASIC program (see the option -C).

DIFFERENCES
  
* In BASIC, for example 5 / 8 equals to 0.625 while in C this is equal 
  to 0 (integer zero) because the binary operator "/" acts as the integer
  division operator when both operands are integer numbers. QB2C translator
  will therefore also produce zero for such expressions unless they are 
  written in one of the following ways:
  5. / 8., 5. / 8, 5 / 8., 5! / 8, 5 / 8!, 5! / 8!, (0.+ 5) / 8 etc. 
 
* DATE$ has more possible formats:
  DATE$ or DATE$(0)  ->   12-27-1996   (the default QuickBASIC format)
  DATE$(2)           ->   27.12.1996
  DATE$(3)           ->   27/12/1996
  DATE$(4)           ->   27-Dec-1996
  DATE$(5)           ->   Sun Dec 27  15:14:37  1996

* INKEY$  This implementation of INKEY$ waits until a key is pressed
  and then returns a string associated to a character pressed. Unlike
  the INKEY$ in QuickBASIC it cannot return empty string (""). This
  should not cause any noticeable differences in operation of programs
  since INKEY$ is usually embedded in an outer loop which is exited when
  a key is pressed. 

  According to QB, when a key is pressed, INKEY$ returns a string which 
  corresponds to the key. Most keys return a string of length one (single 
  character). Extended keys are represented with a string of length 2.
  Key codes of ordinary keys are emulated by QB2C exactly as they are in
  QuickBASIC whereas codes of extended keys are (hopefully insignificantly) 
  different.
  Here is a list of extended keys and their ASCII codes:
  Key   QB2C   QBASIC     Key     QB2C   QBASIC     Key          QB2C  QBASIC  
  F1    1 59   0 59       F9      1 67   0 67       End          1 79  0 79
  F2    1 60   0 60       F10     1 68   0 68       Page Down    1 81  0 81
  F3    1 61   0 61       F11     1 133  0 133      Cursor Up    1 72  0 72
  F4    1 62   0 62       F12     1 134  0 134      Cursor Left  1 75  0 75
  F5    1 63   0 63       Insert  1 82   0 82       Cursor Down  1 80  0 80
  F6    1 64   0 64       Home    1 71   0 71       Cursor Right 1 77  0 77
  F7    1 65   0 65       Page Up 1 73   0 73
  F8    1 66   0 66       Delete  1 83   0 83

  This is not all ! As different implementations of screen codes in UNIX 
  are not unique, it is necessary to 'calibrate' your keyboard in some way.
  If you are going to use INKEY$ function you should definitely do this 
  by running program calib. The program will ask you to press extended keys 
  listed above and will create the file .kbcalib in your $HOME directory. 

TRANSLATOR OPTIONS

* Translation can be called with one or more of the following option flags:
   Option               Meaning
  -i or -int        assume variables with first letter i,j,k,l,m,n 
                    (upper or lower case) to be of the C type 'int' 
                    if not a string.

  -d or -double     assume variables starting with 'd' or 'D'
                    be of C type 'double', if not a string.

  -b or -bcpp       do not be sensitive about the case of QB command 
                    and function names or exact QB spacing of commands 
                    and variables. This actually turns on the bcpp 
                    preprocessor.
                    (However, mixed case is not acceptable even with this     
                    option.)

  -c64 or -C64      this option is should be used with the option '-b' 
                    since it is passed to bcpp. It switches on some 
                    syntax features specific to C-64 (Commodore 64). 

  -l or -long       all integer variables became of type 'long' and all
                    real variables became of type 'double'.

  -p or -post       do not perform post-processing which changes variable                  
                    names like i%, i&, x#, a$ into C-acceptable forms:
                    i_int, i_long, x_double, a_S, and adds headers to 
                    the C text. This is only useful for output C code 
                    or qb2c debugging purposes.

  -a or -ansi       writes out labels according to strict ANSI standard

  -c or -C          lines commented with 'C' are written out as they are;
                    this makes possible direct insertion of lines in C

  -m or -M          allow logical expressions to combine with math. 
                    expressions (eg. i = (a = 1) AND (b <> 2) ) 

REMINDER

 The following pieces of syntax rules are a bit more restrictive than is 
common in various implementations of BASIC including QuickBASIC.
We want to stress their importance since QB2C may produce a bad C code 
without warnings if they are not obeyed:

* all arrays must be declared (DIM) physically before they are used;

* array, constant or function declarations must occur first in a
  given module (MAIN, SUB...) ie. before any other expression or 
  command;

* all SHARED arrays must be declared in MAIN module (even if they are not
  used in the MAIN);

* SHARED array names are passed with empty brackets eg. name();

* Files open in any module (MAIN, SUB or function) are "visible" from 
  all other modules;

* Return type of a FUNCTION is determined by its name, the rules are the
  same as for variables and arrays.

RESTRICTIONS

* Type of a constant, variable or array is determined by suffix in
  its name. The "AS" statement in variable type definition is *not* 
  supported.
  Here is the list of legal suffixes (as used by QuickBASIC):
  $         -> string (or single character)
  %         -> single integer 
  &         -> long integer
  #         -> double float 
  no suffix -> single float
  If a numerical constant contains "." or "!" then it is a single float
  (example: 100 is integer, 100. and 100! are single floats).
  On top of that, user can modify types during translation (see option -l).
    
* All array names MUST be declared explicitly (DIM) at the top of each
  module where they are used.
  In opposite case NO ERROR WILL BE DETECTED at translation time !

* The syntax must be strictly the one as written out by the QBASIC editor
  including case and spacing conventions. If not, preprocessor bcpp 
  should be used on the file:
  bcpp  infile  outfile
  or the option -b used to the qb2c translator (see the option list).

  The bcpp preprocessor may be run with one or more of the following 
  option flags:

  -c64 or -C64      this option switches on recognition of some 
                    syntax features specific to C-64 (Commodore 64)

  -q                bcpp works quietly (suppresses warnings but not
                    errors).

* Arrays cannot be passed as variables to SUBroutines or functions - use 
  SHARED instead.

* IF clauses without THEN such as:  'IF a$ = "a" GOTO 100'
  are not allowed at this moment. In this particular case one should
  use instead: 'IF a$ = "a" THEN GOTO 100' or 'IF a$ = "a" THEN 100'.

* There is no support for sound and graphics.


EXAPMLE

I) As a simple example you may put the following text into a file named 
test.bas:

 for i=1 to 5 
  print i, i^2
 next

 Then do:
 bcpp -i -b test

 This will create the file test.c. Compile and run it with:
 cc -o test test.c
 test

 The result should look like: 
 1          1
 2          4
 3          9
 4          16
 5          25

 Instead of all this you may just have typed: 

 brun test

II) QB2C allows for BASIC and C texts to mix in within a single program.
    For example:

REM Define string 'a$', insert a line in C which gets user name and print it
  a$=""
C getenv(a_S,"LOGNAME"); 
  print a$
  end

 Do note that the names like 'a$' are translated to C as 'a_S' (see the 
more complete list of names changes at the end of the first section of this 
manual).
-----------------------------------------------------------------------------
First version:  4-Apr-1996 
Last revision: 16-Apr-1996    
Author: Stipcevic Mario  mario@darktar.irb.hr
