Pass 4v3.1.0Status: ✅ Vollständig

CodeOrderingPass

Die automatische Code-Sortierung analysiert Abhängigkeiten zwischen Funktionen, Typen und Modulen, um eine korrekte Kompilierungsreihenfolge ohne manuelle Header-Deklarationen zu garantieren.

Funktionsweise

Der CodeOrderingPass eliminiert die Notwendigkeit für Entwickler, Code in einer bestimmten physischen Reihenfolge zu schreiben. Er arbeitet in drei Hauptphasen:

Dependency Graph

Erstellt einen gerichteten Graphen (DAG) aller Items und deren Abhängigkeiten.

Topologische Sortierung

Verwendet den Kahn-Algorithmus, um eine lineare Ordnung der Komponenten zu finden.

AST Reordering

Ordnet die Items im Abstract Syntax Tree physisch neu für die nächsten Passes.

Globale Sortierhierarchie

Items werden nach einer festen Kategorien-Hierarchie vorsortiert, bevor die feingranulare Abhängigkeitsprüfung stattfindet:

  1. 1
    Use Statements

    Importe müssen immer an oberster Stelle stehen.

  2. 2
    Type Aliases & Enums

    Grundlegende Typdefinitionen für komplexe Datenstrukturen.

  3. 3
    Structs

    Datenobjekte, die auf zuvor definierten Typen basieren.

  4. 4
    Traits & Implementations

    Definition von Verhalten und dessen Zuweisung zu Typen.

  5. 5
    Functions

    Ausführbare Logik, die Typen und Traits verwendet.

  6. 6
    Top-Level Code

    Einstiegspunkte und globale Ausdrücke.

Zirkuläre Abhängigkeiten

Zirkuläre Abhängigkeiten werden vom Compiler erkannt und gemeldet. Da VelinScript auf Performance optimiert ist, müssen Zyklen durch Referenzen oder Boxing aufgelöst werden.

// FEHLER: Direkte zirkuläre Abhängigkeit
struct User { service: UserService }
struct UserService { user: User }

// LÖSUNG: Referenz oder Option
struct User { service_id: string }
struct UserService { user: Option<User> }

Beispiel: Automatisches Reordering

Input (Unsortiert)

fn main() {
    process(get_data())
}

struct Data { value: string }

fn get_data(): Data {
    return Data { value: "Velin" }
}

fn process(d: Data) {
    print(d.value)
}

Compiler Output (Geordnet)

struct Data { value: string }

fn get_data(): Data {
    return Data { value: "Velin" }
}

fn process(d: Data) {
    print(d.value)
}

fn main() {
    process(get_data())
}