السلطان
  1. الرئيسية
  2. التوثيق
  3. المرجع

الوحدات والاستيراد

صفحات التوثيق

الوحدات والاستيراد

تحدد هذه الصفحة كيف يجد السلطان الوحدات المصدرية ويسميها ويربط بينها: صيغ الاستيراد، وكيف يُحل مسار الاستيراد إلى ملف، وكيف تضيف بيانات الحزم (manifests) أسماء الجذور، ورسائل التشخيص الخاصة بكل إخفاق. وهي موجهة إلى المبرمجين الذين يقسمون البرنامج على عدة ملفات، وإلى المساهمين الذين يعملون على تحميل الوحدات.

الوحدات

كل ملف .sn وحدة. تُعرَّف الوحدة بمفتاح معتمد هو الزوج (الجذر، المسار المنطقي بعد توحيده). الجذر هو الحزمة أو شجرة المكتبة التي ينتمي إليها الملف، والمسار المنطقي هو الاسم المنقط للملف تحت ذلك الجذر، بدون الامتداد .sn. فالملف shapes/area.sn في حزمة ما مساره المنطقي shapes.area. ولا تعتمد الهوية أبدا على مسار نظام الملفات المستخدم للوصول إلى الملف، ولا على كتابة الجذر، ولا على صيغة الاستيراد: كل استيراد للملف نفسه ينتج مفتاح الوحدة نفسه، والتصريحات نفسها، والرموز نفسها. يملك تحميل الوحدة هذه الهوية المعتمدة فقط، ولا يستنتج الهوية من أسماء الملفات، فهذه من شأن محدِّد مواقع المصادر (source locator).

لا يظهر التصريح للوحدات الأخرى إلا إذا وُسم بـ عام. وكل ما عداه خاص بوحدته، واستخدامه من خارجها خطأ SULTANC-NAME-PRIVATE.

عام نوع مستطيل = { العرض: عدد, الارتفاع: عدد };

عام عرف المساحة(الشكل: &مستطيل): عدد {
    أرجع (*الشكل).العرض * (*الشكل).الارتفاع;
}

عرف مساعد(): عدد { أرجع 0; }

لا يظهر لمن يستورد هذا الملف إلا النوع مستطيل والدالة المساحة.

صيغ الاستيراد

تُكتب import بالعربية استورد، وتُكتب from … import على الصورة من … استورد. ويجوز أن تظهر أي من الكتابتين في أي ملف، بصرف النظر عن اللغة التي كُتب بها باقي الملف.

الاستيراد النسبي بين علامتي تنصيص

استورد "geometry.sn";

المسار بين علامتي التنصيص يسمّي ملفا نسبةً إلى المجلد المنطقي للوحدة المستورِدة. ويبقى داخل الجذر نفسه: فالمسار الذي يصعد خارج الجذر (../x.sn) مرفوض، وكذلك المسار المطلق.

الاستيراد بالاسم

استورد المكتبة.نصوص.number;
استورد أدوات.أشكال.area;

الاستيراد بالاسم مسار منقط من مكونين على الأقل ينتهي بوحدة. المكون الأول يحدد الجذر. فإذا كان كتابةً مسجلة لجذر (المكتبة القياسية، أو الحزمة المستورِدة، أو اعتمادية، أو أي اسم من أسمائها المصرح بها؛ انظر الجذور)، حُل باقي المسار تحت ذلك الجذر. وإن لم يكن كذلك، حُل المسار كاملا تحت جذر مشروع المستورِد نفسه. ولا يُعاد البحث عن المسار أبدا نسبةً إلى مجلد الوحدة المستورِدة، ولا يُعاد البحث الذي فشل تحت جذر مسجل في شجرة المشروع. والمسار ذو المكون الواحد مرجع غير صالح (SULTANC-IMPORT-INVALID-REFERENCE).

استيراد وحدة يُدخل كل اسم عام تصرّح به إلى النطاق، دون تأهيل. واستيراد الوحدة نفسها مرتين لا ضرر فيه. وإذا صرّحت وحدتان مستوردتان بالاسم العام نفسه واستخدمه البرنامج، كان الاستخدام ملتبسا (SULTANC-IMPORT-AMBIGUOUS)؛ أعطِ الاستيرادات أسماء بديلة أو اختر الأسماء التي تحتاجها.

