# VALAPHP Projektvorgaben

Stand: 2026-05-20

Diese Datei sammelt die Architektur- und Transpiler-Vorgaben, damit sie nicht
nur im Chat-Kontext stehen.

## Grundrichtung

- Korrekte PHP-Semantik kommt vor schoenem/statischem Vala-Code.
- Der Default fuer php2vala ist der Cross-File-Optimizer. Ohne Optimizer
  bleibt die Grundsemantik zval-first:
  - globale Variablen bleiben `Php.zval`
  - Funktionsargumente bleiben `Php.zval`
  - Funktionsrueckgaben bleiben `Php.zval`
  - lokale Variablen bleiben ohne Optimizer ebenfalls `Php.zval`
- Statische Vala-Typen sind nur Optimierung, nicht Grundsemantik.
- Die erzeugte `.vala` Datei soll logisch so aussehen wie die `.php` Datei,
  damit man beide Dateien beim Debuggen direkt vergleichen kann.
- Extra-Code fuer PHP-Kompatibilitaet gehoert in die VALAPHP-Runtime, nicht in
  die von php2vala erzeugte `.vala` Datei.

## Runtime statt generierter Wrapper

- php2vala soll keine PHP-Funktionswrapper wie `php2vala_explode()` in die
  generierte `.vala` Datei schreiben.
- Funktionsadapter, zval-Konvertierung, Operatorsemantik, Array-Helfer,
  Truthiness, Count/Empty/Isset und aehnliche Kompatibilitaetslogik gehoeren in
  `valaphp-runtime-core` oder `valaphp-runtime-embed`.
- Generierte Output-Helfer sollen nicht dauerhaft benoetigt werden;
  wiederverwendbare Logik gehoert in Runtime-Module.

## Signaturform und Implementierung sind getrennte Achsen

`*_static` / `*_zval` beschreibt die Signaturform:

- `*_static`: direkte Vala-Typen, z. B. `string`, `int`, `double`, `bool`,
  `Php.zval` nur wenn fachlich noetig.
- `*_zval`: PHP-kompatible zval-in/zval-out-Signatur.

`native` / `embed` beschreibt die Implementierung:

- `native`: eigene VALAPHP-Implementierung in Vala/C.
- `embed`: Ausfuehrung ueber PHP Embed/libphp.

Diese Achsen schliessen sich nicht aus. Gueltige Kombinationen:

