Compiling and targets
Codegen targets#
Faber की एक ही भाषा है और संकलन अनुबंध कई हैं। हर सुविधा को हर लक्ष्य पर निम्न स्तर तक ले जाना आवश्यक नहीं है। यह पृष्ठ बताता है कि प्रत्येक लक्ष्य किन सुविधाओं का समर्थन करता है, किन्हें मिटा देता है, किन पर चेतावनी देता है या किन्हें अस्वीकार करता है।
नीति क्रियाएँ#
| क्रिया | अर्थ |
|---|---|
| समर्थन | इच्छित अर्थविज्ञान के साथ निम्न स्तर तक ले जाता है |
| मिटाना | प्रकार-जाँच होती है; कोड जनरेशन लक्ष्य-विशिष्ट अर्थविज्ञान को हटा देता है |
| चेतावनी | Faber में मान्य है; लक्ष्य पर कोई प्रभाव नहीं पड़ता या व्यवहार घटिया हो जाता है |
| अस्वीकार | जाँच या उत्सर्जन स्पष्ट निदान के साथ विफल होता है |
| स्थगित | पार्स और बाइंड होता है; किसी भी लक्ष्य के लिए निम्न-स्तरीकरण लागू नहीं है |
| सीमित | स्पष्ट उपसमुच्चय द्वारों वाला स्थिर अनुबंध |
लक्ष्य तालिका#
| लक्ष्य | लेन | बिल्ड | रन | पैकेज | नीति |
|---|---|---|---|---|---|
rust | HIR | हाँ | हाँ | हाँ | समर्थन |
fmir-text | MIR | हाँ | हाँ | हाँ | समर्थन |
fmir | MIR | हाँ | हाँ | हाँ | समर्थन |
fmir-bin | MIR | हाँ | हाँ | हाँ | समर्थन |
faber | HIR | हाँ | नहीं | नहीं | समर्थन |
ts | HIR | हाँ | नहीं | नहीं | जाँच |
go | HIR | हाँ | नहीं | नहीं | मिटाना |
wasm | MIR | हाँ | नहीं | नहीं | सीमित |
wasm-text | MIR | हाँ | नहीं | नहीं | सीमित |
llvm-text | MIR | हाँ | नहीं | नहीं | सीमित |
metal-text | MIR | हाँ | नहीं | नहीं | सीमित |
wgsl-text | MIR | हाँ | नहीं | नहीं | सीमित |
sexp | MIR | हाँ | नहीं | नहीं | सीमित |
पाइपलाइन रूटिंग#
Source → Lex → Parse → Collect → Resolve → Lower → Typecheck → Analysis
↓
┌─────────────────────────┴──────────┐
│ │
HIR backends MIR backends
│ │
Rust · Faber · TS · Go fmir · wasm · llvm · metal · wgsl · sexpएप्लिकेशन लेन (HIR)#
| लक्ष्य | मापी गई न्यूनतम क्षमता |
|---|---|
| Rust | प्रोडक्शन पथ। Borrow मोड, CLI जनरेशन और विफल हो सकने वाले Result का निम्न-स्तरीकरण। |
| Faber | प्रमाणिक स्रोत दृश्य / राउंड-ट्रिप। यह निष्पादन बैकएंड नहीं है। |
| TypeScript | 288/318 विश्लेषित · 268/318 प्रकार-जाँच मान्य · 262/318 चलाने योग्य |
| Go | 146/216 सफल। Borrow मोड मिटा दिए जाते हैं; ad अस्वीकार किया जाता है। |
सिस्टम्स लेन (MIR)#
| लक्ष्य | मापी गई न्यूनतम क्षमता |
|---|---|
| fmir* | पैकेज MIR इमेज; रनर स्रोत-स्वतंत्रता प्रमाणित करता है। |
| wasm | 200/289 उत्सर्जित · 195/289 मान्य · 171/289 स्टब-होस्ट पर चलाने योग्य |
| llvm-text | 249/289 उत्सर्जित · 232/289 सत्यापनकर्ता द्वारा मान्य · 65/289 चलाने योग्य |
| metal-text | डिवाइस-सुरक्षित कर्नेल उपसमुच्चय; 88 केंद्रित परीक्षण। अभियान स्थगित है। |
| wgsl-text | naga 30.x के साथ मान्य। 87 केंद्रित परीक्षण। रिफ्लेक्शन साइडकार। |
| sexp | 193 उत्सर्जित · 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-direct — भाषा-सदृश बैकएंड (Rust, Faber, TypeScript, Go) के लिए सीधे टाइप किए गए HIR से उत्सर्जन
- 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-direct बैकएंड#
ये लक्ष्य MIR में लोअर किए बिना सीधे टाइप किए गए HIR से उत्सर्जित होते हैं। ये स्रोत-स्तरीय संरचना को अधिक समय तक सुरक्षित रखते हैं और भाषा-सदृश आउटपुट के लिए उपयुक्त हैं:
| लक्ष्य | स्थिति | भूमिका |
|---|---|---|
Rust | प्राथमिक | प्रोडक्शन मार्ग। पैकेज, बिल्ड, रन और टेस्ट। नेटिव बाइनरी के लिए Cargo + rustc। |
Faber | समर्थन | forma फ़ॉर्मैटर के माध्यम से कैनोनिकल स्रोत दृश्य। राउंड-ट्रिप स्थिरता। |
TypeScript | Probe | केवल फ़ाइल उत्सर्जन। विभिन्न लक्ष्य आकारों में सिमैंटिक्स को प्रमाणित करता है। |
Go | Erase | केवल फ़ाइल उत्सर्जन। Borrow मोड मिटाए जाते हैं; ad अस्वीकृत होता है। |
MIR — मध्य-स्तरीय मध्यवर्ती निरूपण#
MIR निष्पादन-सदृश IR है। यह कंट्रोल फ्लो, लोकल, रनटाइम कॉल, प्लेस, शाखाओं और त्रुटि किनारों को निरूपित करता है — यानी वे तथ्य जिनकी लो-लेवल लक्ष्यों को आवश्यकता होती है। जहाँ HIR स्रोत संरचना को सुरक्षित रखता है, वहीं MIR उसे एक कंट्रोल-फ्लो ग्राफ में समतल कर देता है।
HIR → MIR लोअरिंग भाषा-सदृश संरचनाओं को निष्पादन चरणों में बदलती है। लोअरिंग के बाद MIR को वैलिडेट किया जाता है, ताकि कोई भी बैकएंड उत्सर्जन का प्रयास करने से पहले संरचनात्मक समस्याएँ पकड़ी जा सकें।
सिमैंटिक स्वामित्व। Faber HIR/MIR में लागू किए जाने वाले नियमों (टाइप चेकिंग, निश्चित असाइनमेंट, Borrow मोड लिंट) और लक्ष्य टूलचेन पर छोड़े जाने वाले नियमों (Rust लाइफ़टाइम विश्लेषण, Go टाइप सुरक्षा) के बीच स्पष्ट सीमा रखता है। इससे कंपाइलर उस काम को दोहराने से बचता है जिसे लक्ष्य कंपाइलर पहले ही सही ढंग से करते हैं।
AIR डिटूर#
AIR (Autograd / AI Representation) 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 पर ऑटोडिफ चलाने के लिए उस कोड से प्योरिटी को दोबारा बनाना पड़ता, जिसे म्यूटेशन में लोअर किया जा चुका है।
CPU लक्ष्य लेन#
CPU लक्ष्य MIR का उपभोग करते हैं और या तो एक्ज़ीक्यूटेबल आर्टिफैक्ट बनाते हैं या बाहरी टूलचेन के लिए टेक्स्ट तैयार करते हैं। जहाँ संभव हो, Faber टेक्स्ट उत्सर्जित करता है और अंतिम कंपाइलेशन चरण के लिए लो-लेवल टूलचेन पर निर्भर करता है — ठीक वैसे ही जैसे C कंपाइलर असेंबलर और लिंकर के लिए असेंबली उत्सर्जित करता है।
FMIR — Faber का अपना MIR रनटाइम#
FMIR, MIR-नेटिव पैकेज एक्ज़ीक्यूटर है। कंपाइलर MIR को एक बाइनरी पेलोड में निकालता है और उसे एक छोटे Rust कर्नेल लोडर से रैप करता है। इससे एक स्व-निहित एक्ज़ीक्यूटेबल बनता है, जो Faber के इन-प्रोसेस स्टेपर के माध्यम से MIR चलाता है — अलग रनटाइम इंस्टॉलेशन की आवश्यकता नहीं होती।
| फ़ॉर्मैट | विवरण |
|---|---|
fmir-text | target/faber-mir/image.fmir.txt पर निरीक्षण योग्य FMIR टेक्स्ट इमेज |
fmir | target/faber-mir/image.fmir पर कॉम्पैक्ट बाइनरी FMIR इमेज |
fmir-bin | target/faber-mir/exe/run पर स्व-निहित रनर — FMIR बाइट्स एम्बेड करता है |
LLVM टेक्स्ट#
Faber LLVM IR को टेक्स्ट (.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-direct)#
हालाँकि इनका उपयोग सामान्यतः एप्लिकेशन-स्तरीय फ़ाइल उत्सर्जन के लिए होता है, TypeScript और Go प्रमाण लक्ष्य के रूप में भी काम करते हैं: वे यह वैलिडेट करते हैं कि Faber की सिमैंटिक्स व्यापक रूप से उपयोग की जाने वाली टाइप प्रणालियों में अनुवादित हो सकती हैं, भले ही आज पैकेज कंपाइलेशन और रनटाइम एक्ज़ीक्यूशन केवल Rust तक सीमित हों।
GPU लक्ष्य लेन#
WGSL (WGPU के माध्यम से)#
Faber MIR पाइपलाइन के माध्यम से WGSL कंप्यूट शेडर स्रोत उत्सर्जित करता है।
उत्सर्जित WGSL को naga (30.x) के माध्यम से वैलिडेट किया जाता है और इसमें
बाइंड-ग्रुप मेटाडेटा के लिए एक रिफ़्लेक्शन साइडकार शामिल होता है। यह
डिवाइस-सुरक्षित कर्नेल सबसेट को कवर करता है: rank-1 f32 डिवाइस व्यू समर्थित हैं;
rank-2 व्यू अस्वीकृत होते हैं। WGSL GPU लॉन्च रनटाइम नहीं है — Faber शेडर स्रोत
उत्सर्जित करता है, लेकिन एक्ज़ीक्यूशन के लिए बाहरी WebGPU रनटाइम आवश्यक है।
Metal (रुका हुआ)#
Metal कंप्यूट शेडर टेक्स्ट उत्सर्जन डिज़ाइन किया गया है और आंशिक रूप से कार्यान्वित भी है, लेकिन वर्तमान में रुका हुआ है। आर्किटेक्चर WGSL के समान पैटर्न का पालन करता है: Faber डिवाइस-सुरक्षित कर्नेल सबसेट के लिए Metal Shading Language स्रोत उत्सर्जित करता है, जबकि बाहरी टूलचेन कंपाइलेशन और एक्ज़ीक्यूशन संभालता है। काम फिर से शुरू करने की योजना है।
आर्किटेक्चर नोट#
Faber का कंपाइलेशन आर्किटेक्चर इस दृष्टि से Rust कंपाइलर जैसा है कि दोनों HIR → MIR → LLVM IR के माध्यम से लोअर करते हैं। Rust अंतिम नेटिव कोडजेन के लिए LLVM टूलचेन को सीधे एम्बेड करता है। Faber अधिक लचीला दृष्टिकोण अपनाता है: वह उन्हें एम्बेड करने के बजाय बाहरी टूलचेन के लिए टेक्स्ट (LLVM टेक्स्ट, WGSL, Metal, WAT) उत्सर्जित करता है, जबकि अपने रनटाइम (FMIR) और अपने प्राथमिक पैकेज लक्ष्य (Rust, जहाँ Cargo और rustc डाउनस्ट्रीम पाइपलाइन संभालते हैं) के लिए सीधे कोड उत्सर्जन सुरक्षित रखता है।
टेक्स्ट-उत्सर्जन दृष्टिकोण का अर्थ है कि Faber को LLVM, Wasm रनटाइम या GPU ड्राइवर को बंडल करने की आवश्यकता नहीं पड़ती — ये उपयोगकर्ता द्वारा चुनी गई बाहरी निर्भरताएँ रहती हैं। इसका समझौता यह है कि Faber हर लक्ष्य के लिए एक-कमांड बिल्ड नहीं दे सकता; उपयोगकर्ता को अपने चुने हुए बैकएंड के लिए उपयुक्त टूलचेन इंस्टॉल करना होगा।
लक्ष्य सारांश#
| लक्ष्य | IR | परिवार | बिल्ड | रन | पैकेज |
|---|---|---|---|---|---|
Rust | HIR | CPU | हाँ | हाँ | हाँ |
fmir / fmir-bin | MIR | CPU | हाँ | हाँ | हाँ |
Faber (फ़ॉर्मैट) | HIR | — | नहीं | नहीं | नहीं |
TypeScript | HIR | CPU | नहीं | नहीं | नहीं |
Go | HIR | CPU | नहीं | नहीं | नहीं |
LLVM text | MIR | CPU | नहीं | नहीं | नहीं |
WASM / WAT | MIR | CPU | नहीं | नहीं | नहीं |
WGSL | MIR | GPU | नहीं | नहीं | नहीं |
Metal (रुका हुआ) | MIR | GPU | नहीं | नहीं | नहीं |
*build, run और package Faber वर्कफ़्लो का वर्णन करते हैं। टेक्स्ट-उत्सर्जन
लक्ष्यों के लिए अंतिम कंपाइलेशन को बाहरी टूलचेन (rustc, wasm-tools, naga)
संभालते हैं।*
Compiler performance#
Radix का फ्रंटएंड स्रोत के आकार के साथ लगभग रैखिक रूप से स्केल होता है, और यह प्रक्रिया के भीतर, सिंगल-थ्रेडेड तरीके से चलता है।
फ्रंटएंड कंपाइल समय#
| प्रोग्राम का आकार | स्रोत | माध्यिका कंपाइल समय |
|---|---|---|
| 100 फ़ंक्शन / ~650 पंक्तियाँ | ~10 KB | ~0.6 ms |
| 500 फ़ंक्शन / ~3.3K पंक्तियाँ | ~52 KB | ~3 ms |
| 1,000 फ़ंक्शन / ~6.5K पंक्तियाँ | ~105 KB | ~6 ms |
| 5,000 फ़ंक्शन / ~32K पंक्तियाँ | ~530 KB | ~37 ms |
आज का सबसे बड़ा वास्तविक उदाहरण लगभग 140 पंक्तियों का है, जो शोर की सीमा से काफी नीचे है।
बैकएंड लागत (Rust लक्ष्य)#
faber build के लिए उपयोगकर्ता को महसूस होने वाला समय Faber के फ्रंटएंड के बजाय Cargo/rustc द्वारा लिया जाता है:
| चरण | लागत |
|---|---|
Cold faber निर्भरता कंपाइल (प्रति target dir एक बार) | ~2.8 s |
Cold tokio निर्भरता कंपाइल (केवल आवश्यकता होने पर) | ~2.3 s |
| Warm प्रति-प्रोग्राम बिल्ड (कैश की गई निर्भरताओं के साथ) | ~30–110 ms |
| प्रति-प्रोग्राम Cargo invocation overhead | ~400 ms |
इन्क्रीमेंटल कंपाइलेशन#
faber-runtime क्रेट प्रत्येक target directory के लिए एक बार कंपाइल होता है और .rlib आर्टिफैक्ट के रूप में कैश किया जाता है:
| आप क्या बदलते हैं | faber-runtime क्रेट | आपका प्रोग्राम |
|---|---|---|
| आपके प्रोग्राम का स्रोत | कैश्ड | फिर से कंपाइल होता है |
norma/src/*.fab (Faber स्रोत) | कैश्ड | फिर से कंपाइल होता है |
faber/runtime/rust/src/*.rs | एक बार फिर से कंपाइल होता है | फिर से कंपाइल होता है |
जिस जाल से बचना चाहिए, वह है प्रत्येक प्रोग्राम को नए target/ में बिल्ड करना। कैश किए गए .rlib को गर्म रखने के लिए साझा --target-dir का पुनः उपयोग करें।