Macros


Syntax
Macro <Name> [(Parameter [, ...])]
  ...
EndMacro 
Beschreibung
Makros (englisch "Macros") sind ein sehr mächtiges Feature, hauptsächlich nützlich für fortgeschrittene Programmierer. Ein Makro ist ein Platzhalter für etwas Code (ein Schlüsselwort, eine Zeile oder auch viele Zeilen), welcher (beim Kompilieren) direkt an der Stelle, wo das Makro aufgerufen wird, in den Programmcode eingefügt wird.

In dieser Beziehung unterscheidet es sich von Prozeduren, da Prozeduren beim Aufrufen nicht den Code duplizieren.

Die Macro : EndMacro Deklaration muss vor dem ersten Aufruf des Makros erfolgen. Da Makros zur Kompilier-Zeit komplett durch ihren zugehörigen Code ersetzt werden, sind sie nicht lokal zu einer Prozedur, etc.

Ein Makro kann weder einen Rückgabewert noch typenbasierte Parameter haben. Wenn ein Makro einige Parameter hat, werden diese im Makro exakt durch den wörtlichen Ausdruck ersetzt, der beim Aufruf des Makros an dieses übergeben wurde. Zu diesem Zeitpunkt wird keine Auswertung vorgenommen, was sehr wichtig zum Verstehen ist: Die Auswertung einer Code-Zeile wird begonnen, sobald alle auf dieser Zeile gefundenen Makros erweitert (d.h. durch ihren Inhalt ersetzt) wurden.

Die Makros werden in zwei Kategorien eingeteilt: Einfache (ohne Parameter) und komplexe (mit Parameter, benötigen Klammern beim Aufruf). Bei der Verwendung ohne Parameter ist es möglich, jedes Wort mit einem anderen Wort (oder jeden Ausdrucks) zu ersetzen. Die Makros können rekursiv verwendet werden; wenn jedoch der übergebene Parameter das Verkettungszeichen '#' beinhaltet, wird es nicht erweitert.

Beispiel: Einfaches Makro

  Macro MyNot
    Not
  EndMacro

  a = 0
  If MyNot a   ; Hier wird die Zeile erweitert auf: 'If Not a'
    Debug "Ok"
  EndIf
  
Mit der Verwendung von Parametern ist es möglich, sehr flexible Makros zu erschaffen. Das spezielle Verknüpfungszeichen '#' kann benutzt werden, um neue Labels oder Keywords (Schlüsselwörter) durch Mischen von Makro-Code und Parameter-Ausdrücken zu erschaffen (Leerzeichen zwischen jedem Wort werden durch das Verknüpfungszeichen nicht akzeptiert). Es ist auch möglich, Standardwerte für Parameter zu definieren, sodass sie beim Aufruf des Makros weggelassen werden können.

Beispiel: Makro mit Parameter

  Macro UMsgBox(Title, Body)
    MessageRequester(Title, UCase(Body), 0)
  EndMacro

  Text$ = "World"
  UMsgBox("Hello", "-"+Text$+"-") ; Hier wird die Zeile wie folgt erweitert:
                                  ; 'MessageRequester("Hello", UCase("-"+Text$+"-"), 0)'

Beispiel: Makro mit Standard-Parameter

  Macro UMsgBox(Title, Body = "Ha, no body specified")
    MessageRequester(Title, UCase(Body), 0)
  EndMacro

  UMsgBox("Hello") ; Hier wird die Zeile wie folgt erweitert:
                   ; 'MessageRequester("Hello", UCase("Ha, no body specified"), 0)'

Beispiel: Makro mit Parameter-Verknüpfung

  Macro XCase(Type, Text)
    Type#Case(Text)
  EndMacro

  Debug XCase(U, "Hello")
  Debug XCase(L, "Hello")
  

Beispiel: Fortgeschrittenes mehrzeiliges Makro

  Macro DoubleQuote
    "
  EndMacro

  Macro Assert(Expression)
    CompilerIf #PB_Compiler_Debugger  ; 'Assert' (Erklärung) nur im Debug-Modus aktivieren
      If Expression
        Debug "Assert (Line " + #PB_Compiler_Line + "): " + DoubleQuote#Expression#DoubleQuote
      EndIf
    CompilerEndIf
  EndMacro

  Assert(10 <> 10) ; Wird nichts anzeigen
  Assert(10 <> 15) ; Sollte die Erklärung anzeigen
  

Syntax
UndefineMacro <Name>
Beschreibung
UndefineMacro ermöglicht das Löschen (englisch "Undefine") eines zuvor definierten Makros, und das neue Definieren in einer anderen Art und Weise. Sobald ein Makro gelöscht ("undefined") wurde, steht es nicht mehr für die weitere Verwendung zur Verfügung.

Beispiel: Löschen eines Makros

  Macro Test
    Debug "1"
  EndMacro
  
  Test ; Aufrufen des Makros
  
  UndefineMacro Test ; Löschen des Makros, es existiert jetzt nicht mehr
  
  Macro Test ; Jetzt können wir das Makro erneut definieren
    Debug "2"
  EndMacro
  
  Test ; Aufrufen des Makros
  

Syntax
MacroExpandedCount
Beschreibung
Mittels MacroExpandedCount kann die Anzahl der "Erweiterungen" (englisch "expanded count", d.h. die Anzahl wie oft ein Makro erweitert/aufgerufen wurde) ermittelt werden. Dies kann nützlich sein, um bei jeder Erweiterung/jedem Aufruf einen eindeutigen Bezeichner im gleichen Makro zu generieren (wie Sprungmarken, Prozedur-Namen, etc.).

Beispiel: Anzahl der Makro-Aufrufe

  Macro Test
    Debug MacroExpandedCount
  EndMacro
  
  Test ; Aufrufen des Makros
  Test ; Aufrufen des Makros
  Test ; Aufrufen des Makros