الاستيراد الانتقائي

من المكتبة.نصوص استورد عدد_إلى_نص, يحتوي_نصا;
من المكتبة.دخ استورد اطبع_سطر;

يسمّي الاستيراد الانتقائي مجلدا ويسرد التصريحات التي يجلبها، ولا يدخل النطاق إلا الأسماء المسرودة. يبحث حل الأسماء في التصريحات العامة لوحدات ذلك المجلد. والاسم المسرود الذي لا وجود له أو ليس عاما خطأ SULTANC-NAME-UNKNOWN، والاسم المصرح به في أكثر من وحدة واحدة من المجلد خطأ SULTANC-IMPORT-AMBIGUOUS. لا يتولى تحميل الوحدة إلا اختيار المجلد وهويته المعتمدة، أما الحكم بأن الاسم موجود أو عام أو ملتبس فمن شأن حل الأسماء. وتعمل الصيغة نفسها على مجلدات المشروع كما تعمل على مجلدات المكتبة.

الاستيراد باسم بديل

استورد المكتبة.نصوص.number مثل الأعداد;
استورد المكتبة.دخ.println;

عرف الرئيسية(): عدد {
    اطبع_سطر(الأعداد.عدد_إلى_نص(42));
    أرجع 0;
}

لا يغير مثل إلا الربط المحلي. تصبح أسماء الوحدة متاحة عبر الاسم البديل بوصفه مؤهِّلا (الأعداد.عدد_إلى_نص)، ولا تعود في النطاق دون تأهيل. ولا ينشئ الاسم البديل أبدا وحدة جديدة ولا رمزا جديدا ولا هوية مصدر جديدة. ويعمل الاسم البديل مع الاستيراد بين علامتي تنصيص ومع الاستيراد بالاسم على حد سواء، وبهذه الطريقة تُستخدم معا وحدتان تصرّحان بالاسم نفسه. ولا يمكن كتابة اسم مؤهَّل في موضع نوع.

ترويسات سي ومصادرها

استورد "sqlite3.h";   // تصريحات فقط: اربط المكتبة بـ -l sqlite3
استورد "vec.c";       // التصريحات، ويترجم vec.c ويربط

عرف الرئيسية(): عدد {
    إذا (sqlite3_libversion_number() < 3000000) { أرجع 1; };
    دع ش: *متغير vec = vec_new(4);  // البنية vec معتمة هنا: مقبض بنوعه
    دع تم: ص32 = vec_push(ش, 7);
    vec_free(ش);
    أرجع SQLITE_OK;              // ‏#define ثابت
}

