
# Mimari

Phasis, fırsatçı bir bayt kodu VM'siyle çalışan dört aşamalı bir ağaç gezginidir. Veri akışı şöyledir:

```
JS text
  │
  ▼
┌──────────┐
│  Lexer   │  src/Lexer/
└────┬─────┘
     ▼ tokens
┌──────────┐
│  Parser  │  src/Parser/
└────┬─────┘
     ▼ AST nodes
┌──────────────┐
│ Interpreter  │  src/Runtime/
│  + Bytecode  │  src/Bytecode/
│      VM      │
└────┬─────────┘
     ▼ JsValue
PHP host
```

Her aşama, sonraki aşamanın kullandığı küçük bir arayüze sahip PHP sınıfıdır. Bağlama adımı yoktur; ayrıştırma bir AST üretir ve yorumlayıcı bu ağacı doğrudan gezer.

## Lexer

`src/Lexer/Lexer.php`, kaynak metni `Token` örneklerinden oluşan bir akışa dönüştürür. Her belirteç salt okunur bir yapıdır: tür (`TokenType` enum'u, yaklaşık 80 durum), değer, satır ve sütun.

Lexer şunları işler:

- Sayı sabitleri — ondalık, onaltılık (`0x`), sekizlik (`0o`), ikilik (`0b`), üstel gösterim ve sayısal ayraçlar.
- Dize sabitleri — tek ve çift tırnaklar, tüm kaçış dizileri, iç içe ifadeler içeren şablon dizeleri.
- Düzenli ifade sabitleri — bir `/` ifadesinin düzenli ifade mi yoksa bölme mi olması gerektiğini göz önünde bulundurarak tam `/pattern/flags` belirteçleştirmesi.
- Tanımlayıcılar, anahtar sözcükler ve noktalama işaretleri.
- Açıklamalar (satır ve blok), önemsiz bilgi olarak korunur.
- Unicode kaynağı — UTF-8 baytları, JS UTF-16 kaynağı olarak yorumlanır.

Çıktı, belirteçleri ihtiyaç duyuldukça üreten bir generator'dır. Ayrıştırıcı bunları tek belirteçlik ileri bakışla tüketir.

## Ayrıştırıcı

`src/Parser/Parser.php` elle yazılmış bir Pratt ayrıştırıcısıdır. İfade önceliği `src/Parser/Precedence.php` içinde tanımlıdır. Deyimler kendi özyinelemeli iniş ayrıştırıcısını kullanır.

Değişmez AST düğümlerini `src/Ast/` üzerinden üretir. Her düğüm, yığın izleri ve hata raporlaması için kaynak konumunu taşır.

Dikkat çeken yapılar:

- **İfade**: `Literal`, `Identifier`, `BinaryExpression`, `UnaryExpression`, `AssignmentExpression`, `CallExpression`, `MemberExpression`, `ArrowFunction`, `ObjectExpression`, `ArrayExpression`, `ConditionalExpression`, `TemplateLiteral`, `SpreadElement`, `NewExpression`, `ThisExpression`, `SequenceExpression`, `TaggedTemplate`, `ClassExpression`, `YieldExpression`, `AwaitExpression`.
- **Deyim**: `BlockStatement`, `IfStatement`, `ForStatement`, `ForInStatement`, `ForOfStatement`, `WhileStatement`, `DoWhileStatement`, `SwitchStatement`, `ReturnStatement`, `ThrowStatement`, `TryStatement`, `BreakStatement`, `ContinueStatement`, `ExpressionStatement`.
- **Bildirim**: `VariableDeclaration`, `FunctionDeclaration`, `ClassDeclaration`, `ImportDeclaration`.
- **Desen** (parçalama): `ArrayPattern`, `ObjectPattern`, `RestElement`, `AssignmentPattern`.

Otomatik noktalı virgül ekleme, belirtime uygun olarak lexer'da değil ayrıştırıcıda uygulanır.

## Yorumlayıcı

`src/Runtime/Interpreter.php`, AST gezginidir. Her düğümü ziyaret edip bir `JsValue` (veya kontrol akışını değiştiren deyimler için bir `Completion`) döndürür.

Önemli yardımcı sınıflar:

- **`Environment`** (`src/Runtime/Environment.php`) — sözcüksel kapsam zinciri. Her işlev çağrısı, sözcüksel üst öğesine işaret eden yeni bir ortam oluşturur. `var`, işlev kapsamına taşınır; `let` / `const` blok kapsamlıdır ve TDZ'ye tabidir.
- **`CallStack`** (`src/Runtime/CallStack.php`) — derinlik sınırı olan açık bir yığın. İşlev ve yöntem çağrıları çerçeve ekler; istisnalar bu çerçeveleri kaldırır.
- **`Completion`** (`src/Runtime/Completion.php`) — `normal`, `return`, `throw`, `break`, `continue` değerlerinden oluşan ayırt etiketli birleşim; isteğe bağlı bir değer ve etiket içerir.
- **`Reference`** (`src/Runtime/Reference.php`) — atamalarda ve `delete` işlemlerinde sol taraf değerlendirmesi için belirtimde tanımlanan Reference türü.

## Değerler

JavaScript değerleri, `src/Value/` altında PHP nesneleridir. Her biri `JsValue` arayüzünü uygular ve kendi tür dönüştürme yöntemlerini (`toNumber()`, `toString()`, `toBoolean()`) içerir.

| Sınıf | JS türü |
|---|---|
| `JsUndefined` | `undefined` (tekil örnek) |
| `JsNull` | `null` (tekil örnek) |
| `JsBoolean` | `true` / `false` |
| `JsNumber` | IEEE 754 double; NaN, ±Infinity, ±0 değerlerini korur |
| `JsString` | UTF-16 dize semantiği |
| `JsObject` | Özellik haritası ve prototip zinciri olan temel nesne |
| `JsArray` | Uzunluk takibiyle `JsObject` öğesini genişletir |
| `JsFunction` | Yakalanan `Environment` değerini içeren closure |
| `JsSymbol` | Symbol ilkel değeri |
| `JsBigInt` | bcmath ile keyfi hassasiyet |
| `JsProxy` | 13 tuzağın tümü, geri alınabilir |
| `JsPromise` | Eşzamanlı yürütücü + mikro görev kuyruğu |
| `JsGenerator` | Çift kipli: [Bytcode VM § Çerçeve anlık görüntüsü üreticileri](https://phasis.inline0.dev/tr/docs/advanced/bytecode-vm) bölümüne bakın) ile açıklanan çerçeve anlık görüntüsü (bayt koduna derlenmiş gövdeler); `yield*`, try-with-yield ve asenkron üreticiler için PHP Fiber geri dönüşü |
| `JsMap`, `JsSet`, `JsWeakMap`, `JsWeakSet`, `JsWeakRef`, `JsFinalizationRegistry` | koleksiyonlar |
| `JsArrayBuffer`, `JsSharedArrayBuffer`, `JsDataView`, `JsTypedArray` | ikili veriler |

Sayı işleme, geçmişteki hataların en büyük tek kaynağıdır: `NaN !== NaN` doğru olmalı, `-0 === 0` doğru olmalı; ToNumber sınır durumları bit düzeyinde özen gerektirir. `Spec/TypeConversion` sınıfı belirtimdeki algoritmaları kelimesi kelimesine uygular ve kapsamlı biçimde test edilmiştir.

## Yerleşik kitaplık

`src/BuiltIn/` tüm standart kitaplık nesnelerini sağlar: `Array`, `String`, `Object`, `Math`, `JSON`, `Date`, `RegExp`, `Map`, `Set`, `Promise`, `Proxy`, `Reflect`, `Symbol`, `BigInt`, `TypedArray`, `Temporal`, `Intl`, `console`; ayrıca Web Platformu / Fetch paketleri (`URL`, `Headers`, `Request`, `Response`, `Blob`, `FormData`, tam Streams, `EventTarget`, `AbortController`/`AbortSignal`, `DOMException`, `structuredClone`, `performance`, `TextEncoder`/`TextDecoder`, `atob`/`btoa`), `crypto` + `SubtleCrypto`, `WebSocket`, `XMLHttpRequest` ve olay döngüsü (`setTimeout`, `setInterval`, `queueMicrotask`, `AsyncContext`).

Her yerleşik, bir sınıftaki statik `install()` yöntemidir. `Engine` oluşturma sırasında bunları bağımlılık sırasına göre çağırır. Her biri prototip zincirini tanımlar, yöntemleri `JsFunction` örnekleri olarak PHP closure'ları etrafında kurar ve kurucuyu global olarak sunar.

## PHP↔JS köprüsü

Sınır ötesindeki değer dönüşümü iki yerde bulunur:

- **`Phasis\Interop\PhpToJs::convert()`** — PHP değerinden `JsValue` değerine dönüşüm; `setGlobal()`, `call()` argümanları ve ana makine işlevlerinin dönüş değerleri için kullanılır. Çağrılabilir bir PHP, gövdesi onu çağıran bir `JsFunction` haline gelir.
- **`PhpToJs::toPhp()`** — ana makine işlevinin argümanları için `JsValue` değerinden PHP değerine dönüşüm.
- **`Engine::toPhp()`** (özel) — `eval()` ve `call()` sonuçları için `JsValue` değerinden PHP değerine dönüşüm.

Nesne köprüsü yoktur: çağrılabilir olmayan PHP nesneleri `undefined` değerine dönüştürülür ([sorun #18](https://github.com/inline0/phasis/issues/18)). `src/Bytecode/` içindeki `JsToPhp` sınıfının birlikte çalışabilirlikle ilgisi yoktur; aşağıda açıklanan dönüştürücüdür. Dönüştürme kuralları [Değer dönüştürme](https://phasis.inline0.dev/tr/docs/interop/values) bölümünde açıklanmıştır.

## Hata işleme

Yakalanmamış bir JS `throw`, PHP `Phasis\Exceptions\JsThrowable` haline gelir; altyapının kendisinin oluşturduğu hatalar `Phasis\Exceptions\TypeError`, `RangeError` veya `ReferenceError` olarak görünür ve bunların tümü `Phasis\Exceptions\RuntimeError` alt sınıfıdır. Altyapı içinde bir JS `try` / `catch`, `JsThrowable`'i, her türlü `RuntimeError`'yi ve `Phasis\Exceptions\SyntaxError`'ü yakalar. Ana makine işlevlerinin fırlattıkları dahil diğer PHP istisnalar dönüştürülmez ve doğrudan PHP çağıranına aktarılır ([sorun #20](https://github.com/inline0/phasis/issues/20)).

İki sınır vardır: çağrı yığını üst sınırı (`CallStack::maxDepth`, 4,096 çerçeve; ayrıca dönüştürülmüş closure'lar için 8,192 çerçeveli bir koruma) ve `maxLoopIterations`; `Engine::setLimit()` üzerinden ayarlanır ve yalnızca ağaç gezgini tarafından uygulanır ([sorun #19](https://github.com/inline0/phasis/issues/19)). Her ikisi de `Phasis\Exceptions\InternalError` fırlatır. Dize uzunluğu, çıktı boyutu veya yürütme süresi sınırı yoktur.

## Bayt Kodu VM

Sık çalışan işlevler iki şekilde daha alt düzeye indirilir. `src/Bytecode/` içindeki `JsToPhp`, sayısal veya yerel değişken ağırlıklı gövdeler için PHP closure'ı üretir; bunu PHP izleme JIT'i yerel koda derleyebilir. İşlem hattı `new Ctor(args)`, `obj.method(args)` ve `this.member` okumalarını alt düzeye indirir; bu, döngü içindeki standart sınıf yöntemi örüntüsünün VM'yi tamamen atlamasını sağlar. Diğer her şey, `VM::execute` tarafından tüketilen düz bayt koduna derlenir; özel çağrı yığını, her JS çağrısını tek bir PHP çerçevesinde tutar ve prototip yöntemi okumaları için her PC'de bir satır içi önbellek kullanır. Basit üretici gövdeleri de bayt koduna derlenir; `Op::YIELD`, PHP Fiber'ını geçmek yerine bir yığın çerçevesi anlık görüntüsü yakalar.

Derleyicinin alt düzeye indirmediği her yapı (e.g. `with`, bağlama yeniden atayan bir catch içeren `try`, `yield*`, asenkron üreticiler) ağaç gezginine geri döner. Mekanizmanın tamamı için [Bayt Kodu VM](https://phasis.inline0.dev/tr/docs/advanced/bytecode-vm) bölümüne bakın.
