APIs that need special handling in the parser/compiler:

(Please read name_mangling.txt before this, to see if your special problem
doesn't already have a solution encoded in the function name...)




        Are you sure you don't want to be reading vbs_output.txt?




--------------------------========++++++++++========--------------------------
PRINT (and print #), with more than one parameter (separated by semicolons)
 must be broken into multiple calls. String concatenations should be done
 prior to breaking down the API call. That is, PRINT "crack" + "pipe" would
 be one call, but PRINT "crack"; "pipe" would be two. ALSO -- Semicolons at
 the end of the PRINT statement specify that no newline should be sent to the
 console. This will need to be handled specifically. Solution: the PRINT call
 should, by the parser/compiler, do this: Break down semi-colon separated
 fields into strings, if possible, and call vbpS_print(). Otherwise,
 convert the argument to a variant, and make a call to vbpV_print(), which
 will convert whatever the data was from a variant type to a string, and 
 print it. If there is no semicolon at the end of the line, the 
 parser/compiler will generate a call to __printNewLine() (an internal
 function) after all the vbp?_print() calls. Note that the __printNewLine()
 call might be the only call generated, if there are no parameters to the
 BASIC PRINT statement. If, for some crazy reason, a programmer has
 decided to put a "PRINT ;" statement, the line will not generate any C
 code, but will still produce proper line labling and debug/tracing code.
 (The above discussion also applies to vbp?_print_NC() when using PRINT #)
--------------------------========++++++++++========--------------------------
OPEN calls should all call one function, with default values for optional
 missing values. The OPEN function should determine what action to take
 based on the default values. This avoids the need for 18 jazillion overloaded
 functions.
--------------------------========++++++++++========--------------------------
CLOSE calls need to deal with the optional '#' chars before the numeric
 arguments. Lots of the file i/o API have this problem. Things like
 PRINT # and LINE INPUT # use this character to differentiate between two
 very different functions, too.
--------------------------========++++++++++========--------------------------
SWAP should be generated inline by the parser/compiler.
"SWAP a, b" becomes "tmp = a; a = b; b = tmp", plus type/range checking and
debug/trace code.
--------------------------========++++++++++========--------------------------
In Qbasic, CHR$(255.4999) does not fail, but CHR$(255.5) throws
ERR_ILLEGAL_FUNCTION_CALL. Do all BASIC functions round floating point values
when used as integer arguments, or do some functions truncate?
--------------------------========++++++++++========--------------------------
*-----
BASIC code:
*-----
x = 3
On x GOSUB line1, line2, line3
On x GOTO line1, line2, line3
*-----
must become:
*-----
__GOSUBSUPPORT;
__integer x;
__integer tmp;

x = 3;
tmp = x;   /* needed in case of function...should run only once. */
if ((tmp < 0) || (tmp > 255))  /* negatives or > 255 are errors. */
    __runtimeError(ERR_OUT_OF_RANGE);  /* or whatever error... */
else if (tmp == 1)
    __doGosub(line1, endOfOnNumGosub);
else if (tmp == 2)
    __doGosub(line2, endOfOnNumGosub);
else if (tmp == 3)
    __doGosub(line3, endOfOnNumGosub);

endOfOnNumGosub:

if ((tmp < 0) || (tmp > 255))  /* negatives or > 255 are errors. */
    __runtimeError(ERR_OUT_OF_RANGE);  /* or whatever error... */
else if (tmp == 1)
    __jumpLabel(line1);
else if (tmp == 2)
    __jumpLabel(line2);
else if (tmp == 3)
    __jumpLabel(line3);


*-----
This must be generated INLINE, EVERYTIME, by the parser/compiler.
*-----
--------------------------========++++++++++========--------------------------
Refer to on_events.txt and gosub.txt for details on those, and strange
things like ON ERROR RESUME NEXT...
--------------------------========++++++++++========--------------------------
SELECT CASE statements can NOT be converted directly to switch statements,
since they are more flexible. You'll have to use "if/else if/else" constructs.
--------------------------========++++++++++========--------------------------
RESUME and RESUME 0 should both translate into a __resumeZero() call.
RESUME NEXT should become a __resumeNext() call.
--------------------------========++++++++++========--------------------------
What to do about CHOOSE?
--------------------------========++++++++++========--------------------------
Ugh.
--------------------------========++++++++++========--------------------------

/* end of special_cases.txt ... */

