Pretty C هي لغة برمجة نصية جديدة متوافقة مع لغة C. تعمل Pretty C على تعزيز برامجك من خلال الكتابة الديناميكية والتكرار العام وتتبع الموارد وغيرها من التفاصيل الدقيقة. وهو متوافق مع لغة C وجميع مكتباتها! مستوحاة من Lua وPython وJavaScript وLisp. إليك كيف قد تبدو عملية إعادة التنفيذ الساذجة للأداة المساعدة head
مع 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 ;
}
أهداف Pretty C هي:
#include
-قادرة على استخدام ملف C عشوائي!) لتحويل أي قاعدة تعليمات برمجية إلى قاعدة تعليمات للمبتدئين.الخروج من المستودع
git clone https://github.com/aartaka/pretty.c
أو ببساطة قم بنسخ ملف pretty.h
—Pretty C هي مكتبة للترويسة فقط، لذا يمكنك القيام بذلك
#include "pretty.h"
من أي ملف في الدليل قمت بإسقاط pretty.h
إليه. أو من أي ملف حقًا، إذا قمت بتحديد المسار إلى Pretty C كمسار تضمين ( -I
).
إليك جميع التغييرات الجميلة التي تجعل C hip مرة أخرى.
true
و false
و bool
.uint64_t
.and
&&
or
||
. مرتب! الجميع يحدد هذه، فلماذا لا نقدمها؟
max
والحد min
لعددين.len
لطول المصفوفةdefault
لتوفير قيمة احتياطية.limit
لضمان نطاق القيمة المناسب.between
للتحقق مما إذا كان الرقم يقع في نطاق.divisible
للتحقق مما إذا كان الرقم قابلاً للقسمة على رقم آخر. اكتب الأسماء المستعارة:
string
== char*
.byte
== char
.bytes
== char*
.any
== void*
.uchar
.ushort
.uint
.ulong
. تم تصميمه بشكل أساسي على غرار Lua وLisp:
eq
، لأن iso646.h
لا يحتوي إلا على not_eq
.is
==
أيضا.bitnot
و bitxor
للعمليات التي كان يتم استدعاؤها بشكل غير متسق ( compl
و xor
على التوالي) في iso646.h
.success
fail
/ failure
لنمط success == 0
.below
above
upto
downto
.even
، odd
، positive
، negative
، zero
، empty
كمسندات للأرقام/البيانات.nil
لـ NULL
.until
ينفي while
.elif
else if
.ifnt
for if(!...)
و elifnt
(لقد خمنت ذلك.)repeat
من Lua كاسم مستعار لـ do
.done~/~finish
pass
كأسماء مستعارة لـ break
و continue
على التوالي.always
، forever
، loop
، وإلى indefinitely
حتى تتمكن من إنشاء حلقات لا نهائية (الحدث؟ الخادم؟) always println ( "After all this time?" );
comment
never
بالتعليق على بعض التعليمات البرمجية باستخدام كلمة رئيسية واحدة فقط، مع السماح للمترجم بتحليلها/تحسينها (على غرار نموذج comment
Clojure): never println ( "This never runs, but never gets outdated, because compiler will shout at you if it does." );
نعم، يمكنك أن تفعل
var t = time ( 0 );
let lt = localtime ( & t );
local at = asctime ( lt );
println ( at );
مع بريتي سي.
طباعة print
كل ما تطعمه. يضيف println
سطرًا جديدًا بعده.
println ( 3.1 );
print ( "Hello world!n" );
قارن كل الأشياء!
equal ( "NA" , line ); // true
equal ( 0.3 , 0.2 + 0.1 ); // true
Ternaries مخيفة، لذلك لن يضر إضافة بعض النص العادي. إذا تم أخذ if
و else
، ولكن هناك بدائل لغوية مناسبة تبدو تمامًا مثل Python/Lisp:
return when some_condition
then do_something ()
other do_something_else ();
إنها ثلاثية تحت:
when
يتم توسيعه إلى سلسلة فارغة ويتم توفيره فقط لسهولة القراءة.unless
يتم توسيعه حتى not
يكون نسخة سلبية من when
.then
يتوسع إلى ?
.other
/ otherwise
يتوسع إلى :
. يوجد أيضًا only
عندما يكون شرط otherwise
غير ضروري:
return when done ()
then 42 only ;
otherwhen
للشرط التالي
return when c is 'A'
then 'a'
otherwhen c is 'B'
then 'b' only ;
for
الماكرو وحدات الماكرو هذه هي أسماء مستعارة for
حلقة معينة، حيث يلخص كل منها بعض الاستخدامات المتكررة for
.
foreach (var, type, length, ...)
يمشي هذا على مصفوفة أو منطقة ذاكرة تمت تهيئتها لتعبير vararg. في كل مرة يتم التكرار، يتم تعيين var
كمؤشر لعنصر المصفوفة المعني. نعم، المؤشر — حتى تتمكن من تعديل العنصر في مكانه إذا لزم الأمر.
foreach ( i , int , 10 , vector ( 10 , int , 1 , 2 , 3 , 3 , 4 , 5 ))
println ( * i );
يظهر أيضًا استخدام vector
.
forthese (var, type, ...)
يتكرر على المتغيرات المتوفرة، ويربط كل منها type
-d var
. يمكن ترجمة الحلقة أعلاه على النحو التالي:
forthese ( i , int , 1 , 2 , 3 , 3 , 4 , 5 )
println ( i );
fortimes (var, times)
حالة متكررة للانتقال من 0 إلى بعض الأرقام الإيجابية. يوفر عليك بعض الوقت بالنسبة لك
for ( int i = 0 ; i < 28 ; i ++ )
println ( i + 1 );
تحويلها إلى بسيطة
fortimes ( i , 28 )
println ( i + 1 );
println ( "28 stab wounds, you didn't want to leave him a chance, huh?" );
forrange (var, init, target)
قم بالتكرار على نطاق من الأرقام من init
إلى target
. بايثونسك. إليك حلقة تحويل مئوية إلى فهرنهايت مع forrange
:
forrange ( c , -10 , 20 )
printf ( "Celsius %i = Fahrenheit %fn" , c , ( 32 + ( c * 1.8 )));
لاحظ أن init
و target
عبارة عن أعداد صحيحة عشوائية، موقعة وغير موقعة. وقد يكون init
أكبر من target
وفي هذه الحالة تؤدي خطوة التكرار إلى تقليل المتغير.
forrangeby (var, type, init, target, by)
كرر type
-d var
من iter
إلى target
، مع مرور الوقت by
كل مرة. بايثونسك.
forrangeby ( x , double , 1.0 , 10.0 , 0.5 )
println ( x );
تسمح هذه بالتخصيص السريع والقذر للأنماط النموذجية. تم تصميمه في الغالب على غرار لغة C++.
new (type, ...)
يعد عامل التشغيل new
لـ C++ أمرًا رائعًا، لذا لن يضر وجود شيء مشابه في C، أليس كذلك؟ لا تسأل أكثر:
struct ListNode {
int val ;
struct ListNode * next ;
};
struct ListNode * node = new ( struct ListNode , 2 , new ( struct ListNode , 1 , nil ));
أو، إذا كنت ترغب في ذلك، يمكنك إضافة المزيد من بناء الجملة في الأعلى:
#define cons ( val , ...) new(struct ListNode, val, __VA_ARGS__)
cons ( 2 , cons ( 1 , nil ));
vector (length, type, ...)
سي++ مرة أخرى. std::vector
عبارة عن بنية بيانات مفيدة للغاية ومتعددة الاستخدامات يسهل التفكير فيها. على الرغم من أن هذا الماكرو ليس مميزًا مثل نظيره في C++، إلا أنه يبسط النمط المتكرر المتمثل في "تخصيص مصفوفة من هذا القدر من العناصر وبهذه المحتويات":
double * vec = vector ( 10 , double , 1 , 2 , 3 , 4 , 5 );
delete (...)
في حال كنت لا تحب الموارد free
وتفضل اسم C++ أكثر روعة.
خلاف ذلك نفس free
.
تقوم هذه بإنشاء روابط محلية جديدة، أو ضمان الحسابات المؤجلة، أو التصرف على الكتلة بعدها.
lambda (ret, name, ...)
(GCC، Clang، أو C++)الوظائف المتداخلة/لامبدا/الإغلاقات، الآن في لغة 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, ...)
وهذا يضمن عدم حصولك أبدًا على استخدام بعد الاستخدام المجاني، لأنك تقدم إجراء التحرير ( close
) مقدمًا. مفيد بشكل خاص للكائنات المخصصة ديناميكيًا ومحددات الملفات.
with ( file , fclose , fopen ( "hello.txt" , "w" ))
fprintf ( file , "Hello world!n" );
أحد الجوانب السلبية هو أن var
المنضم عبارة عن void *
، لذا قد تحتاج إلى إجباره على النوع الخاص بك قبل استخدامه.
defer (...)
يقوم بإلغاء تحميل الكود الذي سيتم تنفيذه بعد الكتلة التالية. ليس في نهاية الوظيفة كما في Go، لأن هذا مستحيل من الصعب تنفيذها في C. ومع ذلك، فإن Pretty C defer
مفيد بما فيه الكفاية.
try
catch
معالجة رائعة للأخطاء، الآن في لغة C. مثال معاد تصنيعه من مرجع errno:
try log ( 0.0 );
catch ( NOERR )
println ( "No error." );
catch ( EDOM , ERANGE )
println ( "Math error!" );
يتم توفير NOERR
و NOERROR
أيضًا بواسطة Pretty C، لتسهيل معالجة الأخطاء.
make indent
قبل الالتزام، والتي يجب أن تتعامل مع معظم تفاصيل النمط.