Easter-Egg Befehle im MPR Part VI - Der LIFO-Stapel

Moderator: MVogt

Easter-Egg Befehle im MPR Part VI - Der LIFO-Stapel

Beitragvon Theo_Gottwald » 12. Feb 2017, 14:04

Letzte Woche habe ich mal alte Entwickler-Unterlagen nachgesehen von vor etlichen Jahren.
Und tatsächlich es gibt Befehle, die der MPR kann und die gar nicht in der Hilfe stehen.
Undokumentierte "Geheimbefehle".

Thema in Part VI: Der LIFO-Stapel.

****************************
d_init_stack
****************************

Um verschachtelte Ausdrücke zu parsen, ist ein Stapel-Datentyp sehr hilfreich.

Der "Stack", zu Deutsch "Stapel", ist ein sogenannter LIFO-Datentyp. Das bedeutet "Last-In-First-Out".
Dasjenige Element, welches man zuletzt hinzugefügt hat, ist dasjenige, das man zuerst wieder zurückbekommt.
Vergleichbar mit den Karten auf einem Kartenspiel. Die oberste Karte ist die letzte Karte (Last IN), die auf den Kartenstapel gepackt wurde, so ist sie automatisch die erste Karte (first out), die man von OBEN auch wieder herunternehmen kann.

Wir alle kennen solche Stapel aus dem täglichen Arbeitsleben: das Ein- und Ausgangskörbchen in jedem Büro ist solch ein Stapel.
Um solche Vorgänge script-technisch nachzubilden gibt es nun den Stapel-Datentyp.
Es gibt also nicht nur einen Stapel, sondern viele Stapel.
Um das Scripting damit übersichtlich zu gestalten, bekommen diese Stapel vom User jeweils Namen, damit diese vom System ansprechbar werden.

Hinweis: Wenn man sich z.B. vom Spielkartenstapel die oberste Karte herunternimmt, so ist diese EXKLUSIV in der Hand und auf dem Stapel steht die nächste Karte zur Verfügung. Das ist das normale Verhalten, das wir alle kennen.
Mit dem Parameter "N", kann man dafür sorgen, dass man einen Blick auf die oberste Karte erhält, diese bleibt aber liegen.
Somit hat man quasi eine Kopie der Karte vor Augen.
Um nun wirklich an die nächste Karte vom Stapel zu bekommen, muss man nun manuell dem System sagen, dass die oberste Karte gelöscht werden soll (d_del_stack_item).

Wenn man einen Stapel verwenden möchte, muss man diesen zunächst benennen. Dazu dient der folgende Befehl:

Code: Alles auswählen
GRN\d_init_stack|(Name des Stapels)|(Autodeletefunktion an/aus) durch N oder weglassen


Ab dann steht ein Stapel mit diesem Namen zur Verfügung.
Es gibt die Möglichkeit, als weiteren Parameter das "N" wie "NoAutoDelete" anzugeben.
Ist dieser Parameter gesetzt, dann wird beim Abheben eines Elementes von diesem Stack dieses Element nicht automatisch gelöscht.
Existiert ein Stack dieses Namens bereits, löscht der Befehl den Stack und setzt das "N"-Bit neu.
Nach dem Erzeugen eines Stapels, wird dieser Stapel automatisch selektiert. Das bedeutet, dass "Push" und "Pop" Befehle dann auf diesen Stapel angewendet werden.
Beispiel:

Code: Alles auswählen
GRN\d_init_stack|Loops

' Im folgenden Beispiel wird die "N" Option verwendet.
' Bei diesem Stack werden beim Abheben die Elemente nicht automatisch gelöscht.
' Dies muss man dann explizit mit "d_del_stack_item" tun, da die N Option aktiv ist.
GRN\d_init_stack|Loops|N


****************************
d_select_stack
****************************

Zum Beispiel beim Parsen von XML genügt ein Stack nicht, man benötigt mehrere Stacks.
Um nun festzulegen, welchen der Stacks man aktuell verwendet, wird dieser Befehl benötigt.
Beispiel:
Code: Alles auswählen
GRN\d_init_stack|Loops
' Der neuerliche "d_init_stack" selektiert automatisch den Stack "Ferz"
GRN\d_init_stack|Ferz
' Nun benötigt man den Loops-Stack; also selektiert man diesen
GRN\d_select_stack|Loops

