Inhaltsverzeichnis

LPM — Compiler-Integration

Zurück zu LPM · CLI-Referenz des Compilers

Diese Seite beschreibt, was lpm für die automatische Import-Auflösung bereitstellt und was auf der Compiler-Seite dafür nötig wäre.

<WRAP alert> Die Compiler-Seite ist nicht umgesetzt. lyxc ruft lpm heute nicht auf; ein import net.http ohne lokal vorhandene Datei scheitert weiterhin mit Modul nicht gefunden. Was hier steht, ist die fertige Schnittstelle von lpm aus gesehen — samt der Fundstellen im Compiler, die eine Umsetzung berühren würde.

Stand: 2026-08-15, lpm 0.1.0, lyxc 1.0.21A. </WRAP>


Das Ziel

import net.http;      // liegt lokal nicht vor

lyxc main.lyx
  → Import nicht auffindbar
  → lpm resolve net.http
  → lpm lädt das Paket und meldet, wo es liegt
  → lyxc setzt dort fort


Was lpm liefert

lpm resolve &lt;name&gt; [--entry]

Löst ein Paket auf, lädt es bei Bedarf herunter, prüft den SHA256 und entpackt es in den Cache. Der Aufrufvertrag ist bewusst eng gehalten, damit ein Compiler die Ausgabe ohne Parser verwenden kann:

Kanal Zusage
stdout bei Erfolg genau eine Zeile: ein Pfad, mit \n abgeschlossen. Sonst nichts
stderr alle Meldungen — Fortschritt, Warnungen, Fehler, auch unter –verbose
Exit 0 Paket liegt im Cache, der Pfad auf stdout ist gültig
Exit 1 nicht auflösbar; stdout bleibt leer

Ohne –entry ist die Ausgabe das Paketverzeichnis:

$ lpm resolve net.http
/home/andreas/.lpm/cache/net/http/0.3.0

Mit –entry die Unit-Datei:

$ lpm resolve net.http --entry
/home/andreas/.lpm/cache/net/http/0.3.0/http.lyx

Warum --entry der interessantere Modus ist

lyxc sucht zu import net.http eine Datei — nach heutiger Logik &lt;root&gt;/net/http.lyx (src/sema.lyx:1746-1757). Der Cache liefert aber ein Verzeichnis:

~/.lpm/cache/net/http/0.3.0/
  lyx.toml
  http.lyx          ← die Unit
  FILES.sha256

Ein Include-Root, unter dem net/http.lyx läge, gibt es nicht — und soll es auch nicht geben, weil im Cache mehrere Versionen desselben Pakets nebeneinander liegen. –entry löst das auf der lpm-Seite auf: gesucht wird zuerst [build] entry aus der lyx.toml des Pakets, dann &lt;letztes Namenssegment&gt;.lyx, dann dasselbe mit .lyu. Der Compiler muss das Paketlayout damit nicht kennen.

Weitere Eigenschaften


Was auf der Compiler-Seite nötig wäre

Die Fundstellen beziehen sich auf aurum @ 878189b5.

Der Import wird an drei Stellen unabhängig aufgelöst

Stelle Fundstelle Suchpfad
Sema src/sema.lyx:1700 (_sema_processImport), Kaskade in _sema_readFile src/sema.lyx:1420 CWD → -I–std-path/usr/include/lyx/units
Codegen src/codegen_x86.lyx:16732 (cg_processImportAs) eigene Kaskade, liest Imports ein zweites Mal
IR-Lowering src/ir_lower.lyx:5065-5090 nur relativ, kein Rückfallweg

Ein Hook allein in Sema würde die Übersetzung später im Codegen scheitern lassen, weil der Import dort erneut gesucht wird. Die Fehlerstelle, an der ein Hook ansetzen könnte, ist src/sema.lyx:1804„Modul nicht gefunden (weder .lyx noch .lyu)“.

includePath ist heute ein einzelner Pfad

