php2vala TODO
============

Zielarchitektur: PHP-semantische Kompatibilitaet zuerst
-------------------------------------------------------

- Standardmodus:
  - gegen `valaphp-runtime-embed-0.01` bauen
  - zval-only ausgeben
  - keine lokale statische Typableitung
  - keine native Runtime-Auswahl
- Globale Variablen, Funktionsargumente und Funktionsrueckgaben muessen immer
  `Php.zval` bleiben.
- PHP-Funktionsmappings sollen in der Runtime paarweise vorliegen:
  `*_static` fuer echte Vala-Typen und `*_zval` fuer PHP-kompatible
  zval-in/zval-out-Aufrufe.
- Entwicklungsziel:
  - `valaphp-runtime-embed`: Alle generierten `*_zval` Funktionen nach
    Prioritaet auch als `*_static` bereitstellen, sofern eine saubere native
    Vala-Signatur ohne `Php.zval` moeglich ist.
  - Native `valaphp-runtime-*` Module: Langfristig alle PHP-Funktionen nativ
    verfuegbar machen, die im Embed-Fallback vorhanden sind. php2vala darf dann
    native Funktionen nur verwenden, wenn die passende native Runtime explizit
    erlaubt/verfuegbar ist.
- Namenskonvention strikt halten:
  - `*_zval` gibt immer `Php.zval` zurueck und nimmt an PHP-dynamischen
    Grenzen `Php.zval` entgegen.
  - `*_static` gibt niemals `Php.zval` zurueck. Static bedeutet: der
    Rueckgabetyp ist ein konkreter Vala-Typ wie `int`, `double`, `string`,
    `bool`, `void` oder eine eindeutig typisierte Collection.
  - Wenn eine PHP-Funktion je nach Argument verschiedene Rueckgabetypen haben
    kann, darf es keinen allgemeinen `*_static` geben, der heimlich wieder
    `Php.zval` zurueckgibt. Stattdessen konkrete Varianten bauen, z. B.
    `microtime_float_static()` -> `double` und spaeter ggf.
    `microtime_string_static()` -> `string`; der dynamische Pfad bleibt
    `microtime_zval()`.
  - Status 2026-05-20: Die Altlasten `microtime_static()`,
    `json_decode_static()` und `unserialize_static()` wurden entfernt.
    `microtime(true)` nutzt jetzt eine double-returning static-Variante;
    `json_decode` und `unserialize` bleiben zval-only, bis es konkrete
    statische Varianten mit eindeutigem Rueckgabetyp gibt.
- Wichtig: `static`/`zval` beschreibt nur die Signaturform, nicht die
  Implementierung. `native`/`embed` beschreibt nur, ob die Funktion in Vala/C
  nativ implementiert ist oder ueber PHP Embed/libphp laeuft.
- Daraus folgt: Embed-Code kann `*_static` und `*_zval` anbieten, und native
  Runtime-Module koennen ebenfalls `*_static` und `*_zval` anbieten. Die
  Achsen schliessen sich nicht gegenseitig aus.
- Der zval-first Transpilerpfad soll direkt auf `*_zval` linken. Er soll keine
  PHP-Funktionswrapper wie `php2vala_explode()` in die generierte `.vala`
  schreiben.
- Der Transpiler darf an diesen Grenzen keine statischen Vala-Typen wie
  `string`, `int`, `double`, `Gee.ArrayList<string>` oder
  `Gee.HashMap<string, double?>` erzwingen, weil das PHP-Kompatibilitaet
  bricht, sobald Werte dynamisch ihren Typ wechseln oder aus fremdem Scope
  kommen.

Var-Optimizer
-------------

- Status 2026-05-20: zval-first ist jetzt der Default im Transpiler.
  `--optimize-local-vars` schaltet den alten statischeren Pfad explizit ein;
  `--no-optimize-local-vars` bzw. kein Optimizer-Flag bleibt zval-first.
  Der lokale Optimizer ist damit noch kein sauberer separater Pass, aber der
  CLI-Schalter und die Kompatibilitaetsrichtung sind implementiert.