' Löscht das oberste Item von dem gerade selektierten Stack.
GRN\d_del_stack_item
' Löscht die obersten 4 Items von dem gerade selektierten Stack.
GRN\d_del_stack_item||4


****************************
d_push_on_stack
****************************

Und wie kommen die Items nun auf den Stack? Mit "d_push_on_stack" natürlich.
Die Syntax lautet:
Code: Alles auswählen
GRN\d_push_on_stack|(Item-String)[|(Item-String 2) ...


Beispiel:
Code: Alles auswählen
GRN\d_init_stack|Loops
' Wir legen drei Items auf den neu erstellten Stapel
GRN\d_push_on_stack|Line 150|Line 160|Line 170


****************************
d_pop_from_stack
****************************

Sinn macht das Ganze natürlich erst, wenn wir die Items auch wieder vom Stack zurückbekommen. Das geht mit:

Code: Alles auswählen
GRN\d_pop_from_stack>$$ITM


Man hat die Möglichkeit hier noch den Namen eines Stapels anzugeben:

Code: Alles auswählen
GRN\d_pop_from_stack|Loops>$$ITM


Dann wird das Item von diesem Stapel genommen. Der Stapel wird aber nicht selektiert.
Ein nachfolgender

Code: Alles auswählen
GRN\d_pop_from_stack>$$ITM


wird also das Item vom derzeit selektierten Stapel nehmen.

****************************
d_del_stack_item
****************************

Will man Items vom Stapel entfernen, zum Beispiel weil die Option "N" beim Deklarieren des Stacks (siehe: d_init_stack) verwendet wurde, so ist dies der Befehl der Wahl. Man kann optional noch den Namen eines Stacks und die Anzahl der Items, die gelöscht werden sollen, angeben.

Code: Alles auswählen
' Löscht das oberste Item vom aktuellen Stack
GRN\d_del_stack_item

' Löscht das oberste Item vom Stack "Loops"
GRN\d_del_stack_item|Loops
 
' Löscht die obersten 5 Items vom Stack "Loops"
GRN\d_del_stack_item|Loops|5
 
' Löscht die obersten 5 Items vom aktuell selektierten Stack
GRN\d_del_stack_item||5


Der Befehl gibt auf Wunsch die Anzahl der noch auf dem Stack verbleibenden Elemente zurück.
Code: Alles auswählen
GRN\d_del_stack_item||5>$$CNT


****************************
d_get_stack_count
****************************

Gibt die Anzahl der Elemente auf dem jeweiligen Stapel zurück. Gibt man keinen Stapelnamen an, wird der aktuelle Stapel verwendet.
Gibt man den Namen eines Stapels an, wird dieser verwendet.

Code: Alles auswählen
' Hier bezieht sich der Befehl auf den selektierten Stack
GRN\d_get_stack_count>$$CNT
' Hier bezieht sich der Befehl auf den Stack mit Namen "Loops"
GRN\d_get_stack_count|Loops>$$CNT


****************************
d_erase_stack
****************************

Diese Funktion löscht den Stack und zwar auch den Stack-Namen. Er kann danach für einen neuen Stack erneut mit "d_init_stack" verwendet werden.
Beim Beenden des Scripts werden alle Stackspeicher sowieso freigegeben, dies ist also nicht unbedingt manuell erforderlich.
Bitte bei diesem Befehl den Namen des zu löschenden Stacks stets explizit angeben.

Code: Alles auswählen
GRN\d_erase_stack|Loops

' Im Folgenden erhält $$STK die Anzahl noch deklarierter Stacks.
GRN\d_erase_stack|Loops>$$STK


Aber noch Mal der Hinweis: Die Befehls stehe nicht in der Hilfe und sind derzeit offiziell nicht vorhanden obwohl sie jeder MPR Nutzer sofort nutzen kann. Also dazu ist kein Update nötig die Befehle sind da schon drin und zwar seit Jahren.
Benutzeravatar
Theo_Gottwald
 
Beiträge: 291
Registriert: 03. Okt 2009, 08:57
Wohnort: Herrenstr.11 * 76706 Dettenheim

Zurück zu Package Robot

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast