338 lines
15 KiB
Plaintext
338 lines
15 KiB
Plaintext
# ╔══════════════════════════════════════════════════════════════╗
|
|||
|
|
# ║ 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"
|