Pretty C adalah bahasa skrip baru yang kompatibel dengan C. Pretty C meningkatkan program Anda dengan pengetikan dinamis, iterasi umum, pelacakan sumber daya, dan fasilitas lainnya. Dan itu kompatibel dengan C dan semua perpustakaannya! Terinspirasi oleh Lua, Python, JavaScript, dan Lisp. Berikut tampilan implementasi ulang utilitas head yang naif dengan Pretty C:
#include "pretty.h"
int main ( int argc , string argv [])
{
if ( argc above 1 )
with ( f , fclose , fopen ( argv [ 1 ], "r" ))
fortimes ( line , 10 )
with ( buf , free , vector ( 200 , char , 0 ))
when ( fgets ( buf , 200 , f ))
then print ( buf )
otherwise 0 ;
else
println ( "Please provide an input file" );
return EXIT_SUCCESS ;
}Tujuan dari Pretty C adalah:
#include -able dari file C sembarang!) untuk mengubah basis kode apa pun menjadi basis kode yang ramah bagi pemula.Periksa repositori
git clone https://github.com/aartaka/pretty.c Atau cukup salin file pretty.h —Pretty C adalah perpustakaan khusus header, jadi Anda bisa
#include "pretty.h" dari file apa pun di direktori tempat Anda meletakkan pretty.h . Atau sebenarnya dari file apa pun, jika Anda menentukan jalur ke Pretty C sebagai jalur penyertaan ( -I ).
Inilah semua perubahan cantik yang membuat C kembali keren.
true , false , dan bool .uint64_t .and untuk && dan or untuk || . Rapi! Semua orang mendefinisikannya, jadi mengapa tidak menyediakannya?
max dan min dari dua angka.len untuk panjang array.default untuk memberikan nilai cadangan.limit untuk memastikan kisaran nilai yang tepat.between untuk memeriksa apakah angkanya berada dalam suatu kisaran.divisible untuk memeriksa apakah suatu bilangan modulo habis dibagi bilangan lain. Ketik alias:
string == char* .byte == char .bytes == char* .any == void* .uchar .ushort .uint .ulong . Terutama dimodelkan setelah Lua dan Lisp:
eq , karena iso646.h hanya memiliki not_eq .is == juga.bitnot dan bitxor untuk operasi yang dulunya dipanggil secara tidak konsisten ( compl dan xor masing-masing) di iso646.h .success dan fail / failure untuk pola success == 0 .below , above , upto , dan downto .even , odd , positive , negative , zero , dan empty sebagai predikat angka/data.nil untuk NULL .until untuk dinegasikan while .elif untuk else if .ifnt untuk if(!...) dan elifnt (coba tebak.)repeat dari Lua sebagai alias untuk do .done~/~finish dan pass sebagai alias untuk break dan continue .always , forever , loop , dan indefinitely sehingga Anda dapat membuat loop tak terbatas (event? server?). always println ( "After all this time?" );never dan comment untuk mengomentari beberapa kode hanya dengan satu kata kunci, sambil tetap mengizinkan kompiler untuk menganalisis/mengoptimalkannya (mirip dengan formulir comment Clojure): never println ( "This never runs, but never gets outdated, because compiler will shout at you if it does." );Ya, Anda bisa melakukannya
var t = time ( 0 );
let lt = localtime ( & t );
local at = asctime ( lt );
println ( at );Dengan Cantik C.
print apa pun yang Anda berikan. println menambahkan baris baru setelahnya.
println ( 3.1 );
print ( "Hello world!n" );Bandingkan semua hal!
equal ( "NA" , line ); // true
equal ( 0.3 , 0.2 + 0.1 ); // true Terner memang menakutkan, jadi tidak ada salahnya menambahkan beberapa teks biasa. if dan else diambil, tetapi ada alternatif linguistik yang tepat yang terlihat mirip Python/Lisp:
return when some_condition
then do_something ()
other do_something_else ();Ada terner di bawahnya:
when diperluas ke string kosong dan hanya disediakan untuk keterbacaan.unless diperluas menjadi not versi negatif dari when .then meluas menjadi ? .other / otherwise diperluas ke : . Ada juga only ketika klausa otherwise tidak diperlukan:
return when done ()
then 42 only ; dan otherwhen untuk kondisi selanjutnya
return when c is 'A'
then 'a'
otherwhen c is 'B'
then 'b' only ;for Makro Makro ini adalah alias untuk pola perulangan for tertentu, yang masing-masing mengabstraksi beberapa penggunaan perulangan for yang sering dilakukan.
foreach (var, type, length, ...) Yang ini menjalankan array atau wilayah memori yang diinisialisasi ke ekspresi vararg. Setiap kali diulang, var disetel ke penunjuk ke elemen array masing-masing. Ya, penunjuk—sehingga Anda dapat memodifikasi elemen di tempatnya jika perlu.
foreach ( i , int , 10 , vector ( 10 , int , 1 , 2 , 3 , 3 , 4 , 5 ))
println ( * i ); Juga menunjukkan penggunaan vector .
forthese (var, type, ...) Ulangi vararg yang disediakan, ikat masing-masing vararg ini menjadi type -d var . Loop di atas dapat diterjemahkan sebagai:
forthese ( i , int , 1 , 2 , 3 , 3 , 4 , 5 )
println ( i );fortimes (var, times)Kasus yang sering terjadi dari 0 ke bilangan positif. Menghemat waktu Anda
for ( int i = 0 ; i < 28 ; i ++ )
println ( i + 1 );mengubahnya menjadi sederhana
fortimes ( i , 28 )
println ( i + 1 );
println ( "28 stab wounds, you didn't want to leave him a chance, huh?" );forrange (var, init, target) Ulangi rentang angka dari init ke target . ular piton. Berikut loop konversi Celcius ke Fahrenheit dengan forrange :
forrange ( c , -10 , 20 )
printf ( "Celsius %i = Fahrenheit %fn" , c , ( 32 + ( c * 1.8 ))); Perhatikan bahwa init dan target adalah bilangan bulat arbitrer, bertanda tangan dan tidak bertanda tangan. Dan init mungkin lebih besar dari target dalam hal ini langkah iterasi menurunkan variabel.
forrangeby (var, type, init, target, by) Ulangi type -d var dari iter ke target , by setiap saat. ular piton.
forrangeby ( x , double , 1.0 , 10.0 , 0.5 )
println ( x );Ini memungkinkan alokasi cepat dan kotor untuk pola-pola tertentu. Sebagian besar dimodelkan setelah C++.
new (type, ...) Operator new C++ itu bagus, jadi tidak ada salahnya memiliki sesuatu yang serupa di C, bukan? Jangan bertanya lagi:
struct ListNode {
int val ;
struct ListNode * next ;
};
struct ListNode * node = new ( struct ListNode , 2 , new ( struct ListNode , 1 , nil ));Atau, jika mau, Anda dapat menambahkan lebih banyak sintaksis di atasnya:
#define cons ( val , ...) new(struct ListNode, val, __VA_ARGS__)
cons ( 2 , cons ( 1 , nil ));vector (length, type, ...) C++ lagi. std::vector adalah struktur data yang sangat berguna dan serbaguna yang mudah untuk dipikirkan. Meskipun makro ini bahkan tidak memiliki fitur yang sama seperti versi C++, makro ini menyederhanakan pola umum “mengalokasikan array dengan elemen sebanyak itu dan dengan konten berikut”:
double * vec = vector ( 10 , double , 1 , 2 , 3 , 4 , 5 );delete (...) Jika Anda tidak suka free sumber daya dan lebih memilih nama C++ yang lebih bagus.
Kalau tidak, sama saja dengan free .
Ini menetapkan pengikatan lokal baru, memastikan penghitungan yang ditangguhkan, atau bertindak berdasarkan blok setelahnya.
lambda (ret, name, ...) (GCC, Dentang, atau C++)Fungsi bersarang/lambdas/penutupan, sekarang di C!
int * arr = vector ( 10 , int , 23423 , 23423 , 234 , 5233 , 6 , 4 , 34 , 643 , 3 , 9 );
lambda ( int , cmp , int * a , int * b ) {
return * a - * b ;
};
qsort ( arr , 10 , sizeof ( int ), cmp );
// arr becomes {3, 4, 6, 9, 34, 234, 643, 5233, 23423, 23423}with (var, close, ...) Hal ini memastikan bahwa Anda tidak pernah memiliki penggunaan setelah bebas, karena Anda menyediakan prosedur pembebasan ( close ) dimuka. Sangat berguna untuk objek dan penunjuk file yang dialokasikan secara dinamis.
with ( file , fclose , fopen ( "hello.txt" , "w" ))
fprintf ( file , "Hello world!n" ); Salah satu kelemahannya adalah var yang terikat adalah void * , jadi Anda mungkin perlu memaksakannya ke tipe Anda sebelum menggunakannya.
defer (...) Membongkar kode yang akan dieksekusi setelah blok berikut. Bukan di akhir fungsi seperti di Go, karena itu mustahil sulit diterapkan di C. Namun, Pretty C defer cukup berguna.
try dan catchPenanganan kesalahan yang bagus, sekarang di C. Contoh yang difaktorkan ulang dari referensi errno:
try log ( 0.0 );
catch ( NOERR )
println ( "No error." );
catch ( EDOM , ERANGE )
println ( "Math error!" ); NOERR dan NOERROR juga disediakan oleh Pretty C, untuk kemudahan error switch-casing.
make indent sebelum melakukan, yang seharusnya menangani sebagian besar detail gaya.