العرضar

Compiling and targets

Codegen targets#

فابر لديها لغة واحدة وعقود تحويل برمجي متعددة. ليس بالضرورة أن تتحول كل ميزة إلى كل هدف. توثق هذه الصفحة الميزات التي يدعمها كل هدف، أو يُسقطها، أو يُحذر منها، أو يرفضها.

أفعال السياسة#

الفعلالمعنى
دعميتحول بدلالات مقصودة
إسقاطيتحقق من النوع؛ يُسقط منشئ الكود الدلالات الخاصة بالهدف
تحذيرفابر قانوني؛ لا تأثير أو سلوك متدهور على الهدف
رفضيفشل التحقق أو الإخراج بتشخيص صريح
تأجيلتحليل وربط ناجحان؛ التحويل غير مُنفَّذ لأي هدف
محدودعقد مستقر مع بوابات مجموعة فرعية صريحة

جدول الأهداف#

الهدفالمساربناءتشغيلحزمةالسياسة
rustHIRنعمنعمنعمدعم
fmir-textMIRنعمنعمنعمدعم
fmirMIRنعمنعمنعمدعم
fmir-binMIRنعمنعمنعمدعم
faberHIRنعملالادعم
tsHIRنعملالااستكشاف
goHIRنعملالاإسقاط
wasmMIRنعملالامحدود
wasm-textMIRنعملالامحدود
llvm-textMIRنعملالامحدود
metal-textMIRنعملالامحدود
wgsl-textMIRنعملالامحدود
sexpMIRنعملالامحدود

توجيه المسار#

Source → Lex → Parse → Collect → Resolve → Lower → Typecheck → Analysis
                                                              ↓
                                    ┌─────────────────────────┴──────────┐
                                    │                                    │
                              HIR backends                        MIR backends
                                    │                                    │
            Rust · Faber · TS · Go            fmir · wasm · llvm · metal · wgsl · sexp

مسار التطبيق (HIR)#

الهدفالمستوى المُقاس
Rustمسار الإنتاج. أنماط الاستعارة، توليد CLI، تحويل Result القابل للفشل.
Faberعرض المصدر القانوني ورحلة الذهاب والإياب. ليس خلفية تنفيذية.
TypeScript288/318 محللة · 268/318 صالحة التحقق من النوع · 262/318 قابلة للتشغيل
Go146/216 ناجحة. أنماط الاستعارة مُسقطة؛ ad مرفوض.

مسار الأنظمة (MIR)#

الهدفالمستوى المُقاس
fmir*صور MIR مُعبأة؛ المُشغِّل يُثبت استقلالية المصدر.
wasm200/289 مُخرجة · 195/289 مُتحقق منها · 171/289 قابلة للتشغيل بمُضيف مُبسَّط
llvm-text249/289 مُخرجة · 232/289 صالحة التحقق · 65/289 قابلة للتشغيل
metal-textمجموعة فرعية آمنة للنواة على الجهاز؛ 88 اختبارًا مُركَّزًا. الحملة مُعلَّقة.
wgsl-textتحقق مع naga 30.x. 87 اختبارًا مُركَّزًا. مُرافق انعكاس جانبي.
sexp193 مُخرجة · 190 مُجمَّعة بـ Racket · 190 مُشغَّلة بـ Racket. هدف تحقق.

للحصول على أعلام القدرة المباشرة، شغِّل faber targets.

Compilation lanes#

لدى Faber واجهة أمامية واحدة مشتركة — التحليل النحوي، التحليل، فحص الأنواع — ثم تتفرع إلى مسارات تخفيض متعددة حسب ما يحتاجه الهدف. تشكل التمثيلات الوسيطة خط أنابيب: يُحلل المصدر إلى HIR، ويُخفض اختياريًا إلى MIR، ويُحوّل اختياريًا عبر AIR قبل الإصدار النهائي. يخدم كل IR غرضًا مميزًا، ويستهلك كل هدف من الـ IR الذي يناسب احتياجاته.

نظرة عامة على خط الأنابيب#

Source (.fab)  →  Lex  →  Parse  →  Collect  →  Resolve  →  Lower  →  Typecheck  →  Analysis
                                                              │
                                                    HIR (semantic core)
                                                    ┌─────┴─────┐
                                                    │           │
                                              Reader locale    MIR lowering
                                              (input/output)    │
                                                                │
                                                      ┌─────────┴─────────┐
                                                      │                   │
                                                CPU lanes           GPU lanes
                                                      │                   │
                                            ┌────┬────┼────┬────┐     ┌───┴───┐
                                            │    │    │    │    │     │       │
                                          FMIR LLVM WASM  TS  Go   WGSL   Metal
                                                                          (hold)

