Modül 6 - İleri Seviye Özellikler
Modül 6: İleri Seviye Özellikler
Section titled “Modül 6: İleri Seviye Özellikler”Bu modülde generic’ler, SIMD, atomics, operatör overloading gibi ileri seviye özellikleri öğreneceksiniz.
Bölüm 6.1: Generic Programlama
Section titled “Bölüm 6.1: Generic Programlama”Generic Fonksiyonlar
Section titled “Generic Fonksiyonlar”// İki değeri değiştirme (generic)function takas<T>(a: T, b: T): T[] { return [b, a];}
// Kullanımlet sayilar = takas<i32>(10, 20); // [20, 10]let metinler = takas<string>("a", "b"); // ["b", "a"]
// Minimum değer (generic)function min<T>(a: T, b: T): T { return a < b ? a : b;}
// Maximum değer (generic)function max<T>(a: T, b: T): T { return a > b ? a : b;}Generic Sınıflar
Section titled “Generic Sınıflar”// Generic container sınıfıclass Kutu<T> { private icerik: T;
constructor(deger: T) { this.icerik = deger; }
degerAl(): T { return this.icerik; }
degerAta(deger: T): void { this.icerik = deger; }
bosMu(): bool { // T referans tipi mi kontrolü if (isReference<T>()) { return changetype<usize>(this.icerik) === 0; } return false; }}
// Kullanımlet sayiKutusu: Kutu<i32> = new Kutu<i32>(42);console.log(sayiKutusu.degerAl().toString()); // "42"
let metinKutusu: Kutu<string> = new Kutu<string>("Merhaba");console.log(metinKutusu.degerAl()); // "Merhaba"Generic ile Static Type Checks
Section titled “Generic ile Static Type Checks”// Tür bilinirse derleme zamanında davranışı belirlefunction islemYap<T>(a: T, b: T): T { if (isInteger<T>() && isSigned<T>()) { // Signed integer return unchecked(a + b); } else if (isFloat<T>()) { // Float return unchecked(a + b); } else if (isString<T>()) { // String - parse et ve topla let sayi1: f64 = parseFloat(a); let sayi2: f64 = parseFloat(b); return changetype<T>(sayi1 + sayi2); } return unchecked(a + b);}
// Kullanımlet sonuc1: i32 = islemYap<i32>(10, 20); // 30let sonuc2: f64 = islemYap<f64>(1.5, 2.5); // 4.0let sonuc3: string = islemYap<string>("10", "20"); // "30"Generic ile Dizi İşlemleri
Section titled “Generic ile Dizi İşlemleri”// Dizi toplama (generic)function diziTopla<T>(dizi: T[]): T { let toplam: T = unchecked(0);
for (let i: i32 = 0; i < dizi.length; i++) { toplam = unchecked(toplam + dizi[i]); }
return toplam;}
// Dizi maksimum (generic)function diziMax<T>(dizi: T[]): T { if (dizi.length === 0) return unchecked(0);
let max: T = dizi[0];
for (let i: i32 = 1; i < dizi.length; i++) { if (dizi[i] > max) { max = dizi[i]; } }
return max;}
// Dizi filtreleme (generic)function diziFiltre<T>(dizi: T[], kosul: (deger: T) => bool): T[] { let sonuc: T[] = [];
for (let i: i32 = 0; i < dizi.length; i++) { if (kosul(dizi[i])) { sonuc.push(dizi[i]); } }
return sonuc;}
// Dizi dönüşüm (generic)function diziMap<T, U>(dizi: T[], donusturucu: (deger: T) => U): U[] { let sonuc: U[] = [];
for (let i: i32 = 0; i < dizi.length; i++) { sonuc.push(donusturucu(dizi[i])); }
return sonuc;}Bölüm 6.2: SIMD (Single Instruction Multiple Data)
Section titled “Bölüm 6.2: SIMD (Single Instruction Multiple Data)”SIMD’i Aktifleştirme
Section titled “SIMD’i Aktifleştirme”# SIMD'i aktifleştirasc assembly/index.ts --enable simd --outFile build/simd.wasmv128 Türü
Section titled “v128 Türü”// 128-bit vektör oluşturma
// 16 x 8-bit integerlet v1: v128 = i8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
// 8 x 16-bit integerlet v2: v128 = i16x8(100, 200, 300, 400, 500, 600, 700, 800);
// 4 x 32-bit integerlet v3: v128 = i32x4(1000, 2000, 3000, 4000);
// 2 x 64-bit integerlet v4: v128 = i64x2(1000000, 2000000);
// 4 x 32-bit floatlet v5: v128 = f32x4(1.1, 2.2, 3.3, 4.4);
// 2 x 64-bit floatlet v6: v128 = f64x2(1.111, 2.222);SIMD Aritmetik
Section titled “SIMD Aritmetik”// 4 sayıyı aynı anda toplaexport function vektorTopla4( a1: f32, a2: f32, a3: f32, a4: f32, b1: f32, b2: f32, b3: f32, b4: f32): v128 { let va: v128 = f32x4(a1, a2, a3, a4); let vb: v128 = f32x4(b1, b2, b3, b4);
// 4 float aynı anda toplanır return v128.add<f32>(va, vb);}
// Skalar ile vektör toplamaexport function skalarVektorTopla( skalar: f32, v1: f32, v2: f32, v3: f32, v4: f32): v128 { let sv: v128 = v128.splat<f32>(skalar); let vv: v128 = f32x4(v1, v2, v3, v4);
return v128.add<f32>(sv, vv);}
// Çarpmaexport function vektorCarp4(va: v128, vb: v128): v128 { return v128.mul<f32>(va, vb);}SIMD Lane Operations
Section titled “SIMD Lane Operations”// Lane'den değer okumaexport function laneOku(v: v128, indeks: i32): f32 { return v128.extract_lane<f32>(v, u8(indeks));}
// Lane'e değer yazmaexport function laneYaz(v: v128, indeks: i32, deger: f32): v128 { return v128.replace_lane<f32>(v, u8(indeks), deger);}
// Tüm lane'leri okuexport function tumLaneler(v: v128): Float32Array { let sonuc: Float32Array = new Float32Array(4);
for (let i: i32 = 0; i < 4; i++) { sonuc[i] = v128.extract_lane<f32>(v, u8(i)); }
return sonuc;}SIMD Karşılaştırma
Section titled “SIMD Karşılaştırma”// 4 değerin karşılaştırmasıexport function karsilastir4(va: v128, vb: v128): v128 { // Her lane için karşılaştırma return v128.lt<f32>(va, vb);}
// Herhangi biri true mu?export function herhangiTrue(v: v128): bool { return v128.any_true(v);}
// Tümü true mu?export function tumuTrue(v: v128): bool { return v128.all_true<f32>(v);}Pratik SIMD Örneği
Section titled “Pratik SIMD Örneği”// 4 sayının toplamı (SIMD ile)export function dortluToplaSIMD( a1: f32, a2: f32, a3: f32, a4: f32, b1: f32, b2: f32, b3: f32, b4: f32): Float32Array { let va: v128 = f32x4(a1, a2, a3, a4); let vb: v128 = f32x4(b1, b2, b3, b4);
let sonuc: v128 = v128.add<f32>(va, vb);
// Sonucu diziye çevir let dizi: Float32Array = new Float32Array(4); for (let i: i32 = 0; i < 4; i++) { dizi[i] = v128.extract_lane<f32>(sonuc, u8(i)); }
return dizi;}
// 4 sayının çarpımı (SIMD ile)export function dortluCarpSIMD( a1: f32, a2: f32, a3: f32, a4: f32, b1: f32, b2: f32, b3: f32, b4: f32): Float32Array { let va: v128 = f32x4(a1, a2, a3, a4); let vb: v128 = f32x4(b1, b2, b3, b4);
let sonuc: v128 = v128.mul<f32>(va, vb);
let dizi: Float32Array = new Float32Array(4); for (let i: i32 = 0; i < 4; i++) { dizi[i] = v128.extract_lane<f32>(sonuc, u8(i)); }
return dizi;}Bölüm 6.3: Atomics (Threading)
Section titled “Bölüm 6.3: Atomics (Threading)”Atomics’i Aktifleştirme
Section titled “Atomics’i Aktifleştirme”# Threading'i aktifleştirasc assembly/index.ts --enable threads --outFile build/threads.wasmAtomic Load/Store
Section titled “Atomic Load/Store”// Atomik okumaexport function atomikOku(ptr: usize): i32 { return atomic.load<i32>(ptr);}
// Atomik yazmaexport function atomikYaz(ptr: usize, deger: i32): void { atomic.store<i32>(ptr, deger);}Atomic Aritmetik
Section titled “Atomic Aritmetik”// Atomik toplama (return: eski değer)export function atomikTopla(ptr: usize, deger: i32): i32 { return atomic.add<i32>(ptr, deger);}
// Atomik çıkarmaexport function atomikCikar(ptr: usize, deger: i32): i32 { return atomic.sub<i32>(ptr, deger);}
// Atomik ANDexport function atomikAnd(ptr: usize, deger: i32): i32 { return atomic.and<i32>(ptr, deger);}
// Atomik ORexport function atomikOr(ptr: usize, deger: i32): i32 { return atomic.or<i32>(ptr, deger);}
// Atomik XORexport function atomikXor(ptr: usize, deger: i32): i32 { return atomic.xor<i32>(ptr, deger);}Atomic Compare-Exchange
Section titled “Atomic Compare-Exchange”// Atomik karşılaştırma ve değiştirexport function atomikDegistir( ptr: usize, beklenen: i32, yeni: i32): i32 { return atomic.cmpxchg<i32>(ptr, beklenen, yeni);}
// Eğer ptr == beklenen ise ptr = yeni yap// Eşleşme durumunda true dönerexport function atomikKosul( ptr: usize, beklenen: i32, yeni: i32): bool { let eski: i32 = atomic.cmpxchg<i32>(ptr, beklenen, yeni); return eski === beklenen;}Atomic Wait/Notify
Section titled “Atomic Wait/Notify”// Atomik bekle (mutex benzeri)export function atomikBekle(ptr: usize, beklenen: i32): void { let sonuc: AtomicWaitResult = atomic.wait<i32>(ptr, beklenen, -1);
// sonçolar: // 0 = OK (daha başka bir agent uyandırdı) // 1 = NOT_EQUAL (değer beklenen değildi) // 2 = TIMED_OUT (timeout)}
// Atomik bildir (uyandır)export function atomikBildir(ptr: usize, sayi: i32): i32 { return atomic.notify(ptr, sayi);}Pratik Atomics Örneği
Section titled “Pratik Atomics Örneği”// Basit sayac (thread-safe)class AtomicSayac { private ptr: usize;
constructor(baslangic: i32) { this.ptr = heap.alloc(sizeof<i32>()); store<i32>(this.ptr, baslangic); }
artir(miktar: i32 = 1): i32 { return atomic.add<i32>(this.ptr, miktar); }
deger(): i32 { return atomic.load<i32>(this.ptr); }}Bölüm 6.4: Operatör Overloading
Section titled “Bölüm 6.4: Operatör Overloading”Binary Operator Overloading
Section titled “Binary Operator Overloading”// Vektör sınıfıclass Vec2 { x: f64; y: f64;
constructor(x: f64, y: f64) { this.x = x; this.y = y; }
// Toplama operatörü @operator("+") static add(left: Vec2, right: Vec2): Vec2 { return new Vec2(left.x + right.x, left.y + right.y); }
// Çıkarma operatörü @operator("-") static sub(left: Vec2, right: Vec2): Vec2 { return new Vec2(left.x - right.x, left.y - right.y); }
// Çarpma operatörü @operator("*") static mul(left: Vec2, right: Vec2): Vec2 { return new Vec2(left.x * right.x, left.y * right.y); }
// Bölme operatörü @operator("/") static div(left: Vec2, right: Vec2): Vec2 { return new Vec2(left.x / right.x, left.y / right.y); }
// Skaler çarpma skalerCarp(skalar: f64): Vec2 { return new Vec2(this.x * skalar, this.y * skalar); }
// Dot product dotProduct(diğer: Vec2): f64 { return this.x * diğer.x + this.y * diğer.y; }
// Boyut (length) boyut(): f64 { return Math.sqrt(this.dotProduct(this)); }
// Normalize normalize(): Vec2 { let boyut: f64 = this.boyut(); return new Vec2(this.x / boyut, this.y / boyut); }
toString(): string { return `Vec2(${this.x}, ${this.y})`; }}
// Kullanımlet v1: Vec2 = new Vec2(3, 4);let v2: Vec2 = new Vec2(1, 2);
let v3: Vec2 = v1 + v2; // (4, 6)let v4: Vec2 = v1 - v2; // (2, 2)let v5: Vec2 = v1 * v2; // (3, 8)
let skalar: f64 = v1.dotProduct(v2); // 3*1 + 4*2 = 11let uzunluk: f64 = v1.boyut(); // 5Karşılaştırma Operatörleri
Section titled “Karşılaştırma Operatörleri”class Vec2 { // ... (önceki kod)
// Eşitlik @operator("==") static eq(left: Vec2, right: Vec2): bool { return left.x === right.x && left.y === right.y; }
// Eşitsizlik @operator("!=") static ne(left: Vec2, right: Vec2): bool { return left.x !== right.x || left.y !== right.y; }
// Küçüklük @operator("<") static lt(left: Vec2, right: Vec2): bool { return left.boyut() < right.boyut(); }
// Büyüklik @operator(">") static gt(left: Vec2, right: Vec2): bool { return left.boyut() > right.boyut(); }}
// Kullanımlet esitMi: bool = v1 == v2;let farkliMi: bool = v1 != v2;let kucukMu: bool = v1 < v2;let buyukMu: bool = v1 > v2;Unary Operator Overloading
Section titled “Unary Operator Overloading”class Vec2 { // ... (önceki kod)
// Negasyon (unary -) @operator.prefix("-") static neg(v: Vec2): Vec2 { return new Vec2(-v.x, -v.y); }
// Artırma (prefix ++) @operator.prefix("++") static inc(v: Vec2): Vec2 { return new Vec2(v.x + 1, v.y + 1); }
// Azaltma (prefix --) @operator.prefix("--") static dec(v: Vec2): Vec2 { return new Vec2(v.x - 1, v.y - 1); }}
// Kullanımlet v: Vec2 = new Vec2(3, 4);let neg: Vec2 = -v; // (-3, -4)let inc: Vec2 = ++v; // (4, 5)Indexed Access Overloading
Section titled “Indexed Access Overloading”class Matris { private satir: i32; private sutun: i32; private veriler: Float64Array;
constructor(satir: i32, sutun: i32) { this.satir = satir; this.sutun = sutun; this.veriler = new Float64Array(satir * sutun); }
// Checked indexed get @operator("[]") static get(m: Matris, indeks: i32): f64 { assert(indeks >= 0 && indeks < m.veriler.length, "İndeks dışında"); return m.veriler[indeks]; }
// Unchecked indexed set @operator("{}=") static set(m: Matris, indeks: i32, deger: f64): void { m.veriler[indeks] = deger; }
// 2D indeksleme get2D(s: i32, st: i32): f64 { return this.veriler[s * this.sutun + st]; }
set2D(s: i32, st: i32, deger: f64): void { this.veriler[s * this.sutun + st] = deger; }}
// Kullanımlet m: Matris = new Matris(3, 3);m.set2D(0, 0, 1);m.set2D(1, 1, 2);m{5} = 3; // unchecked setlet deger: f64 = m[2]; // checked getBölüm 6.5: Tree-shaking
Section titled “Bölüm 6.5: Tree-shaking”Branch-Level Tree-shaking
Section titled “Branch-Level Tree-shaking”// Derleme zamanında dallar elenir
export function platformKodu(): i32 { // Bu kod, WASM32 için derlenirse // 32-bitlik versiyon kullanılır if (ASC_TARGET == 1) { // WASM32 kodu return 32; } else { // WASM64 kodu return 64; }}
// Debug/Release kontrolüexport void debugLog(mesaj: string): void { if (!ASC_NO_ASSERT) { console.log(mesaj); }}
// Feature kontrolüexport function hizliTopla(a: i32, b: i32): i32 { if (ASC_FEATURE_SIMD) { // SIMD ile hızlı toplama return 0; // SIMD implementasyonu } else { // Normal toplama return a + b; }}Compile-Time Constants
Section titled “Compile-Time Constants”// Derleme zamanında hesaplanan değerler
export const SABIT_DEGER: i32 = 42;export const HESAPLANAN: i32 = 10 * 10; // Derleme zamanında 100
export const PLATFORM: string = ASC_TARGET == 1 ? "WASM32" : "WASM64";export const DEBUG: bool = !ASC_NO_ASSERT;export const OPTIMIZE: i32 = ASC_OPTIMIZE_LEVEL;Bölüm 6.6: Modül 6 Özeti
Section titled “Bölüm 6.6: Modül 6 Özeti”Öğrendiklerimiz
Section titled “Öğrendiklerimiz”| Konu | Öğrenilenler |
|---|---|
| Generic | Tip parametreleri, static type checks |
| SIMD | v128, lane operations, vector aritmetik |
| Atomics | atomic.load/store, add, cmpxchg, wait/notify |
| Operator Overload | @operator, binary, unary, indexed |
| Tree-shaking | Branch-level, compile-time constants |
Önemli İpuçları
Section titled “Önemli İpuçları”-
Generic’lerde isType() kullanın
if (isInteger<T>()) { ... } -
SIMD için —enable simd
Terminal window asc --enable simd input.ts -
Atomics için —enable threads
Terminal window asc --enable threads input.ts -
Operator overloading @operator ile
@operator("+") static add(a, b) { ... }
Alıştırmalar
Section titled “Alıştırmalar”- Generic stack sınıfı implemente edin
- SIMD ile 8 sayının toplamı
- Thread-safe queue implementasyonu
- Matris operatör overloading
- Compile-time konfigürasyon sistemi
Sonraki Modül
Section titled “Sonraki Modül”Modül 7: Derleyici Kullanımı
Hazır mısınız? 🚀