From 63e1c0312d36484b76e2c190d8f04fa50bd16127 Mon Sep 17 00:00:00 2001 From: Sad Lang Dev Date: Mon, 6 Jul 2026 22:25:33 +0300 Subject: [PATCH 1/2] =?UTF-8?q?RFC:=20=D8=AC=D9=88=D8=AF=D8=A9=20=D8=AA?= =?UTF-8?q?=D8=B4=D8=AE=D9=8A=D8=B5=20=D8=A3=D8=AE=D8=B7=D8=A7=D8=A1=20?= =?UTF-8?q?=D8=A7=D9=84=D9=85=D9=81=D8=B3=D9=91=D8=B1=20(=D8=AA=D8=B5?= =?UTF-8?q?=D9=86=D9=8A=D9=81=20=D8=B5=D8=AD=D9=8A=D8=AD=20+=20=D8=A5?= =?UTF-8?q?=D8=AE=D9=81=D8=A7=D8=A1=20=D8=A2=D8=AB=D8=A7=D8=B1=20=D8=A7?= =?UTF-8?q?=D9=84=D8=A7=D8=B3=D8=AA=D8=B1=D8=AF=D8=A7=D8=AF=20=D8=A7=D9=84?= =?UTF-8?q?=D8=AF=D8=A7=D8=AE=D9=84=D9=8A=D9=91=D8=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit يوثّق أربعة عيوب في تشخيص أخطاء المفسّر (sad-run) وإصلاحها: وسم نحويّ→دلاليّ خاطئ، تسريب إحصائيّات الاسترداد، رسالة الفعل بدل المشكلة، وتلميح استيراد عامّ. إنفاذ لا توسيع لمصدر الحقيقة. التنفيذ في PR s-programming-language#160. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...31\205\331\201\330\263\331\221\330\261.md" | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 "text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" diff --git "a/text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" "b/text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" new file mode 100644 index 0000000..8056b2a --- /dev/null +++ "b/text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" @@ -0,0 +1,97 @@ +- **عنوان المقترح:** تحسين جودة تشخيص أخطاء المفسّر (تصنيف صحيح + إخفاء آثار الاسترداد الداخليّة) +- **النطاق:** لغة `text/` +- **تاريخ البدء:** 2026-07-06 +- **رقم الـ RFC:** (يُترك فارغاً حتى الدمج) +- **الحالة:** مقترَح (PR مفتوح) +- **Issue التتبُّع:** (يُترك فارغاً حتى القبول) + +# ملخّص + +يعالج هذا المقترح أربعة عيوب في تشخيص أخطاء **المفسّر** (`sad-run`) تُضعِف تجربة المبتدئ في أوّل تفاعل مع الأخطاء: + +1. **وسم خاطئ:** خطأ **نحويّ** (SYN) يُوسَم «🔍 هذا خطأ **دلاليّ**». +2. **تسريب آثار داخليّة:** «=== إحصائيات الاسترداد === ناجح/فاشل» تظهر للمستخدم النهائيّ. +3. **رسالة مُضلِّلة + تناقض:** الخطأ المُستردّ يُعرَض بوصف فعل الاسترداد («إدراج ')' المفقودة») بدل وصف المشكلة، فيبدو أنّ الأداة أصلحت الكود ثمّ تُبلّغ عنه خطأً في آن. +4. **تلميح غير ذي صلة:** «استورد الوحدة المطلوبة» يظهر لكلّ **متغيّر** غير معرّف رغم أنّ جوابه الغالب «عرّفه». + +النتيجة المرئيّة: عند حذف قوس إغلاق `)` وتشغيل البرنامج، يرى المستخدم رسالة عربيّة نظيفة تصف المشكلة وتصنّفها **نحويًّا** بلا ضجيج، بدل تقريرٍ متناقض يُوسَم «دلاليًّا» خطأً. + +# الدافع (Motivation) + +جولة الترحيب في محراب (رحلة P0) تَعِد المبتدئ بأنّ الخطأ «معلّمٌ لطيف» يشرح في ثلاث طبقات (ماذا/أين/كيف)، وتطلب منه تحديدًا **حذف `)` وتشغيل البرنامج**. لكنّ هذا المثال بالذات يُخرج أسوأ ناتج ممكن: + +``` +🔧 إدراج ')' المفقودة | Inserted missing ')' +=== إحصائيات الاسترداد === + ناجح: 1 + فاشل: 0 +❌ error [SYN003]: :2:1 +│ إدراج ')' المفقودة +📝 note [SYN003]: ❌ إدراج ')' المفقودة +🔍 هذا خطأ دلالي. +❌ 1 خطأ +``` + +هذا يقوّض ثقة المبتدئ في أوّل ٩٠ ثانية: تصنيفٌ خاطئ، وضجيجٌ داخليّ، وتناقض «ناجح» ⇄ «❌ خطأ». الأخطاء نظام حَسَّاس للثقة؛ صوابُ تصنيفها ونظافةُ عرضها جزءٌ من العقد اللغويّ لا رفاهية. + +# الشرح التوجيهي (Guide-level explanation) + +**قبل** (حذف `)` من `اطبع("مرحبا يا عالم")`): + +``` +🔧 إدراج ')' المفقودة | Inserted missing ')' +=== إحصائيات الاسترداد === ناجح: 1 / فاشل: 0 +❌ error [SYN003]: │ إدراج ')' المفقودة +🔍 هذا خطأ دلالي. +``` + +**بعد**: + +``` +❌ error [SYN003]: :2:1 +│ توقّعت ')' هنا +🔍 هذا خطأ نحوي. +💡 أضف ')' المقابل لإغلاق التعبير. +``` + +المبدأ للمستخدم: **الاسترداد آليّةٌ داخليّة** يستعملها المحلّل ليتابع البحث عن أخطاء أخرى — لا وعدٌ بإصلاح كوده. لذا لا يرى المستخدم «ماذا أدرجت الأداة»، بل «ما المشكلة وأين وكيف يُصلحها». آثار الاسترداد (الإحصائيّات + أفعال «🔧») تبقى متاحةً للمطوّر عند ضبط متغيّر البيئة `SAD_DIAG_STATS`. + +# الشرح المرجعي (Reference-level explanation) + +- **مصدر الحقيقة (`language-truth/`):** **لا تغيير.** الرمز `SYN_UNCLOSED_BRACKET` (SYN003) وطبقاته الوديّة موجودة سلفًا في `errors/syntactic.yaml`. المقترح **إنفاذ** لا توسيع (يوافق مبدأ «الأدوات/الإصلاحات لا توسّع SoT»). + +- **العيب ١ — التصنيف** (`shared/errors/src/smart_teacher_mode.cpp::generateBasicExplanation`): الشرط `errorCode.substr(0,1)=="S"` لفئة «دلاليّ» يلتقط رموز **SYN** (تبدأ بـ`S`) قبل فرع «نحويّ»، فيصير الأخير ميّتًا. الإصلاح: فحص الرموز الثلاثيّة الصريحة (`TYPE`/`SYN`/`SEM`/`LEX`/`RUN`) أوّلًا، وإبقاء الحرف المفرد (`T`/`P`/`S`) احتياطًا لرموز قديمة أحاديّة الحرف فقط. (مثاليًّا يُستبدَل الحدس لاحقًا بـ`getErrorCategory(ErrorCode)` الموثوق — عملٌ تابع.) + +- **العيب ٢ — تسريب الإحصائيّات** (`shared/parser/src/core/parser_main.cpp`): `std::cerr << formatStats(true)` يُبثّ بلا شرط عند حدوث استردادات. الإصلاح: حجبه خلف متغيّر البيئة `SAD_DIAG_STATS` (ثابت `Errors::kDiagStatsEnvVar` في `error_recovery.h`). + +- **العيب ٣ — رسالة الاسترداد + طبع «🔧»** (`shared/parser/src/core/parser_helpers.cpp::tryRecoverFromError`): في حالة `INSERT_TOKEN` تُمرَّر `result.action.description` («إدراج ')'») كرسالة الخطأ. الإصلاح: تمرير رسالة تصف المشكلة «توقّعت '' هنا / Expected '' here»، مع إبقاء تسجيل الخطأ (لا نبتلعه — يظلّ خطأً حقيقيًّا يعكسه `hasErrors()`). وطبعا «🔧» للإدراج والمزامنة يُحجبان خلف `SAD_DIAG_STATS`. + +- **العيب ٤ — تلميح الاستيراد** (`shared/errors/src/smart_suggestions.cpp`): `generateUndefinedSymbolSuggestions` يدفع «استورد الوحدة» (LOW) لكلّ رمز غير معرّف. الإصلاح: قصره على **الدوالّ** غير المعرّفة (`SEM_UNDEFINED_FUNCTION`) عبر مفتاح داخليّ `undef_kind=function` يمرّره `generateFromErrorCode`؛ المتغيّر غير المعرّف يبقى باقتراح «عرّفه» وحده. + +- **المفسّر:** هو المستفيد المباشر (مسار `sad-run`). **المترجم (sadc):** المكوّنات في `shared/` مشتركة؛ لا تغيير سلوكيّ في مسار التوليد (الإصلاحات في طبقتَي التشخيص والاسترداد النصّيّتين). + +- **نظام الأخطاء:** لا رموز جديدة. تُصحَّح رسالة/تصنيف رمزٍ قائم فقط. + +- **التوافق الخلفي:** لا يكسر برامج `.ص` قائمة (رموز الخروج ومنطق `hasErrors()` كما هي؛ التغيير في نصّ الرسائل وحجب آثار المطوّر). قد تحتاج اختبارات ذهبيّة تلتقط النصّ القديم للتحديث. + +# السلبيات (Drawbacks) + +- تغيير نصّ رسائل قد يكسر اختبارات ذهبيّة/لقطات تعتمد الصياغة القديمة (تُحدَّث ضمن هذا العمل). +- حجب الإحصائيّات خلف متغيّر بيئة يعني أنّ المطوّر يحتاج معرفته لتفعيل الأثر (يُوثَّق). + +# المبرّرات والبدائل (Rationale and alternatives) + +- **البديل لـ٢/٣ (حذفٌ كامل بدل حجب):** يفقد المطوّر أداة تشخيص مفيدة؛ الحجب خلف متغيّر بيئة يوازن بين نظافة المستخدم وحاجة المطوّر. +- **البديل لـ١ (استعمال `getErrorCategory` فورًا):** أنظف لكنّه يتطلّب تمرير `ErrorCode` عبر توقيعات وضع المعلّم؛ إعادة الترتيب تُصلح العلّة فورًا بأقلّ خطر، وتُترك الاستعاضة الكاملة عملًا تابعًا. +- **عدم فعل شيء:** يُبقي وعد جولة الترحيب مكسورًا وتجربة الخطأ الأولى مربكة. + +# أعمال سابقة (Prior art) + +- **Rust/Elm:** تفصلان بوضوح بين *ما الخطأ* و*كيف يُصلَح*، ولا تُظهران آليّات الاسترداد الداخليّة للمستخدم. +- **Clang:** يستعمل استرداد الأخطاء داخليًّا («توقّعت ')'») دون بثّ «أدرجتُ ')'» كإنجاز؛ رسالته تصف التوقّع لا الفعل — وهو نموذج العيب ٣ المعتمَد هنا. + +# أسئلة غير محسومة (Unresolved questions) + +- هل يُوحَّد اسم متغيّر البيئة التشخيصيّ (`SAD_DIAG_STATS`) مع أيّ راية verbose مستقبليّة للمحرّكين؟ +- توقيت الاستعاضة الكاملة عن حدس التصنيف بـ`getErrorCategory(ErrorCode)` (عملٌ تابع خارج نطاق هذا الـRFC). +- هل تُحجب أيضًا أفعال «🔧» ذات القيمة الإرشاديّة (did-you-mean / تخطّي رمز زائد)؟ (تُركت ظاهرةً لأنّها إرشادٌ فعليّ للمستخدم لا أثرُ استرداد صامت.) From c3739c60dff29ba338b5ccc62c84e668f5f806b6 Mon Sep 17 00:00:00 2001 From: Sad Lang Dev Date: Tue, 7 Jul 2026 07:10:06 +0300 Subject: [PATCH 2/2] =?UTF-8?q?RFC:=20=D8=A5=D8=B6=D8=A7=D9=81=D8=A9=20?= =?UTF-8?q?=D9=82=D8=B3=D9=85=20=C2=AB=D8=A7=D9=84=D8=A2=D9=81=D8=A7=D9=82?= =?UTF-8?q?=20=D8=A7=D9=84=D9=85=D8=B3=D8=AA=D9=82=D8=A8=D9=84=D9=8A=D8=A9?= =?UTF-8?q?=C2=BB=20=D8=A7=D9=84=D8=A5=D9=84=D8=B2=D8=A7=D9=85=D9=8A=D9=91?= =?UTF-8?q?=20(=D8=A5=D8=B1=D8=B6=D8=A7=D8=A1=20=D9=81=D8=A7=D8=AD=D8=B5?= =?UTF-8?q?=20=D8=A7=D9=84=D8=A8=D9=86=D9=8A=D8=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit الفاحص يتطلّب الأقسام التسعة؛ كان القسم التاسع «مستقبلية» ناقصًا. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...7\331\204\331\205\331\201\330\263\331\221\330\261.md" | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git "a/text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" "b/text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" index 8056b2a..eeeca56 100644 --- "a/text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" +++ "b/text/0000-\330\254\331\210\330\257\330\251-\330\252\330\264\330\256\331\212\330\265-\330\243\330\256\330\267\330\247\330\241-\330\247\331\204\331\205\331\201\330\263\331\221\330\261.md" @@ -95,3 +95,12 @@ - هل يُوحَّد اسم متغيّر البيئة التشخيصيّ (`SAD_DIAG_STATS`) مع أيّ راية verbose مستقبليّة للمحرّكين؟ - توقيت الاستعاضة الكاملة عن حدس التصنيف بـ`getErrorCategory(ErrorCode)` (عملٌ تابع خارج نطاق هذا الـRFC). - هل تُحجب أيضًا أفعال «🔧» ذات القيمة الإرشاديّة (did-you-mean / تخطّي رمز زائد)؟ (تُركت ظاهرةً لأنّها إرشادٌ فعليّ للمستخدم لا أثرُ استرداد صامت.) + +# الآفاق المستقبلية (Future possibilities) + +> ما الامتدادات الطبيعيّة لهذا العمل مستقبلًا؟ + +- استبدال حدس تصنيف الخطأ في وضع المعلّم بالمصدر الموثوق `getErrorCategory(ErrorCode)` (المُشتقّ من `category` في YAML) بدل فحص بادئة السلسلة — يُلغي جذر العيب ١ نهائيًّا. +- توحيد متغيّر البيئة التشخيصيّ `SAD_DIAG_STATS` ضمن راية verbose عامّة للمحرّكين إن استُحدثت. +- ترقية أفعال الاسترداد الإرشاديّة الباقية (did-you-mean / تخطّي رمز زائد) من طبع `cerr` خام إلى تشخيصات ضمن نظام الأخطاء الموحَّد. +- تمييز نصّ تلميح الرمز غير المعرّف: «عرّف الدالّة» للدوالّ مقابل «عرّف المتغير» للمتغيّرات.