- `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.

Folge fuer Runtime-Module:

- Jede PHP-Funktion soll perspektivisch als `*_static` und `*_zval` vorliegen.
- php2vala darf im zval-first Default direkt auf `*_zval` linken.
- Optimierter/static Code darf auf `*_static` linken, wenn die Typen wirklich
  sauber sind.

## Runtime-Aufteilung

- `valaphp-runtime-core`:
  - `Php.zval`, `Php.ValueType`
  - Source-Location/Fehlerhelfer, z. B. `Php.with_php_source(...)`
  - Operatoren wie `concat`, `add`, `sub`, `mul`, `div`, `neg`, `eq`, `ne`,
    `strict_eq`, `strict_ne`
  - Array-/zval-Helfer, soweit sie PHP-Grundsemantik sind
- `valaphp-runtime-embed`:
  - PHP Embed SAPI/libphp Integration
  - Fallback-Mappings fuer PHP-Funktionen
  - je Funktion moeglichst `*_static` und `*_zval`
  - alte Varianten ohne `_static`/`_zval` sind Altlast und sollen entfernt
    werden, sobald keine Nutzer mehr davon abhaengen
- Native Module:
  - `valaphp-runtime-std`, `valaphp-runtime-json`,
    `valaphp-runtime-serialize`, `valaphp-runtime-math` usw.
  - koennen ebenfalls `*_static` und `*_zval` bereitstellen
  - duerfen nur genutzt werden, wenn die Runtime-Auswahl und pkg-Liste das
    erlaubt

## Native Runtime-Dateilayout

- Jede native PHP-Funktion soll in einer eigenen `.vala` Datei liegen, wenn
  eine einzelne Vala-Datei fuer die Implementierung ausreicht.
- Der Normalfall ist direkt unter `src/functions/<php-funktion>.vala`, z. B.
  `src/functions/floor.vala`, `src/functions/microtime.vala` oder
  `src/functions/number_format.vala`.
- Ein eigener Unterordner unter `src/functions/` ist nur vorgesehen, wenn die
  Funktion Begleitdateien braucht, z. B. `.c`/`.h`, mehrere Vala-Quellen oder
  klar zusammengehoerigen Zusatzcode.
- Grosse Sammeldateien wie `basic.vala` sollen fuer native PHP-Funktionen
  vermieden werden, damit Funktion, VAPI-Symbol und Runtime-Zuordnung beim
  Debuggen direkt auffindbar bleiben.
- Dieses Schema gilt fuer alle nativen Runtime-Pakete, nicht nur fuer
  `valaphp-runtime-std`.

## Operatoren

- Operatoren gehoeren in `valaphp-runtime-core`, nicht in Embed.
- Operator-Dateien sollen nach Bedeutung gruppiert sein:
  - `operators/arithmetic`: `add`, `sub`, `mul`, `div`, `neg`
  - `operators/concat`: `concat`
  - `operators/compare`: `eq`, `ne`, `strict_eq`, `strict_ne`
- Direkt an jeder Operator-Funktion soll dokumentiert sein, welchem PHP-Code
  sie entspricht:
  - `concat`: `$left . $right`
  - `add`: `$left + $right`
  - `sub`: `$left - $right`
  - `mul`: `$left * $right`
  - `div`: `$left / $right`
  - `neg`: `-$value`
  - `eq`: `$left == $right`
  - `ne`: `$left != $right` oder `$left <> $right`
  - `strict_eq`: `$left === $right`
  - `strict_ne`: `$left !== $right`

## php2vala Default und CLI-Flags

Default:

- gegen `valaphp-runtime-embed` bauen
- Cross-File-Optimizer aktivieren (`--optimize-cross-file-func-vars`)
- zval-ABI weiterhin erzeugen; statische ABI zusaetzlich nutzen, wo sicher
- keine native Runtime-Auswahl
- Syntaxcheck der Eingabe-PHP-Datei aktiv

Flags:

- `--embed-runtime`: nur Embed-Runtime fuer PHP-Funktionen nutzen. Default.
- `--native-runtime`: nur native Runtime-Module nutzen. Embed-Fallbacks sind
  dabei explizit nicht erlaubt.
- `--both-runtimes`: zuerst native Runtime-Module nutzen; nur wenn keine
  native Bindung existiert, darf Embed als Fallback genutzt werden.
- `--no-optimize-local-vars`: lokale statische Typisierung deaktivieren.
- `--optimize-local-vars`: lokalen Var-Optimizer aktivieren.
- `--optimize-file-func-vars`: ganzen Datei-Kontext fuer lokale Funktionen typisieren.
- `--optimize-cross-file-func-vars`: dateiuebergreifende statische Funktionsaufrufe ueber Stub-Metadaten aktivieren. Default.
- `--no-syntax-check`: PHP-Syntaxcheck nur fuer Debug-/Notfallfaelle
  deaktivieren.

## Optimierungsachsen

Es gibt zwei unabhaengige Optimierungen. Beide koennen einzeln oder gemeinsam
aktiv sein:

1. `zval2static-type`
   - nur fuer eindeutig lokale Variablen innerhalb eines Funktionsbodys
   - nie fuer Globals
   - nie fuer Funktionsargumente
   - nie fuer Funktionsreturns
   - nie fuer Werte, die in gemischte PHP/zval-Strukturen entkommen
   - CLI: `--optimize-local-vars`
2. `native-lib`
   - native Runtime-Module statt Embed-Fallback nutzen
   - nur wenn explizit erlaubt und passende Pakete verfuegbar sind
   - CLI: `--native-runtime`

Die Optimierungen muessen getrennt bleiben:

- Native Runtime-Auswahl darf nicht automatisch lokale statische Typen
  erzwingen.
- Lokale Typoptimierung darf nicht automatisch native Runtime-Module aktivieren.
- zval-only Code kann spaeter trotzdem native Runtime-Module nutzen, wenn diese
  `*_zval` anbieten.

## 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 soll den PHP-Lint/Compile-Pfad nutzen, nicht include/eval
  oder normale Ausfuehrung.

## Compile-Time Includes

- Statische `include`/`include_once`/`require`/`require_once` mit
  String-Literal werden von php2vala vor dem eigentlichen Parser compile-time
  expandiert.
- Die Aufloesung erfolgt relativ zur Datei, in der das Include steht, und
  rekursiv fuer weitere statische Includes.
- Das Ergebnis ist ein gemeinsamer Transpile-Kontext; lokale Funktionen aus
  inkludierten Dateien stehen damit sowohl fuer `--embed-runtime` als auch fuer
  `--native-runtime` normal zur Verfuegung.
- Dynamische Includes bleiben unsupported, weil sie nicht deterministisch zur
  Compile-Time aufloesbar sind.
- Runtime-`include` ueber Embed oder Native ist nicht das Ziel fuer php2vala:
  die Abhaengigkeit soll zur Compile-Time sichtbar und buildbar sein.

## Compile-Time Class Subset

- Einfache Klassen ohne Vererbung/Properties werden im aktuellen php2vala-Subset
  als echte Vala-Klassen ausgegeben.
- Methoden bleiben Methoden der generierten Klasse. Beispiel:
  `class Test { function run() {} }` wird zu
  `public class Test : Object { public Php.zval run (...) ... }`.
- `Class::method()` wird auf `Class.method()` gemappt.
- `$obj = new Class(); $obj->method();` wird nur fuer compile-time bekannte,
  argumentlose Konstruktion/Methoden unterstuetzt und als Vala-Objekt erzeugt.
- Das ist bewusst ein kleines Multifile-/Benchmark-Subset und noch keine
  vollstaendige PHP-OOP-Implementierung.

## phpc

- `phpc` soll kein eigenes Buildsystem werden.
- Meson kennt Vala, und das soll genutzt werden.
- `phpc` kann ein Meson-Helper/Developer-Helper werden:
  - php2vala aufrufen
  - danach Meson/valac-Kontext vorbereiten
  - pkg-Liste explizit anhaengen/dokumentieren
  - deterministisch machen, gegen welche VALAPHP-Pakete gelinkt wird
- Die pkg-Liste ist wichtig, damit php2vala spaeter pruefen kann, ob
  Anforderungen erfuellt sind und welche nativen Runtime-Module erlaubt sind.

## Maintainability

- Grosse `main.vala` Dateien sollen in separate Einheiten gesplittet werden.
- Bestehende Struktur fuer php2vala:
  - `model.vala`: Datenmodelle/Fehler
  - `tokenizer.vala`: PHP-Tags, Include-Aufloesung und Tokenstrom
  - `ast.vala`: PHP-Subset-AST
  - `ir.vala`: abgesenkte IR
  - `zend_op_array.vala` und `zend_opcode_handlers.vala`: Zend-Opcode-Dump und Namen
  - `runtime_call_resolver.vala`: Native/Embed/Both-Runtime-Entscheidungen
  - `zval_statement_generator.vala` und `zval_structure_generator.vala`: zval-Ausgabe
  - `vala_generator_utils.vala` und `vala_generator_writer.vala`: Emit-Helfer und Datei-Ausgabe
  - `cli.vala`: CLI
  - `main.vala`: Kontrollstrang und verbleibende Orchestrierung
- Weitere Splits sind erwuenscht, sobald sie die Wartbarkeit verbessern.

## Build-/Test-Hinweise

- Bei lokalen Builds ggf. `CCACHE_DISABLE=1` setzen, wenn ccache wegen
  Permissions stoert.
- Nach Runtime-Aenderungen mindestens bauen:
  - `valaphp-runtime-core`
  - `valaphp-runtime-embed`
  - `php2vala`
- Nach php2vala-Aenderungen kleine PHP-Snippets transpilen und pruefen, ob die
  gewuenschten Runtime-Calls entstehen.
