Phase 4: Ereignisschleife und klassische Traps
This commit is contained in:
210
openspec/specs/ereignissteuerung/spec.md
Normal file
210
openspec/specs/ereignissteuerung/spec.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# ereignissteuerung Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Die Ereignissteuerung bestimmt, woher Ereignisse kommen, wann ein
|
||||
laufendes Programm sie zu sehen bekommt und wie es darauf reagiert:
|
||||
Ereignisquellen (Tastatur, Maus, Zeit, benutzerdefiniert) und ihre
|
||||
Warteschlange, die abschließende Liste der
|
||||
Zustellpunkte, die Maskierung je Quelle und global, sowie die Zustellung
|
||||
als `GOSUB` in das laufende Programm. Sie ist die gemeinsame Grundlage
|
||||
der klassischen Ereignis-Traps und späterer Forms-Ereignisse.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Ereignisquellen mit Zeit vom Host
|
||||
Die Laufzeit SHALL Ereignisse aus vier Quellen führen: Tastatur, Maus,
|
||||
Zeit und benutzerdefinierte Ereignisse. Die Zeit SHALL vom Host bezogen
|
||||
werden;
|
||||
die Laufzeit MUST NOT für die Ereigniszustellung selbst auf die
|
||||
Systemuhr zugreifen. Ein Host ohne Terminal MUST die Zeit frei stellen
|
||||
können, sodass zeitgesteuerte Programme ohne Wartezeit und mit
|
||||
reproduzierbarem Ergebnis prüfbar sind.
|
||||
|
||||
#### Scenario: Zeitgesteuerter Trap ohne echte Wartezeit
|
||||
- **WHEN** ein Testhost die Zeit um 5 Sekunden vorstellt und ein Programm `ON TIMER(5) GOSUB Marke` mit `TIMER ON` aktiv hat
|
||||
- **THEN** wird der Trap zugestellt, ohne dass der Test tatsächlich wartet
|
||||
|
||||
#### Scenario: Wiederholter Lauf liefert dasselbe Ergebnis
|
||||
- **WHEN** dasselbe zeitgesteuerte Korpusprogramm zweimal mit demselben Zeitverlauf ausgeführt wird
|
||||
- **THEN** ist die Ausgabe beide Male identisch
|
||||
|
||||
### Requirement: Mausereignisse in Zellenkoordinaten
|
||||
Die Darstellungsschicht SHALL Mausereignisse der Ausführungsumgebung an
|
||||
die Laufzeit weitergeben: Drücken, Loslassen und Bewegung, jeweils mit
|
||||
gedrückter Taste, Umschaltzustand und Position. Die Position SHALL in
|
||||
Zellen des Textbildschirms angegeben werden, gezählt wie bei `LOCATE`,
|
||||
also 1-basiert. Ereignisse außerhalb der aktuellen Bildschirmfläche MUST
|
||||
verworfen werden. Die Reihenfolge zwischen Maus- und Tastenereignissen
|
||||
SHALL der Reihenfolge ihres Eintreffens entsprechen. Solange kein
|
||||
Verbraucher ein Mausereignis annimmt, MUST es am Zustellpunkt verworfen
|
||||
werden, damit die Warteschlange nicht unbegrenzt wächst.
|
||||
|
||||
#### Scenario: Position als Zelle
|
||||
- **WHEN** in der linken oberen Ecke der Darstellungsfläche die linke Maustaste gedrückt wird
|
||||
- **THEN** trägt das Ereignis Zeile 1 und Spalte 1
|
||||
|
||||
#### Scenario: Reihenfolge bleibt erhalten
|
||||
- **WHEN** eine Taste gedrückt und danach die Maus geklickt wird
|
||||
- **THEN** liefert die Warteschlange erst das Tasten-, dann das Mausereignis
|
||||
|
||||
#### Scenario: Ereignis außerhalb der Fläche
|
||||
- **WHEN** ein Mausereignis eine Position außerhalb der aktuellen Bildschirmgröße nennt
|
||||
- **THEN** wird es verworfen und erreicht die Warteschlange nicht
|
||||
|
||||
#### Scenario: Kein Verbraucher, keine Anhäufung
|
||||
- **WHEN** ein Programm ohne Verbraucher für Mausereignisse läuft und die Maus dauerhaft bewegt wird
|
||||
- **THEN** wächst die Warteschlange nicht über ihre Grenze und das Programm läuft unverändert weiter
|
||||
|
||||
### Requirement: Abschließende Liste der Zustellpunkte
|
||||
Ereignisse SHALL ausschließlich an folgenden Punkten zugestellt werden
|
||||
— das Vorbild prüft die Ereignismarke „before executing the next
|
||||
statement":
|
||||
an einer Anweisungsgrenze, bei `DOEVENTS`, während `SLEEP` und vor einer
|
||||
blockierenden Eingabe. Zwischen zwei Zustellpunkten MUST NOT ein
|
||||
Trap-Handler beginnen; insbesondere MUST NOT eine Anweisung in ihrer
|
||||
Mitte unterbrochen werden. Ein zugestelltes Ereignis SHALL ein laufendes
|
||||
`SLEEP` beenden.
|
||||
|
||||
#### Scenario: Keine Zustellung innerhalb einer Anweisung
|
||||
- **WHEN** ein Ereignis fällig wird, während eine mehrteilige Anweisung ausgewertet wird
|
||||
- **THEN** läuft die Anweisung zu Ende und der Handler beginnt erst an der folgenden Anweisungsgrenze
|
||||
|
||||
#### Scenario: SLEEP endet durch Ereignis
|
||||
- **WHEN** ein Programm `SLEEP 60` ausführt und nach 2 Sekunden ein aktiver Trap fällig wird
|
||||
- **THEN** wird der Handler ausgeführt und `SLEEP` kehrt danach zurück, ohne die vollen 60 Sekunden abzuwarten
|
||||
|
||||
#### Scenario: DOEVENTS stellt zu
|
||||
- **WHEN** ein anstehendes Ereignis vorliegt und `DOEVENTS` ausgewertet wird
|
||||
- **THEN** läuft der zugehörige Handler, bevor `DOEVENTS` einen Wert liefert
|
||||
|
||||
### Requirement: Maskierung je Quelle mit drei Zuständen
|
||||
Jede Ereignisquelle SHALL drei Zustände kennen. `ON` stellt Ereignisse
|
||||
zu. `OFF` verwirft sie; ein während `OFF` eingetretenes Ereignis MUST
|
||||
NOT nachträglich zugestellt werden, und ein zuvor unter `STOP` gemerktes
|
||||
Ereignis MUST von `OFF` verworfen werden. `STOP` merkt höchstens ein
|
||||
anstehendes Ereignis und stellt es beim nächsten `ON` zu. Ohne
|
||||
vorangehende `ON …`-Trap-Definition MUST eine Steueranweisung wirkungslos
|
||||
bleiben, aber keinen Fehler auslösen.
|
||||
|
||||
#### Scenario: OFF verwirft
|
||||
- **WHEN** `TIMER OFF` gilt, die Frist verstreicht und danach `TIMER ON` ausgeführt wird
|
||||
- **THEN** wird kein Handler ausgeführt
|
||||
|
||||
#### Scenario: STOP merkt genau eines
|
||||
- **WHEN** `KEY(1) STOP` gilt, F1 dreimal gedrückt wird und danach `KEY(1) ON` ausgeführt wird
|
||||
- **THEN** läuft der Handler genau einmal
|
||||
|
||||
#### Scenario: OFF verwirft das unter STOP Gemerkte
|
||||
- **WHEN** `TIMER STOP` gilt, die Frist verstreicht, danach `TIMER OFF` und dann `TIMER ON` ausgeführt werden
|
||||
- **THEN** läuft kein Handler
|
||||
|
||||
### Requirement: EVENT klammert Abschnitte ohne Ereignisprüfung
|
||||
`EVENT OFF` SHALL die Ereignisprüfung für den folgenden Abschnitt
|
||||
abschalten, `EVENT ON` sie wieder einschalten; die beiden klammern einen
|
||||
Abschnitt, in dem keine Ereignisse erkannt werden müssen. Ein dritter
|
||||
Zustand MUST NOT bestehen: `EVENT STOP` ist im Vorbild nicht
|
||||
dokumentiert und MUST namentlich abgewiesen werden. Der Schalter SHALL
|
||||
die Zustände der einzelnen Quellen überlagern, ohne sie zu verändern:
|
||||
nach `EVENT ON` gilt für jede Quelle wieder ihr eigener Zustand.
|
||||
Ereignisse, die während `EVENT OFF` eintreten, MUST NOT nachträglich
|
||||
zugestellt werden.
|
||||
|
||||
#### Scenario: Klammer überlagert Einzelzustand
|
||||
- **WHEN** `TIMER ON` gilt und danach `EVENT OFF` ausgeführt wird
|
||||
- **THEN** wird kein Zeit-Trap zugestellt, und nach `EVENT ON` wird wieder zugestellt, ohne dass `TIMER ON` erneut nötig ist
|
||||
|
||||
#### Scenario: EVENT STOP gibt es nicht
|
||||
- **WHEN** ein Modul `EVENT STOP` enthält
|
||||
- **THEN** wird es namentlich abgewiesen
|
||||
|
||||
### Requirement: Zustellung als GOSUB ohne Wiedereintritt
|
||||
Ein zugestelltes Ereignis SHALL das `GOSUB`-Ziel seines Traps ausführen
|
||||
und danach an die unterbrochene Stelle zurückkehren; der unterbrochene
|
||||
Zustand (aufrufende Prozedur, Schleifen, Variablen) MUST erhalten
|
||||
bleiben. Beim Eintritt in den Handler SHALL für seine eigene Quelle
|
||||
selbsttätig `STOP` wirken, sodass keine rekursiven Traps entstehen; das
|
||||
`RETURN` SHALL für sie selbsttätig `ON` ausführen — es sei denn, im
|
||||
Handler wurde ausdrücklich `OFF` für diese Quelle ausgeführt, dann bleibt
|
||||
sie aus. Ein `RETURN label` aus einem Handler MUST erlaubt sein.
|
||||
|
||||
#### Scenario: Rückkehr in die unterbrochene Schleife
|
||||
- **WHEN** ein Trap während einer `FOR`-Schleife zugestellt wird
|
||||
- **THEN** läuft die Schleife nach `RETURN` mit unverändertem Zählerstand weiter
|
||||
|
||||
#### Scenario: Kein Wiedereintritt
|
||||
- **WHEN** ein Zeit-Trap läuft und die nächste Frist während des Handlers verstreicht
|
||||
- **THEN** wird der Handler nicht erneut betreten, sondern das Ereignis nach `RETURN` einmal zugestellt
|
||||
|
||||
#### Scenario: OFF im Handler überlebt das RETURN
|
||||
- **WHEN** ein Handler `TIMER OFF` ausführt und danach `RETURN` erreicht
|
||||
- **THEN** bleibt die Quelle aus und kein weiterer Zeit-Trap wird zugestellt
|
||||
|
||||
### Requirement: Getrappte Tasten verlassen den Eingabestrom
|
||||
Eine Taste, für die ein aktiver `ON KEY`-Trap besteht, SHALL dem Trap
|
||||
zugestellt werden und MUST NOT zusätzlich über `INKEY$`, `INPUT`,
|
||||
`LINE INPUT` oder `INPUT$` sichtbar werden. Bei `OFF` oder `STOP` der
|
||||
Quelle SHALL die Taste dem normalen Eingabestrom erhalten bleiben.
|
||||
|
||||
#### Scenario: Getrappte Taste erscheint nicht bei INKEY$
|
||||
- **WHEN** `ON KEY(1) GOSUB Marke` mit `KEY(1) ON` gilt und F1 gedrückt wird
|
||||
- **THEN** läuft der Handler und ein anschließendes `INKEY$` liefert den leeren String
|
||||
|
||||
#### Scenario: Nicht getrappte Taste bleibt im Strom
|
||||
- **WHEN** derselbe Trap mit `KEY(1) OFF` gilt und F1 gedrückt wird
|
||||
- **THEN** liefert `INKEY$` die Sondertastenfolge für F1
|
||||
|
||||
### Requirement: Benutzerdefiniertes Ereignis
|
||||
`SetUEvent` SHALL ein benutzerdefiniertes Ereignis auslösen, das über
|
||||
`ON UEVENT GOSUB` und die Steueranweisung `UEVENT` denselben Regeln für
|
||||
Maskierung und Zustellung unterliegt wie die übrigen Quellen.
|
||||
|
||||
#### Scenario: SetUEvent löst den Handler aus
|
||||
- **WHEN** `ON UEVENT GOSUB Marke` mit `UEVENT ON` gilt und `SetUEvent` aufgerufen wird
|
||||
- **THEN** läuft der Handler am nächsten Zustellpunkt genau einmal
|
||||
|
||||
### Requirement: Reihenfolge bei mehreren fälligen Ereignissen
|
||||
Sind an einem Zustellpunkt mehrere Ereignisse fällig, SHALL genau eines
|
||||
zugestellt werden; die übrigen bleiben anstehend und werden an
|
||||
folgenden Zustellpunkten zugestellt. Die Reihenfolge SHALL festgelegt
|
||||
und dokumentiert sein, sodass sie über Läufe hinweg gleich bleibt.
|
||||
|
||||
#### Scenario: Zwei gleichzeitig fällige Traps
|
||||
- **WHEN** an einem Zustellpunkt ein Zeit- und ein Tasten-Trap zugleich fällig sind
|
||||
- **THEN** läuft zuerst genau ein Handler und der andere am nächsten Zustellpunkt
|
||||
|
||||
### Requirement: Fehler in einem Handler
|
||||
Ein Laufzeitfehler in einem Trap-Handler SHALL der geltenden
|
||||
Fehlerbehandlung unterliegen. `RESUME` und `RESUME NEXT` SHALL sich auf
|
||||
die Anweisung im Handler beziehen, nicht auf die unterbrochene
|
||||
Anweisung.
|
||||
|
||||
#### Scenario: Fehler im Handler erreicht den Handler des Moduls
|
||||
- **WHEN** ein Trap-Handler eine Anweisung mit Laufzeitfehler ausführt und ein modulweiter `ON ERROR GOTO`-Handler gesetzt ist
|
||||
- **THEN** wird dieser Handler betreten und `ERL` nennt die Zeile im Trap-Handler
|
||||
|
||||
### Requirement: Signal-Trap auf Betriebssystemsignalen
|
||||
`ON SIGNAL(n%) GOSUB` und die Steueranweisung `SIGNAL(n%)` SHALL
|
||||
denselben Regeln für Maskierung, Zustellung und Wiedereintritt
|
||||
unterliegen wie die übrigen Quellen. `n%` SHALL auf
|
||||
Betriebssystemsignale abgebildet werden, und zwar ausschließlich auf die
|
||||
Menge, die auf allen Zielplattformen besteht: 1 auf den
|
||||
Unterbrechungswunsch (`SIGINT`), 2 auf den Beendigungswunsch
|
||||
(`SIGTERM`). Ein anderer Wert MUST namentlich abgewiesen werden — zur
|
||||
Übersetzungszeit, wenn er konstant ist, sonst mit Laufzeitfehler 5. Ein
|
||||
Signal MUST NOT im Signalkontext verarbeitet werden; es SHALL über den
|
||||
Host als Ereignis in die Warteschlange gelangen. Die Abweichung zur
|
||||
OS/2-gebundenen Quelle des Vorbilds SHALL in der Sprachreferenz
|
||||
ausgewiesen sein.
|
||||
|
||||
#### Scenario: Signal-Trap folgt der Maskierung
|
||||
- **WHEN** `ON SIGNAL(1) GOSUB Marke` mit `SIGNAL(1) STOP` gilt und ein `SIGINT` eintrifft
|
||||
- **THEN** läuft der Handler erst nach `SIGNAL(1) ON`, und zwar genau einmal
|
||||
|
||||
#### Scenario: Unzulässige Signalnummer
|
||||
- **WHEN** ein Modul `ON SIGNAL(7) GOSUB Marke` enthält
|
||||
- **THEN** wird es namentlich abgewiesen und die Meldung nennt den zulässigen Bereich
|
||||
|
||||
#### Scenario: Signal ohne Trap bleibt Abbruch
|
||||
- **WHEN** ein `SIGINT` eintrifft, ohne dass ein `SIGNAL(1)`-Trap aktiv ist
|
||||
- **THEN** bleibt es beim bisherigen Abbruchverhalten
|
||||
@@ -110,3 +110,21 @@ durchlaufen und danach die neuen Grenzen ausnutzen.
|
||||
#### Scenario: Größenänderung mitten im Programm
|
||||
- **WHEN** der Test-Host während der Ausführung von 80×25 auf 120×40 wechselt
|
||||
- **THEN** bleibt der bisherige Inhalt oben links erhalten und die anschließende Ausgabe nutzt die neuen Grenzen
|
||||
|
||||
### Requirement: Korpusabdeckung der Ereignis-Traps
|
||||
Der Testkorpus SHALL die Ereignissteuerung mit Programmen abdecken, die
|
||||
ohne echte Wartezeit und mit reproduzierbarer Ausgabe laufen: Zeit-Trap,
|
||||
Tasten-Trap einschließlich der Frage, ob die Taste im Eingabestrom
|
||||
verbleibt, benutzerdefiniertes Ereignis, die drei Maskierungszustände je
|
||||
Quelle, der Hauptschalter `EVENT` sowie Rückkehr und Nicht-Wiedereintritt
|
||||
eines Handlers. Ein Korpusprogramm mit Zeitbezug SHALL seinen
|
||||
Zeitverlauf im Programmkopf deklarieren; ohne Deklaration MUST der
|
||||
Harness den Lauf abweisen statt auf die Systemuhr auszuweichen.
|
||||
|
||||
#### Scenario: Zeit-Trap im Korpus
|
||||
- **WHEN** ein Korpusprogramm mit deklariertem Zeitverlauf und `ON TIMER` ausgeführt wird
|
||||
- **THEN** entspricht der Bildschirminhalt byte-genau der Sollausgabe und der Lauf benötigt keine messbare Wartezeit
|
||||
|
||||
#### Scenario: Fehlende Zeitdeklaration
|
||||
- **WHEN** ein Korpusprogramm zeitgesteuerte Traps nutzt, aber keinen Zeitverlauf deklariert
|
||||
- **THEN** schlägt der Harness mit einer Meldung fehl, die die fehlende Deklaration nennt
|
||||
|
||||
@@ -199,3 +199,51 @@ Bezeichner oder mit einem generischen Syntaxfehler abgewiesen werden
|
||||
#### Scenario: Typprüfung des Satzarguments
|
||||
- **WHEN** `RETRIEVE #1, x$` mit einem String statt einer Variablen des Tabellentyps geprüft wird
|
||||
- **THEN** wird „Type mismatch" mit Quelltextposition gemeldet
|
||||
|
||||
### Requirement: Ereignis-Traps in Grammatik und Signaturprüfung
|
||||
Der Parser SHALL die Trap-Anweisungen des Vorbilds als eigene Konstrukte
|
||||
erkennen: `ON TIMER(n) GOSUB ziel`, `ON KEY(n) GOSUB ziel`,
|
||||
`ON UEVENT GOSUB ziel` und `ON SIGNAL(n) GOSUB ziel`. Diese Formen MUST
|
||||
NOT als berechnetes `ON ausdruck GOSUB liste` behandelt werden. Die
|
||||
Steueranweisungen `TIMER`, `KEY(n)`, `UEVENT` und `SIGNAL(n)` mit `ON`,
|
||||
`OFF` oder `STOP` SHALL erkannt und nur für diese Quellen zugelassen
|
||||
werden; `EVENT` SHALL nur `ON` und `OFF` zulassen, weil das Vorbild
|
||||
keinen dritten Zustand kennt. `COM`, `PEN`, `PLAY` und `STRIG` MUST als
|
||||
Non-Feature namentlich abgewiesen werden. `SetUEvent` SHALL eine
|
||||
Signatur besitzen. Die Wertebereiche SHALL geprüft werden: `ON KEY(n%)`
|
||||
mit `n%` aus 0, 1–25 oder 30–31, `ON TIMER(n&)` mit `n&` aus 1–86 400
|
||||
und `ON SIGNAL(n%)` mit `n%` aus 1–2. Eine fehlerhafte Verwendung MUST
|
||||
eine Diagnose erzeugen, die das Element namentlich nennt.
|
||||
|
||||
#### Scenario: ON TIMER ist kein berechnetes GOSUB
|
||||
- **WHEN** ein Modul `ON TIMER(5) GOSUB Marke` enthält
|
||||
- **THEN** wird die Anweisung als Zeit-Trap erfasst und nicht als `ON ausdruck GOSUB` mit einer einelementigen Zielliste
|
||||
|
||||
#### Scenario: Ungültige Kennung wird namentlich gemeldet
|
||||
- **WHEN** ein Modul `ON KEY(99) GOSUB Marke` enthält
|
||||
- **THEN** nennt die Diagnose `ON KEY` und den zulässigen Wertebereich
|
||||
|
||||
#### Scenario: EVENT kennt kein STOP
|
||||
- **WHEN** ein Modul `EVENT STOP` enthält
|
||||
- **THEN** nennt die Diagnose `EVENT` und die zulässigen Formen `ON` und `OFF`
|
||||
|
||||
#### Scenario: Zeitintervall außerhalb des Bereichs
|
||||
- **WHEN** ein Modul `ON TIMER(90000) GOSUB Marke` enthält
|
||||
- **THEN** nennt die Diagnose `ON TIMER` und den Bereich 1 bis 86400
|
||||
|
||||
#### Scenario: Non-Feature-Quelle wird abgewiesen
|
||||
- **WHEN** ein Modul `ON PEN GOSUB Marke` enthält
|
||||
- **THEN** meldet die Übersetzung „Feature unavailable" an der Fundstelle der Anweisung — wie bei jedem anderen Non-Feature — und nicht einen generischen Syntaxfehler
|
||||
|
||||
#### Scenario: SetUEvent besitzt eine Signatur
|
||||
- **WHEN** ein Modul `CALL SetUEvent` enthält
|
||||
- **THEN** entsteht keine Diagnose „Subprogram not defined"
|
||||
|
||||
### Requirement: Trap-Ziele sind Sprungziele des Moduls
|
||||
Das Ziel eines Ereignis-Traps SHALL wie ein `GOSUB`-Ziel aufgelöst
|
||||
werden. Ein unbekanntes Ziel MUST zur Übersetzungszeit gemeldet werden
|
||||
und nennt dabei das Label.
|
||||
|
||||
#### Scenario: Unbekanntes Trap-Ziel
|
||||
- **WHEN** ein Modul `ON TIMER(1) GOSUB Fehlt` ohne Label `Fehlt` enthält
|
||||
- **THEN** meldet die Übersetzung ein undefiniertes Sprungziel und nennt `Fehlt`
|
||||
|
||||
@@ -114,3 +114,44 @@ Programmbestandteil.
|
||||
#### Scenario: STOP im Runner
|
||||
- **WHEN** ein per `tbc run` gestartetes Programm `STOP` in Zeile 7 ausführt
|
||||
- **THEN** endet der Prozess mit Exit-Code ungleich 0 und die Meldung nennt Zeile 7
|
||||
|
||||
### Requirement: Ereigniszustellung an Anweisungsgrenzen
|
||||
Die VM SHALL an Anweisungsgrenzen prüfen, ob ein Ereignis zuzustellen
|
||||
ist, und in diesem Fall das `GOSUB`-Ziel des zugehörigen Traps
|
||||
ausführen. Der unterbrochene Zustand — Aufrufkette, Schleifen, Locals,
|
||||
`GOSUB`-Stapel und Fehlerzustand — MUST dabei erhalten bleiben; mit
|
||||
`RETURN` SHALL die Ausführung an der unterbrochenen Stelle fortfahren.
|
||||
Die Prüfung MUST NOT pro Opcode erfolgen; solange kein Trap definiert ist,
|
||||
MUST sie auf einen einzelnen Test hinauslaufen und MUST NOT die Uhr lesen.
|
||||
|
||||
#### Scenario: Trap aus einer Prozedur heraus
|
||||
- **WHEN** ein Ereignis zugestellt wird, während eine `SUB` läuft, und das Trap-Ziel im Modulrumpf liegt
|
||||
- **THEN** läuft der Handler und nach `RETURN` setzt die `SUB` an der unterbrochenen Anweisung fort
|
||||
|
||||
#### Scenario: Ohne aktiven Trap wird die Uhr nicht gelesen
|
||||
- **WHEN** ein Programm ohne jede `ON …`-Trap-Definition ausgeführt wird
|
||||
- **THEN** fragt die Ausführung an keiner Anweisungsgrenze die Zeit ab, und der Durchsatz bleibt im Rahmen der Messgenauigkeit unverändert
|
||||
|
||||
### Requirement: Jede Schleife trägt eine Anweisungsgrenze im Kreis
|
||||
Der zurückspringende Zweig jeder Schleife (`FOR`/`NEXT`, `WHILE`/`WEND`,
|
||||
`DO`/`LOOP` in allen Bedingungsformen) MUST über mindestens eine
|
||||
Anweisungsgrenze führen, auch wenn der Schleifenrumpf leer ist. Andernfalls
|
||||
gäbe es in einer Warteschleife keinen Zustellpunkt: kein Ereignis, kein
|
||||
Breakpoint und kein Abbruch würden dort wirken.
|
||||
|
||||
#### Scenario: Leere Warteschleife
|
||||
- **WHEN** `FOR i% = 1 TO 10000` unmittelbar von `NEXT` gefolgt wird
|
||||
- **THEN** führt der Rücksprung über eine Anweisungsgrenze und ein aktiver Zeit-Trap wird darin zugestellt
|
||||
|
||||
#### Scenario: Leere Schleife in jeder Form
|
||||
- **WHEN** eine `WHILE`/`WEND`-, `DO WHILE`/`LOOP`- oder `DO`/`LOOP UNTIL`-Schleife ohne Rumpf übersetzt wird
|
||||
- **THEN** liegt zwischen Rücksprungziel und Rücksprung eine Anweisungsgrenze
|
||||
|
||||
### Requirement: DOEVENTS gibt die Kontrolle ab
|
||||
`DOEVENTS` SHALL anstehende Ereignisse zustellen und danach einen Wert
|
||||
liefern. Solange keine Formulare geladen werden können, SHALL der Wert 0
|
||||
sein.
|
||||
|
||||
#### Scenario: DOEVENTS in einer Warteschleife
|
||||
- **WHEN** ein Programm in einer Schleife `DOEVENTS` aufruft und ein Trap fällig wird
|
||||
- **THEN** läuft der Handler innerhalb dieser Schleife
|
||||
|
||||
Reference in New Issue
Block a user