تخدم الواجهة الأمامية نفسها كل هدف. بعد أن ينتج التحليل الدلالي HIR، يختار المترجم مسارًا بناءً على الهدف:

  • HIR مباشر — الإصدار مباشرة من HIR المُنمّط للواجهات الخلفية ذات الشكل اللغوي (Rust، Faber، TypeScript، Go)
  • HIR → MIR — التخفيض إلى MIR ذي الشكل التنفيذي، ثم الإصدار لأهداف الأنظمة والأهداف منخفضة المستوى
  • HIR → MIR → AIR → MIR — التحويل عبر AIR الوظيفي الخالص لتحويلات الاشتقاق التلقائي والدمج، ثم العودة إلى MIR

HIR — التمثيل الوسيط عالي المستوى#

HIR هو الحقيقة. إنه IR مُنمّط ذو شكل لغوي يحافظ على التصريحات ومعلومات الأنواع والعلاقات البنيوية. يمر كل برنامج Faber، بغض النظر عن لغته الأصلية أو وجهته المستهدفة، عبر هذا التمثيل.

دمج لغة القارئ#

تعمل لغة القارئ عبر HIR. يُحلل ملف مصدري Faber مكتوب بكلمات مفتاحية تايلاندية ويُخفض إلى نفس HIR الذي ينتجه المصدر اللاتيني المكافئ. اللغة هي تجسيد سطحي لـ HIR، وليست تفرعًا في النواة الدلالية.

  • الإدخال: مصدر مُوطّن (تايلاندي، صيني، عربي، إلخ) → HIR مُطبيع — مُنجز
  • الإخراج: HIR → إعادة إصدار مصدر مُوطّن — قيد التنفيذ (يتم تطبيقه)

عندما يُنجز اتجاه الإخراج، سيقوم faber format --reader-locale=th-TH بتحويل أي مصدر Faber ذهابًا وإيابًا عبر HIR وإصداره بكلمات مفتاحية تايلاندية، مكملًا بذلك التناظر: يمكن لنفس HIR إنتاج أي تجسيد سطحي للغة، تمامًا كما يمكنه إنتاج أي واجهة خلفية مستهدفة.

الواجهات الخلفية المباشرة من HIR#

تُصدر هذه الأهداف مباشرة من HIR المُنمّط دون تخفيض إلى MIR. تحافظ على البنية على مستوى المصدر لفترة أطول وتناسب الإخراج ذا الشكل اللغوي:

الهدفالحالةالدور
Rustأساسيمسار الإنتاج. الحزم، البناء، التشغيل، الاختبار. Cargo + rustc للبرامج الثنائية الأصلية.
Faberدعمعرض المصدر القانوني عبر مُنسّق forma. استقرار التحويل الذهاب والإياب.
TypeScriptاستكشافيإصدار ملفات فقط. يثبت الدلالات عبر أشكال الأهداف.
Goمحوإصدار ملفات فقط. أنماط الاستعارة تُمحى؛ ad مرفوض.

MIR — التمثيل الوسيط متوسط المستوى#

MIR هو IR ذو الشكل التنفيذي. يمثل تدفق التحكم، والمتغيرات المحلية، واستدعاءات وقت التشغيل، والمواضع، والتفرعات، وحواف الأخطاء — الحقائق التي تحتاجها الأهداف منخفضة المستوى. حيث يحافظ HIR على بنية المصدر، يقوم MIR بتسويتها إلى رسم بياني لتدفق التحكم.

يترجم تخفيض HIR → MIR البنى ذات الشكل اللغوي إلى خطوات تنفيذية. يُتحقق من صحة MIR بعد التخفيض لاكتشاف المشكلات البنيوية قبل أن تحاول أي واجهة خلفية الإصدار.

الملكية الدلالية. يحافظ Faber على حدود واضحة بين القواعد المفروضة في HIR/MIR (فحص الأنواع، الإسناد المُحدد، تنبيهات أنماط الاستعارة) والقواعد المتروكة لسلاسل أدوات الهدف (تحليل عمر Rust، سلامة أنواع Go). يمنع هذا المترجم من تكرار العمل الذي تقوم به مترجمات الهدف بشكل صحيح بالفعل.

تحويلة AIR#

AIR (تمثيل الاشتقاق التلقائي / الذكاء الاصطناعي) هو تحويلة تحويل وظيفية خالصة تنحرف عن مسار HIR → MIR. يُدخل إليها بتعليق توضيحي صريح على الدوال الفردية:

@ radix lane "air"
functio loss(numerus predicted, numerus expected)  numerus {
    fixum numerus delta  predicted - expected
    redde delta * delta
}

