Systemprogrammierung – Treiber, Kernel-Module, Echtzeit-Regler, Hardware-Abstraktionen – erfordert direkten Zugriff auf Speicheradressen. Lyx löst das ohne Zeigertypen: Eine Adresse ist ein gewöhnlicher int64, gelesen und geschrieben wird mit den eingebauten Primitiven peek/poke.
Ein Zeigermodell gibt es in Lyx nicht. Diese Seite beschrieb früher eine Pascal-artige Syntax (^Tals Typ,^xfür die Adresse,p^zum Dereferenzieren) sowie mehrere Pragmas. Keines dieser Konstrukte ist umgesetzt:
^ Konstrukt ^ Verhalten ^
|var p: ^int64|unknown type in var decl'^'| > |^x(Adresse von) |expected expression| > |p^(Dereferenz) | Parse-Fehler | > |unsafe { … }|undefined symbol '\unsafe'\| > |@inline,@no_opt,@section,@parallel|unbekanntes Attribut| > >^ist in Lyx ausschließlich der XOR-Operator:6 ^ 3ergibt5. > > Die Grammatik führt inPrimaryTypefolgerichtig keinen Zeigertyp. Was stattdessen gilt, steht unten und ausführlich unter Rohspeicher. </box> → Rohspeicher: alloc, peek & poke · Memory Management · Attribute & Pragmas —- ===== 1. Adressen sind int64 ===== Eine Adresse wird wie eine Zahl behandelt.allocliefert sie,peek/pokegreifen darauf zu,freegibt frei — Größe ist dabei Pflicht, weil Lyx keine versteckten Metadaten führt.peek8^ Primitiv ^ Breite ^ Zweck ^ |import std.io; import std.alloc; fn main(): int64 { var zelle: int64 := alloc(8); // 8 Bytes, Adresse als int64 if (zelle == 0) { return 1; } // 0 = kein Speicher poke64(zelle, 42); // schreiben PrintLn(IntToStr(peek64(zelle))); // lesen -> 42 free(zelle, 8); return 0; }/poke8| 1 Byte | Protokoll-Bytes, Zeichen | |peek16/poke16| 2 Byte | kompakte Felder | |peek32/poke32| 4 Byte | Hardware-Register, IPv4 | |peek64/poke64| 8 Byte | Standardfall, Adressen | |peekf64/pokef64| 8 Byte | Gleitkomma | Alle sind eingebaut — kein Import nötig.allocundfreekommen ausstd.alloc. ==== Einen Wert zurückgeben ==== Da es keinen Adressoperator gibt, lässt sich die Adresse einer lokalen Variablen nicht nehmen. Ein Ausgabeparameter wird deshalb als Zelle übergeben:A.feld—- ===== 2. Structs über Byte-Offsets ===== Ein Struct auf dem Heap wird über seine Feld-Offsets angesprochen. Die Standardbibliothek arbeitet durchgehend so —import std.io; import std.alloc; fn TeileMit(a: int64, b: int64, restZelle: int64): int64 { poke64(restZelle, a % b); return a / b; } fn main(): int64 { var rest: int64 := alloc(8); var quotient: int64 := TeileMit(17, 5, rest); PrintLn(IntToStr(quotient)); // 3 PrintLn(IntToStr(peek64(rest))); // 2 free(rest, 8); return 0; }bezeichnet in Lyx den Byte-Offset des Feldes:sizeof(ausdruck)import std.io; import std.alloc; type Punkt = struct { x: int64; y: int64; }; fn main(): int64 { var p: int64 := alloc(16); poke64(p + Punkt.x, 3); poke64(p + Punkt.y, 4); PrintLn(IntToStr(peek64(p + Punkt.x))); // 3 PrintLn(IntToStr(peek64(p + Punkt.y))); // 4 free(p, 16); return 0; }liefert die Breite eines Werts in Bytes — es nimmt einen Ausdruck, keinen Typnamen:sizeof(1)ergibt8. Für Strukturen auf dem Stack ist der gewöhnliche Feldzugriff der richtige Weg; Rohspeicher braucht es nur, wo die Lebensdauer über den Aufruf hinausreicht oder die Größe erst zur Laufzeit feststeht. —- ===== 3. @volatile – Memory-Mapped I/O ===== Auf Mikrocontrollern sind Hardware-Register in den Adressraum eingeblendet.@volatileverhindert, dass der Compiler wiederholte Zugriffe auf dieselbe Adresse wegoptimiert.poke32Der Zugriff erfolgt über@volatile var GPIO_OUT: int64 := 0x3FF44004;/peek32auf die Adresse:packed struct—- ===== 4. packed struct – Layout ohne Füllbytes =====fn LedAn(pin: int64): int64 { poke32(0x3FF44004, 1 << pin); return 0; }legt die Felder ohne Ausrichtungslücken ab — nötig für Protokollrahmen und Hardware-Strukturen, deren Byte-Anordnung festliegt.flat structtype Kopf = packed struct { typ: uint8; laenge: int64; };gibt es ebenfalls; beide sind unter Datentypen beschrieben. —- ===== 5. null =====nullist gültig und entspricht der Adresse0— dem Wert, denallocim Fehlerfall liefert:[N]T—- ===== 6. Speicherzugriff im Safety-Umfeld ===== ^ Situation ^ Empfehlung ^ | Regelzyklus (DAL-A/B) | Statische Arraysvar zelle: int64 := alloc(64); if (zelle == null) { return 1; } // gleichbedeutend mit == 0und Structs auf dem Stack — keine Allokation | | Puffer bekannter Größe |[N]uint8stattalloc| | Hardware-Register |@volatilepluspeek32/poke32| | Dynamische Größe |alloc/freemit gepaarter Freigabe, außerhalb des Regelzyklus | Eine Freigabe gehört in jeden Pfad, der sie erreicht — Lyx hat keine Destruktoren. Details unter Fehler-Konventionen und Memory Management. —- Weiterführende Seiten: * Rohspeicher — alloc, peek & poke im Detail * Memory Management — Lebensdauer und Freigabe * Attribute & Pragmas — vollständige @-Referenz * Datentypen — packed/flat struct Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen diepub fn-Signaturen inaurum/std'' gehalten, 0 Abweichungen).