$IF: Difference between revisions
No edit summary Tag: Manual revert |
No edit summary |
||
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
'''$IF''' is precompiler [[Metacommand|metacommand]], which determines which sections of code inside its blocks are included into the final code for compliing. | '''$IF''' is an precompiler [[Metacommand|metacommand]], which determines which sections of code inside its blocks are included into the final code for compliing. | ||
{{PageSyntax}} | {{PageSyntax}} | ||
:[[$IF]] variable | : [[$IF]] {{Parameter|variable}} [op value] [[THEN]] | ||
: | : ⋮ | ||
:[[$ELSEIF]] variable | : ⋮ 'some code here | ||
: | : ⋮ | ||
:[[$ELSE]] | : [[$ELSEIF]] {{Parameter|variable}} [op value] [[THEN]] | ||
: | : ⋮ | ||
:[[$END IF]] | : ⋮ 'some code here | ||
: ⋮ | |||
: [[$ELSE]] | |||
: ⋮ | |||
: ⋮ 'some code here | |||
: ⋮ | |||
: [[$END IF]] | |||
{{PageParameters}} | |||
* The {{Parameter|variable}} is the name of any preset (see below) or self-defined (see [[$LET]]) precompiler variable. | |||
* The optional right part must begin with any [[Relational Operations|relational operator]] followed by the value to compare the variable with, using the given operator. | |||
** The [[Equal|equal (=)]] operator also allows to check for the special values '''DEFINED''' and '''UNDEFINED'''. | |||
* Multiple relational compares may be combined using the [[AND]], [[OR]], [[XOR]] operators as needed. | |||
** Note that the other logic operators are not supported by the precompiler. | |||
{{PageDescription}} | {{PageDescription}} | ||
* $IF is the start of a precompiler code block which includes or excludes sections of code from being compiled. | * '''$IF''' is the start of a precompiler code block which includes or excludes sections of code from being compiled. | ||
* There is no single line $IF statement | * There is no single line '''$IF''' statement, it must be used in a valid '''$IF...THEN...$END IF''' block to work properly. | ||
* Like all other metacommands, you can not use more than one metacommand per line. | * Like all other metacommands, you can not use more than one metacommand per line. The use of a colon (:) to separate multiple statements in a single line is not allowed. | ||
* Variable names | * Variable names must follow QB64's variable naming conventions. They will be capitalized automatically. | ||
* | * Values may contain any number of periods to separate numbers or words in a string, e.g. in version numbers such as '''3.14.1''' or strings like '''MARY.HAD.A.LITTLE.LAMB''' etc.. | ||
** Note that strings may not contain spaces and must be given without leading/trailing quotes. | |||
* The precompiler comes with some preset values which can be used to help determine which code blocks to include/exclude. These are: | * The precompiler comes with some preset values which can be used to help determine which code blocks to include/exclude. These are: | ||
** '''WIN''' or '''WINDOWS''' if the user is running QB64 in a Windows environment. | ** '''WIN''' or '''WINDOWS''' is ''true(-1)'' if the user is running QB64 in a Windows environment, it is ''false(0)'' otherwise. | ||
** '''LINUX''' if the user is running QB64 in a Linux environment. | ** '''LINUX''' is ''true(-1)'' if the user is running QB64 in a Linux environment, it is ''false(0)'' otherwise. | ||
** '''MAC''' or '''MACOSX''' if the user is running QB64 in a macOS environment. | ** '''MAC''' or '''MACOSX''' is ''true(-1)'' if the user is running QB64 in a macOS environment, it is ''false(0)'' otherwise. | ||
** '''32BIT''' if the user is running a 32-bit version of QB64. | ** '''32BIT''' is ''true(-1)'' if the user is running a 32-bit version of QB64., it is ''false(0)'' otherwise. | ||
** '''64BIT''' if the user is running a 64-bit version of QB64. | ** '''64BIT''' is ''true(-1)'' if the user is running a 64-bit version of QB64., it is ''false(0)'' otherwise. | ||
** '''VERSION''', which is set to the version of the QB64 compiler. | ** '''VERSION''', which is set to the version of the QB64 compiler. | ||
* | * Some new presets have been introduced with QB64-PE v4.0.0, these are: | ||
* | ** '''_QB64PE_''' is always ''true(-1)'', it indicates the use of the QB64 Phoenix Edition compiler at least v.4.0.0 | ||
* | ** '''_ASSERTS_''' is ''one(1)'' if [[$ASSERTS]] or [[$ASSERTS|$ASSERTS:CONSOLE]] is used, it is ''zero(0)'' otherwise. | ||
* If | ** '''_CONSOLE_''' is ''one(1)'' if a console is active either by using [[$CONSOLE]] directly or implied by [[$ASSERTS|$ASSERTS:CONSOLE]], it is ''two(2)'' if [[$CONSOLE|$CONSOLE:ONLY]] is set, it is ''zero(0)'' if no console is available (both console variants may appear multiple times in a program, the last found one determines the final state). | ||
* | ** '''_DEBUG_''' is ''one(1)'' if [[$DEBUG]] is used, it is ''zero(0)'' otherwise. | ||
** '''_EXPLICIT_''' is ''one(1)'' if the program uses [[OPTION EXPLICIT|OPTION _EXPLICIT]], it is ''zero(0)'' otherwise (note OE also implies '''OPTION _EXPLICITARRAY'''). | |||
** '''_EXPLICITARRAY_''' is ''one(1)'' if the program uses [[OPTION EXPLICITARRAY|OPTION _EXPLICITARRAY]] or [[OPTION EXPLICIT|OPTION _EXPLICIT]], it is ''zero(0)'' otherwise. | |||
* You can check a precompiler variable against special values '''DEFINED''' and '''UNDEFINED''', in order to assess whether the variable has already been assigned a value. Useful for code in libraries which may be repeated. | |||
* '''$END IF''' denotes the end of a valid precompiler '''$IF''' block. | |||
* '''$ELSEIF''' must follow a valid '''$IF''' or '''$ELSEIF''' block. | |||
* If '''$ELSE''' is used, then it must be the last block before '''$END IF'''. There can be no additional '''$ELSEIF''' blocks after the '''$ELSE''' block. | |||
* Only be one '''$ELSE''' block is allowed in an '''$IF-$ELSEIF-$ELSE-$END IF''' construct. | |||
; Important notes regarding the preset values | |||
:* All presets are {{Text|'''read-only'''|red}} values and cannot be redefined by using [[$LET]] on it. | |||
:* The presets shall just serve the ability, for library makers, to easily check what features are active in a program, they shall otherwise not be {{Text|'''misused to enforce'''|red}} certain features, e.g. | |||
::* don't check for '''_CONSOLE_''' and force one to open, if none is there, | |||
::* don't check for '''_EXPLICIT_''' and force it, if it's not in effect, etc. | |||
:* Think of it like checking for '''WINDOWS''' and if it's not forcing the user to buy a Windows system or checking for '''32BIT''' and if it's not forcing the user to downgrade his 64-bit system. You wouldn't do that, right? And by that means you also should not enforce things, which the user did not already use in his program. | |||
{{PageAvailability}} | |||
<!-- QB64 = a version or none, QBPE = a version or all, Platforms = yes or no --> | |||
<gallery widths="48px" heights="48px" mode="nolines"> | |||
File:Qb64.png|'''v1.0''' | |||
File:Qbpe.png|'''all''' | |||
File:Apix.png | |||
File:Win.png|'''yes''' | |||
File:Lnx.png|'''yes''' | |||
File:Osx.png|'''yes''' | |||
</gallery> | |||
<!-- Additional availability notes go below the gallery, e.g. --> | |||
* In '''QB64-PE v4.0.0''' several new presets got added into the precompiler (see above). | |||
{{PageExamples}} | {{PageExamples}} | ||
''Example 1:'' | ''Example 1:'' | ||
{{CodeStart}} | {{CodeStart}} | ||
{{ | {{Cm|$LET}} SCREENMODE = {{Text|32|#F580B1}} | ||
{{ | {{Cm|$IF}} SCREENMODE = {{Text|0|#F580B1}} {{Cm|THEN}} | ||
{{Cl|CONST}} Red = 4 | {{Cl|CONST}} Red = {{Text|4|#F580B1}} | ||
{{ | {{Cm|$ELSEIF}} SCREENMODE = {{Text|32|#F580B1}} {{Cm|THEN}} | ||
{{Cl|CONST}} Red = _RGB32(255,0,0) | {{Cl|CONST}} Red = {{Cl|_RGB32}}({{Text|255|#F580B1}}, {{Text|0|#F580B1}}, {{Text|0|#F580B1}}) | ||
{{ | {{Cm|$END IF}} | ||
{{Cl|COLOR}} Red | {{Cl|COLOR}} Red | ||
{{Cl|PRINT}} "Hello World" | {{Cl|PRINT}} {{Text|<nowiki>"Hello World"</nowiki>|#FFB100}} | ||
{{CodeEnd}} | {{CodeEnd}} | ||
Line 53: | Line 95: | ||
''Example 2:'' | ---- | ||
''Example 2:'' | |||
{{CodeStart}} | {{CodeStart}} | ||
{{ | {{Cm|$IF}} {{Text|WIN|#55FF55}} {{Cm|THEN}} | ||
{{Cl|CONST}} Slash = "\" | {{Cl|CONST}} Slash = {{Text|<nowiki>"\"</nowiki>|#FFB100}} | ||
{{ | {{Cm|$ELSE}} | ||
{{Cl|CONST}} Slash = "/" | {{Cl|CONST}} Slash = {{Text|<nowiki>"/"</nowiki>|#FFB100}} | ||
{{ | {{Cm|$END IF}} | ||
{{Cl|PRINT}} "The proper slash for your operating system is "; Slash | {{Cl|PRINT}} {{Text|<nowiki>"The proper slash for your operating system is "</nowiki>|#FFB100}}; Slash | ||
{{CodeEnd}} | {{CodeEnd}} | ||
''Explanation:'' For the above, the CONST slash is defined by the automatic internal flags which returns what operating system is being used at compile time. On a Windows PC, the Slash will be the backslash; for any other OS it will be the forward slash. | ''Explanation:'' For the above, the CONST slash is defined by the automatic internal flags which returns what operating system is being used at compile time. On a Windows PC, the Slash will be the backslash; for any other OS it will be the forward slash. | ||
---- | |||
''Example 3:'' | ''Example 3:'' | ||
{{CodeStart}} | {{CodeStart}} | ||
{{ | {{Cm|$IF}} {{Text|VERSION|#55FF55}} < {{Text|1.5|#F580B1}} {{Cm|THEN}} | ||
{{ | {{Cm|$ERROR}} Requires QB64 version 1.5 or greater | ||
{{ | {{Cm|$END IF}} | ||
{{CodeEnd}} | {{CodeEnd}} | ||
Latest revision as of 11:08, 18 November 2024
$IF is an precompiler metacommand, which determines which sections of code inside its blocks are included into the final code for compliing.
Syntax
- $IF variable [op value] THEN
- ⋮
- ⋮ 'some code here
- ⋮
- $ELSEIF variable [op value] THEN
- ⋮
- ⋮ 'some code here
- ⋮
- $ELSE
- ⋮
- ⋮ 'some code here
- ⋮
- $END IF
Parameters
- The variable is the name of any preset (see below) or self-defined (see $LET) precompiler variable.
- The optional right part must begin with any relational operator followed by the value to compare the variable with, using the given operator.
- The equal (=) operator also allows to check for the special values DEFINED and UNDEFINED.
- Multiple relational compares may be combined using the AND, OR, XOR operators as needed.
- Note that the other logic operators are not supported by the precompiler.
Description
- $IF is the start of a precompiler code block which includes or excludes sections of code from being compiled.
- There is no single line $IF statement, it must be used in a valid $IF...THEN...$END IF block to work properly.
- Like all other metacommands, you can not use more than one metacommand per line. The use of a colon (:) to separate multiple statements in a single line is not allowed.
- Variable names must follow QB64's variable naming conventions. They will be capitalized automatically.
- Values may contain any number of periods to separate numbers or words in a string, e.g. in version numbers such as 3.14.1 or strings like MARY.HAD.A.LITTLE.LAMB etc..
- Note that strings may not contain spaces and must be given without leading/trailing quotes.
- The precompiler comes with some preset values which can be used to help determine which code blocks to include/exclude. These are:
- WIN or WINDOWS is true(-1) if the user is running QB64 in a Windows environment, it is false(0) otherwise.
- LINUX is true(-1) if the user is running QB64 in a Linux environment, it is false(0) otherwise.
- MAC or MACOSX is true(-1) if the user is running QB64 in a macOS environment, it is false(0) otherwise.
- 32BIT is true(-1) if the user is running a 32-bit version of QB64., it is false(0) otherwise.
- 64BIT is true(-1) if the user is running a 64-bit version of QB64., it is false(0) otherwise.
- VERSION, which is set to the version of the QB64 compiler.
- Some new presets have been introduced with QB64-PE v4.0.0, these are:
- _QB64PE_ is always true(-1), it indicates the use of the QB64 Phoenix Edition compiler at least v.4.0.0
- _ASSERTS_ is one(1) if $ASSERTS or $ASSERTS:CONSOLE is used, it is zero(0) otherwise.
- _CONSOLE_ is one(1) if a console is active either by using $CONSOLE directly or implied by $ASSERTS:CONSOLE, it is two(2) if $CONSOLE:ONLY is set, it is zero(0) if no console is available (both console variants may appear multiple times in a program, the last found one determines the final state).
- _DEBUG_ is one(1) if $DEBUG is used, it is zero(0) otherwise.
- _EXPLICIT_ is one(1) if the program uses OPTION _EXPLICIT, it is zero(0) otherwise (note OE also implies OPTION _EXPLICITARRAY).
- _EXPLICITARRAY_ is one(1) if the program uses OPTION _EXPLICITARRAY or OPTION _EXPLICIT, it is zero(0) otherwise.
- You can check a precompiler variable against special values DEFINED and UNDEFINED, in order to assess whether the variable has already been assigned a value. Useful for code in libraries which may be repeated.
- $END IF denotes the end of a valid precompiler $IF block.
- $ELSEIF must follow a valid $IF or $ELSEIF block.
- If $ELSE is used, then it must be the last block before $END IF. There can be no additional $ELSEIF blocks after the $ELSE block.
- Only be one $ELSE block is allowed in an $IF-$ELSEIF-$ELSE-$END IF construct.
- Important notes regarding the preset values
-
- All presets are read-only values and cannot be redefined by using $LET on it.
- The presets shall just serve the ability, for library makers, to easily check what features are active in a program, they shall otherwise not be misused to enforce certain features, e.g.
- don't check for _CONSOLE_ and force one to open, if none is there,
- don't check for _EXPLICIT_ and force it, if it's not in effect, etc.
- Think of it like checking for WINDOWS and if it's not forcing the user to buy a Windows system or checking for 32BIT and if it's not forcing the user to downgrade his 64-bit system. You wouldn't do that, right? And by that means you also should not enforce things, which the user did not already use in his program.
Availability
- In QB64-PE v4.0.0 several new presets got added into the precompiler (see above).
Examples
Example 1:
$LET SCREENMODE = 32 $IF SCREENMODE = 0 THEN CONST Red = 4 $ELSEIF SCREENMODE = 32 THEN CONST Red = _RGB32(255, 0, 0) $END IF COLOR Red PRINT "Hello World" |
Explanation: The same CONST is defined twice inside the program. Normally, defining a CONST more than once generates an error, but the $IF condition here is choosing which CONST will be inside the final program.
As long as Screenmode is 0, the program will exclude the code where CONST Red is defined as color 4. If Screenmode is 32, CONST Red will be defined as _RGB32(255, 0, 0).
The $LET and $IF statements let the programmer control the code that actually gets compiled, while excluding the other blocks completely.
Example 2:
$IF WIN THEN CONST Slash = "\" $ELSE CONST Slash = "/" $END IF PRINT "The proper slash for your operating system is "; Slash |
Explanation: For the above, the CONST slash is defined by the automatic internal flags which returns what operating system is being used at compile time. On a Windows PC, the Slash will be the backslash; for any other OS it will be the forward slash.
Example 3:
$IF VERSION < 1.5 THEN $ERROR Requires QB64 version 1.5 or greater $END IF |
Explanation: VERSION is a predefined variable that holds the QB64 compiler version. If we know our program needs features only available above a certain version, we can check for that and give the user a helpful error message instead of a confusing error elsewhere in the program.
See also