| Rapid-Q Documentation by William Yu (c)1999-2000 | Chapter 3 |
|
| |
$TYPECHECK
[ OFF | ON ]
Default is OFF
$TYPECHECK is used to tell the
compiler whether you want the source code parsed using strict type checking
ON (all variables must be declared), or relaxed type checking
OFF like traditional BASIC where you don't need to declare your
variables. Note, you can turn ON or OFF type checking at anytime, so you can
type check a portion of your code and turn it OFF afterwards.
Usage:
$TYPECHECK ON
Examples:
PRINT "\""
Output is "
PRINT "\x41"
Output is
A
PRINT "\t\65\66\67\t\68\69\70
Output is ABC
DEF
PRINT "Hey\r\n";
Output is Hey with newline
$MACRO
(This command is VERY buggy and has
limited functionality! Likely will cause strange compiler errors
or crash.
MacroName[(Parameters, ...)] MacroDefinition
A Macro simply
replaces a definition with another. It can be treated like a function if you
supply parameters. Rapid-Q allows Macros to be embedded within another Macro
(foward only to avoid recursion), token pasting using ##, and even macro
overloading. You can also redefine operators and special characters except
quotes. A definition can extend to multiple lines by using the colon as a line
separator. A $MACRO directive is global if it preceeds any $INCLUDE
directives. ie. the included files have access to those Macro definitions. A
$MACRO directive only affects the module level (ie. the current file) if used
in an $INCLUDE file. So if A depends on B and B has some $MACRO directives,
then those $MACRO directives only affect B and A has no access to them
unless redeclared in module A.
Notes:
If you use
the $MACRO directive, you are forcing Rapid-Q to preprocess your code, which
will prolong the compilation process. Rapid-Q normally performs a single-pass
compilation process.
Usage:
$MACRO ~ ,
This redefines the comma character
Try: ? STRING$(10 ~
"A")
$MACRO strcat(a,b) a=a+b
Implements a STRCAT function
strcat(a$,"abc") translates to a$=a$+"abc"
This
won't work --> strcat(a1,b)
a1=a1+b
$MACRO VARID(x) V##x
An example of token pasting
DEFINT VARID(1) translates to DEFINT V1
$MACRO TWO_PI (2*PI)
$MACRO PI 3.14159
Embedded Macros (forward only).
Can't
embed itself as a parameter.
This avoids rescanning &
recursion.
$MACRO ADD(a,b,c,d)
ADD(a,b)+ADD(c,d)
$MACRO ADD(x,y) x+y
$MACRO
ADD(x,y,z) x+y+z
An example of
macro overloading
$Macro examples:
'Char presentation of number Macro as pseudo
SUB
DIM M AS QMemoryStream
$Macro Digit2Char(D,a)
_
M.Write(D):za=sizeOf(D):
_
M.Position=0:a=M.ReadBinStr(za) :
M.Close
dim LPod as double
lpod=33.234
Digit2Char(lpod,sss$)
print "Char LPod=",sss$:
dim tst as
integer
tst=33.234
Digit2Char(tst,zz$)
print "Char tst=",zz$:
A% = "Hello" "World"
A$ = "Hi World!"
A# = 34 + 34 - 324 * 3 / (34 / 5 + 5)
?, ??, ???, %, &, !, #, $They represent BYTE (?), WORD (??), DWORD (???), SHORT (%), LONG (&) or INTEGER, SINGLE (!), DOUBLE (#), and STRING ($), respectively. Of course, if you didn't put any symbol in front of your undeclared variable, it's automatically assumed that the variable is a DOUBLE. That is the implementation used in Rapid-Q, for other languagues, the default maybe SINGLE, LONG, or what have you. Here's a table for your viewing pleasure:
Type ID Size Range
--------- ---- ---- -------------
Byte ? 1 0..255
Word ?? 2 0..65535
Dword ??? 4 Only Linux version for now...
Short % 2 -32768..32767
Integer & 4 -2147483648..2147483647
Long & 4 -2147483648..2147483647
Single ! 4 1.5 x 1045..3.4 x 1038
Double # 8 5.0 x 10324..1.7 x 10308
If you didn't like the way that was done, you could
also use DIM to declare your variables, like
so: DIM Number AS INTEGER
DIM S AS STRING
DIM B AS BYTE
Well, you get the idea. If you turned $TYPECHECK ON, then you will
be forced to declare your variables like that. It's a nice habit to pick up,
especially if you wanted to switch to languages like C or Pascal. You will be
forced to declare all your variables before you use them. Here's something
that's valid in Rapid-Q, but can confuse the daylights out of people: DIM Num$ AS INTEGER Yes, try to avoid obfuscated code like that.
3.3 Rapid-Q Components/Objects
DIM Form AS QFORM
Form.ShowModal
Comparing this to a C/C++ program, it's much cleaner,
and easier to understand. There are a lot of supported components in Rapid-Q,
like QBUTTON, QIMAGE, QFILESTREAM, etc. There are also some which aren't
supported, that's the restriction involved in using Rapid-Q. Components are
created exactly the same way you create variables, by using DIM. Each
component has its own properties, methods and events. Properties are
like the component's attributes. For example, Left, Top, Width, and
Height are properties common to all visible controls, which define its
placement within the form or Window. Caption is a property of type
STRING. For a QFORM component, the Caption property
defines the title of that form. Caption for a QBUTTON defines
the text of that button. Caption for something like QFILESTREAM
does not exist, since a QFILESTREAM isn't a visible component. It has
its own properties. For a complete guide of the properties, methods and events
for all components, please check the Appendix section. Here's a quick example
of how you can assign properties to your components: DIM Form AS QFORM
Form.Caption = "My Application"
Form.Left = 100
Form.Top = 100
Be careful to know which properties are Read-Only,
and which ones are Write-Only. An example of a read-only property is the
ITEMCOUNT property of a QLISTBOX. An example if a write-only
property is the ICON property of a QFORM, used to specify the
location of an icon to use as the default. Reading the Write-Only values, or
Writing to Read-Only values have no defined meaning, and may result in a
compile error or more seriously, your program crashing. DIM Form AS QFORM
Form.Center
Form.ShowModal
We used 2 methods here, Center, and
ShowModal. The Center method is a SUBROUTINE that accepts no
parameters. What it does is center the form on your desktop. ShowModal
is actually a FUNCTION, but we ignore the return value in this case. It's a
method used to Display your form, and wait for the user to close it. Note:
Unlike some BASIC implementations, a FUNCTION can be called like a SUBROUTINE
in Rapid-Q, you just ignore the return value. This is similar to C/C++.
Other methods that you see may require some extra parameters, and some even
accept an infinite number of parameters. You can also write these in Rapid-Q
yourself, but I'll cover that topic later. So basically, methods are functions
which perform a specific task on that component. In our above example, we're
centering the form, and then displaying it. SUB ButtonClicked
PRINT "Button was clicked"
END SUB
DIM Button AS QBUTTON
DIM Form AS QFORM
Button.Parent = Form ' Property
Button.OnClick = ButtonClicked ' Event
Form.ShowModal ' Method
Seems easy enough right? It really is. Whenever an
"OnClick" message/event occurs, the program jumps into your subroutine
ButtonClicked and executes the code you have waiting in there. The
above program is complete, so you can try it out yourself. For a list of all
events that a particular component can receive, just look at the Appendix
section. FUNCTION FindMax (X AS INTEGER, Y AS INTEGER) AS INTEGER
IF X > Y THEN
FindMax = X '' Return value is X
ELSE
FindMax = Y '' Return value is Y
END IF
END FUNCTION
The above code is valid, as is the following: FUNCTION FindMax (X%, Y%) AS INTEGER
IF X% > Y% THEN
FindMax = X% '' Return value is X
ELSE
FindMax = Y% '' Return value is Y
END IF
END FUNCTION
However, as you may notice, you can't have FindMax%
without attaching an AS INTEGER to the end of the function. SUB StrCat (Source AS STRING, Text AS STRING)
Source = Source + Text
END SUB
A$ = "Hello"
StrCat(@A$, " World!")
PRINT A$ '-- Should print: Hello World!
Or if you prefer, you can also
attach a BYREF keyword in your parameter list like
so: SUB StrCat (BYREF Source AS STRING, Text AS STRING)
Source = Source + Text
END SUB
A$ = "Hello"
StrCat(A$, " World!")
PRINT A$ '-- Should print: Hello World!
Yet another approach you can use instead (note that
this is the "old" way, maintained for compatibility reasons): SUB Strcat (A$, B$)
A$ = A$ + B$
END SUB
A$ = "Hello"
Strcat(A$, " world!")
A$ = STACK.STR(0)
PRINT A$
The stack contains an array of integers and strings,
to access the correct parameter, you have to specify the number (from left to
right). The first element being 0. You can also pass QObjects, but you can't
use it as a return value. SUB (Button AS QButton)
Button.Left = 100
END SUB
All components/QObjects are passed by reference.
SUB Test
DIM I AS INTEGER
I = 100
PRINT I
END SUB
DIM I AS INTEGER
I = 10
SUB Test2
PRINT I
END SUB
Test '' Call Subroutine
Test2
Here's how the scope works, for the SUB Test, the
LOCAL variable I only extends down as far as the end of that SUB block.
The variable I in the main program extends down
all the way to the end of your program. That means SUB Test2 can use the
global variable I because it's within its scope. You can also redeclare
the variable I in SUB Test2, in which case the local I is used
instead of the global I. Here's another situation to demonstrate the
scope of variable names: DIM I AS INTEGER
SUB Scope (I AS INTEGER)
DIM I AS INTEGER
PRINT I
END SUB
PRINT I
In fact, the line DIM I AS INTEGER is a wasted statement, since the
variable I is shadowed by the parameter name I. Rapid-Q will warn you about this, but won't error out.
| Prev Chapter | Up | Contents | Next Chapter |