المسار بين علامتي التنصيص المنتهي بـ.h أو .c يستورد سي عبر جسر، واجهة سي الأمامية في سلطان (compiler/jisr). يُبحث عن الملف بجوار المستورِد أولا، ثم في $SULTANC_C_INCLUDE (مفصولة بـ:) وأدلة ترويسات الهدف المترجَم له ($SULTANC_C_SYSROOT إن ضُبط، وأدلة المضيف لهدف المضيف، وحزمة SDK لماك في داروين، وأدلة multiarch لهدف لينكس متقاطع). ويعالجه جسر مسبقا بنفسه، بماكروهات الهدف المعرفة مسبقا (__x86_64__ و__aarch64__ و__APPLE__ و_WIN32 و__LP64__ و__SIZEOF_LONG__…) وبترويساته المستقلة (<stddef.h> و<stdarg.h> و<stdint.h> و<limits.h> وغيرها)؛ ويحلل التصريحات بنموذج بيانات الهدف (LLP64 في ويندوز، وLP64 في غيره، وILP32 في أهداف 32 بتا) وتخطيط بناه؛ ويكتبها وحدة سلطان. ويختار SULTANC_C_PREPROCESSOR=cc المعالج المسبق لمترجم سي في النظام بدلا منه (cc -E -dD أو $CC)، ويكتب SULTANC_C_DUMP=<ملف> الوحدة المولدة في ملف.

  • الدوال public extern def بمعاملات p0 وp1…، وتبقي تسمية asm اسما للربط؛
  • أنواع typedef مرادفات أنواع؛ والبنى التي تخطيطها في سي هو تخطيط سلطان الطبيعي سجلات (والعضو المصفوفة صف)؛ والاتحادات والبنى ذات حقول البتات والبنى المضغوطة تخزين معتم بحجمها ومحاذاتها في سي ({ opaque: (u64, …) })؛ ولا صورة للسجل الذي تتجاوز محاذاته 8 بايتات؛
  • كائنات سي بيانات خارجية (public extern let x: T = "x";) تقرأ حيث تستعمل؛
  • قيم التعداد وكائنات constexpr الصحيحة في سي 23 والماكروهات الكائنية التي توسيعها تعبير عددي ثابت أو عدد عشري أو نص حرفي ثوابت public let بالنوع الذي تعطيه سي (1u << 31 هو u32 و0x100000000LL هو i64)، وتتوسع الماكروهات الدالية داخلها؛
  • تُكتب تصريحات الملف المستورَد والترويسات الأخرى تحت جذره: دليل الترويسات الذي وُجد فيه (استورد "sys/socket.h" فيه AF_INET من ترويسات bits/) أو دليل ملف المشروع. وتُقرأ بقية الترويسات لأنواعها وتعداداتها وماكروهاتها. ولا تُكتب من ترويسة نظام الأسماء التي تحجزها سي للتنفيذ (__x و_X)، وتُكتب أسماء ملف المشروع نفسه؛
  • الاسم الذي هو كلمة محجوزة أو دالة مدمجة في سلطان (match وtype وtruncate…) تلحقه _، وتبقي الدالة رمزها في سي باسم ربط بديل (truncate_ تستدعي truncate).

الأنواع: الأعداد الصحيحة والعشرية تحفظ عرضها في الهدف (int هو i32، وlong هو i64 في LP64 وi32 في ويندوز)، وchar * هو *mutable u8 (و*u8 مع const)، وبقية المؤشرات بأنواعها (*T و*mutable T و*void و*S و*mutable *mutable u8)، ومؤشر الدالة أو النوع الذي لا صورة له كلمة عنوان بعرض مؤشر الهدف. والبنية أو الاتحاد الذي لا يراه البرنامج إلا عبر المؤشرات نوع معتم (public type sqlite3 = opaque;، نظام الأنواع): المصرح به فقط (struct X; وtypedef struct X X; وstruct X * بلا تعريف)، والذي تصرح به ترويسة الاستيراد ناقصا ولا تعرّفه إلا وحدة .c (vec * أعلاه: الترويسة واجهته، فيكتب استورد "vec.h" واستورد "vec.c" النوع نفسه ويشتركان فيه)، والذي لا صورة لتخطيطه في سلطان. وهو سي عادي فلا تشخيص له. ومؤشراته *NAME لـconst NAME * و*mutable NAME لغيره (ويمر *mutable NAME حيث يُنتظر *NAME، كما تمرر سي T * مكان const T *)، وكل بنية نوع قائم بذاته عبر تصريحها المسبق وtypedef وتعريفها، والمقبض من نوع آخر هو SULTANC-CALL-ARGUMENT-TYPE-MISMATCH، وفك مرجعه هو SULTANC-TYPE-OPAQUE-DEREFERENCE. والبنية المعرفة في وحدة .c وحدها تبقى سجلا. ووسيط NULL في سي أو ناتجه هو 0 as *T. وتمر السجلات بالقيمة حيث يسمح صنفها في سي. و_BitInt(N) حتى 64 بتا هو أضيق عدد صحيح يسعه، وlong double هو f64 حيث يكون long double في الهدف هو double (ذراع آبل وويندوز). ولا صورة في سلطان لـlong double الأعرض من double (80 بتا في x87، وbinary128)، و__int128 و_BitInt الأعرض من 64 بتا (لا عدد صحيحا من 128 بتا في سلطان، والسجل الذي يقوم مقامه يمرر بخلافه في AArch64 وWin64)، و_Complex وأنواع المتجهات (__attribute__((vector_size(N)))) والتصريح بلا نموذج (f();) والكائنات المحلية للخيط والكائنات المصفوفات. ويُترك كل تصريح كهذا بتعليق // skipped NAME (file:line): c.skipped.… [SULTANC-C-…] (مفتاح السبب لا نص)، ولا يُكتب بنوع خاطئ أبدا، ويُبلغ عنه تحذيرا بذلك الرمز في موضعه من ملف سي (ينجح الاستيراد مع ذلك، وإنما يغيب الاسم). ويُترك كذلك اسم سي لا تستطيع معرفات سلطان تهجئته (café) (SULTANC-C-NAME-CONFLICT-SKIPPED)، وتستعمله شفرة استيراد .c مع ذلك.

