Pretty.c - C Üzerinde Çalışan Betik Dili
(github.com/aartaka)- Pretty C, C ile uyumlu yeni bir betik dili olup dinamik tipleme, jenerik yineleme ve kaynak takibi gibi kullanışlı özellikleri C programlarına ekler
- Kullanım şekli, yalnızca
pretty.heklenerek çalışan header-only kütüphane biçimindedir; mevcut C dosyaları ve C kütüphaneleriyle birlikte kullanılabilir - Sunulan özellikler arasında
string,any,nilgibi takma adlar,var/lettür çıkarımı,print/printlnjenerik çıktı,equaljenerik karşılaştırma ve okunması kolay üçlü ifade makroları bulunur - Yineleme ve bellek işlemlerini azaltmak için
foreach,forthese,fortimes,forrange,new,vector,delete,with,lambda,try/catchgibi makro tabanlı sözdizimi sağlar - Bazı özellikler GCC, Clang, C23+, C11+ gibi koşullara bağlıdır ve
withile bağlanan değişkenlervoid *olduğundan kullanım öncesinde tür dönüşümü gerekebilir
Pretty C'nin hedefi ve kullanım şekli
- Pretty C, C ile uyumlu bir betik dilidir ve C programlarına dinamik tipleme, jenerik yineleme, kaynak takibi ve çeşitli sözdizimi kolaylıkları ekler
- Mevcut C ve C kütüphaneleriyle geri uyumluluğu korur
- Lua, Python, JavaScript ve Lisp'ten ilham alır
- Kurulum için depo klonlanabilir veya yalnızca
pretty.hdosyası kopyalanarak kullanılabilir- Herhangi bir C dosyasında
#include "pretty.h"ile eklenebilir - Include yoluna Pretty C dizini verilerek de kullanılabilir
- Herhangi bir C dosyasında
Varsayılan dahil edilen başlıklar ve basit makrolar
- Pretty C, standart başlıkları dahil ederek sık kullanılan türlerin ve operatör alternatiflerinin doğrudan kullanılmasını sağlar
- Sık tanımlanan basit makrolar da sunar
max,min: iki sayının en büyük ve en küçük değerilen: dizi uzunluğudefault: fallback değer sağlamalimit: değer aralığını sınırlamabetween: sayının aralık içinde olup olmadığını kontrol etmedivisible: başka bir sayıya tam bölünüp bölünmediğini kontrol etme
Türler ve takma adlar
- Pretty C, C türleri için kısa tür takma adları sağlar
string,char*anlamına gelirbyte,charanlamına gelirbytes,char*anlamına gelirany,void*anlamına gelir- Tamsayı kısaltmaları olarak
uchar,ushort,uint,ulongsunulur
- Lua ve Lisp'ten etkilenmiş sözdizimi takma adları da içerir
eq,is:==bitnot,bitxor: bit işlemi takma adlarısuccess,fail,failure:success == 0kalıbı için takma adlarbelow,above,upto,downto: karşılaştırma operatörlerieven,odd,positive,negative,zero,empty: sayı ve veri predicate'lerinil:NULLuntil: olumsuzwhileelif:else ififnt,elifnt:if(!...)türü ifadelerrepeat: Lua tarzıdotakma adıdone,finish,pass:break,continuetakma adlarıalways,forever,loop,indefinitely: sonsuz döngü ifadelerinever,comment: kodu çalıştırmadan derleyicinin analiz edebilmesini sağlayan ifadeler
Tür çıkarımı, çıktı, karşılaştırma, üçlü ifade
- Tür çıkarımı, GCC, Clang veya C23+ ile kullanılabilir
- Örnek olarak
var t = time(0);,let lt = localtime(&t);,local at = asctime(lt);biçimleri sunulur
- Örnek olarak
- Jenerik çıktı, C11+ ile kullanılabilir
print, verilen değeri yazdırırprintln, çıktının sonuna satır sonu ekler
- Jenerik eşitlik karşılaştırması da C11+ özelliği olarak sunulur
equal("NA", line)gibi string karşılaştırmalarıequal(0.3, 0.2 + 0.1)gibi karşılaştırma örnekleri bulunur
- Üçlü operatör, metin tabanlı makrolarla daha okunabilir hale getirilebilir
when, okunabilirlik için boş string'e genişlerunless,notolarak genişler vewhenin olumsuz biçimi gibi çalışırthen:?otherveotherwise::only,otherwisebölümü gerekmediğinde kullanılırotherwhen, sonraki koşulu zincirlemek için kullanılır
Yineleme makroları
- Pretty C, sık kullanılan
fordöngüsü kalıplarını makrolarla soyutlar foreach (var, type, length, ...)- Bir dizi veya bellek bölgesi üzerinde gezinir
- Her yinelemede
var, ilgili dizi öğesine işaret eden bir pointer olur - Pointer olduğu için gerekirse öğe yerinde değiştirilebilir
forthese (var, type, ...)- Verilen değişken sayıda argümanı dolaşır ve her değeri
typetüründekivardeğişkenine bağlar
- Verilen değişken sayıda argümanı dolaşır ve her değeri
fortimes (var, times)- 0'dan başlayıp pozitif bir sayıya kadar süren yaygın kalıbı kısaltır
forrange (var, init, target)initiletargetarasındaki sayısal aralıkta gezinirinitvetarget, herhangi bir signed veya unsigned tamsayı olabilirinit,targettan büyükse yineleme adımı azalır
forrangeby (var, type, init, target, by)- Türü belirtilmiş
vardeğişkeniniinittentargeta kadarbyaralığıyla dolaştırır
- Türü belirtilmiş
Atama ve blok yardımcıları
- Atama makroları, C++'tan etkilenmiş bir biçimle yaygın bellek ayırma kalıplarını sadeleştirir
new (type, ...): C++newbenzeri biçimde struct vb. oluştururvector (length, type, ...): belirtilen uzunluk ve türde dizi ayırmayı ve başlangıç içeriği vermeyi kolaylaştırırdelete (...):freeile aynıdır, ancak C++ tarzı ad tercih edildiğinde kullanılabilir
- Blok yardımcıları, yerel bağlama, ertelenmiş çalıştırma ve blok düzeyinde işlemler için makrolar sunar
lambda (ret, name, ...): GCC, Clang veya C++ ile iç içe fonksiyon, lambda ve closure benzeri yapıları C'de kullanmayı sağlarwith (var, close, ...): kaynak serbest bırakma fonksiyonucloseu önceden vererek dinamik ayrılan nesneler veya dosya tanıtıcıları için kullanışlıdır- Dezavantaj olarak bağlanan
var,void *olduğundan kullanmadan önce istenen türe dönüştürmek gerekebilir
- Dezavantaj olarak bağlanan
defer: kaldırılmıştır; yerine yeni kullanılabilirdeferin kullanılması önerilirtryvecatch: C'de hata işlemeyi daha gösterişli bir biçimde yazmayı sağlarNOERR,NOERROR: hata switch-case kolaylığı için sunulur
Katkı yöntemi
- Fonksiyon eklerken Linux Kernel Style Guide izlenmesi istenir
- Commit öncesinde
make indentçalıştırılması önerilir
- Commit öncesinde
- A’s Commit Message Guide izlenmesi tercih edilir, ancak zorunlu değildir
1 yorum
Hacker News yorumları
C içinde alana özgü dil oluşturma geleneği epey eskidir
Stephen Bourne, shell’i ALGOL ile yazmak istiyordu; bu yüzden C önişlemcisini ısrarla zorlayıp sonunda kendi tercih ettiği dile benzer görünmesini sağladı
https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh...
https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh...
https://www.ioccc.org/
Bunun bir şaka mı olduğunu, yoksa yazarın gerçekten kafasının mı karışık olduğunu açıklayabilecek biri var mı merak ediyorum
Hiçbir şey mantıklı değil. “Scripting” de değil; “güçlü tip” getirdiğini söylüyor ama tiplere hiçbir şey yapmıyor; Lua ve Lisp’ten esinlendiği söylenen operatör takma adları ise aslında iki dilde de yok. Ama bariz bir parodi gibi de görünmediği için gerçekten kafa karıştırıyor
Scripting dili olduğunu iddia ediyor ama hâlâ programı derlemek gerekiyor. Yuh yani
CINT’i (https://root.cern.ch/root/html534/guides/users-guide/CINT.ht...) ekleyince anında çalıştırma da REPL de mümkün oluyor
Eskiden
./foo’nun nasıl çalıştığını ve ELF dosyalarının nasıl yürütüldüğünü ayrıntılı anlatan bir blog yazısı görmüştüm. Aynı yöntemle.cprogramlarını kaydedip derledikten sonra çalıştırmak da mümkün olabilir[0] https://gist.github.com/jdarpinian/1952a58b823222627cc1a8b83...
[0] https://bellard.org/tcc/tcc-doc.html
“C geliştiricilerine diyabetik kalp krizi geçirtecek kadar sözdizimsel şeker sunar.”
Bu ifadeye bayıldım
CNoEvil[0] ve ogw[1]’ye eklenmesi gereken birkaç şey görüyorum. Bu proje birkaç ayda bir yeniden gündeme geldikçe sanki hep daha fazlası çıkıyor
[0] https://git.sr.ht/~shakna/cnoevil3/
[1] https://git.sr.ht/~shakna/ogw
İçten içe, bütün kalbimle sevmeye başladığım bir cümle
Bu, Python 2 ile aynı hatayı yapıyor. Dizeler ve baytlar aynı tip değildir ve öyle ele alınmamalıdır
argviçindeki değerler ya da alt süreç çıktısının tipi ne sayılmalı merak ediyorumİçinde rastgele çöp değerler bulunabileceği için geçerli UTF-8 dizesi değildir; ama awk ve grep gibi araçlar her yerde kullanılıyor
Dizeler ve baytlar aynı genel tip olarak görülebilir; ancak geçerli UTF-8 baytlarına içeride ayrı bir tip vermenin faydalı olduğu durumlar var. Rust bu kısmı OsString ve String ile genel olarak iyi ele alıyor
https://en.cppreference.com/w/c/string/multibyte
Bunların hiçbiri her zaman doğru değildir. Doğrulanmış bayt dizilerini yalnızca doğrulama yoluyla oluşturulabilen bir tipe sarmak faydalıdır; ama bunu yaptıktan sonra
Utf8StringileEmailAddressfiilen aynı sınıfa girer. Tip sisteminde yalnızca kodlamayı özel muameleye tabi tutmak için bir neden yok“İnsan tarafından okunabilir metin” ise, dizelerin rastgele bayt dizileriyle aynı olmadığına katılıyorum. Ama birçok dil bu tanımı zorunlu kılmaz
Eskiden incelemem gereken bir C++ kod tabanını hatırlattı. Tamamı Java ile yazılmış gibiydi; her şeyde camelCase, her sınıf değişkeninde getter/setter, her yerde arayüzler vardı
https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd...
ALGOL olmadığına inanmak zor
std::stringi sarmalayan ama Java tarzı metotlar eklenmiş kendi String sınıfları bile vardıhttps://learn.microsoft.com/en-us/cpp/cpp/property-cpp?view=...
f(String *)olarak geçiriyorlardı, C++ koduf(new String("Hello")şeklindeydiBu ilginç geldiyse libcello.h da hoşuna gidebilir
https://www.libcello.org
Tip adları güzel,
mingibi yerleşik fonksiyon makrolarının seçimi de kusursuz.Lende hoşuma gittiİsimlendirilmiş boolean operatörler biraz fazla gelebilir ama denemeye değer; üçlü operatör zaten baştan okunması zor, dolayısıyla iyileştirilecek çok şey var. Tüm döngü tanımlarına tamamen ikna olmuş değilim ama bazıları mantıklı. Kaynak takibi etkileyici;
for...biçimi biraz çirkin, başka bir ad verilebilir gibi duruyorGenel olarak epey sağlam bir deneme. Tasarıma 8/10 civarı verirdim. C makrolarıyla eskizlenmiş hâli gerçekten zarif ve fiilen iyi kod gibi görünüyor. Kendim kullanır mıyım bilmiyorum. Sonuçta yeni bir dil ve ben zaten C’yi seviyorum. Yine de uygulanma biçimi çok net; insanların C öğrenmesine ve dil tasarımı üzerine düşünmesine yardımcı olabilir
len(),max/minve birkaç operatör makrosunu kullanıyor. Çünkü diğer lezzetli özelliklerin çoğuna henüz ihtiyaç duymadım. O yüzden sadece birkaç operatör makrosunu bile denemeni öneririmif(!...)içinifntolacaksa, unlessifntten daha okunaklı görünüyorfor(;;)döngüsünealwaysdenmesi de varBaşka dillerde
loopgörmüştüm. Ama Qt bunaforeverdiyor ve bu gerçekten hoş. Ayrıca çok Qt’ye özgüifntyüksek sesle söyleyince eğlenceliunlessi üçlü koşul için ayırmıştım. Çünkü orada her hâlükârda daha kullanışlıAh, bir dakika, John Tromp’muş. BLC’nin yaratıcısı! Hayranıyım