<< Click to Display Table of Contents >> Navigation: 2. Components > 1. PreProcessor & EXE-Compiler > 1.8 : - MACRO-Definitions |
Preprocessor-Directives
MACRO. Definition
Macro definition
Intention
Define your own Commands!
Bundle them to build your personalized robot-language.
Use available commands and put them together to MACROs (to new commands).
Customize the scrip-language to your needs.
While not starting with a '#, this is an preprocessor command. Imagine that you can define your own commands. Save them in include files and call them in your scripts.
Macronames always start with a "%" (percentage sign, ASC 37). Before the script is executed, all MACROS are expanded to their content.
Macros can be used to make your own Instruction.
They can also be used to make your own "condition commands".
In this case, you may end up in the Editor with %IF_Something"
with a incorrect Formatting. Because Number of IXX. / EXX.
do not match.
To handle this, the SPRE-Editor now supports these two Pseudo-Instructions:
'EIF+
'EIF-
These will not influence the Script in any way, just correct the Formatting of the Script in the Editor.
See Example below.
VAN.$$NUA=1
%IF_OR $$NUA|$$NUA|$$NUA
'EIF+
MBX.Was here
EIF.
DMP.1
MBX.1
ENR.
'===========================================================
: %IF_OR 1
SAV.$$M00
#IF PARAMS=1
CAL.$$M00=(§§§01>0)
#EIF
#IF PARAMS=2
CAL.$$M00=(§§§01>0) OR (§§§02>0)
#EIF
#IF PARAMS=3
CAL.$$M00=(§§§01>0) OR (§§§02>0) OR (§§§03>0)
#EIF
#IF PARAMS=4
CAL.$$M00=(§§§01>0) OR (§§§02>0) OR (§§§03>0) OR (§§§04>0)
#EIF
IVV.$$M00>0
#IF RECURS<0
EIF.
#EIF.
SAV.Restore
END%
Important:
We recommend that the Macro-Definitions are being placed at the End of the Script.
As Macros are collected in a separate Pass, they can still be used inside the script.
This way stepping through the script and testing will be easier, as you do not have always to go through the Macro-Definitions first.
Syntax
: %Macroname P1
[Macro Content]
...
END%
Let's see an very easy MACRO example:
: %PrintIt 1
DBP.Hallo my dear §§§01
END%
Lets look at this in detail. The Line:
: %PrintIt 1
starts the MACRO definition and defines that there will be at least one parameter at runtime. Calling the MACRO with less parameters will lead you to an error:
"Macrodefinition contains less parameters as Macrocall"
Now if we call the Macro later in our script we must give the MACRO one parameter, for example a number or a text or a variable. Like this:
%PrintIt Tomas
If we start the script, the Macro will be executed.
The DBP. command will write something like this in the Editor-Text-Area.
[10:22:14] [12] Hallo my dear Thomas
In the first bracket you can see the time when the Message was written. In the second bracket you will see the linenumber of the DBP.-command. In our case its the linenumber of our MACRO.
Executing MACROs in Single step mode will make the Editor "stay on the MACRO line" until the MACRO is completely executed. You can use the DBM.-command.
DBM.2
will make you see every line that was executed inside the MACRO.
Macros make sense, if you need to call subprograms several times in a script.
Like this:
DBM.2
: %PrintIt 1
DBP.Hallo my dear §§§01
:MyDupLabel
END%
%PrintIt Thomas
%PrintIt Ralf
ENR.
Now imagine you call your Macro several times and it contains a label (Jump mark for GTO./ JMP. (=GOTO).
What would happen?
The Macro would expand the Label each time and we would get a Error message:
"Duplicate Label ignored."
Similar problems could arise, if we used fixed variable names inside Macros, and these Macros would call themselves. Or would call other Macros that call these Macros.
To prevent these type of "duplication problems", the §§§95 to §§§99 preprocessor variables are provided. They will be expanded to a numeric value at preprocessing time.
This value has a defined format and will be increased by 1, each time a new MACRO Definition is been expanded. This way you can easily create unique labels and variable names.
Let's see an example:
: %MoreClicks 1
' Get the parameter into a variable
VAR.$$V§§§97=§§§01
IVV.$$V§§§97=0
JMP.Label§§§98
EIF.
FOR.$$X§§§97|1|$$V§§§97
MLC.
NEX.
:Label§§§98
END%
If we call our Macro like this:
%MoreClicks 3
%MoreClicks 4
The source code line
VAR.$$V§§§97=§§§01
will expand to something like that for the first Macro call:
VAR.$$V01=3
and like this for the second Macro call:
VAR.$$V02=4
As we can see, the §§§01 contains the first given parameter. You can call a MACRO with more parameters then defined, but not with less. We could give more parameters to our MACROS like that:
%MoreClicks 3|hallo|99
They are separated with the pipe symbol. In this case the additional parameters will be in
§§§01 -> 3
§§§02 -> hallo
§§§03 -> 99
We can also check how many parameters have been given to our MACRO using the #IF ... #EIF - Decisions in Macros option. The number of given parameters is available inside the §§§00 also.
You can use the special-preprocessor variables §§§95 to §§§99 and the §§§00 to make Macro-unique Labels and temporary variables inside the Macros.
Macros can call themselves. They can call Macros that contain calls to themselves.
They can be nested to any depth. This way you can use recursion to solve your problems. However, the resolver does not check for unlimited nesting.
You can use the #IF ... #EIF - Decisions in Macros #IF RECURS option to prevent unlimited Macro nesting, which will possibly lead to an memory error or stack overflow. Inside Macro-Definitions you can use these special variables:
- §§§95 - unique variable-counter variable, Format "000"
- §§§96 - unique variable-counter variable, Format "00"
- §§§97 - unique variable-counter variable, kein Format
- §§§98 - unique-Label counter-variable, kein Format
- §§§99 - actual recursion-depth at expansion time
- §§§00 - number of Parameters given to the Macro at call-time
Macro-Parameter Substitution:
§§§01 through §§§90 will be substituted with the Macro parameters, which are given to the Macro at call-time. Macro-Parameter must be separated with | (Pipe-Symbol/ASC 124).
Important Note:
Macro Names are case-sensitive!
Using false written Macro-Names will not give an error-message!
These lines will just be ignored.
Parameter Explanation
Macroname - must start with %. Can be of any length. Can not contain spaces.
P1 - Number, defines the minimum number of parameters required for this definition
You can call a MACRO with more parameters but not with less.
Example
'-----------------------------------------------------------
' Macro-Example 1
'-----------------------------------------------------------
: %Press 1
PRT.Forall
#IF PARAMS=1
SCW.ct|button|§§§01
MLC.
PRT.Nur 1 Parameter
#EIF
#IF PARAMS=2
SCW.ct|button|§§§01
MLC.
PRT.Zweiter: §§§02
#EIF
END%
STW.ct|PBWindowClass:0|TestApp
FOR.§§LOP|1|4
%Press Button 1
%Press Button 2
%Press Button 3|we did it!
NEX.
DMP.
MBX.Thats all.
END.
ENR.
'-----------------------------------------------------------
'----------------------------------------
' Macro-Example 2
'----------------------------------------
' Minimum Number of parameters is set to zero
: %MyMacroA 0
PRT.Number of Parameters:§§§00-Parameter=§§§01
END%
' Minimum Number of parameters is set to 1
: %MyMacroB 1
%MyMacroA Mytext
PRT.Number of Parameters:§§§00
END%
%MyMacroA Mytext
%MyMacroB Mytext
DMP.
END.
'----------------------------------------
' Macro-Example 3
'----------------------------------------
PRT.Running
: %Parameter 1
' Example for Macro-unique variable using §§§97
VAR.$$V§§§97=unique Variable
JMP.Label§§§98
PRT.Forall
#IF PARAMS=1
PRT.Only 1 Parameter: §§§01
#ELS
PRT.Not only 1 Parameter: §§§01,§§§02
#EIF
#IF PARAMS>2
PRT.More then 1 Parameter: §§§01,§§§02
#ELS
PRT.3 or more then 3 Parameter
#EIF
' Example for a Macro-unique Label, using §§§98
:Label§§§98
PRT.$$V§§§97
PRT.Macro-Recursion-Depth=§§§99
PRT.Macro- got §§§00 Parameters.
#IF RECURS<5
%Parameter §§§01
#EIF
END%
%Parameter 1
%Parameter 1|2
%Parameter 1|2|3
DMP.
MBX.1
END.
'----------------------------------------
' Macro-Example 3
'----------------------------------------
' Macro prüft und korrigiert parameter 1 gegen
' parameter 2 als Lower Bound und
' falls vorhanden gegen parameter 3 als upper bound
: %Check_Bounds 2
'Here we are!
IVV.§§§01<§§§02
: §§§01=§§§02
EIF.
#IF PARAMS>2
IVV.§§§01>§§§03
: §§§01=§§§03
EIF.
#ELS
PRT.Nur ein Parameter
#EIF
PRT.Hallo
END%
'----------------------------------------
' Macro-Example 4
'----------------------------------------
PRT.1-----
%Parameter 1
PRT.2-----
' Mit DMP.1 kann man sich das expandierte Skript anzeigen lassen.
DMP.1
MBX.Warten
ENR.
'===========================================================
: %Parameter 1
#IF RECURS<3
%Parameter §§§01
PRT.Hallo Depth is: §§§99
#EIF
END%
'----------------------------------------
' Macro-Example 5 using VBS.
'----------------------------------------
'Sample:
STW.ct|ConsoleWindowClass|Eingabeaufforderung
MLI.
VAR.$$NAM=DIR{ENTER}
%VB_Sendkeys $$NAM
ENR.
'------------------------------------
: %VB_Sendkeys
' Use TOS
#IF PARAMS=0
GSB.VB_Sendkeys|$tos$
#EIF
#IF PARAMS=1
GSB.VB_Sendkeys|§§§01
#EIF
END%
'------------------------------------
' P1 - Zu sendender Text
:VB_Sendkeys
SAV.Save|$$NAM
IVV.§§_00|=|1
$$NAM=§§_01
ELS.
$$NAM=Hallo Welt!{ENTER}
EIF.
' Auflösung da VBS. nur vorsichtig, binärkompatibel auflöst.
VAR.$$NAM=$$NAM
VBS.VB|Test|$$NAM
Option Explicit
Function Test(x)
Dim a
Set a = CreateObject("WScript.Shell")
a.SendKeys x(0)
End Function
VBE.
SAV.Restore
RET.
Remarks
Macro Names are case-sensitive!
Using false written Macro-Names will not give an error-message!
These lines will just be ignored.
Limitations:
-
See also:
See also:
•1.1 #INC: - Pre-Processor File-Include
•1.2 #ONCE / # OEND - Multiple Include Protection
•1.4 #IF ... #EIF - Decisions in Macros
See these commands: