#include #include "fiko/parametre/ifade.hpp" #include "fiko_test.hpp" using namespace fiko; using namespace fiko::parametre; namespace { f64 D(const std::string& i, const std::map& d = {}) { return hesapla(i, d).deger; } } // namespace FIKO_TEST(ifade_aritmetik_oncelik) { FIKO_YAKIN(D("2+3*4"), 14.0, 1e-12); // çarpma önce FIKO_YAKIN(D("(2+3)*4"), 20.0, 1e-12); // parantez FIKO_YAKIN(D("2+3-4+5"), 6.0, 1e-12); // soldan FIKO_YAKIN(D("10/4"), 2.5, 1e-12); FIKO_YAKIN(D("10%3"), 1.0, 1e-12); // mod FIKO_YAKIN(D(" 2 + 3 "), 5.0, 1e-12); // boşluk toleransı } FIKO_TEST(ifade_birli_ve_us) { FIKO_YAKIN(D("-5"), -5.0, 1e-12); FIKO_YAKIN(D("--5"), 5.0, 1e-12); FIKO_YAKIN(D("2*-3"), -6.0, 1e-12); FIKO_YAKIN(D("2^3"), 8.0, 1e-12); FIKO_YAKIN(D("2^3^2"), 512.0, 1e-9); // sağ-birleşimli: 2^(3^2)=2^9 FIKO_YAKIN(D("-2^2"), -4.0, 1e-12); // birli us'ten sonra: -(2^2) } FIKO_TEST(ifade_degiskenler) { const std::map d{{"genislik", 100.0}, {"yukseklik", 40.0}}; FIKO_YAKIN(D("genislik + yukseklik", d), 140.0, 1e-12); FIKO_YAKIN(D("genislik / yukseklik", d), 2.5, 1e-12); FIKO_YAKIN(D("genislik * 2 - yukseklik", d), 160.0, 1e-12); FIKO_YAKIN(D("(genislik + yukseklik) / 2", d), 70.0, 1e-12); } FIKO_TEST(ifade_fonksiyonlar) { FIKO_YAKIN(D("sqrt(16)"), 4.0, 1e-12); FIKO_YAKIN(D("abs(-7)"), 7.0, 1e-12); FIKO_YAKIN(D("max(3,7)"), 7.0, 1e-12); FIKO_YAKIN(D("min(3,7)"), 3.0, 1e-12); FIKO_YAKIN(D("pow(2,10)"), 1024.0, 1e-9); FIKO_YAKIN(D("clamp(15,0,10)"), 10.0, 1e-12); FIKO_YAKIN(D("clamp(-5,0,10)"), 0.0, 1e-12); FIKO_YAKIN(D("floor(3.7)"), 3.0, 1e-12); FIKO_YAKIN(D("round(2.5)"), 3.0, 1e-12); FIKO_YAKIN(D("sin(0)"), 0.0, 1e-12); FIKO_YAKIN(D("cos(0)"), 1.0, 1e-12); FIKO_YAKIN(D("deg(180)"), std::numbers::pi, 1e-12); // derece→radyan FIKO_YAKIN(D("sin(deg(90))"), 1.0, 1e-12); // birleşik } FIKO_TEST(ifade_sabitler) { FIKO_YAKIN(D("pi"), std::numbers::pi, 1e-12); FIKO_YAKIN(D("e"), std::numbers::e, 1e-12); FIKO_YAKIN(D("2*pi"), 2 * std::numbers::pi, 1e-12); } FIKO_TEST(ifade_hatalar) { FIKO_KONTROL(!hesapla("").basarili); // boş FIKO_KONTROL(!hesapla("2+").basarili); // eksik operand FIKO_KONTROL(!hesapla("(2+3").basarili); // kapanmayan parantez FIKO_KONTROL(!hesapla("1/0").basarili); // sıfıra bölme FIKO_KONTROL(!hesapla("x+1").basarili); // bilinmeyen değişken FIKO_KONTROL(!hesapla("bilinmez(2)").basarili); // bilinmeyen fonksiyon FIKO_KONTROL(!hesapla("sqrt(1,2)").basarili); // yanlış argüman sayısı FIKO_KONTROL(!hesapla("2 3").basarili); // artık karakter // Başarılı olanlarda hata boş. FIKO_KONTROL(hesapla("2+2").basarili); FIKO_KONTROL(hesapla("2+2").hata.empty()); } FIKO_TEST(ifade_bagimliliklar) { const auto b = bagimliliklar("a + b * sin(c) + pi - 2"); FIKO_KONTROL(b.size() == 3); // a, b, c (sin/pi hariç) FIKO_KONTROL(b[0] == "a" && b[1] == "b" && b[2] == "c"); // Tekrarsız + fonksiyon/sabit dışlanır. const auto b2 = bagimliliklar("x*x + max(x, y) + e"); FIKO_KONTROL(b2.size() == 2 && b2[0] == "x" && b2[1] == "y"); FIKO_KONTROL(bagimliliklar("2 + 3 * 4").empty()); // değişken yok } FIKO_TEST(ifade_karsilastirma_kosul) { // Karşılaştırma → 1.0 (doğru) / 0.0 (yanlış). FIKO_YAKIN(D("3 < 5"), 1.0, 1e-12); FIKO_YAKIN(D("5 < 3"), 0.0, 1e-12); FIKO_YAKIN(D("5 >= 5"), 1.0, 1e-12); FIKO_YAKIN(D("4 > 9"), 0.0, 1e-12); FIKO_YAKIN(D("3 == 3"), 1.0, 1e-12); FIKO_YAKIN(D("3 != 4"), 1.0, 1e-12); FIKO_YAKIN(D("2 + 2 == 4"), 1.0, 1e-12); // aritmetik önce, sonra karşılaştırma // Koşullu if/eger. FIKO_YAKIN(D("if(1, 10, 20)"), 10.0, 1e-12); FIKO_YAKIN(D("if(0, 10, 20)"), 20.0, 1e-12); FIKO_YAKIN(D("eger(5 > 3, 100, 200)"), 100.0, 1e-12); // Mantık ve/veya/degil. FIKO_YAKIN(D("ve(1, 1)"), 1.0, 1e-12); FIKO_YAKIN(D("ve(1, 0)"), 0.0, 1e-12); FIKO_YAKIN(D("veya(0, 1)"), 1.0, 1e-12); FIKO_YAKIN(D("degil(0)"), 1.0, 1e-12); // Değişkenli tasarım kuralı: çap 10'dan küçükse iki katı. const std::map d{{"cap", 8.0}}; FIKO_YAKIN(D("if(cap < 10, cap * 2, cap)", d), 16.0, 1e-12); // Tek '=' / '!' hatası. FIKO_KONTROL(!hesapla("3 = 3").basarili); FIKO_KONTROL(!hesapla("3 ! 3").basarili); }