Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

مقدّمة

لغة ص (Sad) لغة برمجة عربيّة حديثة، أغراضها عامّة، مكتوبة بـ C++17، وملفّات مصدرها بامتداد . صُمِّمت لتكون عربيّةً في صميمها — كلماتها المفتاحيّة ورموزها ورسائل أخطائها بالعربية — مع دعم كامل لـ UTF-8 يسمح بمزج العربية والإنجليزية في الأسماء والنصوص.

تأتي اللغة بمنظومة تنفيذ متكاملة:

  • مفسّر شجريّ (sad-run) لتشغيل البرامج مباشرةً.
  • مترجم (sad-build) يحوّل المصدر عبر LLVM إلى تنفيذيّ أصليّ.
  • خادم LSP، مدير حِزَم، فاحص ساكن، ومنسّق — راجع فصل الأدوات.

ملاحظة قناة: كانت المنظومة تضمّ أيضًا آلة بايت كود (VM) — ما تزال في الإصدار المستقرّ، وأُزيلت في القناة القادمة لإعادة بنائها على أساس أمتن؛ المحرّكان المعتمَدان هما المفسّر والمترجم.

ماذا يغطّي هذا التوثيق؟

هذا الكتاب هو المرجع التقنيّ الموجَّه لمن يكتب برامج بلغة ص. يأخذك من أوّل برنامج حتى الميزات المتقدّمة، ثم يقدّم مرجعًا دقيقًا للنحو والكلمات والأنواع والعوامل.

الجزءلمن؟
البدءالمبتدئ: ثبِّت وشغِّل أوّل برنامج
جولة في اللغةمن يتعلّم: المفاهيم موضوعًا موضوعًا
المرجع التقنيّمن يحتاج الدقّة: جداول الكلمات والعوامل والنحو

لمحة سريعة

# أوّل برنامج بلغة ص
دالة رئيسية()
    اطبع("أهلًا يا عالم")
نهاية

أبرز ملامح النحو (التفصيل في المرجع):

  • 40 كلمة محجوزة فقط + 3 عوامل منطقيّة تُلفظ كلمات: و، أو، ليس.
  • الكتل تُفتَح بكلمتها (دالة، إذا، بينما…) وتُغلَق دائمًا بـنهاية.
  • الفاصلة ، و, متكافئتان، وكذلك المنقوطة ؛ و;.
  • التعليقات: سطريّ #، كتليّ #* ... *#، توثيقيّ ##.
  • أسماء الأنواع (رقم، نص، عشري…) ليست محجوزة — يمكن استعمالها أسماءً خارج سياق النوع.

مصدر الحقيقة

الحقيقة الرسمية لكلّ قاعدة وكلمة ونوع تعيش في language-truth/ داخل المستودع الأساسيّ. هذا الكتاب يَعرِض تلك الحقيقة بصورة مقروءة ولا يخترع غيرها؛ عند أيّ تعارض فـlanguage-truth/ هو الفيصل. راجع مصدر الحقيقة الموحّد.

التثبيت والتشغيل

تُبنى لغة ص من المصدر باستخدام CMake وLLVM ومترجم C++17. هذا الدليل يلخّص خطوات الحصول على المفسّر والمترجم وتشغيل أوّل برنامج.

المتطلّبات

  • مترجم C++17 (MSVC على Windows، أو Clang/GCC على Linux/macOS).
  • CMake 3.20 أو أحدث.
  • LLVM (للمترجم sad-build؛ المفسّر sad-run لا يحتاجه).

البناء

# من جذر مستودع لغة ص
cmake -S . -B build                                   # تهيئة أولى
cmake --build build --config Debug --target sad-run   # المفسّر  → sad-run.exe
cmake --build build --config Debug --target sad-build # المترجم  → sad-build.exe

الهدفان: sad-run يبني المفسّر، وsad-build يبني المترجم. (الأسماء القديمة sad/sadc أُعيدت تسميتها إلى sad-run/sad-build.)

التشغيل

شغّل ملفًّا بالمفسّر مباشرةً:

.\build\bin\Debug\sad-run.exe examples\test_simple.ص

أو ترجمه إلى تنفيذيّ أصليّ بالمترجم:

.\build\bin\Debug\sad-build.exe examples\test_simple.ص -o test_simple.exe
.\test_simple.exe

الاختبارات

ctest --test-dir build -R Comprehensive   # فعّلها بـ -DBUILD_TESTS=ON عند التهيئة

التالي

انتقل إلى أوّل برنامج: أهلًا يا عالم لكتابة وتشغيل أوّل ملفّ .

أوّل برنامج: أهلًا يا عالم

لنكتب أبسط برنامج ونشغّله، ثم نضيف متغيّرات وتحكّمًا بالتدفّق لنرى ملامح اللغة.

الملفّ

أنشئ ملفًّا باسم أهلا.ص بالمحتوى التالي:

دالة رئيسية()
    اطبع("أهلًا يا عالم")
نهاية

ثم شغّله بالمفسّر:

.\build\bin\Debug\sad.exe أهلا.ص

المخرجات:

أهلًا يا عالم

شرح سطرًا سطرًا

  • دالة رئيسية() — تعريف دالة الدخول رئيسية (نقطة بدء البرنامج).
  • اطبع(...) — دالة مضمّنة تطبع نصًّا على المخرج القياسيّ.
  • نهاية — إغلاق كتلة الدالة. كلّ كتلة في لغة ص تُغلَق بـنهاية.

مثال أوسع

دالة رئيسية()
    متغير الاسم = "أحمد"
    متغير العمر = 30

    اطبع("الاسم: " + الاسم)

    إذا العمر >= 18
        اطبع("بالغ")
    وإلا
        اطبع("قاصر")
    نهاية

    لكل رقم في [1، 2، 3]
        اطبع(رقم)
    نهاية
نهاية

لاحظ:

  • متغير يُعرِّف متغيّرًا قابلًا للتغيير (وثابت يُعرِّف ثابتًا).
  • الفاصلة ، العربيّة تكافئ , تمامًا داخل عناصر المصفوفة.
  • إذا/وإلا ولكل ... في كلٌّ منهما كتلة تُغلَق بـنهاية.

التالي

تابع جولة في اللغة لتفصيل كلّ مفهوم، أو اقفز إلى المرجع التقنيّ لجداول الكلمات والعوامل والنحو.

المتغيّرات والثوابت

تُعرَّف المتغيّرات في لغة ص بكلمة متغير، والثوابت بكلمة ثابت. تُستنتَج الأنواع تلقائيًّا من القيمة، ويمكن التصريح بالنوع صراحةً عند الحاجة.

التعريف

متغير العدّاد = 0          # متغيّر قابل للتغيير
ثابت باي = 3.14159        # ثابت لا يتغيّر

العدّاد = العدّاد + 1      # إعادة إسناد مسموحة للمتغيّر
# باي = 3                 # خطأ: لا يمكن تغيير الثابت

التصريح بالنوع

أسماء الأنواع (مثل رقم، نص، عشري) ليست محجوزة، وتُكتب بعد الاسم عند الرغبة في التصريح الصريح:

متغير العمر: رقم = 30
متغير الاسم: نص = "سارة"

محدّدات إضافيّة

  • ساكن — عضو/متغيّر ساكن مرتبط بالصنف لا بالنسخة.
  • خارجي — رمز معرَّف خارج الوحدة (ربط خارجيّ).

انظر أيضًا

الأنواع والقيم الحرفيّة

تُقدّم لغة ص 9 أنواع مدمجة. أسماؤها ليست كلمات محجوزة (يُصدرها المعجمي كمُعرِّفات)، فيمكن استعمالها أسماءً خارج موضع النوع، لكنها تُفسَّر أنواعًا في موضع التصريح.

النوعالاسم الإنجليزيّالمعنىمثال
رقمintegerعدد صحيح42
عشريdoubleعدد عشريّ3.14
نصstringسلسلة نصّيّة"مرحبًا"
منطقيbooleanصحيح/خطأصحيح، خطأ
فراغvoidلا قيمة (مردود دالة)
عدمnullالنوع الفارغ المتمايزلاشيء
مصفوفةarrayقائمة مرتّبة[1، 2، 3]
خريطةmapأزواج مفتاح/قيمة{"أ": 1}
أيanyأيّ نوع

القيم الحرفيّة المحجوزة

ثلاث قيم حرفيّة هي كلمات محجوزة:

متغير يعمل = صحيح     # true
متغير متوقّف = خطأ    # false
متغير قيمة = لاشيء    # null

أمان العدم (Null Safety)

تميّز لغة ص بين القيمة العاديّة والقيمة التي قد تكون «عدمًا». يُكتب النوع الاختياريّ بلاحقةٍ على النوع (مثل نص?)، ويُعالَج بعامل وصول آمن وعامل اندماج فارغ.

الرمز يختلف بحسب الإصدار: الرموز الدقيقة لأمان العدم مُولَّدة من مصدر الحقيقة لكلّ قناة — راجع العوامل والأسبقيّة و الأنواع المدمجة لرؤية رموز إصدارك بالضبط (مع أمثلة جاهزة).

التعبيرات والعمليات

تدعم لغة ص مجموعة كاملة من العوامل الحسابيّة والمنطقيّة والمقارنة، مع ترتيب أسبقيّة محدّد بدقّة. هذا الفصل لمحة؛ والجدول الكامل في العوامل والأسبقيّة.

الحسابيّة

متغير المجموع = 2 + 3 * 4      # 14 (الضرب أسبق)
متغير الباقي = 17 % 5          # 2
متغير القوّة = (2 + 3) * 4      # 20 (الأقواس تُقدَّم)

المقارنة والمنطق

العوامل المنطقيّة الثلاثة كلماتٌ عربيّة: و (and)، أو (or)، ليس (not).

إذا العمر >= 18 و العمر < 65
    اطبع("ضمن سنّ العمل")
نهاية

إذا ليس مكتمل
    اطبع("غير مكتمل")
نهاية

العامل الثلاثيّ

اختصارٌ للشرط داخل تعبير (شرط ؟ قيمة_صحّة : قيمة_خطأ). رمز السؤال يختلف بحسب الإصدار — راجع جدول العوامل لرمز إصدارك الدقيق:

متغير الإشارة = س > 0 ؟ 1 : -1

دمج النصوص

متغير التحيّة = "مرحبًا يا " + الاسم

أمان العدم في التعابير

تُكمِّل ثلاثةُ عوامل النوعَ الاختياريّ (نص؟) على مستوى التعبير:

  • الوصول الآمن ؟. — يصل الحقل/الطريقة إن لم تكن القيمة عدمًا، وإلّا يُرجع لاشيء دون تعطّل (قصر الدائرة):
متغير ك = لاشيء
اطبع_سطر(ك؟.س)      // لاشيء — لا خطأ
  • الاندماج الفارغ ؟؟ — يُرجع الطرف الأيسر إن لم يكن عدمًا، وإلّا الأيمن:
اطبع_سطر(لاشيء ؟؟ 7)   // 7
اطبع_سطر(5 ؟؟ 7)        // 5
  • تأكيد عدم الفراغ مؤكد (لاحقيّ) — يؤكّد أنّ القيمة ليست عدمًا في هذا الموضع.

⚠️ تباعُد مترجم مفتوح (ISSUE-065): الوصول الآمن ؟. على كائنٍ حقيقيّ (غير عدم) بحقلٍ نصّيّ أو عشريّ يطبع في المترجم قيمةَ مؤشّرٍ رقمًا أو يبتر العشريّ. الحالة على لاشيء (ISSUE-064) والحقول العدديّة تعمل مزدوجًا. حدٌّ معماريّ مفتوح في القناتين (يحتاج توحيد نوع الحقل مع حارس العدم — شبيه ISSUE-045/052).

