Lambda-8cc هو برنامج التحويل البرمجي X86 C مكتوب كمصطلح لحساب Lambda المغلقة غير المتوحش.
عند طباعتها على ورق بحجم الحروف ، يصبح طوله 18506 صفحة على PDF 22 ميغابايت دون أي أرقام. يمكن رؤية PDF على صفحات جيثب هنا. مصدر اللاتكس هو 448 ميغابايت ، وملف تسجيل تجميع اللاتكس main.log هو 284 ميغابايت. لم أستطع أن أصدق أن LaTex كان قادرًا على القيام بذلك.
مصطلح حساب حساب التفاضل والتكامل هذا العملاق هو برنامج التحويل البرمجي C. فيما يلي ROT13.C ، وهو برنامج يجمع على مجلس التعاون الخليجي بدون أخطاء. يمكن تجميع نفس البرنامج باستخدام Lambda-8CC لإنتاج ROT13.Bin القابل للتنفيذ X86 ، Runnable على X86/X86-64 Linux:
$ echo ' Hello, world! ' | ./rot13.bin
Uryyb, jbeyq !
$ echo ' Uryyb, jbeyq! ' | ./rot13.bin
Hello, world !على الرغم من حجمها الهائل ، فإن تجميع ROT13.C ينتهي في 8 دقائق على الجهاز الخاص بي باستخدام مترجم حساب حساب Lambda. يمكنك تجربته على جهاز الكمبيوتر الخاص بك عن طريق استنساخ هذا الريبو. يتم تلخيص إحصائيات وقت التشغيل في أوقات التشغيل وقسم استخدام الذاكرة. لاحظ أنه على الرغم من أن التجميع يستغرق وقتًا ، إلا أن الجمع الثنائي المترجم يعمل على الفور.
كميزة إضافية ، لا يمكن فقط تجميع Lambda-8cc C إلى X86 ، ولكن يمكن أيضًا تجميع مصطلحات C إلى Lambda ، مما ينتج عنه شيء مثل Rot13.lam. تعمل مصطلحات Lambda المترجمة على نفس مترجم حساب Lambda المستخدم لتشغيل Lambda-8cc نفسها.
باستخدام خيارات التجميع الخاصة به ، يمكن أن يقوم Lambda-8CC بتجميع C إلى 5 تنسيقات مختلفة. فيما يلي قائمة كاملة بميزاتها:
من بين القائمة Lazy K ، وهي لغة وظيفية قليلة بحتة مع 4 عوامل مدمجة فقط ، على غرار الحد الأدنى من اللغة الضرورية BF التي لديها 8 تعليمات فقط. لقد غطيت قليلاً عن ذلك في منشور مدونتي أيضًا.
يعتمد Lambda-8CC على المشاريع الثلاثة التالية: أول مشاريع هي Lambdavm كتبها مؤلف هذا Repo Hikaru Ikuta ، وهو وحدة المعالجة المركزية الافتراضية القابلة للبرمجة المكتوبة كمصطلح حساب حساب لحساب Lambda. يتم دمج هذا مع 8cc بواسطة Rui Ueyama ، ونسخة معدلة من Elvm من قبل Shinichiro Hamaji.
الصفحة الأولى من PDF تبدو هكذا. لاحظ عدد الصفحات في أعلى اليسار:

خاتمتها الكبرى هي جولة من التصفيق بواسطة صفحة مليئة بالأقواس الصحيحة:

