CodeBlanks Logo Icon CodeBlanks

Meydan okuma 4: Mini derleyici

İleri seviyenin tamamını yoklayan bir görev çözersin.

Mini derleyici: AST + guard + exhaustive

İleri seviyenin özeti: discriminated union ile bir AST modelle, type guard ve switch ile daralt, never ile exhaustive kontrol yap ve recursive türle ifade ağacını kur. Bu dört parça birlikte derleme zamanında güvenli, çalışma zamanında doğru çalışan bir mini derleyici verir.

type Expr =
  | { kind: "num"; value: number }
  | { kind: "add"; left: Expr; right: Expr };

function evalE(e: Expr): number {
  switch (e.kind) {
    case "num": return e.value;
    case "add": return evalE(e.left) + evalE(e.right);
  }
}

Yeni bir düğüm türü eklersen never kontrolü tüm switch'leri güncellemeye zorlar.

Uygulama İfade değerlendirici

Expr discriminated union'ını yaz: num (value: number), add (left, right: Expr), mul (left, right: Expr). evalE(e: Expr): number fonksiyonunu switch ile yaz ve default dalında const _: never = e ile exhaustive kontrol yap. (1 + 2) * 3 ifadesini kur ve sonucu yazdır.

Başlangıç kodu

index.ts
// Expr: num | add | mul (discriminated union, recursive)
// evalE(e: Expr): number — switch ile daralt, never ile exhaustive yap
// (1 + 2) * 3 ifadesini kur ve sonucu yazdır

Örnek çözüm

index.ts
type Expr =
  | { kind: "num"; value: number }
  | { kind: "add"; left: Expr; right: Expr }
  | { kind: "mul"; left: Expr; right: Expr };

function evalE(e: Expr): number {
  switch (e.kind) {
    case "num":
      return e.value;
    case "add":
      return evalE(e.left) + evalE(e.right);
    case "mul":
      return evalE(e.left) * evalE(e.right);
    default:
      const _: never = e;
      throw new Error("exhaustive");
  }
}

const expr: Expr = { kind: "mul", left: { kind: "add", left: { kind: "num", value: 1 }, right: { kind: "num", value: 2 } }, right: { kind: "num", value: 3 } };
console.log(evalE(expr));

Beklenen çıktı

9

Uygulama Type guard ile değerlendir

Aynı Expr union'ını yaz. isNum(e: Expr): e is { kind: "num"; value: number } type guard'ını tanımla. evalE içinde önce isNum(e) ile daralt, sonra add ve mul için işlem yap. 5 + 10 ifadesini kur ve sonucu yazdır.

Başlangıç kodu

index.ts
// Expr discriminated union (num | add | mul)
// isNum(e: Expr): e is { kind: "num"; value: number } type guard'ı yaz
// evalE içinde isNum ile daralt, toplamı yazdır
// add(5, num(10)) → 15

Örnek çözüm

index.ts
type Expr =
  | { kind: "num"; value: number }
  | { kind: "add"; left: Expr; right: Expr }
  | { kind: "mul"; left: Expr; right: Expr };

function isNum(e: Expr): e is { kind: "num"; value: number } {
  return e.kind === "num";
}

function evalE(e: Expr): number {
  if (isNum(e)) return e.value;
  if (e.kind === "add") return evalE(e.left) + evalE(e.right);
  return evalE(e.left) * evalE(e.right);
}

const expr: Expr = { kind: "add", left: { kind: "num", value: 5 }, right: { kind: "num", value: 10 } };
console.log(evalE(expr));

Beklenen çıktı

15

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 `never` ile yapılan exhaustive kontrol neyi garanti eder?

  • Tüm case'ler `return` içerir
  • Switch sonsuz döngüye girmez
  • Yeni varyant eklenirse derleme hatası verir Doğru cevap
  • Fonksiyon daha hızlı çalışır

Açıklama: Exhaustive `never` kontrolü, union'a yeni bir varyant eklendiğinde ama `switch` güncellenmediğinde derleme hatası verir; böylece unutulan case'ler erkenden yakalanır.

2 Exhaustive değişkeni

Soru
function evalE(e: Expr): number {
  switch (e.kind) {
    case "num": return e.value;
    case "add": return evalE(e.left) + evalE(e.right);
    default:
      const _: ____ = e;
      throw new Error("exhaustive");
  }
}
Cevap
function evalE(e: Expr): number {
  switch (e.kind) {
    case "num": return e.value;
    case "add": return evalE(e.left) + evalE(e.right);
    default:
      const _: never = e;
      throw new Error("exhaustive");
  }
}

Açıklama: Exhaustive kontrol için değişken `never` türünde olmalı; ancak `e` gerçekten `never`'a daraldıysa atanır. `any` veya `unknown` kontrolü anlamsız kılar.

3 Derleyici parçaları

Kavram Anlamı
Discriminated union AST düğüm türleri
switch + case tür daraltma
never exhaustive kontrol
Recursive type iç içe ifade ağacı

İleri seviye bölümündeki tüm dersler