النطاق والتشريح

عامل النطاق .. يبني مجالًا (حصريّ النهاية)، وتُشرَّح المصفوفات بأقواس الفهرسة أو بطريقة شريحة:

لكل ن في 1..5              // 1، 2، 3، 4
    اطبع_سطر(ن)
نهاية

متغير م = [10، 20، 30، 40]
اطبع_سطر(م[0:2])          // [10, 20]  — بنقطتين، نهاية حصريّة
اطبع_سطر(م[1..3])         // [20, 30]  — بصيغة النطاق
اطبع_سطر(م[1..])          // [20, 30, 40]  — مفتوحة النهاية (الذيل)
اطبع_سطر(م.شريحة(1))      // [20, 30, 40]  — بصيغة الطريقة

⚠️ فجوة مترجم مفتوحة (ISSUE-066): صيغة الدالّة الحرّة شريحة(م، بداية) غير موصولةٍ في المترجم بعدُ (فشل ربط)؛ استعمل الفهرسة م[أ..ب] أو الطريقة م.شريحة(...) اللتين تعملان مزدوجًا.

راجع العوامل والأسبقيّة لكلّ العوامل ودرجات أسبقيّتها (1 = الأعلى).

التحكّم بالتدفّق

تُوفّر لغة ص الشروط والحلقات ومطابقة الأنماط. كلّ كتلة تُغلَق بـنهاية.

الشرط إذا / وإلا

إذا الدرجة >= 90
    اطبع("ممتاز")
وإلا
    اطبع("دون الممتاز")
نهاية

الحلقة بينما

متغير العدّاد = 0
بينما العدّاد < 5
    اطبع(العدّاد)
    العدّاد = العدّاد + 1
نهاية

الحلقة لكل ... في

لكل عنصر في ["أ"، "ب"، "ج"]
    اطبع(عنصر)
نهاية

تتحكّم توقف (break) واستمر (continue) في سير الحلقة.

المرور على الخرائط

حين يكون المصدر خريطةً تمرّ الحلقة على مدخلاتها. بمتغيّر واحد يُربَط الاسم بكلّ مفتاح، وبمتغيّرين (يفصلهما ،) يُربَط الأوّل بالمفتاح والثاني بالقيمة:

متغير الأعمار = {"سعيد": 30, "نورة": 25}

لكل اسم في الأعمار
    اطبع_سطر(اسم)
نهاية

لكل اسم، عمر في الأعمار
    اطبع_سطر(اسم + ":" + نص(عمر))
نهاية
سعيد
نورة
سعيد:30
نورة:25

والصيغة نفسها تعمل في الاستيعابات.

مطابقة الأنماط طابق

تُقيَّم قيمة طابق مرّةً، ثمّ تُجرَّب أذرع عندما بالترتيب حتى يطابق نمطٌ، فيُنفَّذ جسمه وحده. تُغطّي افتراضي ما لم يطابق. كلمات البنية: طابق (فتح)، عندما (ذراع)، افتراضي (الافتراضيّ)، نهاية (إغلاق).

طابق الحالة
    عندما 1
        اطبع("واحد")
    عندما 2
        اطبع("اثنان")
    افتراضي
        اطبع("غير ذلك")
نهاية

أنواع الأنماط

يقبل عندما أنماطًا أغنى من مجرّد قيمةٍ حرفيّة:

نمط حرفيّ — عددٌ أو نصٌّ أو منطقيٌّ أو عددٌ سالب، يطابق بالتساوي:

عندما 0        // عدد
عندما "نعم"    // نصّ
عندما -1       // سالب

نمط متغيّر ونمط شامل — الاسم المجرّد يطابق أيّ قيمةٍ ويربطها؛ و_ يطابق أيّ قيمةٍ دون ربط:

عندما س        // يطابق أيّ شيء ويربطه بـ«س»
عندما _        // يطابق أيّ شيء دون ربط

نمط النطاق.. نطاقٌ حصريّ النهاية، و..= شاملها:

عندما 1..10    // من 1 إلى 9
عندما 1..=10   // من 1 إلى 10

نمط القائمة — يطابق طولًا محدّدًا ويربط العناصر؛ تدعم القائمة الفارغة [] والعنصر الشامل:

عندما []           // قائمة فارغة
عندما [أ، ب]        // بالضبط عنصران، يُربَطان بـأ وب
عندما [أول، _]      // عنصران، الثاني مُهمَل

نمط البنية — يطابق حقولًا مسمّاة؛ ويدعم الاختصار {حقل} (يربط باسم الحقل) والبنية الفارغة {}:

عندما {الاسم: ن، العمر: ع}   // يربط ن وع
عندما {الاسم}                 // اختصار: يربط «الاسم»

نمط قيمة التعداد — يطابق قيمة تعدادٍ بسيطة، أو قيمةً حاملةً بيانات بأنماطٍ لحقولها:

عندما اللون.أحمر           // قيمة بسيطة
عندما الشكل.دائرة(نق)      // حاملة بيانات، تربط «نق»

نمط البدائل| يطابق أيًّا من عدّة أنماط في ذراعٍ واحد (|| مقبولٌ تساهلًا):

عندما 1 | 2 | 3

الحارس إذا — يقيّد الذراع بشرطٍ إضافيّ بعد مطابقة النمط:

عندما ع إذا ع > 100

⚠️ الحارس على نمطٍ تفكيكيّ (قائمة/بنية) لا يرى العناصر المربوطة في المترجم بعد (يُقيَّم قبل الربط) — استعمله مع نمط متغيّرٍ بسيط. تفصيلٌ في ISSUE-069.

نمط الباقي والأنماط المتداخلة*اسم يجمع ذيل القائمة، والأنماط تتداخل:

عندما [أول، *بقية]         // يربط أول ويجمع البقيّة
عندما [[أ، ب]، [ج، د]]     // قائمة داخل قائمة (متجانسة)

🚧 القناة القادمة: نمط الباقي *اسم والأنماط المتداخلة (قائمةٌ داخل قائمة) متوفّرة في القناة القادمة (/next/) وتنتقل إلى المستقرّ مع الإصدار التالي. في المترجم يقتصر التداخل على القوائم المتجانسة النوع؛ التداخل المتباين النوع أو العميق أو داخل حقل بنيةٍ يسقط إلى افتراضي بأمان (حدٌّ معماريّ موثّق في ISSUE-070).

راجع الكلمات المحجوزة الأربعون لكامل كلمات التحكّم، وقواعد النحو لطبقة الأنماط الرسميّة.

الاستيعابات (القوائم والمجموعات والقواميس)

الاستيعاب (comprehension) صياغة موجزة لبناء قائمة أو مجموعة أو قاموس من مصدر قابل للتكرار، بجملة واحدة بدل حلقة صريحة. تتبع لغة ص الترتيب العربيّ الطبيعيّ: رأس الحلقة أوّلًا، ثمّ الكلمة أنتج تفصله عن تعبير الناتج.

الصيغ الثلاث

قائمة:   [ لكل <متغيّر> في <مصدر> أنتج <ناتج> ]
مجموعة:  { لكل <متغيّر> في <مصدر> أنتج <ناتج> }
قاموس:   { لكل <متغيّر> في <مصدر> أنتج <مفتاح>: <قيمة> }
  • الأقواس [ ] أو المعقوفة { } تحيط بالاستيعاب كلّه.
  • الجزء «إذا <شرط>» — قبل أنتجاختياريّ في الأنواع الثلاثة؛ يرشّح العناصر قبل الإنتاج.
  • الكلمة أنتج تفصل رأس الحلقة عن الناتج. وهي كلمة سياقيّة (تُستعمَل أيضًا للتوليد في المولّدات).