تم كتابة Lambda-8cc كمصطلح لحساب Lambda مغلق
هنا ، حتى الأوتار مشفرة على أنها مصطلحات لامدا. يتم تشفير الأحرف والبايت كقائمة من البتات
لذلك ، يتم إغلاق كل شيء في عملية الحساب ، حتى بما في ذلك الأعداد الصحيحة ، في عالم مصطلحات Lambda النقية ، دون الحاجة إلى إدخال أي كائن من نوع Lambda على الإطلاق. لا يستخدم أي أنواع بدائية بخلاف Lambdas. يجعل Lambda-8CC تخفيض بيتا المتطلب الوحيد لتجميع C إلى X86. لاحظ أن العملية لا تعتمد على اختيار الأسماء المتغيرة أيضًا. بدلاً من ترميز الحرف A كمتغير مع الاسم A كقائمة من أجزاء ASCII ترميز 01000001 .
عملية الترميز هي مرهقة بعض الشيء أن تقول على الأقل تفعل باليد. يمكن حل هذا باستخدام مترجم حساب حساب التفاضل والتكامل Lambda. يتعامل المترجمون المترجمون لجهاز حساب التفاضل والتكامل في Lambda تلقائيًا إلى تنسيق الإدخال/الإخراج بحيث يتم تشغيله على المحطة الطرفية - يتم تشفير المدخلات القياسية في مصطلحات Lambda ، ويتم فك تشفير مصطلح Lambda للإخراج وعرضه على المحطة. باستخدام هؤلاء المترجمين الفوريين ، يمكن تشغيل Lambda-8CC على المحطة لتجميع برامج C تمامًا مثل GCC.
لمزيد من التفاصيل حول كيفية معالجة I/O وكيفية كتابة البرامج في حساب حساب Lambda ، يرجى الاطلاع على تفاصيل تنفيذ مشروع Lambdalisp الخاص بي ، وهو مترجم LISP مكتوب كمصطلح لحساب Lambda غيره.
بالإضافة إلى x86 ، يمكن أن يقوم Lambda-8CC بتجميع C إلى حساب حساب Lambda أيضًا. يعمل برنامج الإخراج على نفس مترجم حساب حساب Lambda المستخدم لتشغيل Lambda-8CC نفسه. تعمل مصطلحات Lambda المترجمة أيضًا على أدنى مترجمين فوريين مثل المترجمة المترجمة المترجمة لحساب Lambda 521 بايت Sectorlambda التي كتبها Justine Tunney ، ومترجم IOCCC 2012 "الأكثر وظيفية" التي كتبها John Tromp (مصدره في شكل λ). وهذا يجعل Lambda-8cc مكتفية ذاتيا في عالم حساب حساب Lambda.
لقد كان معروفًا منذ فترة طويلة في علوم الكمبيوتر أن حساب التفاضل والتكامل Lambda قد تم إكماله. يوضح Lambda-8CC هذا بطريقة مباشرة إلى حد ما من خلال إظهار أنه يمكن تجميع برامج C مباشرة في مصطلحات حساب التفاضل والتكامل Lambda.
الشيء الجميل في حساب حساب Lambda هو أن مواصفات اللغة بسيطة للغاية. مع Lambda-8cc ، نحافظ على المعرفة حول كيفية تجميع C بطريقة خالدة. حتى إذا فقدت الإنسانية المعرفة حول مجموعة تعليمات X86 ، طالما أننا نتذكر قواعد حساب التفاضل والتكامل Lambda ولديها مصطلح Lambda لـ Lambda-8cc ، فلا يزال بإمكاننا استخدام لغة C بأكملها من خلال Lambda-8cc وبناء كل شيء فوقه مرة أخرى.
فيما يلي برنامج ROT13.C الذي يشفر/تدلل المدخلات القياسية من/من تشفير ROT13. يجمع بدون أخطاء باستخدام GCC:
// rot13.c: Encodes/decodes standard input to/from the ROT13 cipher
#define EOF -1
int putchar ( int c );
char getchar ( void );
char c ;
int offset ;
int main ( void ) {
for (;;) {
c = getchar ();
if ( c == EOF ) {
break ;
}
offset = 0 ;
if (( 'a' <= c && c < 'n' ) || ( 'A' <= c && c < 'N' )) {
offset = 13 ;
} else if (( 'n' <= c && c <= 'z' ) || ( 'N' <= c && c <= 'Z' )) {
offset = -13 ;
}
putchar ( c + offset );
}
return 0 ;
}يمكن تجميع نفس البرنامج بواسطة Lambda-8CC خارج الصندوق على النحو التالي.
قم أولاً ببناء الأدوات وإعداد Lambda-8cc:
$ make tools # Build the interpreter uni++ and the tools lam2bin, asc2bin
$ unzip bin/lambda-8cc.lam.zip
$ cat lambda-8cc.lam | bin/lam2bin | bin/asc2bin > lambda-8cc.Blc # Prepare format for uni++المتطلبات هي:
clang++ لبناء uni++gcc أو cc لبناء lam2bin و asc2binالأدوات المصممة هنا هي:
uni++ : مترجم حساب لحساب LAMBDA سريع جدًا كتبه Melvin Zhang.lam2bin : فائدة كتبها Justine Tunney (متوفرة في https://justine.lol/lambda/) ، والتي تحول تدوين حساب حساب التفاضل والتكامل Lambda PlainText ، مثل xx إلى تدوين حساب حساب التفاضل والتكامل الثنائي lambda ، تم قبول التنسيق بواسطة UNI ++.asc2bin : أداة تحزم 0/1 ASCII Bitstream إلى BYTES.يتم بناء الأدوات عبر مجموعة تطوير حساب حساب التفاضل والتكامل.
إن التحويل من Lambda-8cc.lam إلى Lambda-8cc.blc هو ببساطة تحول التدوين لتنسيق مقبوله المترجم Uni ++. يتم وصف التفاصيل بالتفصيل.
ثم يمكن تجميع ROT13.C على النحو التالي:
$ cat lambda-8cc.Blc examples/rot13.c | bin/uni++ -o > a.out
$ chmod 755 a.out
$ echo ' Hello, world! ' | ./a.out
Uryyb, jbeyq !
$ echo ' Uryyb, jbeyq! ' | ./a.out
Hello, world ! هذا يمتد في حوالي 8 دقائق على الجهاز الخاص بي. ولكن كن حذرا - يستغرق الأمر 145 جيجابايت من الذاكرة لتشغيله! إذا كان لديك مساحة تخزين مجانية أو محرك أقراص USB ، فيمكنك استخدام ملف مبادلة مع mkswap و swapon لتمديد المبادلة دون تكوين إعدادات التقسيم. أيضًا ، من خلال تجميع التجميع و X86 قابلة للتنفيذ بشكل منفصل ، يمكنك إلى النصف استخدام RAM إلى 65 جيجابايت ، كما هو موضح في قسم الاستخدام التفصيلي. تستغرق البرامج الصغيرة مثل putchar.c فقط حوالي 40 جيجابايت من الذاكرة. أظن أنه يمكن تقليل استخدام RAM من خلال إدخال GC مارك و SWEX على المترجم الفوري ، على الرغم من أنني لم أؤكد ذلك بعد.
تتوفر المزيد من إحصائيات وقت التشغيل في أوقات التشغيل وقسم استخدام الذاكرة. يمكن العثور على المزيد من البرامج C التي يمكن تجميعها بواسطة Lambda-8CC تحت ./examples.
يتم وصف خيارات التجميع الأخرى في قسم الاستخدام التفصيلي.
يجري كتابته في حساب التفاضل والتكامل Lambda ، بطبيعة الحال ، يتم التعبير عن خيارات تجميع Lambda-8CC على أنها مصطلحات لحساب Lambda أيضًا. يمكن استخدام هذه الخيارات لإلغاء تأمين الميزات الكاملة لـ Lambda-8cc.
يتم استخدام خيارات التجميع عن طريق تطبيق مصطلح اختياري مثل (lambda-8cc option) مسبقًا من الإدخال. هذا يغير سلوك مصطلح Lambda lambda-8cc بحيث يقبل/ينتج تنسيق إدخال/إخراج مختلف.
فيما يلي جميع خيارات تجميع Lambda-8CC:
| مدخل | الإخراج | خيار التجميع |
|---|---|---|
| ج | x86 قابلة للتنفيذ | |
| ج | مصطلح حساب التفاضل والتكامل في نص Lambda Plain | |
| ج | تدوين حساب حساب التفاضل والتكامل الثنائي Lambda (برنامج BLC) | |
| ج | حساب التفاضل والتكامل Combinator Ski (برنامج Lazy K) | |
| ج | جمعية ELVM | |
| جمعية ELVM | x86 قابلة للتنفيذ | |
| جمعية ELVM | مصطلح حساب التفاضل والتكامل في نص Lambda Plain | |
| جمعية ELVM | تدوين حساب حساب التفاضل والتكامل الثنائي Lambda (برنامج BLC) | |
| جمعية ELVM | حساب التفاضل والتكامل Combinator Ski (برنامج Lazy K) |
كل خيار في تنسيق 3-tuple
يمكن استخدام خيارات التجميع المعروضة من قبل في المحطة على النحو التالي.
لتجميع C إلى قائمة مجموعة ELVM as :
( ( cat lambda-8cc.lam ; printf ' (\f.(f (\x.\y.x) (\x.\y.\z.\a.\b.b) (\x.x))) ' )
| bin/lam2bin | bin/asc2bin ; cat input.c ) | bin/uni++ -o > a.s لتجميع قائمة تجميع ELVM as بـ x86 a.out القابلة للتنفيذ:
( ( cat lambda-8cc.lam ; printf ' (\f.(f (\x.\y.y) (\x.\y.\z.\a.\b.x) (\x.x))) ' )
| bin/lam2bin | bin/asc2bin ; cat a.s ) | bin/uni++ -o > a.out
chmod 755 a.out كما هو موضح من قبل ، من خلال التجميع بشكل منفصل as و a.out باستخدام هذه الأوامر ، يمكن قطع الحد الأقصى لاستخدام RAM إلى نصفين حيث يتم تحرير الذاكرة عند انتهاء كل عملية.
من خلال تشغيل Lambda-8cc دون أي إدخال أو خيارات ، يمكنك رؤية رسالة استخدام تعرض مجموعة كاملة من الخيارات:
$ cat lambda-8cc.lam | bin/lam2bin | bin/asc2bin | bin/uni++ -o
lambda-8cc v1.0.0
Usage:
apply lambda-8cc.lam [input-file]
apply lambda-8cc.lam [option] [input-file]
Options:
(f.(f [input] [output] (x.x)))
(f.(f (x.y.x) (x.y.z.a.b.x) (x.x))) : C to x86 (defualt)
(f.(f (x.y.x) (x.y.z.a.b.y) (x.x))) : C to *.lam (plaintext lambda calculus program)
(f.(f (x.y.x) (x.y.z.a.b.z) (x.x))) : C to *.blc (binary lambda calculus program)
(f.(f (x.y.x) (x.y.z.a.b.a) (x.x))) : C to *.lazy (SKI combinator calculus, as a Lazy K program)
(f.(f (x.y.x) (x.y.z.a.b.b) (x.x))) : C to ELVM assembly
(f.(f (x.y.y) (x.y.z.a.b.x) (x.x))) : ELVM assembly to x86
(f.(f (x.y.y) (x.y.z.a.b.y) (x.x))) : ELVM assembly to *.lam
(f.(f (x.y.y) (x.y.z.a.b.z) (x.x))) : ELVM assembly to *.blc
(f.(f (x.y.y) (x.y.z.a.b.a) (x.x))) : ELVM assembly to *.lazy
lambda-8cc includes the following projects. All of the following projects
are released under the MIT license. See the LICENSE in each location for details.
8cc: By Rui Ueyama - https://github.com/rui314/8cc
ELVM: By Shinichiro Hamaji - https://github.com/shinh/elvm
LambdaVM: By Hikaru Ikuta - https://github.com/woodrush/lambdavm
lambda-8cc: By Hikaru Ikuta - https://github.com/woodrush/lambda-8cc
يوضح الجدول التالي وقت الترجمة واستخدام الذاكرة على مترجم حساب حساب Lambda Melvin Zhang.
| برنامج | وقت التجميع | الأعلى. استخدام RAM في وقت التجميع | x86 الحجم الثنائي | وصف |
|---|---|---|---|---|
| putchar.c | 1.8 دقيقة | 31 غيغابايت | 342 بايت | A |
| مرحبا | 2.4 دقيقة | 42 جيجابايت | 802 بايت | مطبوعات Hello, world! |
| صدى | 2.5 دقيقة | 46 جيجابايت | 663 بايت | أصداء المدخلات القياسية |
| rot13.c | 7.7 دقيقة | 84 غيغابايت | 2،118 بايت | ترميز/فك تشفير stdin إلى/من rot13 |
| fizzbuzz.c | 49.7 دقيقة | 240 جيجابايت | 5،512 بايت | يطبع تسلسل FizzBuzz حتى 30 |
| الأوائل | 53.0 دقيقة | 241 غيغابايت | 5500 بايت | يطبع الأعداد الأولية حتى 100 |
الآن هذا هو الكثير من الذاكرة! لتجميع البرامج التي تتطلب ذاكرة الوصول العشوائي الضخمة ، يمكنك تمديد منطقة المبادلة دون تغيير إعدادات التقسيم باستخدام ملف مبادلة. إذا قمت بتشغيل Linux ولديك أي سعة تخزين مجانية أو محرك أقراص USB ، فيمكنك استخدام هذا التخزين لتمديد منطقة المبادلة بسهولة وديناميكية باستخدام mkswap و swapon . يتم تشغيل الإحصائيات على هذا الجدول مع منطقة مبادلة ممتدة بهذه الطريقة. يتم شرح التعليمات في موضوع Askubuntu هذا. أظن أنه يمكن تقليل استخدام RAM من خلال إدخال GC مارك و SWEX على المترجم الفوري ، على الرغم من أنني لم أؤكد ذلك بعد.
لاحظ أن هذه هي أوقات التجميع - أوقات التشغيل لـ X86 Binary المترجمة هي لحظي. هذا يحمل حتى عند تجميع C إلى مصطلحات حساب التفاضل والتكامل Lambda. يتم تشغيل مصطلحات Lambda المترجمة أيضًا على الفور واستخدم فقط بضعة جيجابت من الذاكرة عند التشغيل على مترجم لحساب التفاضل والتكامل Lambda.
تم تشغيل مجموعات هذه الإحصائيات على جهاز Ubuntu 22.04.1 مع ذاكرة الوصول العشوائي 48 جيجابايت ، ومبادلة SSD 16 جيجا بايت (قسم افتراضي) ، ومبادلة HDD 274 جيجابايت (256GIB) (تمت إضافتها ديناميكيًا مع mkswap و swapon ). وقت التشغيل الموضح هنا هو وقت تشغيل ساعة الحائط بما في ذلك عمليات الذاكرة. بالنسبة للبرامج الثقيلة المبادلة ، يمكن تقليل وقت التشغيل باستخدام جهاز بسرعة I/O أسرع.
تم قياس الإحصائيات عن طريق الجري
cp examples/[program].c ./input.c
make الذي يجمع as و a.out للـ input.c بشكل منفصل لحفظ استخدام الذاكرة الكلي. يتم عرض جدول أكثر تفصيلاً من الإحصائيات لكل تمريرة بالتفصيل.
يرجى الاطلاع على التفاصيل.
للحصول على تفاصيل حول المبنى من المصدر ، يرجى الاطلاع على التفاصيل.
Lambda-8cc هو مزيج من 3 مشاريع ، lambdavm ، elvm ، و 8cc. كتب Lambdavm من قبل Hikaru Ikuta ، مؤلف هذا المستودع (Lambda-8cc). كتب هندسة ELVM Shinichiro Hamaji. كتب 8cc من قبل روي أوما. إصدار 8cc المستخدم في Lambda-8CC هو نسخة معدلة من 8cc مدرجة كجزء من ELVM ، تم تعديلها بواسطة Shinichiro Hamaji وغيرها. يشمل Lambda-8CC أيضًا ELC ، وهو جزء من ELVM كتبه Shinichiro Hamaji ، تم تعديله بواسطة Hikaru Ikuta حتى يتمكن من تجميع ELVM Assembly إلى حساب حساب Lambda. كتب Hikaru Ikuta الخلفية Lambda Calculus لـ ELVM ، من خلال دمج Lambdavm في ELVM. تم قياس إحصائيات استخدام وقت التشغيل واستخدام الذاكرة باستخدام مترجم حساب حساب لحساب Lambda كتبه Melvin Zhang. كتب LAM2BIN من قبل جوستين تون.