src/sema.lyx:417 und src/codegen_x86.lyx:790 halten je einen pchar, keine Liste. „Den Include-Pfad ergänzen„ hat also kein bestehendes Konstrukt. Zwei Wege:

  1. Ein eigenes Feld für den von lpm gelieferten Pfad, neben includePath. Kleiner Eingriff, kein Umbau an bestehendem Code.
  2. includePath zu einer echten Liste ausbauen. Größerer Umbau, macht nebenbei mehrfaches -I für Menschen nutzbar — heute wirkt nur der letzte angegebene Pfad.

Mit –entry entfällt die Frage teilweise: der Compiler bekommt einen fertigen Dateipfad und muss ihn nur öffnen, statt einen Suchpfad zu erweitern.

Subprozess-Bausteine sind vorhanden

sys_fork, sys_execve, sys_pipe, sys_pipe2, sys_dup2, sys_dup3 und sys_wait4 sind als Builtins registriert (src/sema.lyx:6229-6254) und werden emittiert (src/codegen_x86.lyx:9923ff, 10020ff). Neue Intrinsics braucht es nicht.

Im Compiler selbst wird bisher nur in src/tooling/self_test.lyx:21-32 ein Kindprozess gestartet — ohne dessen stdout zu lesen. Ein fertiges Muster dafür steht in std/process.lyx:161 (SpawnWithPipes), das lyxc heute nicht importiert.

Vorsicht bei IRLower

src/ir_lower.lyx:5069-5072 hält fest, dass neue Methoden an IRLower die vtable verschieben und der Seed-Compiler daran schon einmal gescheitert ist.

Bootstrap

lyxc ist selbstkompilierend: Quelle src/lyxc.lyx, Seed src/lyxc_bootstrap, Fixpunktprüfung make singularity (S3 == S4). Laut Makefile:5-14 muss der Seed neu verankert werden, sobald sich die Ausgabe des Codegens ändert. Reine Frontend- und Sema-Änderungen kommen mit make build + make bootstrap aus, solange die Singularitätsprüfung hält.

Flags

Vorgesehen ist:

lyxc --pkg-resolve=auto     # Standard: auflösen, wenn lyx.toml vorhanden
lyxc --pkg-resolve=always   # immer
lyxc --pkg-resolve=never    # nie (CI, offline)

Das Parsen gehört nach parseLongFlag (src/lyxc.lyx:751); das Muster für –x=wert gibt es dort bereits bei –include-path= (src/lyxc.lyx:828-831) und –std-path= (src/lyxc.lyx:833-836). Hilfetext bei src/lyxc.lyx:1399ff.


Empfohlener Ablauf im Compiler

Import nicht auffindbar
  └─ --pkg-resolve=never?         → bisheriger Fehler, Ende
  └─ auto und kein lyx.toml da?   → bisheriger Fehler, Ende
  └─ lpm resolve <importname> --entry
       ├─ Exit 0 → stdout ist der Pfad zur Unit-Datei; diese öffnen und
       │           fortsetzen. Den Pfad merken, damit Codegen denselben
       │           Import nicht erneut auflösen muss.
       └─ Exit 1 → bisheriger Fehler, ergänzt um die stderr-Ausgabe von lpm

Drei Absicherungen, die lpm nicht abnehmen kann:


Der Vertrag lässt sich ohne Compiler prüfen

Vollständig von der Kommandozeile nachvollziehbar:

$ cd /tmp/leer && printf '[package]\nname="x"\nversion="0.1.0"\n' > lyx.toml

$ lpm resolve net.http --entry; echo "exit=$?"
/home/andreas/.lpm/cache/net/http/0.3.0/http.lyx
exit=0

$ lpm resolve net.http --entry 2>/dev/null | wc -l
1

$ lpm resolve gibts.nicht --entry; echo "exit=$?"
lpm: error: Paket nicht in der Registry — gibts/nicht (*)
lpm: error: gibts/nicht liess sich nicht aufloesen.
exit=1

Der letzte Fall zeigt beides: Exit 1 und leeres stdout — nachgemessen, wc -l auf stdout ergibt dort 0.