ملف ودالة بداية
ابدأ بملف واحد ودوال على المستوى الأعلى. لا توجد عبارات تنفيذية أو متغيرات عامة خارج الدوال. تستقبل دالة البداية صفرا من المعاملات وتعيد حالة العملية.
اقرأ المثال وافحصه تابع إلى العقد الدقيق الحدود المعيارية للإصدارجارٍ تحميل المحرر…
يجمع هذا البرنامج الأعداد من 1 إلى 10. عند نجاحه يطبع 55 ويعيد الحالة 0. عدّل المصدر ثم اضغط «شغّل».
تجري الترجمة والتنفيذ داخل متصفحك. لا يُرسل المصدر إلى خادم.
تابع إلى تعلّم اللغةابدأ بملف واحد ودوال على المستوى الأعلى. لا توجد عبارات تنفيذية أو متغيرات عامة خارج الدوال. تستقبل دالة البداية صفرا من المعاملات وتعيد حالة العملية.
اقرأ المثال وافحصه تابع إلى العقد الدقيق الحدود المعيارية للإصدارالأنواع العددية المخزنة هي ص8/i8, ص16/i16, ص32/i32, ص64/i64, ط8/u8, ط16/u16, ط32/u32, ط64/u64, ع32/f32, ع64/f64 مع bool, string, c_ptr. تعني unit غياب النتيجة. استخدم دع / let للثبات ومتغير / var للتغيير. تتطلب الشروط قيمة منطقية. يبدأ مثال الجمع البسيط، وتشرح مرجعية الأعداد الأنواع الدقيقة والتحويلات الصريحة.
صرّح بأنواع معاملات الدالة ونتيجتها. افحص المثال المرفوض ثم صحح الربط القابل للتغيير. التشخيص يحدد سبب الخطأ وموضعه، أما توقف وقت التشغيل فينهي التنفيذ فورا.
اقرأ المثال وافحصه تابع إلى العقد الدقيق الحدود المعيارية للإصداراربط اسما محليا بمكتبة ورمز حرفيين عبر محوّل محدد. ضع غير_آمن / unsafe على التصريح وعلى كل استدعاء. افحص المثال محليا قبل تشغيله على المضيف المدعوم.
يحتوي ملف .aspl واحد على تعريفات الدوال والتصريحات الخارجية. دالة ابدأ_الرئيسية / start_main إلزامية بلا معاملات وبنتيجة i64. المجال الصحيح للحالة 0..255، وأي قيمة أخرى توقف التنفيذ ولا تُختزل.
مقبول: دوال على المستوى الأعلى. مرفوض: متغير عام، عبارة خارج دالة، دالة بداية مفقودة أو استدعاؤها من المصدر.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "" native: check 0; success / status 0; stdout ""نزّل المصدر افتح في المحرر
aspl check hello.aspl
aspl run hello.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "" native: check 0; success / status 0; stdout ""نزّل المصدر افتح في المحرر
aspl check hello.aspl
aspl run hello.aspl
الأسباب والنتائج: missing-entry-function, invalid-entry-signature, entry-call-not-allowed; trap / invalid-process-status
تطبيق المضيف: shared
المصدر UTF-8 صارم وفق Unicode 17.0. الأسماء حساسة لحالة الحروف وبتطبيع NFC، وبخط عربي أو لاتيني واحد لكل اسم. المفردات والعوامل الإنجليزية بدائل مطابقة ويمكن مزجها. الأرقام وعلامات الترقيم في الشيفرة من ASCII، وتكتب المساواة والاقتران والفصل بـ matches وand وor أو ببدائلها العربية يطابق وتطابق وو وأو. للأعداد بادئات 0x/0X و0b/0B أو 0س و0ث؛ سداسي عشر العربية يستخدم ا ب ت ث ج ح للقيم 10 إلى 15. تنتهي العبارات بـ . أو ;. يبقى كل رمز عددي LTR في ترتيب المصدر المنطقي، ولا يغير ترتيب العرض بايتات المصدر.
مقبول: كلمات عربية وإنجليزية وبادئا عدد في البرنامج نفسه. مرفوض: أرقام غير محولة خارج النصوص والتعليقات، أو اسم يجمع الخطين، أو تهجئة سداسية عشر تخلط الأبجديتين. يحول المحرر أرقام العربية الهندية والفارسية إلى ASCII خارج النصوص والتعليقات ويعرض محارف التحكم غير المرئية بوضوح.
الأسباب والنتائج: non-ascii-digit, mixed-script-identifier
تطبيق المضيف: shared
لا توجد تحويلات ضمنية. كل قيمة عددية مكتوبة لها نوعها الدقيق وعرضها وإشارتها. العمليات تحتاج نوعي معاملين متطابقين، والحدود أو الحاويات لا تحوّل القيمة. التحويل الوحيد هو تطبيق اسم نوع عددي صريح مثل ط8(value) أو u8(value)، وقد يوقف التنفيذ عند عدم تمثيل القيمة. يبقى ص64/i64 لنتيجة البداية والفهارس والأطوال وحدود يونيكود. النص ثابت، وc_ptr معتم وقابل للقيمة الفارغة، ولا يمكن تخزين unit. يتيح الربط المهيأ استنتاج النوع، وتتطلب if, while شرطا منطقيا، وreturn نتيجة من النوع المعلن.
مقبول: تعديل رابط معلن للتغيير، ومقارنة تنتج شرطا منطقيا. مرفوض: رابط بلا تهيئة، تعديل رابط ثابت أو مزج أنواع الأعداد ضمنيا.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
متغير المجموع: ص64 = 0.
متغير العدد: ص64 = 1.
طالما (العدد <= 10) {
المجموع = المجموع + العدد.
العدد = العدد + 1.
}
إذا (المجموع يطابق 55) {
اطبع("55\n").
أرجع 0.
}
أرجع 1.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "55\n" native: check 0; success / status 0; stdout "55\n"نزّل المصدر افتح في المحرر
aspl check sum-ar.aspl
aspl run sum-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
var المجموع: i64 = 0;
var العدد: i64 = 1;
while (العدد <= 10) {
المجموع = المجموع + العدد;
العدد = العدد + 1;
}
if (المجموع matches 55) {
print("55\n");
return 0;
}
return 1;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "55\n" native: check 0; success / status 0; stdout "55\n"نزّل المصدر افتح في المحرر
aspl check sum-en.aspl
aspl run sum-en.aspl
المتصفح والمضيف الأصلي
fn ابدأ_الرئيسية() -> ص64 {
متغير المجموع: ص64 = 0;
متغير العدد: ص64 = 1;
طالما (العدد <= 10) {
المجموع = المجموع + العدد;
العدد = العدد + 1;
}
إذا (المجموع matches 55) {
print("55\n");
return 0;
}
أرجع 1;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "55\n" native: check 0; success / status 0; stdout "55\n"نزّل المصدر افتح في المحرر
aspl check sum-mixed.aspl
aspl run sum-mixed.aspl
الأسباب والنتائج: immutable-assignment, type-mismatch; trap / integer-overflow
تطبيق المضيف: shared
الأزواج المحجوزة هي ص8/i8 من -128 إلى 127، ص16/i16 من -32768 إلى 32767، ص32/i32 من -2147483648 إلى 2147483647، ص64/i64 من -9223372036854775808 إلى 9223372036854775807، ط8/u8 من 0 إلى 255، ط16/u16 من 0 إلى 65535، ط32/u32 من 0 إلى 4294967295، ط64/u64 من 0 إلى 18446744073709551615، وع32/f32 وع64/f64 لـ IEEE 754 binary32 وbinary64. كل زوج اسم واحد لنوع واحد، ولا يجوز تعريف أي من هذه الأسماء أو أسماء التحليل والتنسيق.
مقبول: قيمة حرفية في موضع نوع معلوم، وتحويل صريح، وقائمة list[u8] منسوخة ثم معدلة. مرفوض: معاملان مكتوبان بنوعين مختلفين، أو تحويل ضمني عند ربط أو استدعاء أو إرجاع أو عنصر قائمة أو حقل سجل أو حمولة نتيجة.
العدد العشري ذو الأصفار البادئة عشري. يقبل السداسي عشر اللاتيني 0x/0X الأرقام وa..f/A..F، ويقبل 0س الأرقام وا ب ت ث ج ح. يقبل الثنائي 0b/0B أو 0ث. يحتاج كل بادئ رقما واحدا على الأقل. تسمح _ بين رقمين صحيحين فقط، فلا تلامس البادئ أو النقطة أو الأس ولا تبدأ أو تنتهي أو تتكرر. لا توجد لاحقات نوعية أو ثماني أو عائم سداسي عشر أو حرفيات NaN أو infinity. النقطة منهي للعبارة ما لم تبدأ كسرا: 1. عدد صحيح ثم منهي و1.0. عدد عائم ثم منهي.
الأسبقية من الأقوى إلى الأضعف هي الاستدعاء والفهرسة والحقل والتجميع، ثم ! - ~، ثم * / %، ثم + -، ثم الإزاحات، ثم & ثم ^ ثم |، ثم المقارنات المرتبة، ثم المساواة، ثم AND المنطقي ثم OR المنطقي. العمليات الثنائية يسارية والوحادية يمينية. نوع السياق يأتي من التصريح أو الإسناد أو المعامل أو الإرجاع أو الحقل أو القائمة أو النتيجة أو معامل مكتوب. العدد بلا سياق هو i64 أو f64. يقبل السالب المباشر أصغر قيمة موقعة، ويمتد حرفي u64 السياقي إلى 18446744073709551615. لا يختار الفاحص أصغر نوع مناسب ولا يحول قيمة مكتوبة سابقا.
الجمع والطرح والضرب والقسمة تحتاج نوعا متطابقا وتعيده، و% للصحيح فقط. فائض الجمع والطرح والضرب والسالب يوقف التنفيذ بـinteger-overflow بدلا من الالتفاف. القسمة تقطع نحو الصفر، والباقي بإشارة المقسوم، والصفر أو أصغر موقّع على -1 يوقف التنفيذ. تعمل ~ & ^ | << >> بعرض المعامل بالضبط. عد الإزاحة أي عدد صحيح، ولا يحول إلى نوع الطرف الأيسر. العدد السالب أو الذي يساوي العرض أو يتجاوزه يوقف التنفيذ بـinvalid-shift-count. اليسرى تطرح البتات العالية، واليمنى غير الموقعة تصفر والعلامية تمد الإشارة.
كل عملية f32 أو f64 تقرب لأقرب زوجي عند عرضها قبل العملية التالية. لا يوجد دمج مضاعفة وجمع. تبقى الأعداد دون العادية، والصفر الموقع، واللانهاية، ونتائج IEEE للقسمة على الصفر. تسوى NaN الناتجة إلى NaN هادئة موجبة، ومقارنتها المرتبة كاذبة. يطبق التحويل الصريح أي اسم نوع على تعبير عددي فقط. تحويل الصحيح إلى صحيح يفحص المدى، والصحيح إلى العائم يقرب العدد الرياضي مباشرة إلى عرض الهدف لأقرب زوجي، وكل صحيح منته؛ لذلك يتحول أكبر u64 إلى 2^64 في f64. العائم إلى صحيح يقطع أولا ثم يفحص المدى، وتحويلات العرض العائم تقرب ولا توقف التنفيذ. الفشل المعتمد على قيمة التحويل لا يقع إلا إذا وصل التنفيذ إليه؛ تصنيفاته below-range وabove-range وnan وpositive-infinity وnegative-infinity. تكمل التحويلات المتداخلة من الداخل وتحفظ كل نقطة تقريب.
لكل نوع محلل ومنسق: حلل_ص8/parse_i8 ونسق_ص8/format_i8؛ حلل_ص16/parse_i16 ونسق_ص16/format_i16؛ حلل_ص32/parse_i32 ونسق_ص32/format_i32؛ حلل_ص64/parse_i64 ونسق_ص64/format_i64؛ حلل_ط8/parse_u8 ونسق_ط8/format_u8؛ حلل_ط16/parse_u16 ونسق_ط16/format_u16؛ حلل_ط32/parse_u32 ونسق_ط32/format_u32؛ حلل_ط64/parse_u64 ونسق_ط64/format_u64؛ حلل_ع32/parse_f32 ونسق_ع32/format_f32؛ حلل_ع64/parse_f64 ونسق_ع64/format_f64. المحلل يأخذ string ويعيد result[T]، والمنسق يأخذ T بالضبط ويعيد string. نص الصحيح إشارة ASCII اختيارية ثم أرقام ASCII عشرية. نص العائم أرقام، وكسر اختياري بأرقام تالية، وأُس اختياري بأرقام، أو واحد من nan, inf, +inf, -inf. هذه قواعد نص وقت التشغيل وليست قواعد حرفيات المصدر: ترفض المسافات والفواصل والبادئات واللاحقات وNUL والذيل والأرقام غير ASCII، ورفض .5 و1. للعائم. يفحص المحلل البنية كلها قبل المدى. الرسائل الحرفية هي invalid number for T أو number out of range for T (MIN through MAX) أو finite number out of range for T. النتيجة الفاشلة بلا تشخيص أو موضع أو أثر. التنسيق ASCII حتمي وقابل للذهاب والإياب للقيم العائمة المنتهية، ويطبع -0 وnan وinf و-inf كما هي.
تخزن الروابط والمعاملات والنتائج وحقول السجلات والقوائم وحمولات النتائج الأنواع العشرة بدقة. لكل خانة محجوزة في قائمة رقمية عرضها: 1 بايت لـi8/u8، و2 لـi16/u16، و4 لـi32/u32/f32، و8 لـi64/u64/f64. طول القائمة والسعة والرسوم منفصلة: القائمة الفارغة سعتها صفر، والسعة غير الفارغة بين الطول وmax(4, 2 * length)، ورسوم العناصر capacity * width. النسخ تشترك أولا ثم تنفصل عند التعديل، وتحرر الذاكرة بعد آخر مالك. لا يوجد عرض بايت عام أو وعد بعنوان أو محاذاة أو ترتيب بايتات أو مخطط C. توقف الذاكرة أو الإلغاء أو فشل التخصيص لا ينشر تعديلا جزئيا.
هذا توثيق تطويري لـ ASPL 0.4.0 وبايت كود خاص إصدار 4 وسلك نتيجة المتصفح إصدار 3. مثال المساهم فقط هو إنشاء بايت كود إصدار 4 صالح ثم تغيير البايت عند الإزاحة 36 بلا تحديث CRC، وحفظه باسم corrupted-v4.asplbc ثم تمريره إلى validate-bytecode corrupted-v4.asplbc؛ يعطي load-failure / invalid-bytecode قبل التنفيذ. ليس هذا مسارا عاما. خطأ الفحص وتشخيصه، وفخ ASPL، وresult الفاشلة، وفشل التحميل، وحد المورد أو الإلغاء أو فشل المضيف نتائج مختلفة. تعرض التشخيصات والفخاخ حقولها التقنية ASCII كاملة العرض في العربية والإنجليزية. التنفيذ المباشر يحدد موضع المصدر؛ البرنامج الأصلي المولد يحدد اسم الدالة وفهرس التعليمة النسبي.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
دع الحد: ط64 = 18446744073709551615.
دع مباشر: ع32 = 1.0000000596046448.
دع بتات: ط8 = 0سحح.
دع محول: ط8 = ط8(255).
إذا (نسق_ط64(الحد) != "18446744073709551615") { أرجع 1. }
إذا (نسق_ع32(مباشر) != "1.00000012") { أرجع 2. }
إذا ((بتات & 0س0ح) != 15 أو (بتات >> 4) != 15 أو محول != 255) { أرجع 3. }
متغير بايتات: قائمة[ط8] = [0, 255].
متغير نسخة: قائمة[ط8] = بايتات.
نسخة[0] = بتات << 0.
إذا (بايتات[0] != 0 أو نسخة[0] != 255) { أرجع 4. }
اطبع("numeric types\n").
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "numeric types\n" native: check 0; success / status 0; stdout "numeric types\n"نزّل المصدر افتح في المحرر
aspl check numeric-types-ar.aspl
aspl run numeric-types-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
let الحد: ط64 = 18446744073709551615;
let مباشر: f32 = 1.0000000596046448;
let بتات: ط8 = 0سحح;
let محول: ط8 = ط8(255);
if (format_u64(الحد) != "18446744073709551615") { return 1; }
if (format_f32(مباشر) != "1.00000012") { return 2; }
if ((بتات & 0س0ح) != 15 or (بتات >> 4) != 15 or محول != 255) { return 3; }
var بايتات: list[ط8] = [0, 255];
var نسخة: list[ط8] = بايتات;
نسخة[0] = بتات << 0;
if (بايتات[0] != 0 or نسخة[0] != 255) { return 4; }
print("numeric types\n");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "numeric types\n" native: check 0; success / status 0; stdout "numeric types\n"نزّل المصدر افتح في المحرر
aspl check numeric-types-en.aspl
aspl run numeric-types-en.aspl
المتصفح والمضيف الأصلي
fn ابدأ_الرئيسية() -> i64 {
دع maximum: u64 = 18446744073709551615.
let direct: ع32 = 1.0000000596046448;
let latin: ط8 = 0xff;
دع عربي: u8 = 0سحح.
let binary_latin: u8 = 0b0011;
دع binary_arabic: ط8 = 0ث0011.
let converted: u8 = ط8(255);
if (نسق_ط64(maximum) != "18446744073709551615") { return 1. }
إذا (format_f32(direct) != "1.00000012") { أرجع 2; }
if ((latin & 0x0f) != 15 or (عربي >> 4) != 15) { return 3. }
إذا ((binary_latin | binary_arabic) != 3 أو converted != 255) { أرجع 4; }
var bytes: قائمة[u8] = [0, latin];
متغير copy: list[ط8] = bytes.
copy[0] = عربي.
if (bytes[0] != 0 or copy[0] != 255) { return 5. }
print("numeric types\n");
return 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "numeric types\n" native: check 0; success / status 0; stdout "numeric types\n"نزّل المصدر افتح في المحرر
aspl check numeric-types-mixed.aspl
aspl run numeric-types-mixed.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
دع بايت: ط8 = 256.
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check source-error; source-error / numeric-literal-out-of-range; stdout "" native: check 1; source-error / status 1 / numeric-literal-out-of-range; stdout ""نزّل المصدر افتح في المحرر
aspl check numeric-range-check-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
let بايت: ط8 = 256;
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check source-error; source-error / numeric-literal-out-of-range; stdout "" native: check 1; source-error / status 1 / numeric-literal-out-of-range; stdout ""نزّل المصدر افتح في المحرر
aspl check numeric-range-check-en.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
دع بايت: ط8 = ط8(256).
اطبع(نسق_ط8(بايت)).
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; trap / invalid-numeric-conversion; stdout "" native: check 0; success / status 5 / invalid-numeric-conversion; stdout ""نزّل المصدر افتح في المحرر
aspl check numeric-conversion-trap-ar.aspl
aspl run numeric-conversion-trap-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
let بايت: ط8 = ط8(256);
print(format_u8(بايت));
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; trap / invalid-numeric-conversion; stdout "" native: check 0; success / status 5 / invalid-numeric-conversion; stdout ""نزّل المصدر افتح في المحرر
aspl check numeric-conversion-trap-en.aspl
aspl run numeric-conversion-trap-en.aspl
الأسباب والنتائج: source-error / numeric-literal-out-of-range; trap / integer-overflow, integer-zero-divisor, invalid-shift-count, invalid-numeric-conversion; result / invalid-number, number-out-of-range; load-failure / invalid-bytecode; limit-stop, cancelled, host-failure
تطبيق المضيف: shared
النص قيمة UTF-8 ثابتة. يحسب طول / length: (string) -> i64 عدد القيم العددية بدءا من الصفر. يعيد محرف_عند / char_at: (string, i64) -> string قيمة واحدة كنص، ويعيد رمز_عند / codepoint_at: (string, i64) -> i64 قيمتها العددية. يبني من_رمز / from_codepoint: (i64) -> string حرفا من قيمة صالحة تشمل الصفر وترفض البدائل والقيم خارج U+10FFFF. يقتطع اقتطع / slice: (string, i64, i64) -> string من البداية شاملا إلى النهاية مستبعدا. يجمع + نصين فقط بالأسبقية الحالية ولا ينسق الأعداد ضمنيا. يجمع اجمع_نصوص / join: (list[string], string) -> string قائمة نصوص بفاصل بين العناصر فقط، فيحسب الحجم مرة واحدة ويخصص النتيجة مرة واحدة؛ القائمة الفارغة تعطي النص الفارغ. يحلل حلل_ص64 / parse_i64: (string) -> result[i64] إشارة ASCII اختيارية تليها أرقام عشرية ASCII تقبل الأصفار البادئة عبر كامل مدى i64 بما فيه أصغر قيمة، ويرفض المسافات والفواصل واللواحق وNUL والذيل والأرقام غير ASCII، ويرجع invalid-number أو number-out-of-range كنتيجة قابلة للاسترداد. ينسق نسق_ص64 / format_i64: (i64) -> string التمثيل العشري القياسي بلا إشارة موجبة أو تجميع أو أصفار زائدة. يحلل حلل_ع64 / parse_f64: (string) -> result[f64] نصا عشريا ASCII بإشارة اختيارية ونقطة عشرية وأس اختياري مع قبول النصوص الصحيحة والتهجئات nan وinf و+inf و-inf، ويرفض المسافات والذيل والأرقام غير ASCII، ويرجع invalid-number أو number-out-of-range كنتيجة قابلة للاسترداد. ينسق نسق_ع64 / format_f64: (f64) -> string نص ASCII مستقلا عن اللغة يقرأه التحليل إلى القيمة الثنائية نفسها ويستخدم nan وinf و-inf للقيم غير المنتهية. تبقى NUL وعلامات الاتجاه والمسافات والتطبيع كما هي، والمساواة بالبايتات الدقيقة.
مقبول: نص فارغ ومقاطع فارغة ودمج نصين وجمع قائمة نصوص بفاصل وتحليل أعداد صحيحة وعشرية وتنسيقها ذهابا وإيابا. مرفوض: فهرس سالب أو خارج النطاق أو مقطع معكوس أو قيمة يونيكود غير صالحة أو مزج نص مع عدد أو عناصر غير نصية في الجمع أو نص عددي بمسافات أو ذيل.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
دع المتن = "aمرحبا😀".
إذا (طول(المتن) != 7) { أرجع 1. }
إذا (محرف_عند(المتن, 1) != "م") { أرجع 2. }
إذا (رمز_عند(المتن, 1) != 1605) { أرجع 3. }
إذا (من_رمز(65) != "A") { أرجع 4. }
إذا (اقتطع(المتن, 1, 3) != "مر") { أرجع 5. }
دع الرسالة = المتن + "!".
اطبع(الرسالة).
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "aمرحبا😀!" native: check 0; success / status 0; stdout "aمرحبا😀!"نزّل المصدر افتح في المحرر
aspl check strings-ar.aspl
aspl run strings-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
let المتن = "aمرحبا😀";
if (length(المتن) != 7) { return 1; }
if (char_at(المتن, 1) != "م") { return 2; }
if (codepoint_at(المتن, 1) != 1605) { return 3; }
if (from_codepoint(65) != "A") { return 4; }
if (slice(المتن, 1, 3) != "مر") { return 5; }
let الرسالة = المتن + "!";
print(الرسالة);
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "aمرحبا😀!" native: check 0; success / status 0; stdout "aمرحبا😀!"نزّل المصدر افتح في المحرر
aspl check strings-en.aspl
aspl run strings-en.aspl
المتصفح والمضيف الأصلي
fn ابدأ_الرئيسية() -> ص64 {
دع المتن = "aمرحبا😀";
if (طول(المتن) != 7) { return 1; }
إذا (char_at(المتن, 1) != "م") { أرجع 2. }
let رمز = رمز_عند(المتن, 1);
if (رمز != 1605) { return 3; }
دع حرف = from_codepoint(65).
إذا (حرف != "A") { أرجع 4. }
let مقطع = اقتطع(المتن, 1, 3);
if (مقطع != "مر") { return 5; }
دع الرسالة = المتن + "!";
اطبع(الرسالة).
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "aمرحبا😀!" native: check 0; success / status 0; stdout "aمرحبا😀!"نزّل المصدر افتح في المحرر
aspl check strings-mixed.aspl
aspl run strings-mixed.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
دع فارغة: قائمة[نص] = [].
إذا (اجمع_نصوص(فارغة, ",") != "") { أرجع 1. }
دع واحدة: قائمة[نص] = ["مرحبا"].
إذا (اجمع_نصوص(واحدة, ",") != "مرحبا") { أرجع 2. }
دع أجزاء: قائمة[نص] = ["a", "b", "c"].
إذا (اجمع_نصوص(أجزاء, ",") != "a,b,c") { أرجع 3. }
إذا (اجمع_نصوص(أجزاء, "") != "abc") { أرجع 4. }
اطبع(اجمع_نصوص(أجزاء, ",")).
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "a,b,c" native: check 0; success / status 0; stdout "a,b,c"نزّل المصدر افتح في المحرر
aspl check join-ar.aspl
aspl run join-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
let فارغة: list[string] = [];
if (join(فارغة, ",") != "") { return 1; }
let واحدة: list[string] = ["مرحبا"];
if (join(واحدة, ",") != "مرحبا") { return 2; }
let أجزاء: list[string] = ["a", "b", "c"];
if (join(أجزاء, ",") != "a,b,c") { return 3; }
if (join(أجزاء, "") != "abc") { return 4; }
print(join(أجزاء, ","));
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "a,b,c" native: check 0; success / status 0; stdout "a,b,c"نزّل المصدر افتح في المحرر
aspl check join-en.aspl
aspl run join-en.aspl
المتصفح والمضيف الأصلي
fn ابدأ_الرئيسية() -> ص64 {
دع فارغة: قائمة[string] = [].
if (اجمع_نصوص(فارغة, ",") != "") { return 1; }
دع واحدة: list[نص] = ["مرحبا"];
إذا (join(واحدة, ",") != "مرحبا") { أرجع 2. }
let أجزاء: قائمة[string] = ["a", "b", "c"];
if (طول(أجزاء) != 3) { return 3; }
إذا (اجمع_نصوص(أجزاء, ",") != "a,b,c") { أرجع 4. }
if (join(أجزاء, "") != "abc") { return 5; }
اطبع(join(أجزاء, ",")).
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "a,b,c" native: check 0; success / status 0; stdout "a,b,c"نزّل المصدر افتح في المحرر
aspl check join-mixed.aspl
aspl run join-mixed.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
اطبع("first: ").
دع سيئ: نتيجة[ط8] = حلل_ط8(اقرأ_سطر()).
إذا (سيئ::نجاح) {
أرجع 1.
}
اطبع(سيئ::الخطأ::الرمز).
اطبع("\nsecond: ").
دع جيد: نتيجة[ص64] = حلل_ص64(اقرأ_سطر()).
إذا (جيد::نجاح) {
إذا (نسق_ص64(-9223372036854775808) != "-9223372036854775808") { أرجع 2. }
اطبع(نسق_ص64(جيد::قيمة + 1)).
اطبع("\n").
أرجع 0.
}
أرجع 3.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "first: number-out-of-range\nsecond: 42\n" native: check 0; success / status 0; stdout "first: number-out-of-range\nsecond: 42\n" scripted stdin lines: ["256","41"]نزّل المصدر افتح في المحرر
aspl check parse-int-ar.aspl
aspl run parse-int-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
print("first: ");
let سيئ: result[ط8] = parse_u8(read_line());
if (سيئ::ok) {
return 1;
}
print(سيئ::error::code);
print("\nsecond: ");
let جيد: result[i64] = parse_i64(read_line());
if (جيد::ok) {
if (format_i64(-9223372036854775808) != "-9223372036854775808") { return 2; }
print(format_i64(جيد::value + 1));
print("\n");
return 0;
}
return 3;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "first: number-out-of-range\nsecond: 42\n" native: check 0; success / status 0; stdout "first: number-out-of-range\nsecond: 42\n" scripted stdin lines: ["256","41"]نزّل المصدر افتح في المحرر
aspl check parse-int-en.aspl
aspl run parse-int-en.aspl
المتصفح والمضيف الأصلي
fn ابدأ_الرئيسية() -> ص64 {
اطبع("first: ").
let سيئ: نتيجة[u8] = parse_u8(اقرأ_سطر()).
إذا (سيئ::ok) { أرجع 1. }
print(سيئ::الخطأ::code).
print("\nsecond: ").
دع جيد: result[ص64] = حلل_ص64(read_line()).
if (جيد::نجاح) {
إذا (format_i64(-9223372036854775808) != "-9223372036854775808") { return 2. }
اطبع(نسق_ص64(جيد::value + 1)).
print("\n").
أرجع 0.
}
return 3.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "first: number-out-of-range\nsecond: 42\n" native: check 0; success / status 0; stdout "first: number-out-of-range\nsecond: 42\n" scripted stdin lines: ["256","41"]نزّل المصدر افتح في المحرر
aspl check parse-int-mixed.aspl
aspl run parse-int-mixed.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
اطبع("first: ").
دع سيئ: نتيجة[ع32] = حلل_ع32(اقرأ_سطر()).
إذا (سيئ::نجاح) {
أرجع 1.
}
اطبع(سيئ::الخطأ::الرمز).
اطبع("\nsecond: ").
دع جيد: نتيجة[ع64] = حلل_ع64(اقرأ_سطر()).
إذا (جيد::نجاح) {
إذا (نسق_ع64(0.5) != "0.5") { أرجع 2. }
إذا (نسق_ع32(1.0000000596046448) != "1.00000012") { أرجع 3. }
اطبع(نسق_ع64(جيد::قيمة + 1.0)).
اطبع("\n").
أرجع 0.
}
أرجع 4.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "first: invalid-number\nsecond: 42\n" native: check 0; success / status 0; stdout "first: invalid-number\nsecond: 42\n" scripted stdin lines: ["12x","41"]نزّل المصدر افتح في المحرر
aspl check parse-float-ar.aspl
aspl run parse-float-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
print("first: ");
let سيئ: result[f32] = parse_f32(read_line());
if (سيئ::ok) {
return 1;
}
print(سيئ::error::code);
print("\nsecond: ");
let جيد: result[f64] = parse_f64(read_line());
if (جيد::ok) {
if (format_f64(0.5) != "0.5") { return 2; }
if (format_f32(1.0000000596046448) != "1.00000012") { return 3; }
print(format_f64(جيد::value + 1.0));
print("\n");
return 0;
}
return 4;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "first: invalid-number\nsecond: 42\n" native: check 0; success / status 0; stdout "first: invalid-number\nsecond: 42\n" scripted stdin lines: ["12x","41"]نزّل المصدر افتح في المحرر
aspl check parse-float-en.aspl
aspl run parse-float-en.aspl
المتصفح والمضيف الأصلي
fn ابدأ_الرئيسية() -> ص64 {
اطبع("first: ").
let سيئ: نتيجة[f32] = parse_f32(اقرأ_سطر()).
إذا (سيئ::ok) { أرجع 1. }
print(سيئ::الخطأ::code).
print("\nsecond: ").
دع جيد: result[ع64] = حلل_ع64(read_line()).
if (جيد::نجاح) {
إذا (format_f64(0.5) != "0.5") { return 2. }
if (نسق_ع32(1.0000000596046448) != "1.00000012") { أرجع 3. }
اطبع(نسق_ع64(جيد::value + 1.0)).
print("\n").
أرجع 0.
}
return 4.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "first: invalid-number\nsecond: 42\n" native: check 0; success / status 0; stdout "first: invalid-number\nsecond: 42\n" scripted stdin lines: ["12x","41"]نزّل المصدر افتح في المحرر
aspl check parse-float-mixed.aspl
aspl run parse-float-mixed.aspl
الأسباب والنتائج: type-mismatch, argument-count-mismatch; trap / string-index-out-of-bounds, string-slice-out-of-bounds, invalid-unicode-scalar
تطبيق المضيف: shared
النوع نتيجة[T] / result[T] يحمل قيمة ناجحة من النوع T أو معلومات خطأ. يبني نجاح / success نتيجة ناجحة بمعامل واحد يستنتج الحمولة أو بلا معاملات فينتج result[unit]، ويبني إخفاق / failure نتيجة فاشلة من رمز نصي ورسالة نصية ويحتاج نوع النتيجة المتوقع من التصريح أو الإسناد أو المعامل أو الإرجاع. يقرأ :: اللاحق الحقول نجاح / ok وقيمة / value والخطأ / error على النتيجة، والرمز / code والرسالة / message على معلومات_خطأ / error_info، ويرتبط أشد من الحساب ولا يترجم أسماء المستخدم. قراءة الفرع الخاطئ توقف التنفيذ، وقراءة حمولة result[unit] خطأ وقتي الترجمة، وتبقى رموز الأخطاء نصوصا ثابتة منفصلة عن الرسائل.
مقبول: إرجاع نجاح أو إخفاق من دالة وتمرير النتائج وإرجاعها وفحص العلم ثم قراءة الفرع الصحيح. مرفوض: إخفاق بلا نوع متوقع أو حقل مجهول أو قراءة القيمة من نتيجة فاشلة أو الخطأ من نتيجة ناجحة أو مساواة نتيجتين.
المتصفح والمضيف الأصلي
دالة حي(الاسم: نص) -> نتيجة[نص] {
إذا (الاسم يطابق "") {
أرجع إخفاق("empty-name", "name was empty").
}
أرجع نجاح("hello " + الاسم).
}
دالة ابدأ_الرئيسية() -> ص64 {
دع جيد: نتيجة[نص] = حي("aspl").
إذا (جيد::نجاح) {
اطبع(جيد::قيمة).
اطبع(" ").
} وإلا {
أرجع 1.
}
دع سيئ: نتيجة[نص] = حي("").
إذا (سيئ::نجاح) {
أرجع 2.
}
اطبع(سيئ::الخطأ::الرمز).
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "hello aspl empty-name" native: check 0; success / status 0; stdout "hello aspl empty-name"نزّل المصدر افتح في المحرر
aspl check results-ar.aspl
aspl run results-ar.aspl
المتصفح والمضيف الأصلي
fn حي(الاسم: string) -> result[string] {
if (الاسم matches "") {
return failure("empty-name", "name was empty");
}
return success("hello " + الاسم);
}
fn start_main() -> i64 {
let جيد: result[string] = حي("aspl");
if (جيد::ok) {
print(جيد::value);
print(" ");
} else {
return 1;
}
let سيئ: result[string] = حي("");
if (سيئ::ok) {
return 2;
}
print(سيئ::error::code);
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "hello aspl empty-name" native: check 0; success / status 0; stdout "hello aspl empty-name"نزّل المصدر افتح في المحرر
aspl check results-en.aspl
aspl run results-en.aspl
المتصفح والمضيف الأصلي
fn greet(name: string) -> نتيجة[string] {
إذا (name matches "") {
return إخفاق("empty-name", "name was empty");
}
return نجاح("hello " + name);
}
fn ابدأ_الرئيسية() -> i64 {
دع good: result[string] = greet("aspl").
if (good::نجاح) {
اطبع(good::value);
print(" ");
} وإلا {
return 1;
}
let bad: نتيجة[string] = greet("");
إذا (bad::ok) {
أرجع 2.
}
print(bad::الخطأ::code);
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "hello aspl empty-name" native: check 0; success / status 0; stdout "hello aspl empty-name"نزّل المصدر افتح في المحرر
aspl check results-mixed.aspl
aspl run results-mixed.aspl
الأسباب والنتائج: result-type-required, invalid-field, unit-value-not-allowed, type-mismatch; trap / wrong-result-branch
تطبيق المضيف: shared
النوع قائمة[T] / list[T] يخزن عددا متغيرا من القيم من النوع نفسه T. تبني الليترالات المربعة قيمها بترتيب الكتابة وتسمح بفاصلة أخيرة، ويستنتج الليترال غير الفارغ نوع عنصره بدقة بلا تحويل عددي، بينما يحتاج الليترال الفارغ نوع العنصر المتوقع من التصريح أو الإسناد أو المعامل أو الإرجاع. تقبل العناصر القوائم المتداخلة وأنواع القيم المخزنة الحالية وترفض عناصر unit ومساواة القوائم الكاملة. يقرأ الفهرس [i] العنصر بالقيمة بدءا من الصفر، ويعيد طول / length عدد العناصر بزمن ثابت من نوع i64. الفهرس السالب أو الخارج عن النطاق يوقف التنفيذ. يضيف أضف / append عنصرا من نوع العنصر نفسه ويعيد unit، ويستبدل الإسناد المفهرس xs[i] = v عنصرا واحدا. تتطلب كلتا العمليتين ربط var جذرا، وتحسم الفهارس من اليسار إلى اليمين مرة واحدة قبل قيمة الإسناد. نسخ القوائم مستقلة: تغيير نسخة، بما فيها القوائم المتداخلة، لا يغير الأصل. تحفظ القوائم الرقمية i8/u8 في بايت لكل خانة محجوزة وi16/u16 في اثنين وi32/u32/f32 في أربعة وi64/u64/f64 في ثمانية، من دون تحويل أو وعد بعرض بايت عام.
مقبول: ليترال فارغ بنوع متوقع وفاصلة أخيرة وقوائم متداخلة وتمرير القوائم وإرجاعها وقراءة العناصر وطولها وإضافة العناصر واستبدالها عبر جذر var ونسخ مستقلة. مرفوض: ليترال فارغ بلا نوع متوقع أو خلط أنواع العناصر أو عناصر unit أو مساواة قائمتين أو فهرس سالب أو خارج النطاق أو التغيير عبر ربط let أو معامل أو قيمة مؤقتة.
المتصفح والمضيف الأصلي
دالة المجموع(القيم: قائمة[ص64]) -> ص64 {
أرجع القيم[0] + القيم[1] + القيم[2].
}
دالة ابدأ_الرئيسية() -> ص64 {
دع القيم: قائمة[ص64] = [3, 4, 5].
إذا (طول(القيم) != 3) { أرجع 1. }
إذا (المجموع(القيم) != 12) { أرجع 2. }
دع بايتات: قائمة[ط8] = [0, 255].
إذا (طول(بايتات) != 2 أو بايتات[0] != 0 أو بايتات[1] != 255) { أرجع 3. }
دع كسور: قائمة[ع64] = [0.5].
إذا (كسور[0] != 0.5) { أرجع 4. }
اطبع("12").
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "12" native: check 0; success / status 0; stdout "12"نزّل المصدر افتح في المحرر
aspl check lists-ar.aspl
aspl run lists-ar.aspl
المتصفح والمضيف الأصلي
fn المجموع(القيم: list[i64]) -> i64 {
return القيم[0] + القيم[1] + القيم[2];
}
fn start_main() -> i64 {
let القيم: list[i64] = [3, 4, 5];
if (length(القيم) != 3) { return 1; }
if (المجموع(القيم) != 12) { return 2; }
let بايتات: list[ط8] = [0, 255];
if (length(بايتات) != 2 or بايتات[0] != 0 or بايتات[1] != 255) { return 3; }
let كسور: list[f64] = [0.5];
if (كسور[0] != 0.5) { return 4; }
print("12");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "12" native: check 0; success / status 0; stdout "12"نزّل المصدر افتح في المحرر
aspl check lists-en.aspl
aspl run lists-en.aspl
المتصفح والمضيف الأصلي
fn total(القيم: list[ص64]) -> i64 {
return القيم[0] + القيم[1] + القيم[2];
}
fn ابدأ_الرئيسية() -> ص64 {
دع xs: قائمة[i64] = [3, 4, 5].
if (طول(xs) != 3) { return 1; }
إذا (total(xs) != 12) { أرجع 2. }
let bytes: قائمة[u8] = [0, 255];
إذا (length(bytes) != 2 أو bytes[0] != 0 أو bytes[1] != 255) { return 3. }
let fractions: list[ع64] = [0.5];
if (fractions[0] != 0.5) { أرجع 4. }
print("12");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "12" native: check 0; success / status 0; stdout "12"نزّل المصدر افتح في المحرر
aspl check lists-mixed.aspl
aspl run lists-mixed.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
متغير xs: قائمة[ص64] = [1, 2].
أضف(xs, 3).
إذا (طول(xs) != 3) { أرجع 1. }
متغير نسخة: قائمة[ص64] = xs.
نسخة[0] = 9.
إذا (xs[0] != 1) { أرجع 2. }
إذا (نسخة[0] != 9) { أرجع 3. }
أضف(xs, xs[0]).
إذا (طول(xs) != 4) { أرجع 4. }
إذا (xs[3] != 1) { أرجع 5. }
متغير nested: قائمة[قائمة[ص64]] = [[1], [2]].
دع nested_copy: قائمة[قائمة[ص64]] = nested.
nested[0][0] = 7.
إذا (nested_copy[0][0] != 1) { أرجع 6. }
إذا (nested[0][0] != 7) { أرجع 7. }
متغير grown: قائمة[ص64] = [].
متغير k = 0.
طالما (k < 32) { أضف(grown, k * 2). k = k + 1. }
إذا (طول(grown) != 32) { أرجع 8. }
إذا (grown[31] != 62) { أرجع 9. }
grown[0] = grown[31].
إذا (grown[0] != 62) { أرجع 10. }
متغير بايتات: قائمة[ط8] = [0, 255].
متغير نسخة_بايتات: قائمة[ط8] = بايتات.
نسخة_بايتات[0] = 255.
إذا (بايتات[0] != 0 أو نسخة_بايتات[0] != 255) { أرجع 11. }
متغير كسور: قائمة[ع64] = [0.5].
كسور[0] = 1.5.
إذا (كسور[0] != 1.5) { أرجع 12. }
اطبع("32").
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "32" native: check 0; success / status 0; stdout "32"نزّل المصدر افتح في المحرر
aspl check list-mutation-ar.aspl
aspl run list-mutation-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
var xs: list[i64] = [1, 2];
append(xs, 3);
if (length(xs) != 3) { return 1; }
var نسخة: list[i64] = xs;
نسخة[0] = 9;
if (xs[0] != 1) { return 2; }
if (نسخة[0] != 9) { return 3; }
append(xs, xs[0]);
if (length(xs) != 4) { return 4; }
if (xs[3] != 1) { return 5; }
var nested: list[list[i64]] = [[1], [2]];
let nested_copy: list[list[i64]] = nested;
nested[0][0] = 7;
if (nested_copy[0][0] != 1) { return 6; }
if (nested[0][0] != 7) { return 7; }
var grown: list[i64] = [];
var k = 0;
while (k < 32) { append(grown, k * 2); k = k + 1; }
if (length(grown) != 32) { return 8; }
if (grown[31] != 62) { return 9; }
grown[0] = grown[31];
if (grown[0] != 62) { return 10; }
var بايتات: list[ط8] = [0, 255];
var نسخة_بايتات: list[ط8] = بايتات;
نسخة_بايتات[0] = 255;
if (بايتات[0] != 0 or نسخة_بايتات[0] != 255) { return 11; }
var كسور: list[f64] = [0.5];
كسور[0] = 1.5;
if (كسور[0] != 1.5) { return 12; }
print("32");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "32" native: check 0; success / status 0; stdout "32"نزّل المصدر افتح في المحرر
aspl check list-mutation-en.aspl
aspl run list-mutation-en.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
متغير xs: list[ص64] = [1, 2];
append(xs, 3);
إذا (طول(xs) != 3) { أرجع 1. }
var نسخة: قائمة[i64] = xs;
نسخة[0] = 9;
if (xs[0] != 1) { return 2; }
إذا (نسخة[0] != 9) { أرجع 3. }
append(xs, xs[0]);
if (طول(xs) != 4) { return 4; }
إذا (xs[3] != 1) { أرجع 5. }
متغير nested: list[قائمة[ص64]] = [[1], [2]];
let nested_copy: قائمة[list[ص64]] = nested;
nested[0][0] = 7;
if (nested_copy[0][0] != 1) { return 6; }
إذا (nested[0][0] != 7) { أرجع 7. }
var grown: list[i64] = [];
متغير k = 0;
while (k < 32) { أضف(grown, k * 2); k = k + 1. }
if (length(grown) != 32) { return 8; }
if (grown[31] != 62) { return 9; }
grown[0] = grown[31];
إذا (grown[0] != 62) { أرجع 10. }
var bytes: قائمة[u8] = [0, 255];
متغير byte_copy: list[ط8] = bytes.
byte_copy[0] = 255;
if (bytes[0] != 0 or byte_copy[0] != 255) { return 11. }
var fractions: قائمة[f64] = [0.5];
fractions[0] = 1.5;
إذا (fractions[0] != 1.5) { أرجع 12. }
print("32");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "32" native: check 0; success / status 0; stdout "32"نزّل المصدر افتح في المحرر
aspl check list-mutation-mixed.aspl
aspl run list-mutation-mixed.aspl
الأسباب والنتائج: immutable-assignment, invalid-assignment-target, result-type-required, type-mismatch; trap / list-index-out-of-bounds
تطبيق المضيف: shared
يعلن سجل / record نوعا اسميا في نطاق الملف بقائمة حقول مفصولة بفواصل مع نقطتين بين الاسم والنوع وفاصلة أخيرة مسموحة. تجمع الأسماء قبل حل أنواع الحقول فلا يهم ترتيب التعريفات. السجلات اسمية: تعريفان مختلفان نوعان مختلفان حتى بتطابق الحقول. البناء يذكر اسم السجل مع كل حقل مرة واحدة تماما بترتيب الكتابة، ويرفض الحقول المجهولة والناقصة والمكررة وأنواع unit. يقرأ :: اللاحق الحقول ويسلسل مع فهارس القوائم بأسبقية أعلى من الحساب، ولا يترجم أسماء حقول المستخدم أبدا. البناء في شرط if أو while مباشرة يحتاج أقواسا حتى لا يلتبس قوس الكتلة.
مقبول: سجلات متداخلة وقوائم ونتائج داخل الحقول، وتمرير السجلات وإرجاعها وحملها في نتائج ناجحة، والكتابة السياقية للقوائم الفارغة والنتائج الفاشلة داخل الحقول، وتحديث الحقول والفهارس المتداخلة عبر جذر var. مرفوض: الأنواع الدائرية المباشرة وغير المباشرة عبر القوائم أو النتائج، ومساواة سجلين كاملين، والتغيير عبر ربط let أو معامل أو قيمة مؤقتة أو إسقاط نتيجة، وقراءة حمولة result[unit].
نسخ القوائم والسجلات مستقلة بدلالات القيم: تغيير نسخة، بما فيها حقل متداخل أو قائمة داخل سجل منسوخ أو سجل داخل قائمة منسوخة، لا يغير الأصل. يفصل النسخ عند الكتابة المسار المتأثر عبر التجمعات المشتركة قبل التغيير، وينمو التخزين الفريد هندسيا للإضافة. تحسم أهداف الإسناد فهارسها من اليسار إلى اليمين مرة واحدة قبل قيمة الإسناد، ويبقى العنصر المأخوذ من القائمة نفسها صالحا أثناء النمو.
تعمم ملكية التشغيل عبر النصوص والقوائم والسجلات والنتائج وفهارس يونيكود: تبقى بايتات النصوص الحرفية مستعارة من البرنامج المترجم، والقيم المملوكة تحرر عند استبدال السجل أو تمرير المعامل أو الإرجاع أو تحديث التجمع أو تنظيف الإطار. التكرارات والتعيينات المتكررة تستعيد القيم المهملة فلا تتراكم النصوص المؤقتة، ويبقى الحي عبر انتظار read_line والاستدعاءات الخارجية والإرجاع. يحتسب حد الذاكرة التخصيصات الحية والسعات الاحتياطية والحمولات وفهارس يونيكود المؤقتة، والتنظيف محدود لا يعتمد على استدعاء C غير محدود.
المتصفح والمضيف الأصلي
سجل رمز { نوع: ص64, متن: نص, سطر: ص64, عمود: ص64 }
سجل حالة_محلل { رموز: قائمة[رمز], مؤشر: ص64 }
دالة رمز_الحالة(حالة: حالة_محلل) -> رمز {
أرجع حالة::رموز[حالة::مؤشر].
}
دالة ابدأ_الرئيسية() -> ص64 {
دع زائد: رمز = رمز { نوع: 1, متن: "+" , سطر: 2, عمود: 7 }.
إذا (زائد::نوع != 1) { أرجع 1. }
إذا (زائد::متن != "+") { أرجع 2. }
إذا (زائد::سطر != 2) { أرجع 3. }
إذا (زائد::عمود != 7) { أرجع 4. }
متغير حالة: حالة_محلل = حالة_محلل { رموز: [زائد], مؤشر: 0 }.
إذا (رمز_الحالة(حالة)::متن != "+") { أرجع 5. }
متغير منقولة: حالة_محلل = حالة.
منقولة::مؤشر = 1.
إذا (حالة::مؤشر != 0) { أرجع 6. }
إذا (منقولة::مؤشر != 1) { أرجع 7. }
منقولة::رموز[0]::عمود = 9.
إذا (حالة::رموز[0]::عمود != 7) { أرجع 8. }
إذا (منقولة::رموز[0]::عمود != 9) { أرجع 9. }
دع موجود: نتيجة[رمز] = نجاح(زائد).
إذا (موجود::نجاح) {
إذا (موجود::قيمة::سطر != 2) { أرجع 10. }
} وإلا {
أرجع 11.
}
اطبع("3 tokens").
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "3 tokens" native: check 0; success / status 0; stdout "3 tokens"نزّل المصدر افتح في المحرر
aspl check records-ar.aspl
aspl run records-ar.aspl
المتصفح والمضيف الأصلي
record رمز { نوع: i64, متن: string, سطر: i64, عمود: i64 }
record حالة_محلل { رموز: list[رمز], مؤشر: i64 }
fn رمز_الحالة(حالة: حالة_محلل) -> رمز {
return حالة::رموز[حالة::مؤشر];
}
fn start_main() -> i64 {
let زائد: رمز = رمز { نوع: 1, متن: "+" , سطر: 2, عمود: 7 };
if (زائد::نوع != 1) { return 1; }
if (زائد::متن != "+") { return 2; }
if (زائد::سطر != 2) { return 3; }
if (زائد::عمود != 7) { return 4; }
var حالة: حالة_محلل = حالة_محلل { رموز: [زائد], مؤشر: 0 };
if (رمز_الحالة(حالة)::متن != "+") { return 5; }
var منقولة: حالة_محلل = حالة;
منقولة::مؤشر = 1;
if (حالة::مؤشر != 0) { return 6; }
if (منقولة::مؤشر != 1) { return 7; }
منقولة::رموز[0]::عمود = 9;
if (حالة::رموز[0]::عمود != 7) { return 8; }
if (منقولة::رموز[0]::عمود != 9) { return 9; }
let موجود: result[رمز] = success(زائد);
if (موجود::ok) {
if (موجود::value::سطر != 2) { return 10; }
} else {
return 11;
}
print("3 tokens");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "3 tokens" native: check 0; success / status 0; stdout "3 tokens"نزّل المصدر افتح في المحرر
aspl check records-en.aspl
aspl run records-en.aspl
المتصفح والمضيف الأصلي
record Token { kind: ص64, text: نص, line: ص64, column: i64 }
سجل ParserState { tokens: قائمة[Token], cursor: ص64 }
fn token_at(state: ParserState) -> Token {
return state::tokens[state::cursor];
}
fn ابدأ_الرئيسية() -> ص64 {
دع plus: Token = Token { kind: 1, text: "+", line: 2, column: 7 }.
if (plus::kind != 1) { return 1; }
إذا (plus::text != "+") { أرجع 2. }
if (plus::line != 2) { return 3; }
إذا (plus::column != 7) { أرجع 4. }
var state: ParserState = ParserState { tokens: [plus], cursor: 0 };
إذا (token_at(state)::text != "+") { أرجع 5. }
var moved: ParserState = state.
moved::cursor = 1.
if (state::cursor != 0) { return 6; }
إذا (moved::cursor != 1) { أرجع 7. }
moved::tokens[0]::column = 9.
if (state::tokens[0]::column != 7) { return 8; }
إذا (moved::tokens[0]::column != 9) { أرجع 9. }
let found: نتيجة[Token] = success(plus).
if (found::نجاح) {
إذا (found::value::line != 2) { أرجع 10. }
} وإلا {
return 11;
}
print("3 tokens");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "3 tokens" native: check 0; success / status 0; stdout "3 tokens"نزّل المصدر افتح في المحرر
aspl check records-mixed.aspl
aspl run records-mixed.aspl
الأسباب والنتائج: immutable-assignment, invalid-assignment-target, invalid-field, result-type-required, type-mismatch, recursive-type; trap / list-index-out-of-bounds, wrong-result-branch
تطبيق المضيف: shared
الدوال فريدة الاسم وعلى المستوى الأعلى، بمعاملات ونتيجة معلنة النوع. تمر القيم بالنسخ. ترتيب التعريفات لا يهم ويسمح بالاستدعاء الذاتي. يجب أن يعيد كل مسار في دالة ذات نتيجة غير unit قيمة. مثال المضروب يعيد الحالة 120 بلا خرج.
مقبول: دالة معرفة لاحقا أو استدعاء ذاتي. مرفوض: تحميل زائد، دالة متداخلة، عدد معاملات خاطئ أو مسار بلا إرجاع.
المتصفح والمضيف الأصلي
دالة مضروب(القيمة: ص64) -> ص64 {
إذا القيمة <= 1 {
أرجع 1.
}
أرجع القيمة * مضروب(القيمة - 1).
}
دالة ابدأ_الرئيسية() -> ص64 {
أرجع مضروب(5).
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 120; stdout "" native: check 0; success / status 120; stdout ""نزّل المصدر افتح في المحرر
aspl check functions-ar.aspl
aspl run functions-ar.aspl
المتصفح والمضيف الأصلي
fn مضروب(القيمة: i64) -> i64 {
if القيمة <= 1 {
return 1;
}
return القيمة * مضروب(القيمة - 1);
}
fn start_main() -> i64 {
return مضروب(5);
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 120; stdout "" native: check 0; success / status 120; stdout ""نزّل المصدر افتح في المحرر
aspl check functions-en.aspl
aspl run functions-en.aspl
الأسباب والنتائج: argument-count-mismatch, type-mismatch, missing-return
تطبيق المضيف: shared
يحمل التشخيص مفتاح سبب ثابت وشدة ومعاملات ذات أنواع وموضعا أوليا ومواضع ثانوية مرتبة وتعديلا اختياريا. اللغة تغير الصياغة فقط، وتبقى أسماء الأنواع والعوامل والحدود والقيم التقنية ASCII كاملة العرض. التحذير لا يمنع التشغيل. يربط التشغيل المباشر التشخيص بالمصدر؛ البرامج المبنية لا تحتوي خريطة المصدر، لكنها تبلغ اسم الدالة وفهرس التعليمة النسبي للفخ. المثال الأول يحاول تعديل رابط ثابت. يستبدل المثال الثاني دع / let بـمتغير / var ويعيد الحالة 1 بصورة طبيعية.
مقبول: تصحيح الرابط ثم إعادة الفحص، أو فرع نتيجة تحليل فاشلة. مرفوض: اعتبار كل حالة غير صفرية خطأ مصدر أو استثناء. فرّق بين التشخيص وفخ ASPL ونتيجة قابلة للاسترداد وفشل تحميل وحد مورد أو إلغاء أو فشل مضيف.
مثال let byte: u8 = 256 خطأ فحص لأن الحرفي السياقي خارج المدى. أما u8(256) فمعامله i64 افتراضي صالح ثم يوقف التنفيذ بفخ invalid-numeric-conversion إذا وصل إليه. وparse_u8("256") يعيد نتيجة فاشلة بالرمز number-out-of-range. لا يتحول واحد من هذه المخرجات إلى الآخر.
حقول خطأ الفحص numeric-literal-out-of-range للأعداد الصحيحة هي spelling, type, minimum, maximum، وللعائم spelling, type, classification حيث التصنيف finite-overflow. وحقول numeric-operator-not-supported هي operator, type.
حقول الفخ العددية مرتبة: integer-overflow يحمل type, operation, operand-count, operands؛ وinteger-zero-divisor يحمل type, operation, dividend؛ وinvalid-shift-count يحمل left-type, count-type, count, width؛ وinvalid-numeric-conversion يحمل source-type, target-type, classification ثم source-value أو source-bits. تحمل القيم غير الموقعة حتى u64 كاملة بلا تقريب JavaScript.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
دع قيمة = 0.
قيمة = 1.
أرجع قيمة.
}
النتائج المتوقعة والخرج الحرفي
browser: check source-error; source-error / immutable-assignment; stdout "" native: check 1; source-error / status 1 / immutable-assignment; stdout ""نزّل المصدر افتح في المحرر
aspl check diagnostic-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
let قيمة = 0;
قيمة = 1;
return قيمة;
}
النتائج المتوقعة والخرج الحرفي
browser: check source-error; source-error / immutable-assignment; stdout "" native: check 1; source-error / status 1 / immutable-assignment; stdout ""نزّل المصدر افتح في المحرر
aspl check diagnostic-en.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
متغير قيمة = 0.
قيمة = 1.
أرجع قيمة.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 1; stdout "" native: check 0; success / status 1; stdout ""نزّل المصدر افتح في المحرر
aspl check corrected-ar.aspl
aspl run corrected-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
var قيمة = 0;
قيمة = 1;
return قيمة;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 1; stdout "" native: check 0; success / status 1; stdout ""نزّل المصدر افتح في المحرر
aspl check corrected-en.aspl
aspl run corrected-en.aspl
الأسباب والنتائج: source-error / immutable-assignment, numeric-literal-out-of-range; trap / integer-overflow, integer-zero-divisor, invalid-shift-count, invalid-numeric-conversion; result / invalid-number, number-out-of-range; load-failure / invalid-bytecode; limit-stop, cancelled, host-failure
تطبيق المضيف: shared
توقيع الطباعة المدمجة هو اطبع / print: (string) -> unit. يكتب بايتات النص بالترتيب، بما فيها NUL، بلا سطر جديد أو تفريغ تلقائي. أضف \n صراحة. لا يمكن إعادة تعريف أي من الاسمين. يعرض المتصفح بايتات الخرج بأمان ولا يفسرها كترميز صفحة.
مقبول: نص واحد، بما فيه النص الفارغ. مرفوض: عدد أو معاملات متعددة أو تخزين النتيجة.
الكتابة متزامنة، والنص الفارغ لا يلمس المضيف. يعيد المضيف الأصلي محاولة الكتابات المقطوعة ويتابع الكتابات القصيرة. يبقى أي خرج مقبول قبل الفشل ظاهرا. لا توجد معالجة خاصة لإشارة SIGPIPE؛ قد ينهي الأنبوب المغلق العملية بها. إذا تجاهلت البيئة الإشارة أو حجبتها وأعادت الكتابة EPIPE، تكون النتيجة فشل مضيف بالحالة 8.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
اطبع("مرحبا\n").
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "مرحبا\n" native: check 0; success / status 0; stdout "مرحبا\n"نزّل المصدر افتح في المحرر
aspl check output-ar.aspl
aspl run output-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
print("مرحبا\n");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "مرحبا\n" native: check 0; success / status 0; stdout "مرحبا\n"نزّل المصدر افتح في المحرر
aspl check output-en.aspl
aspl run output-en.aspl
الأسباب والنتائج: type-mismatch, argument-count-mismatch; host-failure / host-operation-failed / write-program-output; limit-stop / output-limit
تطبيق المضيف: shared
الدالة المدمجة اقرأ_سطر / read_line: () -> string تقرأ سطرا واحدا. لا تقبل معاملات أو وسم غير_آمن / unsafe، ولا يمكن تعريف اسم من أسمائها. اطبع أي مطالبة قبل الاستدعاء، فالدالة نفسها لا تكتب مطالبة أو صدى أو فاصلة نهاية. ينتهي السطر بـLF أو CRLF وتزال النهاية. السطر الفارغ نص فارغ. يعاد السطر الأخير غير المنتهي مرة واحدة عند EOF، ثم يوقف الاستدعاء التالي بـinput-exhausted.
مقبول: تمرير النص المقروء إلى دالة أو إعادته أو مقارنته أو طباعته أو قياسه أو فهرسته أو اقتطاعه أو جمعه أو تحليله صراحة بدالة عددية. مرفوض: اعتبار نص المصدر أو أرقام العربية الهندية إدخالا عدديا مقبولا، أو تحويل النص ضمنيا إلى عدد.
يتحقق وقت التشغيل من بايتات السطر كلها بوصفها UTF-8 صارما. تبقى المسافات وNUL وعلامات العربية ومحارف الاتجاه والأرقام العربية الهندية وشكل التطبيع كما أرسله المضيف. لا يمر إدخال البرنامج عبر محرر المصدر أو محلله أو تحويل أرقامه. السطر غير الصالح يوقف التنفيذ بـinvalid-input-utf8 مع موضع أول بايت غير صالح.
الحد في المضيفين هو 65536 بايت حمولة للسطر، من دون LF أو CRLF. يقبل الحد بالضبط، أما تجاوزه فينهي التنفيذ بـinput-line-limit من دون نص مبتور. إلغاء التنفيذ أثناء الانتظار إلغاء وليس EOF.
تملك العملية النص غير الفارغ الناجح بملكية تشغيلية مشتركة: تبقى بايتات النص الحرفية مستعارة من البرنامج المترجم بلا نسخ، وتحمل السجلات والمعاملات والنتائج البايتات الثابتة نفسها عبر الاستدعاءات والإرجاع. استبدال ربط أو تنظيف إطار يستعيد النص المهمل، لذلك يحتسب حد ذاكرة الآلة النصوص الحية فقط.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
اطبع("ما اسمك؟ ").
دع الاسم = اقرأ_سطر().
اطبع("مرحبا ").
اطبع(الاسم).
اطبع("\n").
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "ما اسمك؟ مرحبا ليلى\n" native: check 0; success / status 0; stdout "ما اسمك؟ مرحبا ليلى\n" scripted stdin lines: ["ليلى"]نزّل المصدر افتح في المحرر
aspl check input-ar.aspl
aspl run input-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
print("ما اسمك؟ ");
let الاسم = read_line();
print("مرحبا ");
print(الاسم);
print("\n");
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "ما اسمك؟ مرحبا Mina\n" native: check 0; success / status 0; stdout "ما اسمك؟ مرحبا Mina\n" scripted stdin lines: ["Mina"]نزّل المصدر افتح في المحرر
aspl check input-en.aspl
aspl run input-en.aspl
المتصفح والمضيف الأصلي
fn مرر(value: string) -> string {
return value;
}
fn start_main() -> i64 {
print("first: ");
var first = اقرأ_سطر();
let kept = first.
let returned = مرر(first).
اطبع("second: ").
let second = read_line().
first = second.
إذا returned matches kept {
print("equal: ");
print(returned).
اطبع(" / ").
print(kept).
اطبع("\n").
return 0.
}
أرجع 1.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "first: second: equal: ١٢٣ / ١٢٣\n" native: check 0; success / status 0; stdout "first: second: equal: ١٢٣ / ١٢٣\n" scripted stdin lines: ["١٢٣","١٢٣"]نزّل المصدر افتح في المحرر
aspl check input-mixed.aspl
aspl run input-mixed.aspl
الأسباب والنتائج: argument-count-mismatch, unsafe-on-safe-call; trap / input-exhausted, invalid-input-utf8; limit-stop / input-line-limit; cancelled
تطبيق المضيف: shared
تقبل الأداة ملف مصدر واحدا. يفحص check المصدر، ويشغّل run داخل العملية، وينشر build برنامج ELF باستبدال ذري بعد التحقق. يختار --diagnostic-language=ar|en صياغة التشخيص فقط. يبقى خرج البرنامج على stdout والتشخيصات والفخاخ على stderr. لا يفتح الفحص والبناء مكتبات البرنامج. لا يستدعي البناء مترجم C أو رابطا. تعيش البرامج المبنية مستقلة عن تثبيت الأداة.
مقبول: خيارات التشخيص قبل الأمر ومسار واحد بعده. مرفوض: مصادر متعددة أو إخراج بايت كود عام أو معاملات برنامج. استخدم -- قبل مسار يبدأ بشرطة.
الأسباب والنتائج: 0 success; 1 source-error; 2 usage-error; 3 policy-rejection; 4 load-failure; 5 trap; 6 limit-stop; 7 cancelled; 8 host-failure; 9 internal-failure
تطبيق المضيف: native
aspl --diagnostic-language=en check hello.aspl
aspl run hello.aspl
aspl build -o hello hello.aspl
./hello
اقرأ المثال وافحصه
الحدود المعيارية للإصدار
يقرأ aspl run من stdin الموروث، سواء أكان طرفية أم أنبوبا أم ملفا معادا توجيهه. يعمل القارئ نفسه داخل برنامج مبني بـaspl build من نوع ELF. يحتوي البرنامج المبني بايت كود خاصا بالإصدار 4 وآلته، ويعمل بعد إزالة المترجم ووقت التشغيل من PATH.
تظهر المطالبة التي تطبعها ASPL قبل الانتظار، حتى بلا سطر جديد. يزيل القارئ نهاية السطر فقط ولا يقرأ إلى السطر التالي، ولذلك تبقى بايتات لاحقة لدالة خارجية تقرأ stdin. تقاطع الإشارة أو طلب الإيقاف أثناء الانتظار لا يتحول إلى input-exhausted.
تطبيق المضيف: native
printf 'Mina\n' | aspl run input.en.aspl
aspl build -o input input.en.aspl
printf 'Mina\n' | ./input
الحدود المعيارية للإصدار
الدالة المدمجة اقرأ_ملف_نصي / read_text_file: (string) -> result[string] تقرأ ملفا كاملا كنص UTF-8 صارم، والدالة المدمجة اكتب_ملف_نصي / write_text_file: (string, string) -> result[unit] تكتب بايتات UTF-8 المعطاة كما هي دون إضافة سطر جديد. لا تقبل أي منهما وسم غير_آمن / unsafe، ولا يمكن تعريف اسم من أسمائهما. المسار النسبي يحل ضد دليل العمل للعملية، ولا توسعة صدفية ولا إنشاء ضمني للمجلدات. الملف الفارغ ينجح بنص فارغ، وتحفظ بايتات المحتوى كما هي بما فيها BOM ونهايات الأسطر وNUL والتطبيع.
مقبول: قراءة اسم ملف من سطر إدخال ثم فحص العلم وقراءة الفرع الصحيح، وكتابة خرج نسبي بعد قراءة مساره من الإدخال. مرفوض: مسار فارغ أو توسعة صدفية أو قراءة دليل أو جهاز أو أنبوب كملف كامل، أو إنشاء المجلدات ضمنيا عند الكتابة.
يقبل المضيف الأصلي للقراءة الملفات العادية فقط، بما فيها وصلة رمزية تحل إلى ملف عادي، بحد افتراضي 16 MiB لكل ملف. يرفض أثناء الجمع لا بعده، فيعيد file-too-large دون تخصيص غير محدود. المسار الفارغ أو المحتوي على NUL يعيد invalid-path، وغير العادي يعيد not-regular-file، وغير الصالح UTF-8 يعيد invalid-utf8.
يستخدم المتصفح مجموعة ملفات افتراضية مستوردة أو مولدة، بأسماء UTF-8 دقيقة حساسة لحالة الأحرف حتى 255 بايت دون شرطات أو شرطات مائلة عكسية أو محارف تحكم، ويرفض النقطة والنقطتين. تستبدل الكتابة الناجحة الإدخال في المجموعة ذريًا، ويمكن قراءتها في التشغيل نفسه. الحد الافتراضي 1 MiB لكل ملف و64 ملفًا و8 MiB للمحتوى الكلي. لكل تشغيل ميزانية نقل تحديثات مقدارها 8 MiB، تحاسب بايتات الاسم والمحتوى و128 بايتًا لكل رسالة، حتى للمحتوى الفارغ. تجاوز أي حصة يعيد virtual-file-limit ويبقي المحتوى السابق. القراءة المفقودة تعيد not-found وغير الصالحة UTF-8 تعيد invalid-utf8 والكبيرة file-too-large. تبقى الملفات في ذاكرة الصفحة عبر التشغيلات وتغيير اللغة، وتمسح عند التحديث، دون رفع أو تخزين دائم.
تكتب الكتابة الأصلية المحتوى الفارغ بنجاح، وتطبق حد 16 MiB لكل ملف قبل النشر دون إنشاء أي ملف. تجهز الخرج في ملف مؤقت داخل مجلد الوجهة، ثم تنشره بإعادة تسمية ذرية تستبدل عنصر الدليل الأخير، بما فيه وصلة رمزية أخيرة، دون تتبعها. الفشل قبل النشر يحافظ على الوجهة السابقة وينظف الملف المؤقت، ولا وعود بمعاملات عبر ملفات ولا بمتانة ضد الأعطال. الإلغاء قبل النشر يبقي المحتوى القديم، والإلغاء بعد النشر الناجح لا يتراجع عن الكتابة.
رموز الفشل مستقرة: invalid-path للمسار الافتراضي غير الصالح وnot-found للمفقود وpermission-denied للإذن وvirtual-file-limit لحصص المتصفح وio-error لغيرها. يعود unsupported-host فقط من مضيف مساهم لا يقدم محول ملفات. استنفاد الذاكرة وفشل التخصيص والإلغاء تبقى تصنيفات تنفيذية لا نتائج قابلة للاسترداد. الفحص والبناء يتحققان من الاستدعاء دون قراءة ملف المصدر أو كتابة الخرج.
لغة الحساب المصغرة docs/examples/mini-arith/mini-arith.aspl هي الدليل المتكامل: تطلب سطرين من الإدخال هما اسم ملف المصدر والعملية (interpret أو generate)، وتطلب عند التوليد سطرا ثالثا هو اسم ملف الخرج. تفسير ملف demo.txt الذي يعلن i ومجموع وlimit ويجمع من 1 إلى 10 في حلقة while مع فرع if يطبع File: Operation: 55. التوليد يكتب مصدر ASPL صالحا عبر write_text_file بعد نجاح التحليل فقط، ثم يفحص وينفذ ويبنى بالسلسلة المعتادة فيطابق خرج المفسر. المصدر الخاطئ يفشل قبل نشر أي خرج، وفشل الخرج يحافظ على الوجهة السابقة. في المتصفح استورد demo.txt من قائمة الملفات وأجب عن الأسئلة نفسها، فيظهر الملف المولد كملف افتراضي جاهز للتنزيل دون أن يترجم المتصفح النص المولد في التشغيل نفسه. وحدة التحكم المكتبية تشغل المثال نفسه بدليل عمل ملف المصدر المختار وإدخال الأسطر المعتاد.
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
اطبع("File: ").
دع الاسم = اقرأ_سطر().
دع المحتوى: نتيجة[نص] = اقرأ_ملف_نصي(الاسم).
إذا (المحتوى::نجاح) {
اطبع(المحتوى::قيمة).
} وإلا {
اطبع("error: ").
اطبع(المحتوى::الخطأ::الرمز).
اطبع("\n").
}
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "File: error: not-found\n" native: check 0; success / status 0; stdout "File: error: not-found\n" scripted stdin lines: ["missing.txt"]نزّل المصدر افتح في المحرر
aspl check read-file-ar.aspl
aspl run read-file-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
print("File: ");
let الاسم = read_line();
let المحتوى: result[string] = read_text_file(الاسم);
if (المحتوى::ok) {
print(المحتوى::value);
} else {
print("error: ");
print(المحتوى::error::code);
print("\n");
}
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "File: error: not-found\n" native: check 0; success / status 0; stdout "File: error: not-found\n" scripted stdin lines: ["missing.txt"]نزّل المصدر افتح في المحرر
aspl check read-file-en.aspl
aspl run read-file-en.aspl
المتصفح والمضيف الأصلي
دالة ابدأ_الرئيسية() -> ص64 {
اطبع("Output: ").
دع المحفوظ: نتيجة[وحدة] = اكتب_ملف_نصي("generated.txt", "generated\n").
إذا (المحفوظ::نجاح) {
اطبع("saved\n").
} وإلا {
اطبع("error: ").
اطبع(المحفوظ::الخطأ::الرمز).
اطبع("\n").
}
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "Output: saved\n" native: check 0; success / status 0; stdout "Output: saved\n"نزّل المصدر افتح في المحرر
aspl check write-file-ar.aspl
aspl run write-file-ar.aspl
المتصفح والمضيف الأصلي
fn start_main() -> i64 {
print("Output: ");
let المحفوظ: result[unit] = write_text_file("generated.txt", "generated\n");
if (المحفوظ::ok) {
print("saved\n");
} else {
print("error: ");
print(المحفوظ::error::code);
print("\n");
}
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; success / start_main 0; stdout "Output: saved\n" native: check 0; success / status 0; stdout "Output: saved\n"نزّل المصدر افتح في المحرر
aspl check write-file-en.aspl
aspl run write-file-en.aspl
الأسباب والنتائج: argument-count-mismatch, unsafe-on-safe-call, type-mismatch; result / invalid-path, not-found, permission-denied, not-regular-file, invalid-utf8, file-too-large, io-error, virtual-file-limit, unsupported-host
تطبيق المضيف: native
printf 'hello\n' > hello.txt
printf 'hello.txt\n' | aspl run read-file.en.aspl
aspl build -o read-file read-file.en.aspl
printf 'hello.txt\n' | ./read-file
printf '\n' | aspl run write-file.en.aspl
printf 'docs/examples/mini-arith/demo.txt\ninterpret\n' | aspl run docs/examples/mini-arith/mini-arith.aspl
printf 'docs/examples/mini-arith/demo.txt\ngenerate\n/tmp/demo-generated.aspl\n' | aspl run docs/examples/mini-arith/mini-arith.aspl
aspl check /tmp/demo-generated.aspl
aspl run /tmp/demo-generated.aspl
aspl build -o /tmp/demo-generated /tmp/demo-generated.aspl
/tmp/demo-generated
الحدود المعيارية للإصدار
حين يصل البرنامج إلى read_line يعرض الملعب حالة انتظار وحقل سطر واحد وزري Send وClose input وStop. يرسل Send المسودة الحالية للطلب المعروض فقط، ثم يمسحها بعد إقرار العامل. يرسل Close input EOF ولا يرسل المسودة، وتبقى ظاهرة بوصفها غير مرسلة. يوقف Stop التنفيذ ولا يعني EOF.
لا يقبل الحقل لصقا متعدد الأسطر أو محرفي CR وLF، ويعرض حد البايتات. تبقى بايتات المسودة والأرقام كما أدخلت ولا تمر عبر محرر المصدر. تسجل أصداء الإدخال كسجلات واجهة منفصلة ولا تدخل في خرج البرنامج أو حد خرجه.
تعرض قائمة الملفات أسماء الملفات وأحجام البايت مع أزرار استيراد وتنزيل وإزالة ومسح. الاستيراد يطلب ملفات محلية دون رفعها إلى خادم، وتكتب البرامج ملفات مولدة بلا حوار تأكيد. يقبل المتصفح تحديثات الملف من الوظيفة النشطة فقط، وتبقى التحديثات التي وصلت قبل فخ أو إيقاف متاحة للتنزيل. التنزيل فعل مستخدم صريح وتلغى عناوين الكائنات المؤقتة بعده. يؤكد الاستيراد استبدال الاسم الموجود ومسح المجموعة، ويعطل التغييرات أثناء التشغيل مع تثبيت لقطة كل تشغيل. تبقى الملفات عبر التشغيلات وتغيير لغة الواجهة في ذاكرة الصفحة فقط.
يقيس حد التنفيذ زمن العمل المتراكم فقط. الوقت الذي يقضيه البرنامج منتظرا الإدخال لا يستهلكه. تحافظ أزرار Auto وLTR وRTL على بايتات الخرج والمسودة ولقطة المصدر وهوية الطلب، وتعيد تنسيق العرض والمحاذاة فقط.
تطبيق المضيف: browser
المتصفح يشغّل البايت كود محليا ويطبق سقف 10000000 تعليمة لكل تشغيل. الحلقة التالية تنتهي بالصنف limit-stop عند هذا السقف. يعرض الجدول حدود المضيفين. الوحدة MiB = 1048576 bytes والوحدة KiB = 1024 bytes. تعني none غياب سقف منتج، وتعني n/a عدم التطبيق.
مقبول: تشغيل اللغة المشتركة في المتصفح. مرفوض: استيراد خارجي حتى إن لم يُستدع. لا ترسل المثال ذي الحلقة غير المنتهية إلى التشغيل الأصلي.
| المورد | المضيف الأصلي | المتصفح |
|---|---|---|
| بايتات المصدر | 16 MiB | 1 MiB |
| الوحدات المعجمية | 1048576 | 131072 |
| عقد الصياغة | 1048576 | 131072 |
| عمق الصياغة | 256 | 128 |
| ذاكرة المترجم العاملة | 512 MiB | 128 MiB |
| بايتات البايت كود | 64 MiB | 8 MiB |
| الدوال | 65536 | 4096 |
| الاستيرادات الخارجية | 4096 | 0 |
| ثوابت الأعداد الصحيحة | 1048576 | 131072 |
| ثوابت الأعداد العائمة | 1048576 | 131072 |
| مراجع النصوص | 1048576 | 131072 |
| بايتات النصوص | 16 MiB | 2 MiB |
| حمولة سطر الإدخال | 65536 bytes | 65536 bytes |
| تعليمات البايت كود | 4194304 | 524288 |
| السجلات لكل دالة | 65536 | 8192 |
| التعليمات المنفذة | none | 10000000 |
| إطارات وقت التشغيل | 4096 | 512 |
| مواضع قيم وقت التشغيل | 1048576 | 131072 |
| ذاكرة التنفيذ المملوكة للآلة | 256 MiB | 64 MiB |
| الخرج الملتقط | none | 256 KiB |
| زمن الفحص | none | 2 s |
| زمن التنفيذ | none | 3 s |
| الذاكرة الخطية | n/a | 256 MiB |
| وظائف العامل المتزامنة | n/a | 1 |
يشمل المصدر كل بايت مقروء بما فيه علامة بداية النص. تشمل ذاكرة المترجم كل تخصيص حي للترجمة. تشمل ذاكرة التنفيذ الإطارات ومواضع القيم وإعارة النص والنصوص الحية المملوكة للتنفيذ، وتستبعد البرنامج الثابت والمكتبات وتخصيصات الشيفرة الخارجية. يتقدم فشل الحد البنيوي على حد الذاكرة عند العملية نفسها. فشل التخصيص دون السقف هو host-failure / allocation-failed.
يبدأ مؤقت الفحص حين يقبل العامل المحمّل المهمة، ومؤقت التنفيذ حين يقبل التشغيل بعد نجاح الفحص. لا يدخل التحميل في المؤقتين، ولا يدخل انتظار إدخال المستخدم في مؤقت التنفيذ. أول حد ملحوظ يحدد النتيجة؛ بلوغ الموعد ينهي العامل بسبب time-limit. يرفض حد الخرج الاستدعاء الذي يتجاوزه بأكمله ويبقي الخرج السابق جزئيا. ليس للتنفيذ الأصلي سقف منتج للتعليمات أو الوقت أو الخرج، مع بقاء الحد التمثيلي لعداد التعليمات.
يستخدم تطوير ASPL 0.4.0 صيغة البايت كود الخاصة بالإصدار 4 وسلك نتائج المتصفح للإصدار 3. ترفض البنى الحالية كل إصدار بايت كود آخر. ليست الصيغة واجهة توافق عامة.
المتصفح فقط
دالة ابدأ_الرئيسية() -> ص64 {
طالما صواب {}
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check success; limit-stop / execution-instruction-limit / ceiling 10000000; stdout ""نزّل المصدر افتح في المحرر
المتصفح فقط
fn start_main() -> i64 {
while true {}
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check success; limit-stop / execution-instruction-limit / ceiling 10000000; stdout ""نزّل المصدر افتح في المحرر
الأسباب والنتائج: policy-rejection / foreign-imports-not-supported; limit-stop / execution-instruction-limit
تطبيق المضيف: browser
هذه حدود أرشيف بيان المطابقة 0.1.1. يربط كل معرّف بالنص المرجعي الذي يملكه، ولا تصف ميزات إدخال ASPL 0.4.0.
على x86-64 Linux مع glibc، يستطيع برنامج ASPL أصلي تحميل أي مكتبة مشتركة يقبلها المحمّل الديناميكي لـglibc واستدعاء دالة مسماة حين يطابق نوعها الدقيق في C أحد محوّلات الاستدعاء الخارجي المدعومة. يدعم الإصدار الأدنى int(const char *) كـ(string) -> i64 وdouble(double) كـ(f64) -> f64. لا تضيف عائلة الأعداد محوّلات C ضيقة أو غير موقعة أو f32. اكتب تحويلات صريحة قبل حد i64 أو f64. تبقى إتاحة المكتبة وصلاحية المؤشر وسلوك الدالة الخارجية مسؤولية البرنامج.
مقبول: مكتبة ورمز حرفيان غير فارغين وبلا NUL، مع وسم عدم الأمان في الموضعين. مرفوض: تكرار المكتبة والرمز، توقيع لا يطابق المحوّل أو غياب الوسم.
المحوّل سي_صحيح__مؤشر_محرف_ثابت / c_int__const_char_ptr يحول (string) -> i64 إلى int (*)(const char *). قبل دخول C يرفض النص ذا NUL وينسخ البايتات ويضيف فاصلة النهاية. تنتهي الإعارة بعودة الدالة. يجوز القراءة فقط أثناء الاستدعاء ولا يجوز التعديل أو الاحتفاظ بالمؤشر. تحول نتيجة int بالقيمة، وتبقى القيم السالبة بيانات عادية.
المحوّل سي_مزدوج__مزدوج / c_double__double يطابق (f64) -> f64 مع double (*)(double). يمرر القيم الثنائية ويطبّع نتيجة NaN ويستعيد بيئة الحساب العائم. لا يفحص أي من المحوّلين errno أو أعلام الاستثناءات أو اصطلاحات أخطاء المكتبة.
يفحص check وbuild التصريحات بلا فتح مكتبات. يجهز التنفيذ كل الاستيرادات قبل دالة البداية بترتيب بايتات المكتبة ثم الرمز ثم رقم المحوّل. يفتح كل اسم مرة واحدة باستخدام RTLD_NOW | RTLD_LOCAL ثم يبحث عبر dlsym وdlerror. تمر الأسماء بلا تعديل وفق قواعد محمّل glibc. أول فشل يمنع دالة البداية ويغلق المقابض المفتوحة بالترتيب العكسي.
في مثال puts، نزّل المصدر وافحصه ثم شغّله على المضيف الأصلي. تضيف دالة المكتبة السطر الجديد. افحص النتيجة السالبة بنفسك ولا تستخدم القيمة الموجبة غير المحددة كحالة العملية. فشل تخصيص الإعارة فشل مضيف؛ ولا يضمن النظام تحويل انهيار الدالة الخارجية أو احتفاظها بالمؤشر إلى توقف مضبوط.
المضيف الأصلي فقط
خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف policy-rejection / foreign-imports-not-supported قبل التنفيذ، حتى إن لم يُستدع.
غير_آمن خارجي اطبع_سطر(رسالة: نص) -> ص64
= سي_صحيح__مؤشر_محرف_ثابت("libc.so.6", "puts").
دالة ابدأ_الرئيسية() -> ص64 {
دع النتيجة = غير_آمن اطبع_سطر("مرحبا").
إذا النتيجة < 0 { أرجع 1. }
أرجع 0.
}
النتائج المتوقعة والخرج الحرفي
browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout "" native: check 0; success / status 0; stdout "مرحبا\n"نزّل المصدر افحص رفض المتصفح
aspl check puts-ar.aspl
aspl run puts-ar.aspl
المضيف الأصلي فقط
خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف policy-rejection / foreign-imports-not-supported قبل التنفيذ، حتى إن لم يُستدع.
unsafe foreign اطبع_سطر(رسالة: string) -> i64
= c_int__const_char_ptr("libc.so.6", "puts");
fn start_main() -> i64 {
let النتيجة = unsafe اطبع_سطر("مرحبا");
if النتيجة < 0 { return 1; }
return 0;
}
النتائج المتوقعة والخرج الحرفي
browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout "" native: check 0; success / status 0; stdout "مرحبا\n"نزّل المصدر افحص رفض المتصفح
aspl check puts-en.aspl
aspl run puts-en.aspl
المضيف الأصلي فقط
خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف policy-rejection / foreign-imports-not-supported قبل التنفيذ، حتى إن لم يُستدع.
غير_آمن خارجي جذر(قيمة: ع64) -> ع64
= سي_مزدوج__مزدوج("libm.so.6", "sqrt").
دالة ابدأ_الرئيسية() -> ص64 {
دع النتيجة = غير_آمن جذر(4.0).
إذا النتيجة تطابق 2.0 { أرجع 0. }
أرجع 1.
}
النتائج المتوقعة والخرج الحرفي
browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout "" native: check 0; success / status 0; stdout ""نزّل المصدر افحص رفض المتصفح
aspl check double-ar.aspl
aspl run double-ar.aspl
المضيف الأصلي فقط
خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف policy-rejection / foreign-imports-not-supported قبل التنفيذ، حتى إن لم يُستدع.
unsafe foreign جذر(قيمة: f64) -> f64
= c_double__double("libm.so.6", "sqrt");
fn start_main() -> i64 {
let النتيجة = unsafe جذر(4.0);
if النتيجة matches 2.0 { return 0; }
return 1;
}
النتائج المتوقعة والخرج الحرفي
browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout "" native: check 0; success / status 0; stdout ""نزّل المصدر افحص رفض المتصفح
aspl check double-en.aspl
aspl run double-en.aspl
الأسباب والنتائج: unknown-foreign-adapter, foreign-signature-mismatch, invalid-foreign-library-name, invalid-foreign-symbol-name, duplicate-foreign-target, unsafe-required-on-foreign-declaration, unsafe-required-on-foreign-call; load-failure / foreign-library-open-failed, foreign-symbol-lookup-failed; trap / foreign-string-contains-nul; host-failure / allocation-failed; policy-rejection / foreign-imports-not-supported
تطبيق المضيف: native
الهدف Linux x86-64 الأساسي مع glibc 2.34 أو أحدث. يجب أن تكون النتائج Linux وx86_64 وglibc 2.34 أو أحدث. فشل تحديد مكتبة GNU libc لا يثبت التوافق. راجع الحدود المعيارية للمضيف.
uname -s
uname -m
getconf GNU_LIBC_VERSION
الحدود المعيارية للإصدار
إصدار ASPL الحالي هو 0.4.0. نزّل أرشيف Linux x86-64 وملف البصمة، ثم افحصهما قبل الفك. هذا إصدار مشروع معلن ولا يدعي المطابقة الرسمية الكاملة لـASPL MVP.
يتضمن مجلد التنزيل الأرشيف وSHA256SUMS والتراخيص. يحتوي المجلد المطابق داخل الأرشيف على aspl, LICENSE-MIT, LICENSE-APACHE وTHIRD-PARTY-NOTICES فقط. الترخيص باختيار MIT OR Apache-2.0.
نزّل أرشيف 0.4.0 وملف البصمة إلى المجلد نفسه. يحتوي ملف البصمة سطرا واحدا من 64 رقما سداسيا صغيرا ومسافتين ثم اسم الملف وسطر جديد. يجب أن يبلغ الفحص aspl-0.4.0-x86_64-linux-gnu.tar.xz: OK قبل الفك. البصمة تحقق سلامة المحتوى ولا تثبت هوية الناشر.
يتضمن هذا الأرشيف إشعارات Unicode لأن الأداة تحتوي جداول مشتقة منه. اقرأ النصوص الكاملة: MIT وApache-2.0 وإشعارات الطرف الثالث.
اعمل في مجلد تنزيل جديد لكل إصدار. افحص القائمة قبل الفك؛ يجب أن تطابق المجلد والملفات والصلاحيات المذكورة. توقف عند فشل أي أمر أو اختلاف القائمة أو النسخة، ولا تنفذ أوامر التثبيت التالية.
يحافظ إصدار 0.4.0 على القراءة التفاعلية بالسميتين اقرأ_سطر / read_line ويستخدم صيغة البايت كود الخاصة بالإصدار 4. صيغة البايت كود داخلية وليست واجهة توافق عامة.
sha256sum --check SHA256SUMS &&
tar -tvJf aspl-0.4.0-x86_64-linux-gnu.tar.xz
tar -xJf aspl-0.4.0-x86_64-linux-gnu.tar.xz &&
./aspl-0.4.0-x86_64-linux-gnu/aspl --version
الحدود المعيارية للإصدار
بعد التحقق، ضع أداة إصدار 0.4.0 المستخرجة في مسارك أو ثبّت بناء المصدر محليا. يجب أن تطبع aspl 0.4.0. وحدة التحكم المكتبية اختيارية وتبنى منفصلة.
يجب أن يحل command -v aspl إلى $HOME/.local/bin/aspl. إن لم يحدث ذلك استخدم export PATH="$HOME/.local/bin:$PATH" في الصدفة الحالية. للاستمرار أضف السطر نفسه يدويا إلى ~/.bashrc في Bash أو ~/.zshrc في Zsh. في Fish استخدم fish_add_path "$HOME/.local/bin". افتح صدفة جديدة وأعد فحص المسار والنسخة.
للتثبيت بإدارة المسؤول بعد الفحص نفسه استخدم sudo install -m 0755 ./build/aspl /usr/local/bin/aspl. افحص المسار حتى لا تحجب نسخة قديمة الأداة المختارة.
لبناء وحدة التحكم المكتبية على Linux ثبّت Qt 6.11 وCMake 3.21 أو أحدث، ثم نفّذ أوامر البناء. يحدد الخيار --aspl أداة ASPL التي يستخدمها التشغيل. الملف المختار من سطر الأوامر لا يبدأ حتى تختار Run. تشغّل Run الأداة عبر CLI من دليل عمل الملف المختار، وتبقي stdout وstderr منفصلين، ويغير اختيار لغة التشخيص صياغة التشخيص لا المصدر أو ناتج البرنامج.
test "$(./build/aspl --version)" = "aspl 0.4.0" &&
install -d "$HOME/.local/bin" &&
install -m 0755 ./build/aspl "$HOME/.local/bin/aspl"
command -v aspl
aspl --version
cmake -S projects/terminal -B build/terminal &&
cmake --build build/terminal &&
build/terminal/aspl-console --aspl ./build/aspl docs/examples/input.en.aspl
الحدود المعيارية للإصدار
احفظ المثال العربي أو الإنجليزي المرتبط باسم hello.aspl. يجب أن تطبع النسخة aspl 0.4.0. ينجح الفحص بلا خرج على أي من القناتين وبالحالة 0. بعد ذلك جرّب مثال الإدخال الصريح.
aspl --version
aspl check hello.aspl
اقرأ المثال وافحصه
تابع إلى العقد الدقيق
الحدود المعيارية للإصدار
للترقية أعد فحص المضيف وتنزيل الإصدار الجديد والتحقق والفك وفحص النسخة المستخرجة ثم استبدل الأداة بأمر التثبيت نفسه. للتراجع اتبع الخطوات نفسها مع إصدار مؤرشف مختار وبصمته. كل إصدار منشور ثابت ولا يتغير تحت الاسم نفسه. لا توجد نسخة احتياطية آلية؛ احتفظ بالأرشيف إن أردت التراجع دون اتصال. أحدث إصدار فقط يتلقى الإصلاحات قبل 1.0.
الإزالة تحذف الأداة المختارة فقط، وتترك إعداد الصدفة والمصدر والبرامج المبنية والأرشيفات. احذف المسار الذي اخترته فقط.
بعد الإزالة شغّل command -v aspl لاكتشاف نسخة أخرى ما زالت على المسار.
rm -- "$HOME/.local/bin/aspl"
للموضع الذي يديره المسؤول فقط: sudo rm -- /usr/local/bin/aspl