يجب أن تستوفي دوال مسار AIR سياسة نقاء — لا طفرة، لا تأثيرات، لا حلقات. تُرفض الدوال التي تخالف ذلك بتشخيص قبل أن يبدأ تخفيض AIR. يستمر باقي البرنامج في استخدام Faber العادي مع الطفرة والتأثيرات والحلقات.

بعد أن يكمل تحويل AIR عمله (مستقبلًا: الاشتقاق التلقائي، الدمج)، يُعاد تخفيض النتيجة إلى MIR وتنضم مجددًا إلى خط أنابيب MIR الخلفي العادي. لا يمتلك AIR واجهات خلفية ولا مدقق أنواع مستقل — إنه نقطة تفتيش تحويلية، وليس IR موازيًا.

HIR  →  AIR purity check  →  HIR to AIR lowering  →  AIR validation  →  AIR to MIR re-lowering  →  MIR backend

تعكس هذه البنية نهج JAX: الاحتفاظ بتمثيل وظيفي خالص للتحويلات، والتخفيض إلى IR أمري فقط في النهاية. يوجد AIR لأن تشغيل الاشتقاق التلقائي على MIR أمري سيتطلب إعادة بناء النقاء من كود تم تخفيضه إلى طفرة.

مسارات أهداف وحدة المعالجة المركزية#

تستهلك أهداف وحدة المعالجة المركزية MIR وتنتج إما قطعًا أثرية قابلة للتنفيذ أو نصوصًا لسلاسل الأدوات الخارجية. يُصدر Faber نصوصًا حيثما أمكن ويعتمد على سلاسل أدوات منخفضة المستوى لخطوة التجميع النهائية — على غرار كيفية إصدار مترجم C للتجميع للمُجمّع والرابط.

FMIR — وقت تشغيل MIR الخاص بـ Faber#

FMIR هو مُنفذ الحزم الأصلي لـ MIR. يستخرج المترجم MIR إلى حمولة ثنائية ويغلفها بمُحمل نواة Rust قصير. ينتج هذا برنامجًا تنفيذيًا مكتفيًا ذاتيًا يشغل MIR عبر مُشغّل Faber داخل العملية — لا يتطلب تثبيت وقت تشغيل منفصل.

الصيغةالوصف
fmir-textصورة نصية قابلة للتفحص من FMIR في target/faber-mir/image.fmir.txt
fmirصورة FMIR ثنائية مضغوطة في target/faber-mir/image.fmir
fmir-binمُشغّل مكتفٍ ذاتيًا في target/faber-mir/exe/run — يُضمّن بايتات FMIR

نص LLVM#

يُصدر Faber IR الخاص بـ LLVM كنص (.ll)، وليس كتوليد كود LLVM مُدمج. الـ IR المُصدر مُعد لخطوات سلسلة الأدوات الخارجية — التحقق، التحسين، وتوليد الكود الأصلي تُعالج بواسطة أدوات LLVM اللاحقة. هذا هدف مرحلي وتحقق، وليس مسار توليد كود أصلي مُدمج في المترجم.

WASM#

يُصدر Faber صيغ نصوص WebAssembly (.wat) والصيغ الثنائية (.wasm). يستخدم Wasm المُصدر استيرادات مضيف خارجية (رموز وقت تشغيل faber_*) ويُتحقق من صحته عبر wasm-tools validate. Wasm هو هدف مدعوم مع قيود — يثبت خط أنابيب تخفيض MIR لصيغة معيارية مفتوحة، لكنه ليس وقت تشغيل لتسليم الحزم.

الصيغةهدف CLIالمُخرج
wasm-text-t wasm-text (اسم مستعار wat)صيغة نص WAT
wasm-t wasmوحدة Wasm ثنائية

TypeScript و Go (مباشر من HIR)#

رغم استخدامهما عادةً لإصدار ملفات على مستوى التطبيق، يعمل TypeScript و Go أيضًا كأهداف إثبات: يتحققان من أن دلالات Faber تترجم إلى أنظمة أنواع واسعة الاستخدام، حتى لو بقي تجميع الحزم والتنفيذ في وقت التشغيل حصريًا لـ Rust اليوم.

مسارات أهداف وحدة معالجة الرسوميات#

WGSL (عبر WGPU)#

يُصدر Faber مصدر تظليل WGSL الحسابي عبر خط أنابيب MIR. يُتحقق من صحة WGSL المُصدر عبر naga (الإصدار 30.x) ويتضمن ملفًا جانبيًا عاكسًا لبيانات مجموعة الربط. يغطي هذا المجموعة الفرعية للنواة الآمنة للجهاز: طرق عرض f32 للأجهزة من الرتبة 1 مدعومة؛ طرق العرض من الرتبة 2 مرفوضة. WGSL ليس وقت تشغيل لإطلاق GPU — يُصدر Faber مصدر التظليل، لكن التنفيذ يتطلب وقت تشغيل WebGPU خارجي.