لماذا هذا الترتيب؟ العربيّة تُقدّم السبب ثمّ الجواب: «لكلّ عنصرٍ في القائمة … أنتِج كذا». فالقارئ يعرف ما الذي نمرّ عليه قبل ما الذي نبنيه — على خلاف الترتيب البايثونيّ الذي يضع الناتج أوّلًا. (سابقة مماثلة: from … where … select في C# LINQ حيث المصدر أوّلًا.)


استيعاب القائمة

يبني قائمةً بتطبيق تعبير الناتج على كلّ عنصر (بعد الترشيح إن وُجد شرط).

متغير المضاعفات = [لكل س في [1، 2، 3، 4] أنتج س * 2]
اطبع_سطر(المضاعفات)
[2, 4, 6, 8]

مع شرط ترشيح قبل أنتج:

متغير الكبار = [لكل س في [1، 2، 3، 4، 5] إذا س > 2 أنتج س]
اطبع_سطر(الكبار)
[3, 4, 5]

استيعاب المجموعة

يبني مجموعة (عناصر فريدة، بلا تكرار) داخل { } بلا نقطتين بعد الناتج. تُزال التكرارات على قيمة الناتج، مع الحفاظ على ترتيب أوّل ظهور.

متغير الفريدة = {لكل س في [1، 2، 2، 3] أنتج س}
اطبع_سطر(الفريدة)
[1, 2, 3]

بما أنّ إزالة التكرار تكون على الناتج لا على المصدر، فإنّ تحويلًا يطوي مدخلاتٍ متمايزةً يُصغّر المجموعة:

متغير البواقي = {لكل س في [1، 2، 3، 4] أنتج س % 3}
اطبع_سطر(طول(البواقي))
3

المصدر [1، 2، 3، 4] متمايز (٤ عناصر)، لكنّ س % 3 يُنتج [1، 2، 0، 1] فتُطوى 1 المكرّرة ⇒ المجموعة [1، 2، 0] بطول ٣.


استيعاب القاموس

يبني قاموسًا داخل { } عندما يكون الناتج على هيئة مفتاح: قيمة (وجود : بعد الناتج هو ما يميّز القاموس عن المجموعة).

متغير المربّعات = {لكل س في [1، 2، 3] أنتج نص(س): س * س}
اطبع_سطر(المربّعات)
{"1": 1, "2": 4, "3": 9}
  • متغيّر الحلقة مفرد (لا يُفكّك زوجًا) ما دام المصدر مصفوفةً؛ أمّا حين يكون المصدر خريطةً فانظر فكّ الزوج أدناه.
  • عند تصادُم مفتاحين، يفوز الأخير (كالخريطة الحرفيّة).
  • الشرط إذا — إن وُجد — يسبق أنتج كالمعتاد:
متغير الزوجيّة = {لكل س في [1، 2، 3، 4] إذا س % 2 == 0 أنتج نص(س): س * 10}
اطبع_سطر(الزوجيّة)
{"2": 20, "4": 40}

فكّ الزوج: التكرار على الخرائط

🚧 القناة القادمة: هذه الميزة متوفّرة في القناة القادمة (/next/)؛ ستنتقل إلى المستقرّ مع الإصدار التالي.

يمكن أن يكون المصدر خريطةً لا مصفوفةً. عندئذٍ يمرّ الاستيعاب على مدخلات الخريطة. وله شكلان — بمتغيّر واحد (المفتاح فقط) أو بمتغيّرين (فكّ الزوج):

متغيّر واحد:   [ لكل <مفتاح> في <خريطة> أنتج <ناتج> ]
متغيّران:      [ لكل <مفتاح>، <قيمة> في <خريطة> أنتج <ناتج> ]

بمتغيّر واحد يُربَط الاسم بكلّ مفتاح (لا القيمة):

متغير المفاتيح = [لكل مفتاح في {"أ": 1} أنتج مفتاح]
اطبع_سطر(المفاتيح)
[أ]

المصفوفات تطبع عناصرها النصّيّة بلا علامتَي اقتباس ([أ])، بخلاف مفاتيح الخريطة المقتبسة ({"أ": …}).

الفاصلة ، تُدخِل متغيّر القيمة (فكّ الزوج): يُربَط الأوّل بالمفتاح والثاني بالقيمة — على منوال حلقة لكل حين تمرّ على خريطة:

متغير القيم = [لكل مفتاح، قيمة في {"س": 5} أنتج قيمة]
اطبع_سطر(القيم)
[5]

ويعمل فكّ الزوج في الأنواع الثلاثة. مثال يعيد بناء قاموس بقِيَم مضاعفة:

متغير المضاعف = {لكل مفتاح، قيمة في {"أ": 3} أنتج مفتاح: قيمة * 2}
اطبع_سطر(المضاعف["أ"])
6

والشرط إذا — إن وُجد — يستطيع الإشارة إلى متغيّر القيمة:

متغير الكبيرة = [لكل مفتاح، قيمة في {"أ": 2، "ب": 5} إذا قيمة > 3 أنتج قيمة]
اطبع_سطر(طول(الكبيرة))
1

ترتيب المدخلات غير محدَّد. كحلقة لكل على الخرائط، لا تضمن اللغة ترتيب المرور على المدخلات. لنتيجةٍ حتميّة استعمل خريطةً بمفتاحٍ واحد، أو عمليّةً لا تعتمد على الترتيب (كالجمع أو طول)، أو رتّب النتيجة صراحةً.


قاموس أم مجموعة؟ قاعدة التمييز

كلاهما داخل { }؛ الفارق وجود : بعد الناتج:

الصياغةالنوع
{لكل س في مصدر أنتج ناتج}مجموعة (ناتج مفرد)
{لكل س في مصدر أنتج مفتاح: قيمة}قاموس

أخطاء شائعة

  • الترتيب القديم مرفوض: [س * 2 لكل س في القائمة] (الناتج قبل لكل) لم يعد صالحًا؛ استعمل [لكل س في القائمة أنتج س * 2].
  • نسيان أنتج: [لكل س في القائمة] خطأ نحويّ؛ رأس الحلقة يتطلّب أنتج <ناتج>.
  • موضع الشرط: إذا يسبق أنتج دائمًا: [لكل س في م إذا شرط أنتج ناتج].
  • فاصلة فكّ الزوج بلا اسم: [لكل م، في خريطة أنتج م] خطأ نحويّ؛ الفاصلة تتطلّب اسم متغيّر القيمة بعدها: [لكل م، ق في خريطة أنتج م].

انظر أيضًا

الدوال

تُعرَّف الدوال بكلمة دالة، وتُعيد القيم بـارجع. دالة الدخول للبرنامج اسمها رئيسية.

التعريف والاستدعاء

دالة اجمع(أ، ب)
    ارجع أ + ب
نهاية

دالة رئيسية()
    متغير الناتج = اجمع(3، 4)
    اطبع(الناتج)        # 7
نهاية

التصريح بالأنواع والمردود

دالة مربّع(س: رقم): رقم
    ارجع س * س
نهاية

ويُقبَل نوع المردود قبل الاسم أيضًا (صيغة بديلة مكافئة):

دالة رقم جمع(أ: رقم، ب: رقم)
    ارجع أ + ب
نهاية

دوال لامدا (تعبيريّة)

كلمة لامدا سياقيّة تُنشئ دالة مجهولة الاسم:

متغير ضاعِف = لامدا(س) ارجع س * 2 نهاية
اطبع(ضاعِف(5))          # 10

المولّدات وأنتج

دالة أعداد()
    أنتج 1
    أنتج 2
    أنتج 3
نهاية

الكلمات ذات الصلة: دالة، ارجع (محجوزتان)، ولامدا، أنتج، مولد، ترجع (سياقيّة). راجع الكلمات المحجوزة الأربعون.

البرمجة الكائنيّة

تدعم لغة ص الأصناف والبنى والتعدادات والوراثة والسمات وتحميل العوامل الزائد.

الأصناف

صنف شخص
    خاص الاسم: نص
    خاص العمر: رقم

    باني(الاسم، العمر)
        هذا.الاسم = الاسم
        هذا.العمر = العمر
    نهاية

    عام دالة تحيّة()
        ارجع "أنا " + هذا.الاسم
    نهاية
نهاية

دالة رئيسية()
    متغير ص = جديد شخص("ليلى"، 25)
    اطبع(ص.تحيّة())
نهاية
  • صنف يفتح الصنف، باني المُنشئ، هذا يشير إلى النسخة الحاليّة.
  • جديد يُنشئ نسخة.
  • محدّدات الوصول: عام، خاص، محمي؛ ومجرد للصنف/العضو المجرَّد.

الوراثة

صنف موظّف يرث شخص
    خاص الراتب: عشري

    باني(الاسم، العمر، الراتب)
        الأساس(الاسم، العمر)   # استدعاء باني الأب
        هذا.الراتب = الراتب
    نهاية
نهاية

يرث للوراثة، والأساس للوصول إلى الصنف الأب.

بنى وتعدادات

بنية نقطة
    س: رقم
    ص: رقم
نهاية

تعداد لون
    أحمر
    أخضر
    أزرق
نهاية

الخصائص وتحميل العوامل

كلمات سياقيّة مثل خاصية واحصل/عيّن (getter/setter)، وعامل لتحميل العوامل. راجع الكلمات المحجوزة الأربعون لكامل كلمات الكائنيّة.

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

تُنظَّم البرامج في وحدات، مع كلمات استورد، من، كـ، صدّر.

الاستيراد

استورد "رياضيات"                  # استيراد وحدة كاملة
استورد جذر، جا من "رياضيات"        # استيراد رموز محدّدة
استورد "رياضيات" كـ ر             # استيراد باسم بديل

التصدير

صدّر دالة مساحة_دائرة(نق)
    ارجع 3.14159 * نق * نق
نهاية

الكلمات

الكلمةالإنجليزيّةالدور
استوردimportجلب وحدة/رموز
منfromتحديد مصدر الرموز
كـasاسم بديل
صدّرexportإتاحة رمز للوحدات الأخرى

تشمل المكتبة القياسيّة وحدات core، io، math، string، network، graphics. راجع الكلمات المحجوزة الأربعون.

معالجة الأخطاء

تتبع لغة ص نموذج «حاول/امسك/أخيرًا» مع كلمة ارمي لإطلاق الأخطاء.

حاول / امسك / أخيرًا

حاول
    متغير الناتج = اقسم(10، 0)
    اطبع(الناتج)
امسك خطأ
    اطبع("حدث خطأ: " + خطأ.الرسالة)
أخيراً
    اطبع("انتهى التنفيذ")
نهاية
  • حاول يفتح الكتلة المحميّة.
  • امسك يلتقط الخطأ (مع ربطه باسم).
  • أخيراً يُنفَّذ دائمًا (نجح أو فشل).

إطلاق خطأ

دالة اقسم(أ، ب)
    إذا ب == 0
        ارمي "القسمة على صفر غير مسموحة"
    نهاية
    ارجع أ / ب
نهاية

الكلمات المحجوزة: حاول، امسك، ارمي، أخيراً. راجع الكلمات المحجوزة الأربعون.

التشفير والأمان

توفّر وحدة تأكيدات (تحتاج استيراد) دوال هاش وتشفير متماثل، إضافة إلى دوال التأكيد المعروفة (تأكد_يساوي وأخواتها).

استورد تأكيدات

هاش — SHA-256

اطبع_سطر(هاش("مرحبا"))

هاش(نص) يُرجع بصمة SHA-256 (FIPS 180-4) كنصّ ست عشريّ من 64 حرفًا، بصرف النظر عن طول المدخل. التنفيذ مطابق حرفيًّا بين المفسّر والمترجم — نفس المدخل يُنتج نفس الهاش على كلا المحرّكين دائمًا.

هاش("")     # e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
هاش("abc")  # ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

شفّر / فك_تشفير — SHA-256-CTR

متغير مشفّر = شفّر("سر", "مفتاح")
اطبع_سطر(فك_تشفير(مشفّر, "مفتاح"))   # سر

شفّر(نص، مفتاح) تشفير متماثل مبنيّ على SHA-256 بنمط العدّاد (CTR): مقطع عشوائي (nonce) من 8 بايت يُضاف لبداية الناتج، وكل كتلة 32 بايت من النصّ تُخفى بـSHA-256(مفتاح ‖ nonce ‖ عدّاد) كتيّار مفاتيح XOR. الناتج نصّ ست عشريّ، ويختلف مع كل استدعاء حتى لنفس المدخلات (بسبب الـnonce العشوائي) — لذا لا يصلح اختبار الناتج الخام حرفيًّا، بل التبادليّة:

فك_تشفير(شفّر(نص، مفتاح), مفتاح) == نص   # صحيح دائمًا

النصّ المشفّر بأحد المحرّكين (مفسّر/مترجم) يُفكّ بالآخر دون مشكلة — نفس الخوارزميّة بالضبط في الاثنين.

تنبيه أمنيّ: هذا تشفير متماثل بسيط (CTR بلا مصادقة/tag) وليس بديلًا عن معايير موثوقة كـAES-GCM عند الحاجة لمقاومة العبث (tampering). مناسب لإخفاء بيانات داخل تدفّق تتحكّم فيه، لا لتخزين أسرار حسّاسة عالية المخاطر.

ملاحظة تنفيذيّة

لا توجد وحدة stdlib/crypto منفصلة قائمة على OpenSSL — هذه الدوال مُنفَّذة ذاتيًّا (self-rolled) داخل وقت التشغيل المشترك بين المفسّر والمترجم، لتبقى الوحدة قابلة للعمل حتى في أهداف الوضع الحرّ (freestanding) التي لا يمكنها الربط بمكتبات نظام تشغيل مضيف.

وحدة تشفير — المكتبة الموسَّعة

وحدة تشفير (منفصلة عن تأكيدات أعلاه) توفّر مكتبة تشفير حديثة أوسع: هاش/مصادقة (BLAKE3)، اشتقاق مفاتيح (PBKDF2/HKDF/Argon2id)، تشفير موثَّق (AEAD)، وتبادل مفاتيح + تواقيع رقميّة على منحنى Curve25519 (X25519/Ed25519). كل الدوال ذاتيّة التنفيذ بالكامل (بلا OpenSSL) فتعمل على هدف الوضع الحرّ كذلك، ومطابقة حرفيًّا بين المفسّر والمترجم — نفس المدخل يُنتج نفس المخرَج عبر كلا المحرِّكين دائمًا، ومُتحقَّقة مقابل شعاعات الاختبار الرسميّة لكل معيار (RFC/مسابقة قياسيّة).

استورد تشفير

بلايك3 / هاش_مفتاح — BLAKE3

اطبع_سطر(بلايك3("مرحبا"))
اطبع_سطر(هاش_مفتاح("رسالة", "سرّ"))

بلايك3(نص) يُرجع هاش BLAKE3 (256 بت) كسلسلة ست عشريّة من 64 حرفًا — أحدث وأسرع من هاش (SHA-256)، ومُتحقَّق مقابل شعاعات BLAKE3 الرسميّة.

هاش_مفتاح(رسالة، مفتاح) مصادقة رسالة (MAC) عبر نمط BLAKE3 المُفتاح الأصيل — أبسط من HMAC التقليديّ لأنّ الحماية من هجمات امتداد الطول جزء من تصميم الخوارزميّة نفسها، لا طبقة إضافيّة. إن كان طول المفتاح 32 بايت يُستعمَل مباشرة، وإلّا يُشتقّ منه مفتاح 32 بايت عبر بلايك3(مفتاح) أوّلًا.

اشتق_مفتاح_مرور / اشتق_مفتاح / أرجون2 — اشتقاق المفاتيح (KDF)

ثلاث دوال اشتقاق مفتاح لأغراض مختلفة — لا تبادل بينها:

اطبع_سطر(اشتق_مفتاح_مرور("كلمة_سرّ", "ملح", 100000))
اطبع_سطر(اشتق_مفتاح("سرّ_مشترك", "ملح", "سياق", 16))
اطبع_سطر(أرجون2("كلمة_سرّ", "ملح_عشوائي_٨_بايت_فأكثر", 65536, 3))
الدالّةالمعيارالغرض
اشتق_مفتاح_مرور(كلمة_المرور، ملح، عدد_التكرارات)PBKDF2-HMAC-SHA256 (RFC 2898/8018)إبطاء زمنيّ فقط؛ عدد_التكرارات معامل تحكّم صريح (يُنصح بـ100000 فأكثر)
اشتق_مفتاح(سرّ، ملح، سياق، الطول)HKDF-SHA256 (RFC 5869)توسيع/تقسيم سرّ (مثل ناتج تبادل_مفتاح) إلى مفاتيح فرعيّة مستقلّة بالسياق؛ الطول بين 1 و8160 بايت
أرجون2(كلمة_المرور، ملح، تكلفة_الذاكرة، عدد_التكرارات)Argon2id (RFC 9106)إبطاء زمنيّ وذاكريّ معًا — مقاومة أقوى لتسريع الاختراق بعتاد مخصَّص (ASIC/GPU) من PBKDF2؛ تكلفة_الذاكرة بالكيلوبايت (8 فأكثر، يُنصح بعشرات الآلاف لكلمات المرور)، الملح 8 بايت على الأقلّ

استعمل اشتق_مفتاح_مرور أو أرجون2 لاشتقاق مفتاح من كلمة مرور (بطء مقصود لمقاومة التخمين)، واشتق_مفتاح لتوسيع سرّ عشوائيّ موجود أصلًا (كناتج تبادل مفاتيح) إلى عدّة مفاتيح مستقلّة — لا لكلمات مرور.

تنبيه: جميع هذه الدوال تفشل بخطأ صريح على بارامترات خارج الحدود الآمنة الموصى بها في المعيار المرجعيّ (مثلًا عدد_التكرارات صفر، أو تكلفة_الذاكرة أقلّ من 8، أو ملح أقصر من 8 بايت لـأرجون2)، لا تنفّذ بصمت بقيم ضعيفة.

شفر_موثق / فك_تشفير_موثق — تشفير موثَّق (AEAD)

متغير مغلف = شفر_موثق("سرّ حسّاس", "مفتاح_كلمة_مرور")
اطبع_سطر(فك_تشفير_موثق(مغلف, "مفتاح_كلمة_مرور"))

شفر_موثق/فك_تشفير_موثق تشفير موثَّق (AEAD) عبر ChaCha20-Poly1305 (RFC 8439) — بخلاف شفّر/فك_تشفير أعلاه (تشفير بلا مصادقة)، ينتج شفر_موثق وسم مصادقة Poly1305 يكشف أيّ عبث بالنصّ المشفَّر عند فكّه. المفتاح: يُستعمَل مباشرةً إن كان 32 بايت، وإلّا يُشتقّ منه مفتاح عبر SHA-256. يُولَّد nonce عشوائيّ جديد لكلّ استدعاء، فتشفير النصّ نفسه مرّتين ينتج مغلَّفين مختلفين — سلوك مقصود لا خلل.

⚠️ فشل المصادقة يتباعد بين المحرِّكين عمدًا: عند مفتاح خاطئ أو مغلَّف مُعبَث به، المفسّر يرمي خطأً قابلًا للالتقاط بـحاول/امسك؛ المترجم يفشل مُغلَقًا (fail-closed) — رسالة عامّة على stderr ثمّ إنهاء البرنامج، لأنّ وقت تشغيل المترجم لا يملك اليوم مسار استثناء قابلًا للالتقاط من كود C. الاثنان لا يُرجعان أبدًا نصًّا مُحرَّفًا صامتًا — فقط آليّة الإبلاغ عن الفشل تختلف.

ولّد_مفتاح_خاص_x25519 / اشتق_مفتاح_عام_x25519 / تبادل_مفتاح — تبادل مفاتيح X25519

متغير أ_خاص = ولّد_مفتاح_خاص_x25519()
متغير ب_خاص = ولّد_مفتاح_خاص_x25519()
متغير ب_عام = اشتق_مفتاح_عام_x25519(ب_خاص)
متغير سرّ_مشترك = تبادل_مفتاح(أ_خاص, ب_عام)
اطبع_سطر(اشتق_مفتاح(سرّ_مشترك, "ملح", "جلسة", 32))

تبادل مفاتيح ديفي-هيلمان على منحنى Curve25519 (X25519، RFC 7748):

  • ولّد_مفتاح_خاص_x25519() — يولّد مفتاحًا خاصًّا عشوائيًّا جديدًا (32 بايت).
  • اشتق_مفتاح_عام_x25519(مفتاح_خاص) — يشتقّ المفتاح العامّ المقابل حتميًّا.
  • تبادل_مفتاح(مفتاح_خاص، مفتاح_عام_الطرف_الآخر) — يُنتج سرًّا مشتركًا 32 بايت يتّفق عليه الطرفان دون تبادله مباشرة.

السرّ الخامّ لا يُستعمَل مفتاحًا مباشرةً عادةً — مرّره عبر اشتق_مفتاح (HKDF) أوّلًا. فحص أمنيّ إلزاميّ (RFC 7748 §6.1): تبادل_مفتاح يرفض بخطأ صريح أيّ سرّ مشترك كلّه أصفار (ناتج ممكن عن مفاتيح عامّة خبيثة منخفضة الرتبة).

ولّد_مفتاح_خاص_توقيع / اشتق_مفتاح_عام_توقيع / وقّع / تحقق_توقيع — تواقيع Ed25519

متغير خاص = ولّد_مفتاح_خاص_توقيع()
متغير عام = اشتق_مفتاح_عام_توقيع(خاص)
متغير توقيع = وقّع("رسالة مهمّة", خاص)
اطبع_سطر(تحقق_توقيع("رسالة مهمّة", توقيع, عام))   # صحيح

توقيع رقميّ عبر Ed25519 (RFC 8032، مبنيّ على SHA-512 ذاتيّ التنفيذ):

  • ولّد_مفتاح_خاص_توقيع() — بذرة مفتاح خاصّ عشوائيّة جديدة.
  • اشتق_مفتاح_عام_توقيع(مفتاح_خاص) — المفتاح العامّ المقابل حتميًّا.
  • وقّع(رسالة، مفتاح_خاص) — توقيع حتميّ 64 بايت (لا عشوائيّة — نفس الرسالة والمفتاح يُنتجان دومًا نفس التوقيع).
  • تحقق_توقيع(رسالة، توقيع، مفتاح_عام)دالّة استعلام لا بوّابة: تُرجع صحيح/خطأ فقط، ولا ترمي استثناءً ولا تُنهي البرنامج على توقيع فاسد أو مدخل مشوَّه — الغرض أصلًا فحص مدخلات غير موثوقة بأمان.

ملاحظة تنفيذيّة (وحدة تشفير)

كل دوال وحدة تشفير مُنفَّذة ذاتيًّا (self-rolled، بلا OpenSSL/libsodium) داخل وقت التشغيل المشترك، ومُتحقَّقة كلّ واحدة مقابل شعاعات الاختبار الرسميّة لمعيارها (BLAKE3-team، RFC 2898/5869/7748/8032/8439/9106، ومقابل libargon2/hashlib بايثون لـأرجون2/اشتق_مفتاح_مرور).

التزامن: أطلق والقنوات

تقدّم لغة ص تزامنًا على نمط Go: خيوط خفيفة تُطلَق بكلمة أطلق، وتتواصل عبر قنوات بدل الذاكرة المشتركة، مع أدوات مزامنة (مجموعة انتظار، قفل، مستقبل) وجملة اختر للاختيار بين قنوات.

الخيوط الخفيفة: أطلق

تُطلق أطلق استدعاءَ دالّة أو كتلةً كاملة في خيط خفيف يعمل بالتوازي:

دالة حساب_مربع(ق، قيمة)
    ق.أرسل(قيمة * قيمة)
نهاية

متغير ق = قناة(5)
أطلق حساب_مربع(ق، 3)
أطلق حساب_مربع(ق، 4)

انتظر_الكل()

وبصيغة الكتلة (تنتهي بـنهاية):

متغير م = مستقبل()

أطلق
    متغير مجموع = 0
    لكل ن في 1..10
        مجموع = مجموع + ن
    نهاية
    م.عيّن(مجموع)
نهاية

اطبع_سطر(م.احصل())
55
  • انتظر_الكل() تحجب حتى تنتهي كلّ الخيوط المُطلَقة.
  • الترتيب غير مضمون بين الخيوط — اجمع النتائج عبر قناة ثم رتّبها إن لزم الترتيب.

⚠️ تباعُد مترجم مفتوح (ISSUE-072): أطلق بسطرٍ واحد يُرسِل مباشرةً عبر قناة (أطلق ق.أرسل(4)) لا يُطلق الخيط في المترجم (بينما يعمل في المفسّر)؛ استعمل صيغة الكتلة أطلق ... نهاية التي تعمل مزدوجًا بثبات.

القنوات

القناة أنبوب FIFO آمن بين الخيوط، تُنشأ بـقناة(سعة) (قناة مخزّنة بسعةٍ محدّدة):

متغير ق = قناة(5)

ق.أرسل(10)
ق.أرسل(20)
ق.أرسل(30)

اطبع_سطر(ق.استقبل())
اطبع_سطر(ق.استقبل())
اطبع_سطر(ق.الحجم())
اطبع_سطر(ق.فارغة())
10
20
1
خطأ
الطريقةالمعنى
أرسل(قيمة)إرسال إلى القناة
استقبل()استقبال (بترتيب الإرسال FIFO)
الحجم()عدد العناصر المنتظرة
فارغة()هل القناة فارغة؟
أغلق() / مغلقة()إغلاق القناة / فحص الإغلاق
حاول_ارسل(قيمة) / حاول_استقبل()إرسال/استقبال غير حاجب
أرسل_بمهلة(قيمة، مللي) / استقبل_بمهلة(مللي)إرسال/استقبال بمهلة قصوى
السعة()سعة القناة القصوى

نمط شائع — إرسال ثم إغلاق ثم تفريغ:

متغير ق = قناة(5)
ق.أرسل(1)
ق.أرسل(2)
ق.أغلق()

بينما (ليس ق.فارغة())
    اطبع_سطر(ق.استقبل())
نهاية

الاختيار بين القنوات: اختر

تنتقي اختر أوّل فرعٍ قناتُه جاهزة — نظير select في Go:

متغير ق = قناة(1)
ق.أرسل(1)

اختر
    عندما ق.استقبل():
        اطبع_سطر("جاهز")
نهاية

أدوات المزامنة

مجموعة الانتظار

عدّاد مهامّ: أضف(n) قبل الإطلاق، وأنهي() من كلّ خيط عند اكتماله، وانتظر() تحجب حتى يصل العدّاد إلى الصفر:

متغير مج = مجموعة_انتظار()
متغير ق = قناة(100)

مج.أضف(50)
لكل _ في 1..50
    أطلق
        ق.أرسل(1)
        مج.أنهي()
    نهاية
نهاية

مج.انتظر()
اطبع_سطر(ق.الحجم())
50

القفل

قفل استبعاد متبادل (mutex) لحماية حالة مشتركة:

متغير ق_ف = قفل()
اطبع_سطر(ق_ف.مقفل())
ق_ف.اقفل()
اطبع_سطر(ق_ف.مقفل())
ق_ف.افتح()
خطأ
صحيح

كما تتوفّر حاول_قفل() — محاولة قفل غير حاجبة تُرجع نجاحها فورًا.

فضّل تمرير البيانات عبر القنوات على مشاركة الحالة خلف قفل — على المأثور الشائع في مجتمع Go: «لا تتواصل بمشاركة الذاكرة؛ شارك الذاكرة بالتواصل».

المستقبل

قيمة واحدة تُنتَج لاحقًا: عيّن(قيمة) من الخيط المُنتِج، واحصل() تحجب حتى الجاهزيّة، وجاهز() فحص غير حاجب:

متغير م = مستقبل()
اطبع_سطر(م.جاهز())
م.عيّن(42)
اطبع_سطر(م.جاهز())
اطبع_سطر(م.احصل())
خطأ
صحيح
42

غير المتزامن غير_متزامن/انتظر

إلى جانب نمط Go توجد كلمتا غير_متزامن (async) وانتظر (await) للدوالّ غير المتزامنة — راجع ميزات متقدّمة.

ميزات متقدّمة

تتجاوز لغة ص الأساسيّات إلى ميزات حديثة: القوالب، المولّدات، إدارة الموارد، الماكرو، العقود، وغيرها. هذا الفصل تعريفيّ؛ وللتزامن (أطلق/القنوات/اختر) فصلٌ مستقلّ في التزامن.

القوالب (الأنواع العامّة)

قالب يكتب دالةً أو صنفًا يعمل على أنواعٍ متعدّدة دون تكرار؛ يسبقه معاملُ نوعٍ واحد على الأقلّ بين <...>:

قالب <نوع ت>
دالة هوية(ت س)
    ارجع س
نهاية

اطبع_سطر(هوية(7))          // استنتاج النوع
اطبع_سطر(هوية<رقم>(4))     // تخصيص صريح

ويدعم القوالب الثابتة (const-generics) بقيمةٍ ثابتة بدل نوع:

قالب <ثابت رقم ن>
دالة الحجم()
    ارجع ن
نهاية
اطبع_سطر(الحجم<3>())      // 3

وتُقيَّد معاملات النوع بجملة حيث:

قالب <نوع ت>
دالة الأكبر(ت أ، ت ب) حيث ت: مقارن
    ...
نهاية

⚠️ تباعُد مترجم مفتوح (ISSUE-071): التخصيص الصريح بوسيطٍ نصّيّ هوية<نص>("ن") يُرجع قيمةً خاطئة في المترجم بينما ن في المفسّر؛ التخصيص بوسيطٍ رقميّ يعمل مزدوجًا.

المولّدات: مولد وأنتج

الدالة المسبوقة بـمولد تُنتج قيمًا كسولةً عبر أنتج، وتُستهلَك بحلقة لكل:

مولد دالة عدّ()
    أنتج 1
    أنتج 2
    أنتج 3
نهاية

لكل ع في عدّ()
    اطبع_سطر(ع)          // 1، 2، 3
نهاية

بادئة مولد إلزاميّة: أنتج صالحةٌ فقط داخل دالةٍ مسبوقةٍ بـمولد — لا في دالةٍ عاديّة ولا في المستوى الأعلى. وتُستعمَل أنتج أيضًا لفصل رأس الحلقة عن الناتج في الاستيعابات.

إدارة الموارد: باستخدام وأجّل

باستخدام كتلةُ سياقٍ لموردٍ يُغلَق عند الخروج؛ الاسم المستعار بعد كـ اختياريّ، والكتلة تُغلَق بـنهاية:

باستخدام 5 كـ م
    اطبع_سطر(م)
نهاية

(في الاستعمال الحقيقيّ يكون المورد كائنًا يُنفّذ بروتوكول السياق فيُغلَق تلقائيًّا.)

أجّل يؤجّل تنفيذ جملةٍ (أو كتلة) إلى خروج الدالة، بترتيب LIFO (الأخير أوّلًا) — مثاليّ للتنظيف المضمون:

دالة عالِج()
    أجّل اطبع_سطر("أُغلِق")   // يُنفَّذ آخرًا
    اطبع_سطر("عُولِج")
نهاية
عالِج()                        // عُولِج ثمّ أُغلِق

الماكرو: ماكرو

يُعرَّف بـماكرو ويُستدعى بعلامة تعجّبٍ ! تميّزه عن الدالة:

ماكرو ضِعف(س)
    ارجع س * 2
نهاية
اطبع_سطر(ضِعف!(21))          // 42

استدعاؤه بلا ! يُعامَل دالةً غير معرّفة (خطأ دلاليّ) — العلامة إلزاميّة.

العقود: عقد

عقد يُعرّف نوعًا شبيهًا بالصنف (بأعضاء وطرائق، ويدعم يرث) بدلالة «العقد الذكيّ»:

عقد محفظة
    متغير عام رصيد = 0
    دالة عام إيداع(مبلغ)
        هذا.رصيد = هذا.رصيد + مبلغ
    نهاية
نهاية

متغير م = محفظة()
م.إيداع(50)
اطبع_سطر(م.رصيد)              // 50

معاملات العمر (Lifetimes)

تعليقُ عمرٍ يبدأ بفاصلةٍ عليا ، يُوسَم على البنى والدوال لتتبّع الاستعارة:

بنية مرجع<'أ>
    رقم قيمة = 0
نهاية

اختبار الخصائص: اختبر

كتلةُ اختبارٍ قائمٍ على الخصائص، الأقواس حول الاسم إلزاميّة، مع تكرارات/بذرة اختياريّتين:

استورد تأكيدات
اختبر("الجمع تبادليّ") تكرارات 100
    تأكد_صحيح(1 + 2 == 2 + 1)
نهاية

(دوال التأكيد في وحدة تأكيدات ⇒ تلزم استورد تأكيدات أوّلًا.)

الواجهة والبرمجة الأجنبيّة

  • الواجهة (SadUI): واجهة/@حالة/اعرض لبناء واجهات تفاعليّة — راجع خصائص واجهة SadUI والتخطيط.
  • الربط الأجنبيّ (FFI، تجريبيّ): خارجي "C" لاستدعاء دوالٍ أصليّة.

الكلمات السياقيّة المتقدّمة

أغلب ما سبق كلماتٌ سياقيّة (لا محجوزة): قالب، مولد، أنتج، باستخدام، أجّل، ماكرو، عقد، اختبر، حيث، انتظر — يجوز استعمالها أسماءً خارج سياقها. (أمّا خارجي فكلمةٌ محجوزة.) راجع الكلمات المحجوزة الأربعون للتمييز.

أدوات لغة ص — نظرة عامّة

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

الأداةالدورالصفحة
sad-runالمفسّر — تنفيذ ملفّات مباشرةًالتشغيل والترجمة
sad-buildالمترجم — ترجمة إلى ملفّ تنفيذيّ أصليّ (LLVM)التشغيل والترجمة
sad-pkgمدير الحزم — تثبيت الاعتماديّات ونشر الحزممدير الحزم
sad-fmtالمنسّق — تنسيق الشيفرة تلقائيًّا وفق أسلوب موحَّدالجودة
sad-checkالفاحص الساكن — فحص الملكيّة والأنواع دون تشغيلالجودة
sad-lspخادم اللغة — إكمال وتشخيص داخل المحرّرات (بروتوكول LSP)الجودة

المحرّكان متكافئان سلوكيًّا: البرنامج الواحد يعطي المخرجات نفسها مفسَّرًا (sad-run) ومُترجَمًا (sad-build) — تحرسه بوّابة مطابقة آليّة في كلّ تغيير.

أوّل تشغيل

sad-run برنامجي.ص          # تنفيذ فوريّ بالمفسّر
sad-build برنامجي.ص -o برنامجي   # ترجمة إلى تنفيذيّ أصليّ
./برنامجي                   # تشغيل الناتج المُترجَم (على Windows: .\برنامجي.exe)

أين أجد الأدوات؟

بعد بناء المستودع تجدها في build/bin/Release/ (والمنسّق python x.py build يثبّت المحرّكين sad-run/sad-build تحديدًا في dist/<Config>/). راجع التثبيت والتشغيل.

التشغيل والترجمة: sad-run وsad-build

المفسّر sad-run

ينفّذ ملفّ مباشرةً — أسرع طريق أثناء التطوير:

sad-run برنامجي.ص

أوضاع الذاكرة الموحَّدة

الرايةالمرادف العربيّالمعنى
--gcجامع قمامة، فحوص الملكيّة معطَّلة (الافتراضيّ)
--prod--إنتاجملكيّة صارمة بلا جامع قمامة
--learn--تعلميشرح انتهاكات الملكيّة دون إيقاف — مناسب للتعلّم
--auto--تلقائياختيار تلقائيّ بحسب البيئة
--gc=<strategy>استراتيجيّة الجامع: tracing أو refcount أو none
--ملكية=<level>مستوى الملكيّة: disabled/warnings/strict/ultra
--no-std--نواةوضع بلا مكتبة قياسيّة (freestanding)

رايات التحليل والتشخيص

الرايةالمرادف العربيّالمعنى
--ownership--ملكيةتفعيل نظام الملكيّة
--type-check--فحص-أنواعفحص الأنواع
--strict-types--أنواع-صارمةفحص أنواع صارم
--security--أمانفحوص الأمان
--profile--تنميطتنميط الأداء (مع --profile-format=/--profile-output=/--profile-top=)
--hot-reload--مراقبةإعادة تحميل ساخنة عند تغيّر الملفّ
--docs--وثّقاستخراج توثيق ## (مع --docs-out=/--docs-project=/--docs-format=)
--explain[=<مستوى>]شرح الأخطاء: brief/normal/detailed/teacher (الافتراضيّ detailed)
--lang=<لغة>لغة الرسائل: ar أو en أو both
--debug-serverخادم تنقيح بواجهة DAP (للمحرّرات)

المترجم sad-build

يترجم إلى ملفّ تنفيذيّ أصليّ عبر LLVM — لا يحتاج الناتجُ وقتَ تشغيل خارجيًّا يُثبَّت:

sad-build برنامجي.ص -o برنامجي        # ترجمة وربط
sad-build برنامجي.ص -O3 -o برنامجي    # بأقصى تحسين
sad-build برنامجي.ص -c -o جزء.o       # ترجمة فقط (بلا ربط)
sad-build *.o -o برنامجي              # ربط ملفّات كائنيّة

أهمّ الخيارات

المجموعةالخيارات
الإخراج-o <ملفّ> · -c · -S (تجميعيّ) · --emit-llvm · --emit-bc
التحسين-O0-O3 (الافتراضيّ -O2) · -Os (الحجم) · --lto/--lto=full · --lto=thin
التنقيح-g · --emit-ast · --emit-sir · --time-passes
الأخطاء--explain[=brief|normal|detailed|teacher] (الافتراضيّ detailed) · --lang=ar|en|both
الربط-L<مسار> · -l<مكتبة> · --static · -T<سكربت-ربط>
الهدف--target=<ثلاثيّة> · --freestanding (بلا نظام تشغيل)

استخراج التوثيق

المترجم يستخرج تعليقات التوثيق ## إلى Markdown أو JSON أو HTML:

sad-build --docs برنامجي.ص                       # إلى stdout
sad-build --وثّق --docs-out=دليل.md برنامجي.ص     # إلى ملفّ
sad-build --docs-project=مشروعي/ --docs-format=html   # مشروع كامل

وضع الأنظمة (freestanding)

لبرمجة النوى والعتاد بلا مكتبة قياسيّة:

sad-build --freestanding --no-main --abort-on-panic \
          --linker-script=kernel.ld نواتي.ص -o نواتي.elf

مع --entry-point=<اسم> لنقطة دخول مخصّصة و--allow-alloc للسماح بالتخصيص الديناميكيّ. والراية --no-std مكافئة تمامًا لـ--freestanding في المترجم.

مدير الحزم: sad-pkg وsad-build pkg

طريقان لإدارة الحزم: الأداة المستقلّة sad-pkg (الكاملة)، وتكامل مدير الحزم داخل المترجم sad-build pkg (الأوامر الأساسيّة بأسماء عربيّة). تعرض مساعدة التكامل الاسم التاريخيّ sadc — وهو نفسه الثنائيّ sad-build.

الأداة المستقلّة sad-pkg

أوامر المشروع

الأمرالمعنى
initإنشاء حزمة جديدة (ملفّ تعريف الحزمة)
install [حزمة]تثبيت الاعتماديّات (أو حزمة بعينها)
add <حزمة> [إصدار]إضافة اعتماديّة
remove <حزمة> (أو rm)إزالة اعتماديّة
update (أو upgrade)تحديث الاعتماديّات كلّها
list (أو ls)سرد المثبَّت
verifyالتحقّق من سلامة المثبَّت

أوامر السجلّ

الأمرالمعنى
search <نصّ>البحث في السجلّ المركزيّ
info <حزمة>معلومات حزمة
publish [--local]نشر حزمة (يتطلّب رمز نشر — انظر أدناه)

أوامر مساعدة

الأمرالمعنى
config <مفتاح> [قيمة]قراءة/ضبط الإعدادات (المفتاحان: registry وtoken)
doctorتشخيص البيئة
cleanتنظيف الخبيئة

عنوان السجلّ المركزيّ

الافتراضيّ https://sila-hub.dev (عبر HTTPS). ويمكن تغييره بثلاث طبقات، الأعلى أسبقيّةً أوّلًا:

🚧 القناة القادمة: قراءة sad-pkg لمتغيّر البيئة SAD_REGISTRY_URL (الطبقة 1) متوفّرة في القناة القادمة (/next/) وتنتقل إلى المستقرّ مع الإصدار التالي. أمّا sad-build pkg فيقرؤه في المستقرّ أيضًا، والطبقتان 2 و3 مستقرّتان.

  1. متغيّر البيئة SAD_REGISTRY_URL — الأنسب للتجارب وبيئات CI:

    SAD_REGISTRY_URL=http://localhost:3000 sad-pkg search رياضيات
    

    (صيغة السطر أعلاه لصدفات POSIX؛ في PowerShell: $env:SAD_REGISTRY_URL = "http://localhost:3000" ثمّ نفّذ الأمر.)

  2. الإعداد الدائم عبر config:

    sad-pkg config registry https://سجلّي-الخاصّ.example
    
  3. الافتراضيّ المضمَّن في الأداة.

النشر ورمز الاعتماد

النشر إلى السجلّ يتطلّب رمزًا (token) يُضبط مرّة واحدة:

sad-pkg config token <الرمز>
sad-pkg publish

⚠️ لا تضع الرمز في ملفّات المشروع أو سكربتاته المتتبَّعة — يُقرأ من الإعداد المحلّيّ (خارج المستودع) أو من متغيّر البيئة SAD_TOKEN في CI.

تكامل المترجم sad-build pkg

الأوامر الأساسيّة نفسها من داخل المترجم، وبأسماء عربيّة:

الأمرالمرادف العربيّالمعنى
install <حزمة>تثبيتتثبيت من السجلّ المركزيّ (مع --version <إصدار> اختياريًّا)
listسردسرد المثبَّت محلّيًّا
syncمزامنةمزامنة الحزم من ملفّ sad.toml
search <نصّ>بحثالبحث في السجلّ
sad-build pkg تثبيت شبكة-http
sad-build pkg install sad-math --version 1.2.0
sad-build pkg سرد
sad-build pkg مزامنة

ويحترم sad-build pkg متغيّر البيئة SAD_REGISTRY_URL نفسه لتجاوز عنوان السجلّ.

أين تُخزَّن الحزم؟

  • حزم المشروع: في مجلّد حزم/ داخل المشروع (لكلّ حزمة ملفّ تعريف package.json أو حزمة.صم ومصادرها).
  • الخبيئة العامّة: في مجلّد بيانات المستخدم (sad-lang/cache) — نظّفها بـsad-pkg clean.

أدوات الجودة: sad-fmt وsad-check وsad-lsp

المنسّق sad-fmt

ينسّق شيفرة تلقائيًّا وفق أسلوب موحَّد — ملفًّا واحدًا أو مجلّدًا كاملًا:

sad-fmt برنامجي.ص           # تنسيق ملفّ (كتابة في المكان)
sad-fmt src/                # تنسيق مجلّد تكراريًّا
sad-fmt --check src/        # فحص فقط دون كتابة (لبوّابات CI)
sad-fmt --diff برنامجي.ص    # عرض الفرق دون كتابة
الخيارالمعنى
--check <مسار>فحص الالتزام دون تعديل — يفشل إن وُجد ما يحتاج تنسيقًا
--diff <مسار>عرض الفروق المقترحة
--stdinالقراءة من الدخل القياسيّ (تكامل المحرّرات)
--config <ملفّ> / --initملفّ إعداد مخصّص / إنشاء الإعداد الافتراضيّ
--compact / --verboseتطبيق نمط مضغوط / مفصَّل
--dry-run <مجلّد>تجربة على مجلّد دون كتابة

الفاحص الساكن sad-check

يفحص الملكيّة والأنواع دون تشغيل البرنامج — يلتقط أصنافًا من الأخطاء قبل أوانها، وهو الأنسب لبوّابات CI:

sad-check برنامجي.ص
sad-check src/ --recursive --summary   # مجلّد كامل بمخرَج CI مختصر
الخيارالمعنى
-r, --recursiveفحص كلّ ملفّات في المجلّد
--summaryمخرَج إحصائيّ مختصر (مناسب لـCI)
--jsonالنتائج بصيغة JSON (للأتمتة)
--explainملاحظة سياق إضافيّة حول كلّ خطأ
-w, --watchإعادة الفحص عند تغيّر الملفّات
-q, --quietكتم رسائل النجاح
--no-colorتعطيل ألوان ANSI

رموز الخروج: 0 سليم · 1 أخطاء ملكيّة/تحليل · 2 فشل قراءة · 3 استخدام خاطئ لسطر الأوامر — اربطها ببوّابة CI مباشرة.

خادم اللغة sad-lsp

خادم بروتوكول خادم اللغة (LSP) يمنح المحرّرات (VS Code وغيرها) الإكمالَ التلقائيّ والتشخيصات والتنقّل للتعريف — يعمل تحليلًا ساكنًا على قلب اللغة نفسه (المعجم والمحلّل ونظام الأنواع من مصدر الحقيقة الموحَّد)، فلا ينفّذ شيفرتك أبدًا.

يشغّله المحرّر تلقائيًّا عبر إضافة لغة ص؛ لا يحتاج تشغيلًا يدويًّا في الاستعمال الاعتياديّ.

الكلمات المحجوزة الأربعون

تُصنِّف لغة ص كلماتها بحسب طريقة معالجة المعجمي (Lexer) لها:

الفئةالعددسلوك المعجميصالحة كاسم متغيّر؟
محجوزة (reserved)40يُصدر KEYWORD_*
عوامل منطقيّة (operators)3يُصدر OP_*
سياقيّة (contextual)43يُصدر IDENTIFIER (يقرّره المحلّل)
أنواع مدمجة (builtin)11يُصدر IDENTIFIER

المصدر: language-truth/keywords.yaml — المصدر الوحيد المطلق.


الكلمات المحجوزة (40)

تُصدرها المعجمي رمزًا خاصًّا، ولا يجوز استعمالها أسماءً.

الدوال والبنيات والأصناف (11)

الكلمةالإنجليزيّةبدائل
دالةfunction
ارجعreturn
صنفclass
بنيةstruct
تعدادenum
يرثinherits
نهايةend
جديدnew
هذاthis
بانيconstructor
الأساسsuper

التحكّم في التدفّق (7)

الكلمةالإنجليزيّةبدائل
إذاifاذا
وإلاelseوالا
بينماwhile
لكلfor
فيin
توقفbreak
استمرcontinue

مطابقة الأنماط (3)

الكلمةالإنجليزيّةبدائل
طابقmatch
عندماwhen
افتراضيdefault

معالجة الأخطاء (4)

الكلمةالإنجليزيّةبدائل
حاولtry
امسكcatch
ارميthrow
أخيراًfinallyأخيرا

التحكّم بالوصول (4)

الكلمةالإنجليزيّةبدائل
عامpublic
خاصprivate
محميprotected
مجردabstract

الوحدات (4)

الكلمةالإنجليزيّةبدائل
استوردimport
منfrom
كـas
صدّرexportصدر

المتغيّرات (4)

الكلمةالإنجليزيّةبدائل
متغيرvar
ثابتconst
ساكنstatic
خارجيexternخارجية

القيم الحرفيّة (3)

الكلمةالإنجليزيّةبدائل
صحيحtrue
خطأfalse
لاشيءnull

العوامل المنطقيّة (3)

تُلفظ كلماتٍ، يُصدرها المعجمي رموز عوامل، ولا تُستعمل أسماءً.

الكلمةالإنجليزيّة
وand
أوor
ليسnot

الكلمات السياقيّة (لمحة)

كلمات يُصدرها المعجمي مُعرِّفات، ويميّزها المحلّل بحسب الموضع — فيجوز استعمالها أسماءَ متغيّرات خارج سياقها. أمثلة: مؤكد، خاصية، احصل، عيّن، هدم، عامل، رئيسية، محكم، ترجع، حالة، غير_متزامن، انتظر، لامدا، أنتج.

للقائمة الكاملة راجع language-truth/keywords.yaml.

انظر أيضًا

العوامل والأسبقيّة

جميع عوامل لغة ص مرتّبةً حسب الأسبقيّة: الدرجة 1 هي الأعلى (تُحسَب أوّلًا) و15 هي الأدنى. الترابط يحدّد اتجاه التجميع عند تساوي الأسبقيّة.

المصدر: language-truth/operators.yaml — المشتقّ من ترتيب الأسبقيّة الفعليّ في المحلّل.

الأسبقيّةالعاملالاسمالترابطالفئةالنوعيّة
1مؤكد / مؤكدةتأكيد عدم الفراغيسارأمان العدمأحاديّ
1.وصول للعضويساروصولثنائيّ
1[]وصول بالفهرسيساروصولثنائيّ
1()استدعاء دالةيساروصولثنائيّ
2؟.وصول آمنيسارأمان العدمثنائيّ
2**أسّيمينحسابيّثنائيّ
3!نفي منطقييمينمنطقيّأحاديّ
3ليسليس (كلمة)يمينمنطقيّأحاديّ
3-نفي حسابييمينحسابيّأحاديّ
3~نفي بتّييمينبتّيّأحاديّ
3++زيادةيمينحسابيّأحاديّ
3--نقصانيمينحسابيّأحاديّ
4*ضربيسارحسابيّثنائيّ
4/قسمةيسارحسابيّثنائيّ
4//قسمة صحيحةيسارحسابيّثنائيّ
4%باقي القسمةيسارحسابيّثنائيّ
5+جمعيسارحسابيّثنائيّ
5-طرحيسارحسابيّثنائيّ
6<<إزاحة يساريساربتّيّثنائيّ
6>>إزاحة يمينيساربتّيّثنائيّ
7<أصغر منيسارمقارنةثنائيّ
7<=أصغر من أو يساوييسارمقارنةثنائيّ
7>أكبر منيسارمقارنةثنائيّ
7>=أكبر من أو يساوييسارمقارنةثنائيّ
7فيعضويةيسارعضويّةثنائيّ
7..نطاقبلاعضويّةثنائيّ
8==يساوييسارمقارنةثنائيّ
8!=لا يساوييسارمقارنةثنائيّ
9&و البتّييساربتّيّثنائيّ
10^XOR البتّييساربتّيّثنائيّ
11|أو البتّييساربتّيّثنائيّ
12&&و المنطقييسارمنطقيّثنائيّ
12وو (كلمة)يسارمنطقيّثنائيّ
13؟؟اندماج فارغيسارأمان العدمثنائيّ
13||أو المنطقييسارمنطقيّثنائيّ
13أوأو (كلمة)يسارمنطقيّثنائيّ
14؟ :ثلاثييمينثلاثيّثلاثيّ
15=إسناديمينإسنادثنائيّ
15+=إسناد جمعيمينإسنادثنائيّ
15-=إسناد طرحيمينإسنادثنائيّ
15*=إسناد ضربيمينإسنادثنائيّ
15/=إسناد قسمةيمينإسنادثنائيّ
15%=إسناد باقييمينإسنادثنائيّ

ملاحظات

  • العوامل المنطقيّة بصيغتين: كلمات (و، أو، ليس) ورموز (&&، ||، !) بالأسبقيّة نفسها؛ الكلمات هي المفضّلة عربيًّا.
  • أمان العدم: ؟؟ اندماج فارغ، ؟. وصول آمن، ومؤكد تأكيد عدم الفراغ (تتبع رموز هذا الفرع تحديدًا).

انظر أيضًا

الأنواع المدمجة

تُقدّم لغة ص 11 نوعًا مدمجًا. أسماؤها يُصدرها المعجمي مُعرِّفات (لا كلمات محجوزة)، فيجوز استعمالها أسماءً خارج موضع النوع.

المصدر: keywords.yaml (فئة builtin_types) + types.yaml.

النوعالإنجليزيّةالفئةالوصف
رقمintegerعدديّعدد صحيح (i64)
عشريdoubleعدديّعدد عشري (f64)
نصstringنصّيّنص (UTF-8)
منطقيbooleanمنطقيّقيمة منطقية (صحيح/خطأ)
فراغvoidخاصّنوع الإرجاع الفارغ — لا قيمة. متمايز عن «عدم» (type.null): «فراغ» ما لم يُرجَع أصلاً (مفتاح غائب، بحثٌ بلا مطابقة)، و«عدم» قيمةُ لاشيء الصريحة. فحصُ أحدهما وحده يمرّ ناقصًا
عدمnullخاصّالعدم — غياب القيمة، متمايز عن فراغ (void). وتمثيلُه حارسٌ صحيحُ البتّات، فالحكمُ عليه يلزمُ أن يقومَ على وسمِ النوعِ لا على شكلِ التمثيل: مقارنةُ العدمِ بقيمةٍ من نوعٍ آخر تُحسَمُ بتطبيعِ الطرفِ الآخرِ إلى عرضِ الحارسِ ومقارنتِه به عدديًّا، فلا تُستدعى مقارنةُ نصوصٍ على الحارسِ أبدًا؛ و«عدم == عدم» صحيح. والوسمُ الساكنُ لا يكفي وحدَه ولا يمكنُ أن يكفي: خانةٌ نوعُها المُصرَّحُ «نصّ» تقبلُ نصًّا في موقعِ نداءٍ وعدمًا في آخر، فلا وسمَ ساكنًا واحدًا يصدُقُ على الاثنَين — والسؤالُ نفسُه سؤالُ زمنِ تشغيل. لذلكَ مقارنةُ النصوصِ آمنةٌ من العدمِ وقتَ التشغيل: يُفحَصُ الطرفانِ على الحارسِ قبلَ أيِّ قراءةِ ذاكرة، فالعدمُ يساوي العدمَ ولا يساوي نصًّا، ولا يُمرَّرُ الحارسُ إلى مقارنةِ نصوصٍ أبدًا
مصفوفةarrayمركّبمصفوفة<T> ديناميكية
خريطةmapمركّبخريطة<K,V>
أيanyخاصّأي نوع (ديناميكي)
طبيعي64uint64عدديّعدد طبيعي 64-بت
بايتbyteعدديّبايت (u8، 0–255)

القيم الحرفيّة المحجوزة

متغير يعمل = صحيح     # true
متغير متوقّف = خطأ    # false
متغير قيمة = لاشيء    # null

الأنواع الاختياريّة وأمان العدم

يُكتب النوع الاختياريّ باللاحقة ؟ ليقبل القيمة أو لاشيء، ويُعالَج بعوامل ؟. (وصول آمن) و؟؟ (اندماج فارغ):

متغير الوسط: نص؟ = لاشيء
متغير الطول = الوسط؟.الطول
متغير قيمة = الوسط ؟؟ "مجهول"

راجع العوامل والأسبقيّة لعوامل أمان العدم ورموزها الدقيقة.

خصائص واجهة SadUI والتخطيط

واجهة SadUI عربيّة RTL-أوّلًا: محتوى الشاشة يبدأ من اليمين. تُوصَف العناصر بخصائص عربيّة قانونيّة معرَّفة في مصدر الحقيقة.

المصدر: language-truth/ui_props.yaml — 94 مفتاحًا. لكلّ مفتاح ثابت مولَّد sad::ui::props::<ID> يُقرأ في كود الرسوميّات (لا سلاسل خام).

المحاذاة المتقاطعة

خاصّيّة محاذاة تضبط المحاذاة المتقاطعة لأبناء العمود/الصفّ:

الوضعالعمود (RTL)الصفّ
بداية (افتراضيّ)يمينًاأعلى
وسطتوسيطتوسيط عموديّ
نهايةيسارًاأسفل
تمدّديملأ العرضيملأ الارتفاع
  • «محاذاة» يُكرِّمها العمود والصفّ حصرًا (الشبكة/المكدّس/الالتفاف لها تموضع RTL مبيَّت خاصّ).

كلّ المفاتيح (94)

المفتاحالثابت props::النوعلاتينيّ؟الوصف
عنوانTITLEنصنصّ العنوان الظاهر للزرّ والشريط والحوار والتبويب
محتوىCONTENTنصمحتوى النصّ لعنصر نص_عنصر ونظائره
نصTEXTنصنصّ عامّ (اسم بديل شائع للمحتوى، ونصّ التلميح)
أيقونةICONنصرمز/أيقونة الزرّ العائم وزرّ الأيقونة (يقبل رمزًا نصّيًّا)
مصدرSOURCEنصمصدر الصورة (مسار أو رابط)
اسمNAMEنصاسم الأيقونة المتجهة (مفتاح عنصر «أيقونة» — لا يخلط بمفتاح ICON)
تلميحHINTنصنصّ التلميح الافتراضيّ لحقل الإدخال ومنطقة النصّ
قيمةVALUEعدد أو منطقيّالقيمة الحاليّة (عدديّة للمنزلق/شريط التقدّم، منطقيّة للمفتاح/خانة الاختيار)
رسالةMESSAGEنصنصّ الرسالة لشريط الإشعار
عرضWIDTHعددالعرض الثابت (بالبكسل) لصندوق المقاس
ارتفاعHEIGHTعددالارتفاع الثابت (بالبكسل) لصندوق المقاس
محاذاةALIGNنصالمحاذاة. للنصّ: «يمين»/«وسط» (أو right/center) — وإلّا يُحاذى النصّ العربيّ يمينًا تلقائيًّا. لحاويات العمود/الصفّ (المحور المتقاطع): «بداية» (افتراضيّ، اتّجاهيّ: العمود RTL يمينًا واللاتينيّ يسارًا، الصفّ أعلى) · «وسط» · «نهاية» (العمود يسار المحتوى في RTL، الصفّ أسفل) · «تمدّد» (يملأ المحور المتقاطع؛ يتخطّاه الابن ذو المقاس الصريح في ذلك المحور).
حشوةPADDINGعددالحشو الداخليّ للحاوية (بالبكسل) — إزاحة الأبناء داخل حدود العنصر
حشوة_أعلىPADDING_TOPعددالحشو العلويّ للحاوية (بالبكسل) — منطقيّ عموديّ ثابت
حشوة_أسفلPADDING_BOTTOMعددالحشو السفليّ للحاوية (بالبكسل) — منطقيّ عموديّ ثابت
حشوة_بدايةPADDING_STARTعددحشو جهة البداية (بالبكسل) — منطقيّ واعٍ بالـRTL (start=يمين)
حشوة_نهايةPADDING_ENDعددحشو جهة النهاية (بالبكسل) — منطقيّ واعٍ بالـRTL (end=يسار)
هامشMARGINعددالهامش الخارجيّ (بالبكسل) — يُقحِم منطقة محتوى الحاوية
تباعدSPACINGعددالتباعد (بالبكسل) بين أبناء العمود/الصفّ المتتالين
وزنWEIGHTعددوزن المرونة (flex) — حصّة الابن من المساحة المتبقّية على المحور الرئيسيّ
أعمدةCOLUMNSعددعدد أعمدة الشبكة (Grid)
حجم_خطFONT_SIZEعددحجم خطّ النصّ (بالبكسل) — يؤثّر على قياس النصّ عرضًا وارتفاعًا
حجم_الخطFONT_SIZE_ALTعددهجاء بديل لـ«حجم_خط» (بأل التعريف) — مقبول في القياس
حجمSIZEعدداسم مختصر لحجم الخطّ (بديل لـ«حجم_خط»)
flexFLEX_LATINعددبديل لاتينيّ لـ«وزن» (flex) — يقرؤه التخطيط فقط
columnsCOLUMNS_LATINعددبديل لاتينيّ لـ«أعمدة» — يقرؤه التخطيط فقط
widthWIDTH_LATINعددبديل لاتينيّ لـ«عرض» — يقرؤه التخطيط فقط
heightHEIGHT_LATINعددبديل لاتينيّ لـ«ارتفاع» — يقرؤه التخطيط فقط
لونCOLORنصاللون العامّ للعنصر (سلسلة سداسيّة #RRGGBB أو اسم لون)
لون_النصTEXT_COLORنصلون النصّ
لون_نصTEXT_COLOR_ALTنصهجاء بديل لـ«لون_النص» (بلا أل)
خلفيةBGنصلون الخلفية (مفتاح مختصر)
لون_خلفيةBG_COLORنصلون خلفية العنصر (المعدّل الرسميّ)
لون_نشطACTIVE_COLORنصلون الحالة النشطة (مفتاح/زرّ مفعَّل)
حد_لونBORDER_COLORنصلون الحدّ الخارجيّ
زواياCORNER_RADIUSعددنصف قطر تدوير الزوايا (بالبكسل)
نصف_قطرRADIUSعددنصف القطر (للدائرة/التدوير)
سماكةTHICKNESSعددسماكة الخطّ/الحدّ (بالبكسل)
شفافيةOPACITYعددالشفافية (0.0 شفّاف تمامًا … 1.0 معتِم)
ظلSHADOWنصمواصفة الظلّ (وجوده/لونه)
تدرجGRADIENTنصلون بداية التدرّج
تدرج_نهايةGRADIENT_ENDنصلون نهاية التدرّج
رفعELEVATIONعددالارتفاع البصريّ (شدّة الظلّ)
مفعلENABLEDمنطقيّهل العنصر مفعَّل (تفاعليّ) أم مُعطَّل
المجموعTOTALعددالقيمة القصوى (لشريط التقدّم/المنزلق)
الحاليCURRENTعددالقيمة الحاليّة (لشريط التقدّم/المنزلق)
إزاحة_سOFFSET_Xعددالإزاحة الأفقيّة بالبكسل — تمرير للحاويات القابلة للتمرير، وموضع حرّ لغيرها
إزاحة_صOFFSET_Yعددالإزاحة الرأسيّة بالبكسل — تمرير للحاويات القابلة للتمرير، وموضع حرّ لغيرها
ايقونةICON_ALTنصهجاء بديل لـ«أيقونة» (بألف بلا همزة) — اسم الأيقونة
رمزSYMBOLنصرمز نصّيّ (مثل محرف الأيقونة)
حرفCHARنصمحرف واحد يُعرَض (نحو أوّل حرف من عنصر)
مسارPATHنصمسار المورد (صورة ونحوها)
مجموعةGROUPنصاسم مجموعة العنصر (أزرار الاختيار المترابطة ونحوها)
أدنىMINعددالقيمة الدنيا (منزلق/مدى)
أقصىMAXعددالقيمة القصوى (منزلق/مدى)
إجماليTOTAL_SUMعددالمجموع الكلّيّ (بديل دلاليّ لـ«المجموع»)
أرقام_أسطرLINE_NUMBERSمنطقيّإظهار أرقام الأسطر (محرِّر الشيفرة)
حجم_خليةCELL_SIZEعددحجم الخليّة (بالبكسل) في الشبكة/الجدول
حدودBOUNDSنصحدود المنطقة (نطاق/إطار)
دائرةCIRCLEمنطقيّهل الشكل دائريّ (نحو صورة رمزيّة)
داكنDARKمنطقيّهل السمة داكنة
سمكTHICKNESS_ALTعددهجاء بديل لـ«سماكة» (سمك الخطّ/الحدّ)
صفحةPAGEعددرقم الصفحة (ترقيم الصفحات)
كودCODEنصنصّ الشيفرة المصدريّة (كتلة/محرِّر شيفرة)
لغةLANGUAGEنصلغة الشيفرة (للإبراز النحويّ)
لون_الايقونةICON_COLORنصلون الأيقونة
لون_المقبضHANDLE_COLORنصلون مقبض المنزلق/المفتاح
محددSELECTEDمنطقيّهل العنصر محدَّد (خانة اختيار/تبويب نشط)
نص_بديلALT_TEXTنصالنصّ البديل (وصف الصورة للوصوليّة)
نوعTYPEنصنوع العنصر (نوع حقل الإدخال ونحوه)
وصفDESCRIPTIONنصوصف نصّيّ للعنصر
contentCONTENT_LATINنصبديل لاتينيّ لـ«محتوى»
titleTITLE_LATINنصبديل لاتينيّ لـ«عنوان»
sourceSOURCE_LATINنصبديل لاتينيّ لـ«مصدر»
languageLANGUAGE_LATINنصبديل لاتينيّ لـ«لغة»
altALT_LATINنصبديل لاتينيّ لـ«نص_بديل»
maxMAX_LATINعددبديل لاتينيّ لـ«أقصى»
minMIN_LATINعددبديل لاتينيّ لـ«أدنى»
latLAT_LATINعددخطّ العرض الجغرافيّ (خريطة)
lngLNG_LATINعددخطّ الطول الجغرافيّ (خريطة)
srcSRC_LATINنصبديل لاتينيّ لـ«مسار/مصدر» (مسار الصورة)
valueVALUE_LATINعدد أو منطقيّبديل لاتينيّ لـ«قيمة»
placeholderPLACEHOLDER_LATINنصبديل لاتينيّ لـ«تلميح»
scroll_xSCROLL_X_LATINعددإزاحة تمرير أفقيّة (مفتاح لاتينيّ داخليّ للمُرسِّم)
scroll_ySCROLL_Y_LATINعددإزاحة تمرير رأسيّة (مفتاح لاتينيّ داخليّ للمُرسِّم)
مرونةFLEXعددنصيبُ العنصرِ من المساحةِ الفائضةِ في صفٍّ أو عمود (موسع/مرن)
نسبةRATIOعددنسبةُ العرضِ إلى الارتفاعِ لعنصرِ «نسبة_عرض»
عامل_العرضWIDTH_FACTORعددكسرٌ من عرضِ الأبِ (٠–١) لعنصرِ «صندوق_نسبي»
عامل_الارتفاعHEIGHT_FACTORعددكسرٌ من ارتفاعِ الأبِ (٠–١) لعنصرِ «صندوق_نسبي»
أدنى_عرضMIN_WIDTHعددالحدُّ الأدنى للعرضِ في عنصرِ «صندوق_مقيد»
أقصى_عرضMAX_WIDTHعددالحدُّ الأقصى للعرضِ في عنصرِ «صندوق_مقيد»
أدنى_ارتفاعMIN_HEIGHTعددالحدُّ الأدنى للارتفاعِ في عنصرِ «صندوق_مقيد»
أقصى_ارتفاعMAX_HEIGHTعددالحدُّ الأقصى للارتفاعِ في عنصرِ «صندوق_مقيد»
textTEXT_LATINنصبديل احتياطيّ لاتينيّ (مسار UINode) — يقرؤه المُرسِّم فقط

التفصيل المعماريّ (المحاور، الأوضاع، الهامش/الأوزان، الحرّاس) في مستودع اللغة: docs/architecture/sadui-layout-alignment.md.

قواعد النحو (Grammar)

نحوُ لغة ص موصوفٌ وصفًا رسميًّا مدفوعًا بالبيانات (data-driven): كلّ قاعدة إنتاج مكتوبة بصيغة EBNF ومربوطة بدالة التحليل الفعليّة في المحلّل (حقل maps_to)، فيتحقّق الـCI من تطابق الوصف مع السلوك. هذا يجعل النحو مصدرَ حقيقة قابلًا للتنفيذ لا مجرّد توثيق.

المصدر: language-truth/grammar/ — موزّع على ثماني طبقات.

طبقات القواعد

الملفّالطبقةيغطّي
00_program.yamlالبرنامجالجذر، التصريح الأعلى، الكتلة
10_statements.yamlالجُملالإسناد، الشروط، الحلقات، التحكّم
20_declarations.yamlالتصريحاتالمتغيّرات، الدوال، الوحدات
30_oop.yamlالكائنيّةالأصناف، البنى، التعدادات، الوراثة
40_expressions.yamlالتعبيراتالعوامل، الاستدعاءات، الوصول
50_patterns.yamlالأنماططابق/عندما/افتراضي
60_advanced.yamlالمتقدّمةالتزامن، القوالب، فضاءات الأسماء
70_lexical.yamlالمعجميّةالرموز، القيم الحرفيّة، المُعرِّفات

صيغة الترميز (EBNF)

تتبع القواعد ترميز EBNF القياسيّ:

  • { X } تكرار صفر أو أكثر.
  • [ X ] اختياريّ.
  • X | Y بديل.
  • ( ... ) تجميع.
  • الطرفيّات تشير إلى المعجم ولا تُعرَّف داخل ملفّات النحو.

أمثلة من القواعد

البنية العليا للبرنامج والكتلة (الكتلة تُغلَق دائمًا بـنهاية):

Program     = { Declaration } EOF ;
Block       = { Statement } "نهاية" ;
IfStmt      = "إذا" Expression Block [ "وإلا" Block ] ;
WhileStmt   = "بينما" Expression Block ;
ForStmt     = "لكل" Identifier "في" Expression Block ;
FuncDecl    = "دالة" Identifier "(" [ ParamList ] ")" [ ":" Type ] Block ;
MatchStmt   = "طابق" Expression { "عندما" Pattern Block } [ "افتراضي" Block ] "نهاية" ;

هذه الأمثلة توضيحيّة للقارئ؛ الصيغة الرسميّة الكاملة (مع alternatives وmaps_to وast_node لكلّ قاعدة) في ملفّات language-truth/grammar/.

مبادئ نحويّة ثابتة

  • كلّ كتلة تُغلَق بـنهاية (عدا كتل باستخدام التي تُغلَق بـنهاية_استخدام).
  • الفواصل متكافئة: ،, و؛;.
  • التعليقات: سطريّ #، كتليّ #* ... *#، توثيقيّ ##.
  • الرموز العربيّة حصريّة حيث نُصَّ عليها (مثل ؟ = U+061F لأمان العدم والثلاثيّ).

التوثيق المُولَّد

تُولَّد صفحات قواعد المحلّل آليًّا من هذا المصدر إلى docs/parser_rule/_generated في المستودع الأساسيّ عبر gen_parser_grammar_docs.py، فيبقى التوثيق متزامنًا مع السلوك.

انظر أيضًا

مصدر الحقيقة الموحّد (SoT)

تتبنّى لغة ص مبدأ مصدر الحقيقة الموحّد (Single Source of Truth): تُوصَف اللغة — كلماتها وأنواعها وعواملها وقواعدها وأخطاؤها — في ملفّات بيانات مُحكَّمة بمخطّطات، ثم يُولَّد منها الكود والتوثيق. هذا يمنع التضارب بين الوصف والسلوك.

الموقع: language-truth/ في المستودع الأساسيّ.

لماذا؟

  • اتّساق: تعريف واحد للكلمة/النوع يُغذّي المعجمي والمحلّل والتوثيق معًا.
  • تحقّق آليّ: الـCI يطابق الوصف بالسلوك (حقول maps_to وconformance).
  • توثيق حيّ: هذا الكتاب وصفحات docs/parser_rule/_generated تُشتقّ من المصدر.

أبرز الملفّات

الملفّيحوي
keywords.yamlالمعجم: 40 محجوزة + 3 عوامل + سياقيّة + 9 أنواع
operators.yamlالعوامل وأسبقيّتها وترابطها
types.yamlالأنواع المدمجة وخصائصها
grammar/*.yamlقواعد الإنتاج (EBNF) عبر ثماني طبقات
errors/كتالوج رموز الأخطاء ورسائلها
builtins/الدوال المضمّنة
stdlib/وحدات المكتبة القياسيّة
_schemas/مخطّطات JSON التي تُحكِّم كلّ ما سبق

القاعدة الذهبيّة

عند أيّ تعارض بين هذا التوثيق وlanguage-truth/، فإنّ language-truth/ هو الفيصل. دور هذا المستودع أن يَعرض الحقيقة ويشرحها للقارئ، لا أن يُنشئ قاعدةً جديدة.

انظر أيضًا