RapidQ Basic News & Tips


HOME


FEEDBACK



HotBasic

News

June 8, 2004 With HotBasic, my patched RapidQ libraries are no longer required.

June 26, 2003 Having read in RapidQ Forums that users have found that recursive calls to a subroutine did not work, do my patched libraries also fix that problem? Now with my patched libraries, work on the HotBasic compiler which uses recursive calls suggests so far (fingers crossed) that recursive calls do work. For example, in a GetNum SUB, which evaluates an expression, the same GetNum may be itself called a number of times. Please see tips below on writing code with recursive calls.

May 29, 2003 Work has begun on HotBasic, which is designed as an RQ-compatible true compiler from .bas to .exe. The present RapidQ compiler, rc.exe, produces "byte code" which is interpreted at run time. Therefore, RapidQ executables contain a language interpreter and are slower and require more system resources.

Both RapidQ Basic and HotBasic share advantages.
The program development software consists of stand-alone components which do not alter the system Registry or require information from it. Installation does not create CLSID's nor an entangled mess of classes and objects, which the user probably does not understand anyway. In contrast, the mere installation of some other programming software is a sort of "assault" on the system, much less the use of it.
This slim-trim-isolated profile may generally have favorable security implications as well. By the code written, the user knows exactly which system functions are invoked. This degree of isolation of software development from system services may give the user more control and may avoid inadvertant incorporation into user programs of bugs or vulnerabilities in system services.
On the other hand, user programs may interact with the Registry and create classes, types and objects in RapidQ Basic and HotBasic.

May 10-18, 2003 Eight patched RapidQ libraries were posted.

Tips

Upgrade to HotBasic. You will save yourself countless hours of debugging certain malfunctions which are due to the flaws in the original libraries rather than faults in your Basic code.
RapidQ can provide good service only if programs run a short period of time with few SUB/FUNCTION calls, or do not use subroutines and functions, which have a 4 byte memory leak with each call. The loss of 4 bytes of RAM with each call eventually utilizes all system RAM and grinds systems to a halt.
Recursive SUB calls (SUB calls itself). Just be sure you have the right values at a particular level of recursion. Try this:
(1) Dimension scalar values as arrays.
(2) On program startup, make nAA=-1&.
(3) Before calling SUB AA, clear your error flag. E.g., e$=""
(4) At beginning of SUB AA,
INC(nAA)
IF nAA>UBOUND(array1) THEN e$="Too much recursion"
IF e$<>"" THEN Goto SubAADone 'check for error
array1(nAA)=value1: array2(nAA)=value2: 'etc
The idea here is you save values that may be altered by a recursive call, but which may be used within SUB AA after a recursive call.
(5) Do not use "Exit Sub". Instead have only one path out with: ExitSubAA:
value1=array1(nAA): value2=array2(nAA): 'etc
SubAADone:
DEC(nAA)
END SUB
Thus, when the previous instance of AA resumes processing, variables (like value1, value2, etc) with key data will always have the right data.
Calling SUB in IF blocks. With AA declared as a SUB, this may not work: IF x>0 THEN AA: [other instructions, same line] But this works: IF x>0 THEN Call AA: [other instructions, same line] Sometimes this does not work: IF x>0 THEN Call AA ELSE [other instructions] But this does: IF x>0 THEN
Call AA
ELSE
[other instructions]
END IF

Study of the byte code produced by RapidQ reveals several points which may be used to optimize program speed and reduce executable size.

All numbers should be type-coded. Consider this statement.

i=1

For the constant/number "1", the byte code will allocate by default eight bytes in a real8 (DOUBLE) representation. If you say, "i=1&", then only four bytes are used. The same applies to constant statements:

CONST i=1

In the above statement, both "i" and "1" are treated as DOUBLE items, not as some sort of integer values! If i is INTERGER/LONG (which are the same), use "CONST i&=1&".

In summary, wherever a number appears in your programs -- called an immediate value, be sure it is type-coded. Then you will both reduce program size and increase program speed because RQ will not have to convert the value type from DOUBLE to the applicable type every time the statement is executed. [Leaving a decimal number like "1.5" without type coding may be OK if you intend to store the default DOUBLE representation (8 bytes). To match SINGLE values (4 bytes), use "1.5!".

If you have $TYPECHECK OFF (the default), use $OPTION DIM, repeatedly, if necessary. For dimensioning, all variables and arrays default to real8/DOUBLE. If you use,

$OPTION DIM LONG

then the "i" in "i=1" will be dimensioned implicitly as LONG and not as DOUBLE. In brief, if your variables/arrays are type-coded properly, you may save the need to convert value types every time a statement is run. $OPTION DIM applies only to variables when $TYPECHECK OFF, not to numbers!

Regardless of $OPTION DIM, numbers will be complied as DOUBLE unless you specify type with each instance of a number in your program. Examples: Each "0" must be "0&" in the common case where a LONG value is type-matched in a particular statement. With "q$=CHR$(34?)" and "q$=CHR$(34)", 1 and 8 bytes are used respectively to represent "34".

Apply the above to all CONST statements, which are compiled as a DIM statement and an assignment statement. Thus, the above example is:

CONST i=1 compiles to DIM i AS DOUBLE: i=1#
CONST i=1& compiles to DIM i AS DOUBLE: i=1&
CONST i&=1& compiles to DIM i& AS LONG: i&=1&

in which case throughout your program "i" is referred to as "i&". [User symbols do not appear in the byte code since each dimensioned item is identified by a numerical index.] If you use "DIM i As LONG: i=1&" instead of a CONST statement, "i" is referenced as just "i" in your program. By the way, this analysis implies that a CONST can be changed at any time in a user program. E.g., "i=NewValue".

Copyright © 2003 Global Services
Original Publication: May 29, 2003

Please use Back on your browser to return to Net Census.