CodeBlanks Logo Icon CodeBlanks

Birleştirme

Tüm parçaları birleştirerek çalışan derleyiciyi yazarsın.

Birleştirme

Tür güvenli derleyici, AST modeli, visitor deseni, type guard'lar ve exhaustive eval fonksiyonunun birleşimidir. AST düğümleri discriminated union ile modellenir; visitor deseni dolaşmayı sağlar; type guard'lar dış kodun daraltmasını kolaylaştırır; exhaustive eval tüm türleri güvenli işler.

type Node =
  | { kind: "number"; value: number }
  | { kind: "string"; value: string }
  | { kind: "add"; left: Node; right: Node };

function assertNever(x: never): never {
  throw new Error("Unexpected");
}

function evalNode(n: Node): string {
  switch (n.kind) {
    case "number": return String(n.value);
    case "string": return n.value;
    case "add": return evalNode(n.left) + evalNode(n.right);
    default: return assertNever(n);
  }
}

Tam derleyici

Tam bir derleyici, AST modelini alır, visitor ile dolaşır, type guard'larla dış daraltma sağlar ve exhaustive eval ile değerlendirir. Yeni düğüm eklendiğinde tüm parçalar güncellenmelidir; assertNever bunu garanti eder.

const ast: Node = {
  kind: "add",
  left: { kind: "number", value: 2 },
  right: { kind: "string", value: "x" }
};

console.log(evalNode(ast));  // "2x"

Uygulama Tam derleyici yaz

assertNever(x: never): never fonksiyonunu tanımla (throw new Error("Unexpected") ile). Node discriminated union türünü tanımla ("number" (value: number), "string" (value: string), "add" (left: Node, right: Node)). evalNode(n: Node): string fonksiyonunu switch (n.kind) ile yaz: number için String(n.value), string için n.value, add için evalNode(n.left) + evalNode(n.right), default için return assertNever(n);. ast adında bir Node değeri tanımla: { kind: "add", left: { kind: "number", value: 2 }, right: { kind: "string", value: "x" } }. console.log(evalNode(ast)) ile sonucu yazdır.

Başlangıç kodu

index.ts
// assertNever fonksiyonunu tanımla (never parametre, throw ile)

// Node discriminated union türünü tanımla (kind: number, string, add)

// evalNode fonksiyonunu switch ile yaz, default'ta assertNever çağır

// ast değerini tanımla ve evalNode ile değerlendirip yazdır

Örnek çözüm

index.ts
function assertNever(x: never): never {
  throw new Error("Unexpected");
}

type Node =
  | { kind: "number"; value: number }
  | { kind: "string"; value: string }
  | { kind: "add"; left: Node; right: Node };

function evalNode(n: Node): string {
  switch (n.kind) {
    case "number":
      return String(n.value);
    case "string":
      return n.value;
    case "add":
      return evalNode(n.left) + evalNode(n.right);
    default:
      return assertNever(n);
  }
}

const ast: Node = {
  kind: "add",
  left: { kind: "number", value: 2 },
  right: { kind: "string", value: "x" }
};

console.log(evalNode(ast));

Beklenen çıktı

2x

Soru ve cevaplar

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

1 Tür güvenli derleyicide hangi desenler birlikte kullanılır?

  • Yalnızca sınıflar
  • Yalnızca fonksiyonlar
  • Yalnızca interface'ler
  • Discriminated union, visitor, type guard, exhaustive check Doğru cevap

Açıklama: Tür güvenli derleyici, AST modeli için discriminated union, dolaşma için visitor, daraltma için type guard ve güvenli değerlendirme için exhaustive check bir arada kullanır.

2 add düğümü tanımı

Soru
type Node =
  | { kind: "number"; value: number }
  | { kind: "string"; value: string }
  | { kind: ____; left: Node; right: Node };
Cevap
type Node =
  | { kind: "number"; value: number }
  | { kind: "string"; value: string }
  | { kind: "add"; left: Node; right: Node };

Açıklama: add düğümü kendi discriminant değeri "add" ile tanımlanır; left ve right alt düğümleri taşır.

3 Birleştirme parçaları

Kavram Anlamı
AST modeli discriminated union ile
Visitor deseni ağacı dolaşır
Type guard'lar dış daraltma sağlar
Exhaustive eval tüm türleri güvenli işler

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