مقدّمة
لغة ص (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]. - نسيان
أنتج:[لكل س في القائمة]خطأ نحويّ؛ رأس الحلقة يتطلّبأنتج <ناتج>. - موضع الشرط:
إذايسبقأنتجدائمًا:[لكل س في م إذا شرط أنتج ناتج]. - فاصلة فكّ الزوج بلا اسم:
[لكل م، في خريطة أنتج م]خطأ نحويّ؛ الفاصلة تتطلّب اسم متغيّر القيمة بعدها:[لكل م، ق في خريطة أنتج م].
انظر أيضًا
- التحكّم بالتدفّق — الحلقة
لكل ... في. - المولّدات و
أنتج— الاستعمال الآخر لكلمةأنتج. - قواعد النحو (Grammar) — نظرة عامّة على النحو الرسميّ.
التعريف الكامل على مستوى القاعدة (
gr.adv.list_comprehension،gr.adv.dict_comprehensionوما يقابلهما للمجموعة) مُولَّد فيdocs/parser_rule/_generatedبالمستودع الأساسيّ. - الكلمات المحجوزة الأربعون — تمييز المحجوز عن السياقيّ.
الدوال
تُعرَّف الدوال بكلمة دالة، وتُعيد القيم بـارجع. دالة الدخول للبرنامج اسمها رئيسية.
التعريف والاستدعاء
دالة اجمع(أ، ب)
ارجع أ + ب
نهاية
دالة رئيسية()
متغير الناتج = اجمع(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 مستقرّتان.
-
متغيّر البيئة
SAD_REGISTRY_URL— الأنسب للتجارب وبيئات CI:SAD_REGISTRY_URL=http://localhost:3000 sad-pkg search رياضيات(صيغة السطر أعلاه لصدفات POSIX؛ في PowerShell:
$env:SAD_REGISTRY_URL = "http://localhost:3000"ثمّ نفّذ الأمر.) -
الإعداد الدائم عبر
config:sad-pkg config registry https://سجلّي-الخاصّ.example -
الافتراضيّ المضمَّن في الأداة.
النشر ورمز الاعتماد
النشر إلى السجلّ يتطلّب رمزًا (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) | 44 | يُصدر IDENTIFIER (يقرّره المحلّل) | ✅ |
| أنواع مدمجة (builtin) | 17 | يُصدر 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 | %= | إسناد باقي | يمين | إسناد | ثنائيّ |
ملاحظات
- العوامل المنطقيّة بصيغتين: كلمات (
و،أو،ليس) ورموز (&&،||،!) بالأسبقيّة نفسها؛ الكلمات هي المفضّلة عربيًّا. - أمان العدم:
؟؟اندماج فارغ،؟.وصول آمن، ومؤكدتأكيد عدم الفراغ (تتبع رموز هذا الفرع تحديدًا).
انظر أيضًا
- التعبيرات والعمليات — أمثلة استعمال.
- الأنواع المدمجة — الأنواع الاختياريّة وأمان العدم.
الأنواع المدمجة
تُقدّم لغة ص 17 نوعًا مدمجًا. أسماؤها يُصدرها المعجمي مُعرِّفات (لا كلمات محجوزة)، فيجوز استعمالها أسماءً خارج موضع النوع.
المصدر:
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 | خاصّ | أي نوع (ديناميكي) |
طبيعي | uint64 | عدديّ | عدد طبيعي 64-بت |
طبيعي8 | uint8 | عدديّ | عدد طبيعي 8-بت (0–255) |
رقم8 | int8 | عدديّ | عدد صحيح 8-بت |
رقم16 | int16 | عدديّ | عدد صحيح 16-بت |
رقم32 | int32 | عدديّ | عدد صحيح 32-بت |
طبيعي16 | uint16 | عدديّ | عدد طبيعي 16-بت |
طبيعي32 | uint32 | عدديّ | عدد طبيعي 32-بت |
عشري32 | float32 | عدديّ | عشري 32-بت |
القيم الحرفيّة المحجوزة
متغير يعمل = صحيح # 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 | عدد | اسم مختصر لحجم الخطّ (بديل لـ«حجم_خط») | |
flex | FLEX_LATIN | عدد | ✔ | بديل لاتينيّ لـ«وزن» (flex) — يقرؤه التخطيط فقط |
columns | COLUMNS_LATIN | عدد | ✔ | بديل لاتينيّ لـ«أعمدة» — يقرؤه التخطيط فقط |
width | WIDTH_LATIN | عدد | ✔ | بديل لاتينيّ لـ«عرض» — يقرؤه التخطيط فقط |
height | HEIGHT_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 | نص | وصف نصّيّ للعنصر | |
content | CONTENT_LATIN | نص | ✔ | بديل لاتينيّ لـ«محتوى» |
title | TITLE_LATIN | نص | ✔ | بديل لاتينيّ لـ«عنوان» |
source | SOURCE_LATIN | نص | ✔ | بديل لاتينيّ لـ«مصدر» |
language | LANGUAGE_LATIN | نص | ✔ | بديل لاتينيّ لـ«لغة» |
alt | ALT_LATIN | نص | ✔ | بديل لاتينيّ لـ«نص_بديل» |
max | MAX_LATIN | عدد | ✔ | بديل لاتينيّ لـ«أقصى» |
min | MIN_LATIN | عدد | ✔ | بديل لاتينيّ لـ«أدنى» |
lat | LAT_LATIN | عدد | ✔ | خطّ العرض الجغرافيّ (خريطة) |
lng | LNG_LATIN | عدد | ✔ | خطّ الطول الجغرافيّ (خريطة) |
src | SRC_LATIN | نص | ✔ | بديل لاتينيّ لـ«مسار/مصدر» (مسار الصورة) |
value | VALUE_LATIN | عدد أو منطقيّ | ✔ | بديل لاتينيّ لـ«قيمة» |
placeholder | PLACEHOLDER_LATIN | نص | ✔ | بديل لاتينيّ لـ«تلميح» |
scroll_x | SCROLL_X_LATIN | عدد | ✔ | إزاحة تمرير أفقيّة (مفتاح لاتينيّ داخليّ للمُرسِّم) |
scroll_y | SCROLL_Y_LATIN | عدد | ✔ | إزاحة تمرير رأسيّة (مفتاح لاتينيّ داخليّ للمُرسِّم) |
مرونة | FLEX | عدد | نصيبُ العنصرِ من المساحةِ الفائضةِ في صفٍّ أو عمود (موسع/مرن) | |
نسبة | RATIO | عدد | نسبةُ العرضِ إلى الارتفاعِ لعنصرِ «نسبة_عرض» | |
عامل_العرض | WIDTH_FACTOR | عدد | كسرٌ من عرضِ الأبِ (٠–١) لعنصرِ «صندوق_نسبي» | |
عامل_الارتفاع | HEIGHT_FACTOR | عدد | كسرٌ من ارتفاعِ الأبِ (٠–١) لعنصرِ «صندوق_نسبي» | |
أدنى_عرض | MIN_WIDTH | عدد | الحدُّ الأدنى للعرضِ في عنصرِ «صندوق_مقيد» | |
أقصى_عرض | MAX_WIDTH | عدد | الحدُّ الأقصى للعرضِ في عنصرِ «صندوق_مقيد» | |
أدنى_ارتفاع | MIN_HEIGHT | عدد | الحدُّ الأدنى للارتفاعِ في عنصرِ «صندوق_مقيد» | |
أقصى_ارتفاع | MAX_HEIGHT | عدد | الحدُّ الأقصى للارتفاعِ في عنصرِ «صندوق_مقيد» | |
text | TEXT_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،
فيبقى التوثيق متزامنًا مع السلوك.
انظر أيضًا
- الكلمات المحجوزة الأربعون — الطرفيّات التي تشير إليها القواعد.
- مصدر الحقيقة الموحّد — فلسفة الـ data-driven.
مصدر الحقيقة الموحّد (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/ هو الفيصل.
دور هذا المستودع أن يَعرض الحقيقة ويشرحها للقارئ، لا أن يُنشئ قاعدةً جديدة.
انظر أيضًا
- قواعد النحو — كيف تُوصَف القواعد بصيغة EBNF.
- دليل المطوّرين الداخليّ — تفصيل توليد الكود من SoT.