- Status 2026-05-20: `valaphp-runtime-embed` enthaelt fuer die vorhandenen
  Embed-Funktionen `*_static` und `*_zval` Varianten; der zval-first Pfad
  erzeugt direkte `PhpEmbed.<funktion>_zval(...)` Aufrufe.
- Status 2026-05-20: Der Default soll `runtime-embed + zval-only` sein. Native
  Runtime-Module und lokale statische Typisierung sind Optimierungen, die
  explizit aktiviert werden muessen.

Optimierungsachsen
------------------

Es gibt zwei voneinander unabhaengige Optimierungen. Beide koennen einzeln oder
gemeinsam aktiviert werden:

1. `zval2static-type`
   - optimiert nur eindeutig lokale Variablen innerhalb eines Funktionsbodys
   - darf keine Globals, Funktionsargumente oder Funktionsreturns statisch
     spezialisieren
   - darf keine Werte spezialisieren, die in gemischte PHP/zval-Strukturen
     entkommen
   - CLI: `--optimize-local-vars`
   - Gegenflag/Default: `--no-optimize-local-vars`
2. `native-lib`
   - nutzt native VALAPHP Runtime-Module statt Embed-Fallback, wenn explizit
     erlaubt und ein passendes Mapping vorhanden ist
   - Beispiele: `valaphp-runtime-json`, `valaphp-runtime-serialize`,
     `valaphp-runtime-math`, spaeter weitere Module
   - darf nur Funktionen auf native Module mappen, deren Pakete im Build
     explizit erlaubt/verfuegbar sind
   - CLI: `--native-runtime`
   - Gegenflag/Default: `--embed-runtime`
   - Expliziter Hybrid-Modus: `--both-runtimes` bedeutet native Runtime mit
     Embed-Fallback fuer noch nicht native PHP-Helfer.
   - `--native-runtime` ist strikt: Wenn eine benoetigte Funktion nicht nativ
     verfuegbar ist, muss php2vala fehlschlagen statt Embed zu benutzen.

Kombinationen:

- Default: `--embed-runtime --no-optimize-local-vars`
- Nur lokale Typoptimierung: `--embed-runtime --optimize-local-vars`
- Nur native Runtime-Auswahl: `--native-runtime --no-optimize-local-vars`
- Hybrid-Auswahl: `--both-runtimes --no-optimize-local-vars`
- Native Runtime plus lokale Typoptimierung: `--native-runtime --optimize-local-vars`
- Hybrid plus lokale Typoptimierung: `--both-runtimes --optimize-local-vars`

Die beiden Optimierungen muessen getrennt bleiben: native Runtime-Auswahl darf
nicht automatisch lokale statische Typen erzwingen, und lokale Typoptimierung
darf nicht automatisch native Runtime-Module aktivieren.

Ebenso muessen Runtime-Implementierung und Signatur getrennt bleiben:

- `embed + zval`: PHP-Funktion ueber libphp, PHP-kompatible zval-Signatur
- `embed + static`: PHP-Funktion ueber libphp, direkte Vala-Typ-Signatur
- `native + zval`: native VALAPHP-Implementierung, PHP-kompatible zval-Signatur
- `native + static`: native VALAPHP-Implementierung, direkte Vala-Typ-Signatur

Lokaler Var-Optimizer
---------------------

- Einen lokalen Var-Optimizer bauen, der innerhalb eines eindeutig lokalen
  Funktionsscopes statische Vala-Typen nutzen darf.
- Der Optimizer darf nur Variablen spezialisieren, die vollstaendig lokal zu
  genau einem Funktionsbody sind:
  - keine globale Variable
  - kein Funktionsargument
  - kein Funktionsreturn
  - nicht per Referenz oder Closure/externem Scope sichtbar
  - keine Variable, deren Wert in ein globales/returned/mixed PHP-Array
    entkommt
- Beispiele fuer erlaubte Optimierung:
  - lokale Schleifenvariable `i` -> `int`
  - lokaler String-Zwischenwert nach `trim()` -> `string`
  - lokaler numerischer Zwischenwert fuer reine Rechnung -> `double`
