====== Module und Import-System ====== Jede Lyx-Quelldatei ist gleichzeitig ein **Modul** (in Lyx-Terminologie: eine **Unit**). Die Unit-Deklaration am Dateianfang legt den Namensraum fest. ''import'' lädt eine andere Unit und macht ihre öffentlichen Symbole sichtbar. ''pub'' steuert, welche Symbole exportiert werden. Das System ist bewusst einfach: keine Pakete, keine Versionsverwaltung im Sprachkern, keine zyklischen Importe. Eine Unit = eine Datei = ein Namensraum. → [[lyx_-_programmiersprache:sprache:syntax|Syntax-Referenz]] · [[lyx_-_programmiersprache:erste-schritte|Erste Schritte]] · [[lyx_-_programmiersprache:units|Standard Library]] ---- ===== 1. Unit-Deklaration ===== Jede ''.lyx''-Datei beginnt mit einer ''unit''-Deklaration: unit my_module; **Pflichtregeln:** * Der Unit-Name muss exakt mit dem Dateinamen übereinstimmen (ohne ''.lyx''-Endung) * Unterverzeichnisse werden durch Punkte getrennt: Datei ''net/http_client.lyx'' → ''unit net.http_client;'' * Erlaubte Zeichen: Kleinbuchstaben, Ziffern, Unterstriche. Keine Großbuchstaben, keine Bindestriche. * Die ''unit''-Zeile muss die **erste** Zeile der Datei sein (vor jedem Import, vor jedem Kommentar). // Datei: sensors/temp_reader.lyx unit sensors.temp_reader; import std.io; import std.math; ---- ===== 2. Import-Syntax ===== Imports folgen direkt auf die Unit-Deklaration, vor allen anderen Deklarationen: unit my_app; // Standardbibliothek import std.io; import std.string; import std.net.socket; // Eigene Units import sensors.temp_reader; import utils.math_helpers; * Die Import-Reihenfolge spielt keine Rolle für den Compiler. * Mehrere Imports der gleichen Unit sind erlaubt, aber redundant. * Zirkuläre Importe (A importiert B, B importiert A) sind **nicht erlaubt** und erzeugen einen Compiler-Fehler. * Eine Unit kann sich nicht selbst importieren. ==== Qualifizierte Namen ==== Nach dem Import sind alle ''pub''-Symbole der Ziel-Unit direkt (unqualifiziert) sichtbar: import std.string; fn Greet(name: pchar): void { var upper: pchar := alloc(256); StrToUpper(upper, name); // kein "string." Prefix nötig Print(upper); } Wenn zwei importierte Units dasselbe Symbol exportieren, entsteht eine **Namenskollision**. Der Compiler meldet das als Fehler. Lösung: Einen der Importe weglassen oder die Symbole umbenennen (derzeit kein Alias-Import). ---- ===== 3. Sichtbarkeit mit pub ===== Standardmäßig ist alles **privat** — nur innerhalb der eigenen Unit sichtbar. ''pub'' macht ein Symbol exportierbar: ==== Funktionen ==== unit math_utils; // Öffentlich — von anderen Units importierbar pub fn Square(x: int64): int64 { return x * x; } // Privat — nur innerhalb math_utils sichtbar fn SquareInternal(x: int64): int64 { return x * x; } ==== Konstanten ==== unit constants; pub con PI: f64 := 3.14159265358979; pub con MAX_CONN: int64 := 1024; con INTERNAL_BUF: int64 := 4096; // privat ==== Variablen ==== unit config; pub var LogLevel: int64 := 2; // Von außen lesbar und schreibbar var _internalState: int64 := 0; // Privat > Öffentliche Variablen (''pub var'') sind selten sinnvoll — sie erzeugen globalen Zustand der von jeder importierenden Unit verändert werden kann. Bevorzuge ''pub fn Get...()'' / ''pub fn Set...()'' Accessoren. ==== Typen, Enums, Structs, Klassen ==== unit geometry; // Öffentlicher Typ — andere Units können Point verwenden pub type Point = struct { x: f64; y: f64; }; // Öffentliches Enum pub enum Axis { X, Y, Z } // Privater Hilfstyp — nur intern type InternalMatrix = struct { data: int64; }; ---- ===== 4. Namensraum und Kollisionen ===== Lyx hat keine explizite Namespace-Syntax — jede Unit **ist** ihr Namensraum. Nach dem Import sind alle ''pub''-Symbole direkt im lokalen Scope sichtbar. import std.db.sqlite; // exportiert: SQLiteOpen, SQLiteClose, SQLITE_ROW, ... import std.db.postgres; // exportiert: PGConnect, PGClose, PGQuery, ... // Kein Konflikt — unterschiedliche Präfixe per Konvention (SQLite* vs. PG*) var db: int64 := SQLiteOpen("/data/app.db"); var conn: int64 := PGConnect("localhost", 5432, "mydb", "user", "pass"); Die Standardbibliothek nutzt konsequent **Unit-spezifische Präfixe** als Konvention, um Kollisionen ohne Namespace-Qualifier zu vermeiden: ^ Unit ^ Prefix-Konvention ^ Beispiel ^ | ''std.db.sqlite'' | ''SQLite*'' | ''SQLiteOpen'', ''SQLITE_ROW'' | | ''std.db.postgres'' | ''PG*'' | ''PGConnect'', ''PGQuery'' | | ''std.pdf.builder'' | ''Pdf*'' | ''PdfCreate'', ''PdfSave'' | | ''std.net.socket'' | ''TCP*'' / ''UDP*'' / ''Socket*'' | ''SocketTCPListen'' | | ''std.string'' | ''Str*'' / ''Char*'' | ''StrFind'', ''CharToUpper'' | | ''std.crypto.aes'' | ''AES*'' | ''AESEncryptBlock'' | Eigene Units sollten dasselbe Muster verwenden — kurzer, eindeutiger Präfix vor allen öffentlichen Symbolen. ---- ===== 5. Standard Library importieren ===== Die Standardbibliothek liegt im ''std.''-Namespace. Alle wichtigen Units: // Basisfunktionalität import std.io; // Print, PrintLn, ReadLine, ... import std.string; // StrFind, StrReplace, StringBuilder, ... import std.alloc; // malloc, free_mem, ... import std.math; // Sin, Cos, Sqrt, Floor, ... import std.result; // Result // Netzwerk import std.net.socket; // TCP, UDP, Unix Sockets import std.net.http; // HTTP/1.1 Client import std.net.dns; // DNS-Auflösung // Datenbanken import std.db.sqlite; // SQLite3 import std.db.postgres; // PostgreSQL import std.db.redis; // Redis // PDF import std.pdf; // PDF erstellen (High-Level-Einstiegspunkt) // Crypto import std.crypto.aes; // AES-Verschlüsselung import std.hash; // Hashing // System import std.fs; // Dateisystem import std.process; // Prozessverwaltung import std.thread; // Threads import std.time; // Zeitfunktionen import std.env; // Kommandozeilenargumente Alle verfügbaren Units: → [[lyx_-_programmiersprache:units|Standard Library — vollständige Übersicht]] ---- ===== 6. Eigene Multi-Unit-Projekte strukturieren ===== Eine typische Projektstruktur mit mehreren Units: my_project/ ├── main.lyx → unit main; ├── config.lyx → unit config; ├── db/ │ ├── connection.lyx → unit db.connection; │ └── queries.lyx → unit db.queries; └── api/ ├── handler.lyx → unit api.handler; └── response.lyx → unit api.response; // db/connection.lyx unit db.connection; import std.db.postgres; pub con DB_HOST: pchar := "localhost"; pub con DB_PORT: int64 := 5432; pub fn Connect(dbName: pchar): int64 { var conn: int64 := PGConnect(DB_HOST, DB_PORT, dbName, "app", "secret"); if (conn == 0 || PGIsConnected(conn) == 0) { return 0; } return conn; } // api/handler.lyx unit api.handler; import std.io; import std.net.http; import db.connection; // eigene Unit — relativer Pfad pub fn HandleGetUsers(conn: int64): void { // conn kommt aus db.connection.Connect(...) var res: int64 := PGQuery(conn, "SELECT id, name FROM users"); // ... } // main.lyx unit main; import std.io; import db.connection; import api.handler; pub fn main(): int64 { var conn: int64 := Connect("myapp"); if (conn == 0) { PrintLn("Datenbankverbindung fehlgeschlagen"); return 1; } HandleGetUsers(conn); PGClose(conn); return 0; } ---- ===== 7. Suchpfad und Compilation ===== Der Compiler sucht Units in dieser Reihenfolge: - Das Verzeichnis der aktuell compilierten Datei - Alle Verzeichnisse in ''--include-path'' (''lyxc --include-path=/my/libs ...'') - Das Standard-Library-Verzeichnis (automatisch, ''std.*''-Units) # Einfacher Build lyxc main.lyx -o my_app # Mehrere Include-Pfade lyxc main.lyx --include-path=./libs --include-path=/opt/lyx/contrib -o my_app # Alle .lyx-Dateien angeben (bei kleinen Projekten) lyxc main.lyx db/connection.lyx api/handler.lyx -o my_app ---- ===== 8. Best Practices ===== Empfehlungen für die Strukturierung von Lyx-Projekten: ^ Situation ^ Empfehlung ^ | Namenskollision zwischen Units | Präfix-Konvention einhalten (''MyUnit*'') | | Globaler Zustand | Lieber ''pub fn Get()'' / ''pub fn Set()'' als ''pub var'' | | Zyklische Abhängigkeit | Unit aufteilen — gemeinsame Typen in eine separate ''types''-Unit | | Große Units (> 500 Zeilen) | In Unterunits aufteilen: ''mylib.core'', ''mylib.helpers'', ... | | Init-Code beim Import | Nicht in Unit-Scope — stattdessen ''pub fn Init()'' explizit aufrufen | | Interne Hilfsfunktionen | Privat lassen — nur was wirklich von außen gebraucht wird mit ''pub'' | → [[lyx_-_programmiersprache:sprache:syntax|Vollständige Syntax-Referenz]]\\ → [[lyx_-_programmiersprache:erste-schritte|Erste Schritte — erstes Programm]]\\ → [[lyx_-_programmiersprache:tools:compiler-parameter|Compiler-Parameter]] Letzte Aktualisierung: 2026-06-05