Metal (مُعلق)#

إصدار نصوص تظليل Metal الحسابية مُصمم ومُنفذ جزئيًا لكنه مُعلق حاليًا. تتبع البنية نفس نمط WGSL: يُصدر Faber مصدر لغة تظليل Metal للمجموعة الفرعية للنواة الآمنة للجهاز، مع تولي سلسلة الأدوات الخارجية للتجميع والتنفيذ. العمل مُخطط لاستئنافه.

ملاحظة معمارية#

بنية تجميع Faber مشابهة في روحها لكيفية عمل مترجم Rust. يُخفض Rust عبر HIR → MIR → LLVM IR، مُدمجًا سلسلة أدوات LLVM مباشرة لتوليد الكود الأصلي النهائي. يتخذ Faber نهجًا أكثر ليونة: يُصدر نصوصًا لسلاسل الأدوات الخارجية (نص LLVM، WGSL، Metal، WAT) بدلًا من تضمينها، مع حجز الإصدار المباشر للكود لوقت تشغيله الخاص (FMIR) وهدفه الأساسي للحزم (Rust، حيث يتولى Cargo و rustc خط الأنابيب اللاحق).

نهج إصدار النصوص يعني أن Faber لا يحتاج أبدًا إلى تجميع LLVM، أو وقت تشغيل Wasm، أو مُشغّل GPU معه — تبقى هذه تبعيات خارجية يختارها المستخدم. المقايضة هي أن Faber لا يمكنه تقديم أمر بناء واحد لكل هدف؛ يجب على المستخدم تثبيت سلسلة الأدوات المناسبة للواجهة الخلفية التي اختارها.

ملخص الأهداف#

الهدفIRالعائلةبناءتشغيلحزمة
RustHIRCPUنعمنعمنعم
fmir / fmir-binMIRCPUنعمنعمنعم
Faber (تنسيق)HIRلالالا
TypeScriptHIRCPUلالالا
GoHIRCPUلالالا
نص LLVMMIRCPUلالالا
WASM / WATMIRCPUلالالا
WGSLMIRGPUلالالا
Metal (مُعلق)MIRGPUلالالا

تصف `build` و `run` و `package` سير عمل Faber. تتولى سلاسل الأدوات الخارجية (rustc، wasm-tools، naga) التجميع النهائي لأهداف إصدار النصوص.

Compiler performance#

تتدرج واجهة Radix الأمامية خطيًا تقريبًا مع حجم المصدر، وتعمل داخل العملية وبخيط تنفيذ واحد.

أوقات ترجمة الواجهة الأمامية#

حجم البرنامجالمصدرمتوسط وقت الترجمة
100 دالة / ~650 سطرًا~10 ك.ب~0.6 ملّي ثانية
500 دالة / ~3.3K سطرًا~52 ك.ب~3 ملّي ثانية
1,000 دالة / ~6.5K سطرًا~105 ك.ب~6 ملّي ثانية
5,000 دالة / ~32K سطرًا~530 ك.ب~37 ملّي ثانية

أكبر مثال حقيقي اليوم يبلغ ~140 سطرًا، وهو أقل بكثير من حد الضوضاء.

تكاليف النهاية الخلفية (هدف Rust)#

بالنسبة لأمر faber build، يهيمن Cargo/rustc على الزمن الذي يلاحظه المستخدم، وليس واجهة Faber الأمامية:

المرحلةالتكلفة
ترجمة تبعيات faber الباردة (مرة واحدة لكل دليل هدف)~2.8 ثانية
ترجمة تبعيات tokio الباردة (فقط عند الحاجة)~2.3 ثانية
بناء البرنامج الدافئ (تبعيات مخزنة مؤقتًا)~30–110 ملّي ثانية
عبء استدعاء Cargo لكل برنامج~400 ملّي ثانية

الترجمة التزايدية#

تُترجم حزمة faber-runtime مرة واحدة لكل دليل هدف وتُخزَّن مؤقتًا كقطع أثرية .rlib:

ما تغيّرهحزمة faber-runtimeبرنامجك
مصدر برنامجكمخزنة مؤقتًايُعاد ترجمته
norma/src/*.fab (مصدر Faber)مخزنة مؤقتًايُعاد ترجمته
faber/runtime/rust/src/*.rsيُعاد ترجمته مرة واحدةيُعاد ترجمته

المأزق الذي يجب تجنبه هو بناء كل برنامج في دليل target/ جديد. أعد استخدام --target-dir مشترك للحفاظ على ملفات .rlib المخزنة مؤقتًا دافئة.