# ╔══════════════════════════════════════════════════════════════╗ # ║ KabaLang Hesap Makinesi ║ # ║ İşlem önceliğini bilen, geçmişini tutan bir masaüstü ║ # ║ hesap makinesi. Hesaplama motoru baştan sona KabaLang. ║ # ╚══════════════════════════════════════════════════════════════╝ # # Çalıştır: kabalang calistir hesap-makinesi.kbl kullan kaba.arayuz kullan kaba.sistem izinler: ag_erisim = yanlis # ── 1. HESAP MOTORU ─────────────────────────────────────────────── # İşlem türleri kapalı bir küme: derleyici yanlış üyeyi yakalar. sayilabilir Islem: TOPLA CIKAR CARP BOL fonksiyon oncelik(i: Islem) -> sayi: eger i == Islem.CARP veya i == Islem.BOL: don 2 don 1 fonksiyon uygula(a: ondalik, b: ondalik, i: Islem) -> ondalik: eger i == Islem.TOPLA: don a + b degilse eger i == Islem.CIKAR: don a - b degilse eger i == Islem.CARP: don a * b don a / b fonksiyon islem_mi(c: metin) -> mantik: don "+−×÷".icerir(c) fonksiyon islem_coz(c: metin) -> Islem: eger c == "+": don Islem.TOPLA degilse eger c == "−": don Islem.CIKAR degilse eger c == "×": don Islem.CARP don Islem.BOL # İki yığınlı değerlendirici: sayılar bir yığına, işlemler öbürüne. # Yeni gelen işlemin önceliği düşükse, yığındaki güçlü işlemler önce yapılır. fonksiyon hesapla(ifade: metin) -> ondalik: sayilar = [0.0] sayilar.sil(0) islemler = [Islem.TOPLA] islemler.sil(0) i = 0 iken i < ifade.uzunluk(): c = ifade.parca(i, 1) eksi_basta = c == "−" ve (i == 0 veya islem_mi(ifade.parca(i - 1, 1))) eger islem_mi(c) ve degil eksi_basta: yeni = islem_coz(c) iken islemler.uzunluk() > 0 ve oncelik(islemler[islemler.uzunluk() - 1]) >= oncelik(yeni): b = sayilar[sayilar.uzunluk() - 1] sayilar.sil(sayilar.uzunluk() - 1) a = sayilar[sayilar.uzunluk() - 1] sayilar.sil(sayilar.uzunluk() - 1) sayilar.ekle(uygula(a, b, islemler[islemler.uzunluk() - 1])) islemler.sil(islemler.uzunluk() - 1) islemler.ekle(yeni) i = i + 1 devam bas = i i = i + 1 iken i < ifade.uzunluk() ve degil islem_mi(ifade.parca(i, 1)): i = i + 1 sayi_metni = ifade.parca(bas, i - bas).degistir("−", "-").degistir(",", ".") sayilar.ekle(ondalik(sayi_metni)) iken islemler.uzunluk() > 0: b = sayilar[sayilar.uzunluk() - 1] sayilar.sil(sayilar.uzunluk() - 1) a = sayilar[sayilar.uzunluk() - 1] sayilar.sil(sayilar.uzunluk() - 1) sayilar.ekle(uygula(a, b, islemler[islemler.uzunluk() - 1])) islemler.sil(islemler.uzunluk() - 1) don sayilar[0] # ── 2. SAYIYI GÜZEL YAZMAK ──────────────────────────────────────── # 1234567.5 → "1.234.567,5" (Türkçe binlik ve ondalık ayırıcı) fonksiyon binlik(tam: metin) -> metin: eksi = tam.ile_baslar("-") eger eksi: tam = tam.parca(1, tam.uzunluk() - 1) sonuc = "" sayac = 0 i = tam.uzunluk() - 1 iken i >= 0: eger sayac > 0 ve sayac % 3 == 0: sonuc = "." + sonuc sonuc = tam.parca(i, 1) + sonuc sayac = sayac + 1 i = i - 1 eger eksi: don "−" + sonuc don sonuc fonksiyon bicimle(x: ondalik) -> metin: ham = f"{x:.8f}" nokta = ham.bul(".") tam = ham.parca(0, nokta) kesir = ham.parca(nokta + 1, ham.uzunluk() - nokta - 1) iken kesir.ile_biter("0"): kesir = kesir.parca(0, kesir.uzunluk() - 1) eger tam == "-0" ve kesir == "": tam = "0" eger kesir == "": don binlik(tam) don binlik(tam) + "," + kesir # Ekrandaki "1.234,5" biçimini motorun okuduğu "1234,5" biçimine çevirir. fonksiyon ham_sayi(gorunen: metin) -> metin: don gorunen.degistir(".", "") # ── 3. TUŞ MANTIĞI ──────────────────────────────────────────────── fonksiyon son_karakter(m: metin) -> metin: eger m.uzunluk() == 0: don "" don m.parca(m.uzunluk() - 1, 1) # Arka arkaya iki işlem tuşu: sonuncusu öncekinin yerine geçer. fonksiyon ifadeye_ekle(ifade: metin, tus: metin) -> metin: eger islem_mi(tus): eger ifade == "": eger tus == "−": don "−" don "" eger islem_mi(son_karakter(ifade)): don ifade.parca(0, ifade.uzunluk() - 1) + tus eger tus == ",": # Aynı sayıda ikinci virgül olmaz i = ifade.uzunluk() - 1 iken i >= 0 ve degil islem_mi(ifade.parca(i, 1)): eger ifade.parca(i, 1) == ",": don ifade i = i - 1 eger ifade == "" veya islem_mi(son_karakter(ifade)): don ifade + "0," don ifade + tus # Sondaki yarım işlemi at: "12+" → "12" fonksiyon temiz_ifade(ifade: metin) -> metin: iken ifade != "" ve islem_mi(son_karakter(ifade)): ifade = ifade.parca(0, ifade.uzunluk() - 1) don ifade # Ekranın göstereceği metin. Sıfıra bölme gibi hatalar burada yakalanır. fonksiyon canli_sonuc(ifade: metin) -> metin: ifade = temiz_ifade(ifade) eger ifade == "" veya ifade == "−": don "0" dene: don bicimle(hesapla(ifade)) yakala h: don "Tanımsız" fonksiyon yuzde(ifade: metin) -> metin: sonuc = canli_sonuc(ifade) eger sonuc == "Tanımsız": don ifade don ham_sayi(bicimle(hesapla(ham_sayi(sonuc)) / 100.0)) # ± tuşu: o anki sonucun işaretini çevirir fonksiyon isaret(ifade: metin) -> metin: eger canli_sonuc(ifade) == "Tanımsız" veya temiz_ifade(ifade) == "": don ifade don ham_sayi(bicimle(0.0 - hesapla(temiz_ifade(ifade)))) ilk_acilis = dogru pencere HesapMakinesi: baslik = "KabaLang Hesap Makinesi" genislik = 840 yukseklik = 660 tema = "koyu" yatay_kutu Govde: dikey_kutu SolTaraf: etiket Ifade: metin = "" stil = "font-size: 20px; color: #7d8aa8; padding: 8px 6px 0px 6px; min-height: 28px;" # Ekran BAĞLIDIR: ifade her değiştiğinde sonuç kendiliğinden yenilenir. etiket Ekran: metin = canli_sonuc(Ifade.metin) stil = "font-size: 60px; font-weight: 800; color: #ffffff; padding: 0px 6px 14px 6px;" yatay_kutu Satir1: dugme Temizle: metin = "C" stil = "font-size: 20px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #1a2030; color: #22d3ee;" tiklandiginda: Ifade.metin = "" dugme Sil: metin = "⌫" stil = "font-size: 20px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #1a2030; color: #22d3ee;" tiklandiginda: eger Ifade.metin.uzunluk() > 0: Ifade.metin = Ifade.metin.parca(0, Ifade.metin.uzunluk() - 1) dugme Yuzde: metin = "%" stil = "font-size: 20px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #1a2030; color: #22d3ee;" tiklandiginda: Ifade.metin = yuzde(Ifade.metin) dugme Bol: metin = "÷" stil = "font-size: 26px; font-weight: 700; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #1d2a4d; color: #7fb0ff;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "÷") yatay_kutu Satir2: dugme Yedi: metin = "7" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "7") dugme Sekiz: metin = "8" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "8") dugme Dokuz: metin = "9" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "9") dugme Carp: metin = "×" stil = "font-size: 26px; font-weight: 700; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #1d2a4d; color: #7fb0ff;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "×") yatay_kutu Satir3: dugme Dort: metin = "4" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "4") dugme Bes: metin = "5" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "5") dugme Alti: metin = "6" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "6") dugme Cikar: metin = "−" stil = "font-size: 26px; font-weight: 700; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #1d2a4d; color: #7fb0ff;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "−") yatay_kutu Satir4: dugme Bir: metin = "1" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "1") dugme Iki: metin = "2" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "2") dugme Uc: metin = "3" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "3") dugme Topla: metin = "+" stil = "font-size: 26px; font-weight: 700; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #1d2a4d; color: #7fb0ff;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "+") yatay_kutu Satir5: dugme Isaret: metin = "±" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = isaret(Ifade.metin) dugme Sifir: metin = "0" stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, "0") dugme Virgul: metin = "," stil = "font-size: 24px; font-weight: 600; min-height: 68px; min-width: 92px; border-radius: 16px; border: 1px solid #1c2336; background: #121829; color: #e6e9f2;" tiklandiginda: Ifade.metin = ifadeye_ekle(Ifade.metin, ",") dugme Esittir: metin = "=" stil = "font-size: 26px; font-weight: 800; min-height: 68px; min-width: 92px; border-radius: 16px; border: none; background: #377ef4; color: #ffffff;" tiklandiginda: sonuc = canli_sonuc(Ifade.metin) eger sonuc != "Tanımsız" ve Ifade.metin != ham_sayi(sonuc): Gecmis.ekle(temiz_ifade(Ifade.metin) + " = " + sonuc) Ifade.metin = ham_sayi(sonuc) dikey_kutu SagTaraf: etiket GecmisBasligi: metin = "Geçmiş" stil = "font-size: 17px; font-weight: 700; color: #22d3ee; padding: 6px 4px;" liste Gecmis: stil = "font-size: 18px; color: #c9d1e6; background: #0d1220; border: 1px solid #1c2336; border-radius: 12px; padding: 8px; min-width: 330px; max-width: 360px;" secildiginde: # Geçmişten bir satır seçince sonucu yeniden kullan satir = Gecmis.secili_metin eger satir.icerir(" = "): parcalar = satir.bol(" = ") Ifade.metin = ham_sayi(parcalar[1]) dugme GecmisiTemizle: metin = "Geçmişi temizle" stil = "font-size: 14px; min-height: 36px; border-radius: 10px; border: 1px solid #1c2336; background: #0d1220; color: #7d8aa8;" tiklandiginda: Gecmis.temizle() # Açılışta geçmişe, işlem önceliğini gösteren örnekler düşer. zamanlayici 50ms: eger ilk_acilis: ilk_acilis = yanlis dongu ornek icinde ["2+3×4", "100−20÷4×3", "−15+40×2", "99,9×3", "22÷7", "1250×12−2500"]: Gecmis.ekle(ornek + " = " + bicimle(hesapla(ornek))) Ifade.metin = "1250×12−2500"