Phase 4: Ereignisschleife und klassische Traps
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
# Umfang und Form der Ereignis-Elemente (Aufgaben 1.1, 1.2)
|
||||
|
||||
**Quelle.** `bas7advr.hlp` (BASIC 7 Advisor), Einzelseiten unter
|
||||
https://dos-help.soulsphere.org/bas7advr.hlp/ (abgerufen 2026-09-04);
|
||||
Gegenprobe `qb45advr.hlp` unter derselben Domain. Zitate wörtlich aus den
|
||||
Einzelseiten, Übersetzung nur in den Kommentarzeilen.
|
||||
|
||||
## 1.1 Einzelseiten
|
||||
|
||||
| Element | Seite |
|
||||
|---|---|
|
||||
| `ON TIMER` | `x_dot_ontimerrr.html` |
|
||||
| `ON KEY` | `x_dot_onkeyr.html` |
|
||||
| `ON UEVENT` | `x_dot_onur.html` |
|
||||
| `ON SIGNAL` | `x_dot_onsigbar.html` |
|
||||
| `TIMER` (Anweisung) | `x_dot_timersr.html` |
|
||||
| `KEY(n)` (Ereignis) | `x_dot_ketvr.html` |
|
||||
| `UEVENT` | `x_dot_uevvvr.html` |
|
||||
| `SIGNAL` | `x_dot_signalr.html` |
|
||||
| `EVENT` | `x_dot_evntonr.html` |
|
||||
| `SetUEvent` | `x_dot_SETUEVr.html` |
|
||||
|
||||
### ON TIMER
|
||||
|
||||
> `ON TIMER(n&) GOSUB {linenumber | linelabel}`
|
||||
>
|
||||
> „The maximum number of seconds that can be specified for the time
|
||||
> interval, n&, is the number of seconds in a 24-hour day (86,400)."
|
||||
>
|
||||
> „A linenumber value of 0 disables event trapping and does not specify
|
||||
> line 0 as the start of the routine."
|
||||
|
||||
Der Zeitwert ist **LONG** (`n&`), Bereich 1–86 400 Sekunden.
|
||||
`GOSUB 0` schaltet den Trap ab.
|
||||
|
||||
### TIMER ON/OFF/STOP
|
||||
|
||||
> „TIMER ON enables timer-event trapping."
|
||||
>
|
||||
> „TIMER OFF disables timer-event trapping. … Events occurring while
|
||||
> trapping is off are ignored."
|
||||
>
|
||||
> „TIMER STOP suspends timer-event trapping. … Events occurring while
|
||||
> trapping is off are remembered and processed when the next TIMER ON
|
||||
> statement is executed."
|
||||
|
||||
**Wiedereintritt — wörtlich belegt:**
|
||||
|
||||
> „an automatic TIMER STOP is executed so that recursive traps cannot
|
||||
> take place."
|
||||
>
|
||||
> „The RETURN from the trapping routine automatically performs a TIMER ON
|
||||
> statement unless an explicit TIMER OFF was performed inside the
|
||||
> routine."
|
||||
|
||||
Das ist genauer als „die Quelle gilt während des Handlers als gestoppt":
|
||||
`RETURN` schaltet die Quelle **auf ON**, außer im Handler stand ein
|
||||
ausdrückliches `OFF`.
|
||||
|
||||
### KEY(n) — Wertebereich
|
||||
|
||||
> ```
|
||||
> KEY(n%) ON
|
||||
> KEY(n%) OFF
|
||||
> KEY(n%) STOP
|
||||
> ```
|
||||
|
||||
| n% | Taste |
|
||||
|---|---|
|
||||
| 0 | alle Tasten dieser Tabelle |
|
||||
| 1–10 | F1–F10 |
|
||||
| 11 | Pfeil hoch |
|
||||
| 12 | Pfeil links |
|
||||
| 13 | Pfeil rechts |
|
||||
| 14 | Pfeil runter |
|
||||
| 15–25 | benutzerdefinierte Tasten |
|
||||
| 30–31 | F11–F12 (101-Tasten-Tastatur) |
|
||||
|
||||
`ON KEY` selbst: `ON KEY(n%) GOSUB {linenumber | linelabel}`. Zur Frage,
|
||||
ob eine getrappte Taste im Eingabestrom bleibt, sagt die Einzelseite nur:
|
||||
|
||||
> „After a key is trapped, the information on which key was trapped is no
|
||||
> longer available."
|
||||
|
||||
Die Gegenprobe in `qb45advr.hlp` (`x_dot_onkeyba.html`, `x_dot_ketv.html`)
|
||||
enthält dazu **nichts**. → Festlegung nötig, siehe 1.2.
|
||||
|
||||
### Benutzerdefinierte Tasten 15–25
|
||||
|
||||
Die Einzelseite zu `KEY n, zeichenkette$` (`x_dot_setfkr.html`) behandelt
|
||||
**nur** die Makrozuweisung für 1–10 und 30–31; die Erklärungsform für
|
||||
15–25 steht in keiner der beiden Hilfen, ebenso wenig die Bedeutung der
|
||||
Bits des Tastaturflagbytes. Belegt ist dagegen die **Scancode-Tabelle**
|
||||
(`qb45advr.hlp`, `x_dot_kbsct.html`), aus der die Zuordnung Zeichen →
|
||||
Scancode stammt:
|
||||
|
||||
> ESC 01 · „! or 1" 02 … „) or 0" 0B · „_ or -" 0C · „+ or =" 0D ·
|
||||
> TAB 0F · Q 10 … P 19 · ENTER 1C · A 1E … L 26 · Z 2C … M 32 ·
|
||||
> SPACEBAR 39 · F1 3B … F10 44 · HOME 47 · UP 48 · LEFT 4B · RIGHT 4D ·
|
||||
> END 4F · DOWN 50 · INS 52 · DEL 53
|
||||
|
||||
→ Festlegung nötig für das Flagbyte, siehe 1.2.
|
||||
|
||||
### UEVENT und SetUEvent
|
||||
|
||||
> `ON UEVENT GOSUB {linenumber | linelabel}`
|
||||
>
|
||||
> „This event typically originates from a hardware interrupt but can also
|
||||
> be triggered by software."
|
||||
>
|
||||
> „SetUEvent … sets a flag that BASIC checks before executing the next
|
||||
> statement."
|
||||
|
||||
Bestätigt die Zustellung **an der Anweisungsgrenze**.
|
||||
|
||||
> ```
|
||||
> UEVENT ON
|
||||
> UEVENT OFF
|
||||
> UEVENT STOP
|
||||
> ```
|
||||
>
|
||||
> UEVENT STOP „preserves events in memory for processing once UEVENT ON
|
||||
> resumes, though executing UEVENT OFF afterward will discard these queued
|
||||
> events."
|
||||
|
||||
`OFF` verwirft also auch ein unter `STOP` gemerktes Ereignis.
|
||||
|
||||
`SetUEvent` ist eine **Routine** ohne dokumentierte Argumentliste und ohne
|
||||
dokumentierten Rückgabewert:
|
||||
|
||||
> „It sets the BASIC entry point that causes a user-defined event."
|
||||
|
||||
### SIGNAL
|
||||
|
||||
> ```
|
||||
> SIGNAL(n%) ON
|
||||
> SIGNAL(n%) OFF
|
||||
> SIGNAL(n%) STOP
|
||||
> ```
|
||||
>
|
||||
> `ON SIGNAL(n%) GOSUB {linenumber | linelabel}`
|
||||
>
|
||||
> „A linenumber value of 0 disables event trapping."
|
||||
|
||||
Quelle der Signale — wörtlich:
|
||||
|
||||
> „OS/2 protected-mode signal"
|
||||
>
|
||||
> „Process flags A, B, and C are used for communicating between
|
||||
> processes."
|
||||
>
|
||||
> aktiviert durch die OS/2-Funktion `DOSFLAGPROCESS` aus einem anderen
|
||||
> Prozess.
|
||||
|
||||
Ein **Wertebereich für `n%` ist nicht dokumentiert**; die Einzelseite
|
||||
verweist auf „Chapter 9, ‚Event Handling'" des Programmer's Guide, der
|
||||
nicht vorliegt.
|
||||
|
||||
### EVENT
|
||||
|
||||
> ```
|
||||
> EVENT ON
|
||||
> EVENT OFF
|
||||
> ```
|
||||
>
|
||||
> „EVENT OFF … equivalent to compiling a program from the BC command line
|
||||
> without using /V or /W."
|
||||
>
|
||||
> „EVENT OFF and EVENT ON can be used to bracket sections of code where
|
||||
> events do not need to be detected and trapped, and fast performance is
|
||||
> required."
|
||||
|
||||
**`EVENT STOP` ist nicht dokumentiert.** `EVENT` ist im Vorbild kein
|
||||
Laufzeit-Hauptschalter mit drei Zuständen, sondern eine Klammer, die die
|
||||
Erzeugung der Ereignisprüfungen im Kompilat ein- und ausschaltet.
|
||||
|
||||
### Reihenfolge und Trapping in Prozeduren
|
||||
|
||||
Zu beidem geben die Einzelseiten **nichts** her; sie verweisen auf
|
||||
Kapitel 9 des Programmer's Guide. → Festlegung nötig, siehe 1.2.
|
||||
|
||||
## 1.2 Abweichungen der Delta-Spec vom Beleg
|
||||
|
||||
Nach der Leitplanke „Referenzverhalten schlägt Eleganz … das gilt auch
|
||||
gegenüber den eigenen Spezifikationen" ist bei jeder Abweichung die
|
||||
**Spec** anzugleichen.
|
||||
|
||||
| Nr. | Delta-Spec sagt | Beleg sagt | Folge |
|
||||
|---|---|---|---|
|
||||
| A | `EVENT` hat `ON`/`OFF`/`STOP` und überlagert die Einzelzustände | nur `ON`/`OFF`; Klammer um die Erzeugung der Prüfungen | Spec angleichen; `EVENT STOP` wird namentlich abgewiesen |
|
||||
| B | „während des Handlers gilt die Quelle als gestoppt; mit `RETURN` gilt wieder ihr Zustand" | Eintritt = automatisches `STOP`; `RETURN` = automatisches `ON`, außer im Handler stand ein ausdrückliches `OFF` | Spec präzisieren |
|
||||
| C | `OFF` verwirft künftige Ereignisse | `OFF` verwirft **auch** ein unter `STOP` gemerktes | Spec ergänzen |
|
||||
| D | `ON KEY(n)` mit Wertebereich | 0, 1–25, 30–31 mit fester Tastenzuordnung | Spec unverändert, Bereich jetzt belegt |
|
||||
| E | `ON TIMER(n)` | `n&` ist LONG, 1–86 400; `GOSUB 0` schaltet ab | Spec unverändert, Form jetzt belegt |
|
||||
|
||||
**Ohne Beleg — unsere Festlegungen (gehören nach `sprachreferenz.md`
|
||||
unter „Abweichungen"):**
|
||||
|
||||
1. **Getrappte Tasten verlassen den Eingabestrom.** Von keiner der beiden
|
||||
Hilfen belegt. Wir legen fest: eine Taste mit aktivem Trap erscheint
|
||||
nicht zusätzlich bei `INKEY$`/`INPUT`. Begründung: andernfalls sähe ein
|
||||
Programm dieselbe Taste zweimal, und `KEY(n) OFF` wäre die einzige Art,
|
||||
eine Taste überhaupt normal zu lesen.
|
||||
2. **Reihenfolge gleichzeitig fälliger Ereignisse.** Unbelegt. Wir legen
|
||||
fest: `KEY` (aufsteigend nach `n`), dann `TIMER`, dann `UEVENT`, dann
|
||||
`SIGNAL` — Tasten zuerst, weil sie an einer Benutzereingabe hängen.
|
||||
3. **Trapping in Prozeduren.** Unbelegt. Wir legen fest: die Zustellung
|
||||
erfolgt an jeder Anweisungsgrenze, auch innerhalb von `SUB`/`FUNCTION`;
|
||||
das Ziel liegt im Modulrumpf. Das entspricht dem bereits umgesetzten
|
||||
Verhalten des modulweiten `ON ERROR`.
|
||||
4. **Bits des Tastaturflagbytes** in `KEY n, CHR$(flag)+CHR$(scan)`.
|
||||
Unbelegt. Wir legen die Belegung des BIOS-Flagbytes zugrunde:
|
||||
1 rechte Umschalttaste, 2 linke Umschalttaste, 4 Strg, 8 Alt. Im
|
||||
Terminal sind linke und rechte Umschalttaste nicht unterscheidbar,
|
||||
beide Bits gelten deshalb gleich; NumLock und CapsLock spielen für
|
||||
einen Trap keine Rolle und werden ignoriert.
|
||||
5. **`SIGNAL`-Quelle.** Die belegte Quelle ist OS/2-gebunden
|
||||
(`DOSFLAGPROCESS`, Prozessflags A/B/C) und existiert auf keiner
|
||||
Zielplattform; ein Wertebereich ist nicht dokumentiert. → **Entscheidung
|
||||
des Projektinhabers ausstehend**, siehe unten.
|
||||
|
||||
## Entscheidung zu `SIGNAL` (Projektinhaber, 2026-09-04)
|
||||
|
||||
`SIGNAL` wird auf **Betriebssystemsignale** abgebildet, und zwar nur auf
|
||||
die minimale Menge, die auf allen Zielplattformen existiert.
|
||||
|
||||
Der C-Standard garantiert überall — Linux, macOS **und** Windows —
|
||||
`SIGABRT`, `SIGFPE`, `SIGILL`, `SIGINT`, `SIGSEGV`, `SIGTERM`. Von diesen
|
||||
sind nur zwei asynchron, von außen ausgelöst und fortsetzbar; die vier
|
||||
Fault-Signale entstehen aus dem eigenen Programmzustand, und ein
|
||||
`RETURN` aus ihrem Handler führte in denselben Fehler zurück. Abgebildet
|
||||
werden deshalb:
|
||||
|
||||
| `n%` | Signal | Bedeutung |
|
||||
|---|---|---|
|
||||
| 1 | `SIGINT` | Unterbrechungswunsch von außen |
|
||||
| 2 | `SIGTERM` | Beendigungswunsch von außen |
|
||||
|
||||
Ein anderer Wert als 1 oder 2 wird namentlich abgewiesen — zur
|
||||
Übersetzungszeit, wenn er konstant ist, sonst mit Laufzeitfehler 5.
|
||||
|
||||
**Zustellung.** Signale erreichen die Laufzeit wie die Zeit über den
|
||||
Host; nur er berührt das Betriebssystem. Ein Signal wird nicht im
|
||||
Signalkontext verarbeitet, sondern setzt eine Marke, die der Host beim
|
||||
nächsten Abholen in ein Ereignis übersetzt.
|
||||
|
||||
**Verhältnis zum Abbruch.** Im Rohmodus liefert das Terminal Strg+C als
|
||||
Taste, nicht als Signal; daran ändert sich nichts. Trifft `SIGINT`
|
||||
dagegen von außen ein (`kill -INT`), gilt: mit aktivem Trap läuft der
|
||||
Handler, ohne aktiven Trap bleibt es beim bisherigen Abbruch. Dieselbe
|
||||
Regel wie bei getrappten Tasten.
|
||||
|
||||
**Abweichungen, die zu dokumentieren sind:**
|
||||
|
||||
1. Die belegte Quelle des Vorbilds (OS/2-Prozessflags A/B/C über
|
||||
`DOSFLAGPROCESS`) existiert nicht; `n%` bedeutet bei uns etwas
|
||||
anderes als im Vorbild. Ein Wertebereich war im Vorbild ohnehin nicht
|
||||
dokumentiert.
|
||||
2. `SIGTERM` ist unter Windows von außen nicht zustellbar (es gibt kein
|
||||
`kill`); `SIGNAL(2)` bleibt dort wirkungslos. `SIGNAL(1)` wird dort
|
||||
über den Konsolen-Steuerhandler (`CTRL_C_EVENT`) bedient.
|
||||
Reference in New Issue
Block a user