- Beispiele fuer nicht erlaubte Optimierung:
  - Parameter wie `$cmd`
  - Rueckgabewerte von `get_total_mem_*()`
  - globale Variablen
  - gemischte PHP-Arrays wie `$ret`, wenn sie zurueckgegeben werden

Optimizer-Flag
--------------

- Der Var-Optimizer muss per CLI-Flag deaktivierbar sein.
- Flags:
  - `--optimize-local-vars` aktiviert lokale statische Typisierung
  - `--no-optimize-local-vars` deaktiviert sie explizit
- Default ist `--no-optimize-local-vars` bzw. zval-only.

Runtime-Flag
------------

- Die Runtime-Auswahl muss per CLI-Flag steuerbar sein.
- Flags:
  - `--embed-runtime` nutzt ausschliesslich `valaphp-runtime-embed` fuer PHP
    Funktionsaufrufe. Das ist der Default.
  - `--native-runtime` nutzt ausschliesslich native Runtime-Module. Embed ist
    in diesem Modus verboten; fehlende native Helfer sind Fehler.
  - `--both-runtimes` ist der explizite Name fuer denselben Hybrid-Modus,
    wenn im Aufruf sichtbar sein soll, dass beide Runtime-Familien erlaubt sind.
- Spaeter sollte die native Runtime-Auswahl zusaetzlich an eine explizite
  pkg-Liste gekoppelt werden, damit klar ist, welche nativen Module erlaubt
  sind.

PHP-Syntaxcheck
---------------

- `php2vala` soll die Eingabe-PHP-Datei vor dem Transpilieren standardmaessig
  mit `PhpEmbed.syntax_check_file_static(path, out error)` pruefen.
- Der Check darf PHP-Code nicht ausfuehren; die Runtime-Funktion nutzt nur den
  PHP-Lint/Compile-Pfad.
- CLI:
  - Default: Syntaxcheck aktiv.
  - `--no-syntax-check` deaktiviert ihn nur fuer Debug-/Notfallfaelle.

Implementierungsrichtung
------------------------

1. `Php.zval` als kanonische IR fuer PHP-Werte verwenden.
2. Runtime-/Embed-Funktionen auf zval-in/zval-out harmonisieren.
3. Array-Zugriffe, `foreach`, `count`, `empty`, `isset`, Arithmetik und String-
   Operationen zuerst zval-semantisch korrekt abbilden.
4. Danach lokalen Var-Optimizer als separaten Pass implementieren.
5. Runtime-Auswahl als separaten Mapping-Schritt behandeln:
   Default Embed, optional native Runtime.
6. Optimizer-/Runtime-Ausgaben in den generierten Metadaten sichtbar machen,
   z. B.:
   `php2vala optimizer: local-vars enabled/disabled`
   `php2vala runtime: embed-runtime/native-runtime/both-runtimes`.

Wichtige Regel
--------------

Korrektheit und PHP-Kompatibilitaet gehen vor schoenem Vala-Code. Statische
Vala-Typen sind eine Optimierung, nicht die Grundsemantik.

Generierte Vala-Dateien als PHP-Spiegel
---------------------------------------

- Die von `php2vala` erzeugte `.vala` Datei soll logisch und strukturell so
  nah wie moeglich an der urspruenglichen `.php` Datei bleiben, damit beide
  Dateien beim Debuggen direkt vergleichbar sind.
- Der generierte Code soll primaer das PHP-Programm ausdruecken:
  Funktionen, Schleifen, Bedingungen, Array-Zugriffe und Echo/Return-Fluss
  sollen im Output wiedererkennbar bleiben.
- Extra-Code fuer PHP-Kompatibilitaet, zval-Konvertierung, Operatorsemantik,
  Array-Helfer, Truthiness, Count/Empty/Isset und Funktionsadapter gehoert in
  `valaphp-runtime-core` bzw. `valaphp-runtime-embed`.
- Keine lokalen Helper-Bloecke oder generierten Wrapper in die `.vala` Ausgabe
  schreiben, wenn dieselbe Logik in der Runtime liegen kann.
- Debug-Informationen im Output sind ok, solange sie knapp bleiben und den
  Vergleich mit der PHP-Datei nicht unnoetig verdecken.