وتُكتب الدالة المتغيرة المعاملات (printf) بمعاملاتها الثابتة وباسم الربط printf...1: فيمررها النداء بعرف سي للمعاملات المتغيرة على كل هدف (AL في x86-64 System V، والمكدس في ذراع آبل، وتكرار المعاملات العشرية في سجلات الأعداد الصحيحة في Win64). ولتمرير معاملات أكثر صرّح بشكل نداء له اسم الربط SYMBOL...N نفسه، وN عدد المعاملات الثابتة:

خارجي عرف اطبع_اثنين(الصيغة: *ط8, أ: ص32, ب: ع64): ص32 = "printf...1";

وأخطاء سي تشخيصات قائمة بذاتها: يُبلغ عن خطأ سي في الملف المستورَد أو ترويسات مشروعه (#error، و#include مفقود، وخطأ نحوي، وتصريحان متعارضان، و_Static_assert فاشل، ومعامل غير صالح في شفرة مترجمة) برمزه SULTANC-C-… عند سطر ملف سي وعموده مع سطر مصدر سي، قبل أي خطأ سلطان ينتج عن فشل الاستيراد، بالعربية أو الإنجليزية مثل كل تشخيص آخر. ويسلم جسر هوية التشخيص وسببه في سي وحقائقه (اسم سي ونوعه والرمز المتوقع والموجود والقيمة ومسار التضمين)، وتصوغها iSpeak. ويذكر الملف الذي أدخله #include أسطر #include التي أدت إليه، الأعمق أولا. ومصدر سي بصيغة UTF-8: البايتات التي ليست كذلك (SULTANC-C-INVALID-UTF8) ومحرف المعرف الخارج عن XID_Start/XID_Continue في C23 (SULTANC-C-INVALID-IDENTIFIER-CHARACTER) خطآن حيث يستعمل الرمز. والخطأ في ترويسة لا يقرؤها الاستيراد إلا قراءة (لا يكتب شيئا من تصريحاتها) لا يفشل الاستيراد: هو التحذير SULTANC-C-READ-HEADER-UNTRANSLATED وخطأ سي ملاحظة فيه. وتطبع التحذيرات (#warning والتصريحات المتروكة) حين ينجح الاستيراد.

وحين لا تكون ترويسات سي الخاصة بالهدف مثبتة، تقرأ ترويسات المضيف مكانها إن كان للمضيف نموذج البيانات نفسه: داخل تلك الترويسات تسري ماكروهات المضيف المعرفة مسبقا، وفي غيرها ماكروهات الهدف (وتذكر الوحدة ذلك بـSULTANC-C-HOST-HEADERS)، وإلا فالترويسات المستقلة وحدها متاحة.

وكثيرا ما تصرح استيرادات سي بالشيء نفسه: يصرح stdio.h وstdlib.h كلاهما بـsize_t، وتضمن ترويستا مشروع كلتاهما <stdint.h>. ويُكتب التصريح مرة واحدة في البرنامج: إذا كان استيراد سي آخر تحت جذر المصادر نفسه (وللهدف نفسه) يصدّر التصريح نفسه (نص سلطان نفسه، وهو في السجلات قاعدة سي نفسها لبنى وحدات الترجمة المنفصلة)، استوردته الوحدة المولدة (import "stdio.h"; // declarations this C import shares with it) بدل أن تصرح بالاسم ثانية. والأسماء التي تأخذها وحدة استيراد سي هكذا من وحدة استيراد سي آخر تعد من أسمائها لكل من يستوردها (مباشرة أو باسم بديل): فالوحدة التي تستورد stdlib.h وحدها ترى size_t، والتي تستورد الاثنين ترى size_t واحدا لا اثنين ملتبسين. فالسجل الذي يأخذه استيرادا .c من ترويسة مشتركة نوع واحد أينما كان الاستيرادان. ويبقى الاسم الذي يصرح به استيرادا سي تصريحين مختلفين ملتبسا حيث يستعمل، إلا أن الدالة التي يصرح بها استيراد سي ويعرّفها استيراد .c دالة واحدة (التعريف المترجم).

ويترجم جسر نفسه ملف .c المستورد عبر خط الترجمة المعتاد: تصير دواله وكائناته شفرة سلطان في الوحدة (compiler/jisr/lower.sn)، فيُبنى لكل هدف وخلفية (الخلفيات الأصيلة وLLVM والمفسر) بلا مترجم سي، والأهداف المتقاطعة منها. وتعريفات دواله غير الساكنة public def بتواقيعها في سي، وكائناته العددية غير الساكنة public let؛ ولا تُكتب main أبدا، ويُترك نموذج الدالة التي لا يعرّفها للاستيراد الذي يعرّفها. وتشمل الشفرة المترجمة عبارات سي 11 وتعابيرها: goto واللافتات، وswitch مع السقوط ومدى الحالات في GNU، وجهاز داف، وحساب المؤشرات، والبنى والاتحادات وحقول البتات بالقيمة وفي الذاكرة، والحرفيات المركبة، والمهيئات المعيّنة، والمتغيرات المحلية الساكنة، والكائنات العامة المهيأة، ومؤشرات الدوال، وتعابير العبارات، و_Generic، والتعريفات المتغيرة المعاملات (va_list وva_arg وva_copy وتمريرها إلى vprintf)، ونداء دوال مكتبة سي (المتغيرة المعاملات منها)، وقراءة كائنات الملفات الأخرى وكتابتها وأخذ عناوينها عبر رموزها في سي، وconstexpr و#embed وtypeof و_BitInt(N) (حتى 128 بتا) وحساب __int128 من سي 23، وهذه الامتدادات:

  • المصفوفات متغيرة الطول (int a[n]; وlong rows[n][2];): يصنع تخزين كل منها حيث يصرح بها، في كل مرة، وsizeof إحداها حجمها وقت التشغيل؛
  • goto المحسوب (اللافتات قيما): &&label مؤشر void * يسمي اللافتة، وgoto *p يتابع منها، وجداولها (static void *ops[] = { &&a, &&b };) تعمل كما في المفسرات المخيطة في GCC؛
  • الكائنات المحلية للخيط (_Thread_local و__thread، على مستوى الملف أو static في كتلة): يعمل كل خيط على نسخته من قيمها الأولى، تصنع عند أول استعمال له (وتبقى النسخة حتى ينتهي البرنامج)؛
  • long double حيث يكون double.

وما لا تترجمه يُبلغ عنه بـSULTANC-C-UNSUPPORTED في موضعه: عبارات asm، وقيم long double حيث يكون أعرض من double، و_BitInt الأعرض من 128 بتا، وقيم المتجهات. والبرنامج الذي يكتب عبر stdio في سي يستدعي fflush(0) قبل أن يعود: برنامج سلطان لا يخرج عبر مكتبة سي.

ودوال سي في البرنامج مجموعة واحدة كما بعد الربط: الدالة التي يصرح بها استيراد سي (نموذج في ترويسة، أو نداء في ملف .c لدالة لا يعرّفها) ويعرّفها استيراد .c آخر في البرنامج تُستدعى مباشرة أينما كان الاستيرادان، حين تكون أنواع معاملات التصريح وناتجه أنواع التعريف؛ يربط MSIR التصريح بالتعريف المترجم (compiler/msir/lowering/functions.sn)، ولا دخل لرمز ربط. فملفات .c التي تستوردها وحدات سلطان مختلفة يستدعي بعضها بعضا، والمتعاودة منها أيضا.

ويستورد استورد "a.c+b.c" عدة وحدات ترجمة من دليل واحد وحدةً واحدة: تعالج كل منها مسبقا وتحلل وتترجم وحدها (فتبقى ساكناتها لها)، وتُكتب التصريحات المشتركة بينها مرة واحدة، ونداء إحداها دالة تعرّفها أخرى نداء مباشر؛ ونداء دالة متغيرة المعاملات في وحدة أخرى يمرر معاملاتها المتغيرة في خانات من 8 بايتات إلى دالة تلك الوحدة المترجمة، كما يفعل النداء داخل وحدة واحدة. أما النداء المتغير من استيراد .c منفصل لدالة استيراد آخر فما زال نداء سي متغيرا لرمز خارجي، ولا يمكن تسليم مؤشر دالة سي مترجمة لشفرة سي خارجية (qsort أو رد نداء): فالدوال المترجمة بعرف نداء سلطان، وليس في سلطان مدخل يستدعيه سي لدالة بأي توقيع.

ويترجم SULTANC_C_COMPILER=cc ملفات .c المستوردة بمترجم سي في النظام بدلا منه (cc -c -O2 -fPIC أو $CC) لهدف المضيف وحده: فتصرح الوحدة حينئذ بتعريفاتها خارجية، وتُربط كائناتها بالبرنامج، وتضاف مكتبة سي إن لم يذكرها سطر الأوامر. ولا يُختار ذلك ضمنيا أبدا.

الجذور

الجذر شجرة من الوحدات لها مجموعة من الكتابات التي تختارها. يمكن أن تختار عدة كتابات جذرا واحدا، وكلها تنتج مفاتيح الوحدات نفسها.

المكتبة القياسية جذر واحد له الكتابتان std والمكتبة، ويعرفهما المترجم بنفسه. ولمجلداتها الفرعية كتابات بحسب كل لغة أيضا، فالأسماء std.io.println والمكتبة.دخ.println وstd.entree_sortie.println تسمّي وحدة واحدة. وتُعلن هذه الكتابات في ملف جذر المكتبة library/std/std.sn (انظر تهجئات الوحدات):

المجلد العربية المجلد العربية
io دخ net شبكة
fs ملفات http ويب
text نصوص debug تصحيح
chars حروف meta انعكاس
bytes بايتات error أخطاء
encoding ترميز fmt تنسيق
memory ذاكرة process عمليات
env بيئة crypto تشفير
toml تومل collections مجموعات
version إصدار time وقت

ويعطي ملف الجذر أيضا كتابات فرنسية وإسبانية لبعض المجلدات. أما أسماء الملفات داخل المجلد (println، number) فلا تُترجم، وتبقى كما كُتبت في اللغتين. والمجلدات التي ليس لها كتابة، مثل std.json، لها اسم واحد.

يجد المترجم المكتبة القياسية من بنيتها، أي مجلد std/ (انظر أين يبحث المترجم عن المكتبة القياسية).

تهجئات الوحدات

يعلن ملف جذر المجلد تهجئات أبناء المجلد المباشرين بالكلمة وحدة (module بالإنجليزية):

وحدة io { ar: دخ, fr: entree_sortie, es: entrada_salida };

الاسم بعد وحدة هو الابن كما هو على القرص: ملف NAME.sn أو مجلد NAME بجوار ملف الجذر. وكل تهجئة معرف، ولا تكون كلمة محجوزة. ملف جذر المجلد هو FOLDER/FOLDER.sn (لا mod.sn أبدا)، وملف جذر الحزمة هو SOURCE_ROOT/PACKAGE.sn باسم الحزمة (library/std/std.sn للمكتبة القياسية). وقد يضم ملف الجذر تصريحات أخرى، ولا تقع وحدة في غيره.

يُقرأ مسار الاستيراد جزءا جزءا: في المكتبة.دخ.println تختار المكتبة المكتبة القياسية، ويقابل std.sn بين دخ وio، وقد يقابل io/io.sn إن وُجد بين تهجئة وprintln. والجزء الذي لا يقابله ملف جذر يبقى كما كُتب. والتهجئة اسم آخر لوحدة واحدة، لا وحدة ثانية. ويُقرأ كل ملف جذر مرة واحدة في الترجمة، لسطور وحدة فقط.

تضيف الحزمة جذورها الخاصة: اسمها name، وكل كتابة من كتاباتها spellings، والاسم الذي تعطيها إياه الحافة إذا كانت اعتمادية. ولذلك يمكن للمشروع أن يستورد نفسه باسمه (استورد app.helper;)، وأن يستورد الاعتمادية بالاسم الذي أُعطي لها.

الحزم ورسم الحزم

لا يقرأ السلطان الملف Supax.toml. يقرأ سوباكس، مدير الحزم، ملفات البيانات ويتحقق منها، ويحل الاعتماديات ويجلبها، ويكتب للمترجم رسم حزم واحدا، build/supax/package-graph.toml، ويمرره بالخيار --package-graph=<ملف> (أو --package-graph <ملف>) في البناء وcheck وrun وtest. ويقرأ --package-graph=- (أو --package-graph -) الرسم من الإدخال القياسي بدلا من ذلك، كما يمرر محرر أو أداة رسما لم يكتبه في ملف؛ ويُقرأ الرسم مرة واحدة في كل عملية للمترجم، وتُحل مساراته النسبية (source_root) بالنسبة إلى الدليل الحالي، إذ لا دليل للإدخال القياسي. لا يكتشف المترجم ملف بيانات أبدا، ولا يتتبع الاعتماديات، ولا يقرأ Supax.lock، ولا يستعمل الشبكة.

داخل مشروع سوباكس شغّل supax check أو supax build أو supax run. أما sultanc check src/main.sn وحده فيترجم الملف مستقلا: لا يرى اعتماديات المشروع ولا اسم الحزمة نفسها، حتى إن كان بجواره Supax.toml.

وبلا --package-graph تكون الترجمة مستقلة: الملفات المسماة واستيراداتها النسبية (استورد "util.sn";) والمكتبة القياسية. وجذر المشروع هو مجلد العمل للمصادر النسبية، أو المجلد المشترك بين المصادر. ويُترجم الملف المصدري من المكتبة القياسية نفسها بوصفه من المكتبة القياسية.

version = 1
root = "app"                      # الحزمة التي تملك الملفات المترجمة

[[package]]
id = "app"                        # فريد ومبهم؛ "std" محجوز للمكتبة القياسية
source_root = "src"               # مطلق، أو نسبي إلى هذا الملف
name = "app"                      # كتابة الجذر الأصلية
spellings = { ar = "تطبيق" }      # كتابات أخرى للجذر بحسب اللغة
entry = "lib"                     # اختياري: الوحدة التي تسميها كتابات الجذر

[[edge]]
from = "app"
to = "json@1.2.0"
name = "json"                     # اسم الاعتمادية داخل from
المدخل المحتوى
version 1.
root معرف الحزمة التي يضم جذر مصادرها الملفات المسماة في سطر الأوامر.
[[package]] id وsource_root وname، وspellings وentry اختياريان. تُحل الوحدات تحت source_root.
[[edge]] الحزمة to مرئية داخل from باسمها وكتاباتها وباسم الحافة name.

يجب أن يكون اسم الحزمة name وكل كتابة واسم الحافة name معرفات لا كلمات محجوزة في اللغة؛ ويتحقق المترجم من ذلك بقائمة كلماته المحجوزة نفسها. وترى كل حزمة المكتبة القياسية بالكتابات نفسها التي يراها المشروع، وترى نفسها بأسمائها. ولا يصف الرسم المكتبة القياسية، فالمترجم يعرفها بنفسه. ويُنظَّف source_root معجميا كما يفعل Cargo دون تتبع الوصلات الرمزية: app/../util هو util، فلا تحمل أسماء المصادر ولا رسائل التشخيص .. أبدا. وحزمتان يؤول جذرا مصدريهما بعد التنظيف إلى مجلد واحد خطأ. ويُبلَّغ عن الخطأ في الرسم بالرمز SULTANC-PACKAGE-GRAPH-INVALID عند المسار:السطر:العمود مع السطر نفسه، كما يُبلَّغ عن خطأ في ملف مصدري.

وليست تهجئات الوحدات داخل الحزمة جزءا من الرسم: يعلنها ملف جذر الحزمة. فبهذا الرسم، ومع src/app.sn الذي يضم وحدة shapes { ar: أشكال };، تُستورد وحدة الحزمة src/shapes/area.sn على الصورة app.shapes.area، أو تطبيق.shapes.area، أو تطبيق.أشكال.area، وتُستورد الوحدة lib.sn من الحزمة json على الصورة json.lib.

رسائل التشخيص

الهوية المعنى
SULTANC-MODULE-NOT-FOUND لا يوجد مصدر للجذر والمسار المختارين.
SULTANC-MODULE-INVALID-LOGICAL-PATH أحد مكونات مسار المصدر ليس اسم وحدة صالحا.
SULTANC-IMPORT-INVALID-REFERENCE شكل الاستيراد خاطئ، مثل مسار من مكون واحد.
SULTANC-IMPORT-CYCLE وحدات يستورد بعضها بعضا في حلقة.
SULTANC-IMPORT-AMBIGUOUS استيرادان يوفران الاسم نفسه، أو استيراد انتقائي يطابق عدة وحدات.
SULTANC-NAME-UNKNOWN اسم مختار لا وجود له في النطاق المستورد.
SULTANC-NAME-PRIVATE الاسم موجود لكنه ليس عام.
SULTANC-PACKAGE-GRAPH-INVALID رسم حزم تتعذر قراءته أو مشوه أو من إصدار آخر أو يسمي ما لا وجود له؛ ويُبلَّغ عنه عند سطره وعموده.
SULTANC-STD-NOT-FOUND لا يوجد دليل مكتبة فيه std/ حيث يبحث المترجم عن المكتبة القياسية.
SULTANC-MODULE-SPELLING-NO-CHILD تصريح وحدة لا يسمي ملفا ولا مجلدا في مجلده.
SULTANC-MODULE-SPELLING-SHARED ابنان لمجلد واحد يشتركان في تهجئة، أو التهجئة اسم ابن آخر.
SULTANC-MODULE-SPELLING-RESERVED تهجئة الوحدة كلمة محجوزة.
SULTANC-MODULE-OUTSIDE-ROOT-FILE وحدة في ملف ليس ملف جذر مجلد ولا ملف جذر حزمة.

الرموز SULTANC-PACKAGE-MANIFEST-INVALID وSULTANC-PACKAGE-GIT-DEPENDENCY-UNRESOLVED وSULTANC-PACKAGE-DEPENDENCY-MAP-INVALID متقاعدة: لم يعد sultanc يصدرها، ويبلغ سوباكس عن أخطاء البيان والاعتماديات. ولا يُعاد استعمال رمز عام أبدا.

غياب وحدة من وحدات المشروع وغياب وحدة تحت جذر مكتبة مسجل كلاهما يفشل بوصفه غيابا لمصدر في الجذر الذي اختير من قبل.

مصادر الوحدات الصريحة

لا يغير --module-source=<module>=<file> إلا المكان الذي يُقرأ منه مصدر وحدة موجودة. يُحل <module> المنقط انطلاقا من الوحدة الجذرية تماما كما يُحل الاستيراد بالاسم، فيحتفظ كل استيراد لتلك الوحدة بالمفتاح المعتمد نفسه. ويصبح الملف موقع المصدر الصريح لذلك المفتاح في البيئة المنطقية، وهو ما يرجع إليه محدِّد مواقع المصادر قبل اشتقاق المسار. ويُرفض جذر المكتبة القياسية الموثوق، والمدخلات المباشرة، والوحدات غير المعروفة، والروابط المكررة. وتستخدمه عمليات البناء لاختيار قدرات بناء المترجم (انظر قدرات بناء المترجم).

القيود

  • لا يمكن أن يظهر اسم مؤهَّل من استيراد باسم بديل في موضع نوع.
  • يسرد الاستيراد الانتقائي أسماء مجردة، ولا تدعم القائمة إعادة تسمية اسم بـ مثل.
  • يُرفض الاستيراد بالاسم ذو المكون الواحد.

انظر أيضا