اكتب بالعربية. شغّل هنا.

جارٍ تحميل المحرر…

يجمع هذا البرنامج الأعداد من 1 إلى 10. عند نجاحه يطبع 55 ويعيد الحالة 0. عدّل المصدر ثم اضغط «شغّل».

تجري الترجمة والتنفيذ داخل متصفحك. لا يُرسل المصدر إلى خادم.

تابع إلى تعلّم اللغة

تعلّم من برنامج واحد

ارجع إلى العقد

البرنامج وحالة العملية

يحتوي ملف .aspl واحد على تعريفات الدوال والتصريحات الخارجية. دالة ابدأ_الرئيسية / start_main إلزامية بلا معاملات وبنتيجة i64. المجال الصحيح للحالة 0..255، وأي قيمة أخرى توقف التنفيذ ولا تُختزل.

مقبول: دوال على المستوى الأعلى. مرفوض: متغير عام، عبارة خارج دالة، دالة بداية مفقودة أو استدعاؤها من المصدر.

hello-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
hello-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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 أو ببدائلها العربية يطابق وتطابق وو وأو؛ ويختار مصدر العربية صيغة المساواة الموافقة لسياقه النحوي. تنتهي العبارات بـ . أو ;، وتستخدم الأمثلة العربية النقطة. ترتيب العرض لا يغير بايتات المصدر.

مقبول: كلمات عربية وإنجليزية في البرنامج نفسه. مرفوض: أرقام غير محولة خارج النصوص والتعليقات أو اسم يجمع الخطين. يعرض المحرر محارف التحكم غير المرئية بوضوح.

الأسباب والنتائج: non-ascii-digit, mixed-script-identifier

تطبيق المضيف: shared

اقرأ المثال وافحصه الحدود المعيارية للإصدار

الأنواع والتدفق

لا توجد تحويلات ضمنية. العدد الصحيح i64 موقّع وفائضه يوقف التنفيذ. العدد f64 هو IEEE 754 binary64. النص ثابت ويأتي من قيمة حرفية أو من إدخال سطر ناجح أو من عمليات يونيكود الجديدة، والمؤشر c_ptr معتم وقابل للقيمة الفارغة. لا يمكن تخزين unit. يتيح الربط المهيأ استنتاج النوع. لا يوجد حجب للأسماء؛ المعاملات والروابط ثابتة ما لم يصرّح الرابط المحلي بالتغيير. تتطلب if, while شرطا منطقيا، وreturn نتيجة من النوع المعلن.

مقبول: تعديل رابط معلن للتغيير، ومقارنة تنتج شرطا منطقيا. مرفوض: رابط بلا تهيئة، تعديل رابط ثابت أو مزج أنواع الأعداد ضمنيا.

sum-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
sum-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
sum-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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

الحدود المعيارية للإصدار

النصوص ويونيكود

النص قيمة 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 وعلامات الاتجاه والمسافات والتطبيع كما هي، والمساواة بالبايتات الدقيقة.

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

strings-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
strings-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
strings-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
join-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
join-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
join-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
parse-int-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص64 {
    اطبع("first: ").
    دع سيئ: نتيجة[ص64] = حلل_ص64(اقرأ_سطر()).
    إذا (سيئ::نجاح) {
        أرجع 1.
    }
    اطبع(سيئ::الخطأ::الرمز).
    اطبع("\nsecond: ").
    دع جيد: نتيجة[ص64] = حلل_ص64(اقرأ_سطر()).
    إذا (جيد::نجاح) {
        إذا (نسق_ص64(-9223372036854775808) != "-9223372036854775808") { أرجع 2. }
        اطبع(نسق_ص64(جيد::قيمة + 1)).
        اطبع("\n").
        أرجع 0.
    }
    أرجع 3.
}

النتائج المتوقعة والخرج الحرفي

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-int-ar.aspl
aspl run parse-int-ar.aspl
parse-int-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

fn start_main() -> i64 {
    print("first: ");
    let سيئ: result[i64] = parse_i64(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: 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-int-en.aspl
aspl run parse-int-en.aspl
parse-int-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

fn ابدأ_الرئيسية() -> ص64 {
    اطبع("first: ").
    let سيئ: نتيجة[i64] = parse_i64(اقرأ_سطر()).
    إذا (سيئ::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: 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-int-mixed.aspl
aspl run parse-int-mixed.aspl
parse-float-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص64 {
    اطبع("first: ").
    دع سيئ: نتيجة[ع64] = حلل_ع64(اقرأ_سطر()).
    إذا (سيئ::نجاح) {
        أرجع 1.
    }
    اطبع(سيئ::الخطأ::الرمز).
    اطبع("\nsecond: ").
    دع جيد: نتيجة[ع64] = حلل_ع64(اقرأ_سطر()).
    إذا (جيد::نجاح) {
        إذا (نسق_ع64(0.5) != "0.5") { أرجع 2. }
        اطبع(نسق_ع64(جيد::قيمة + 1.0)).
        اطبع("\n").
        أرجع 0.
    }
    أرجع 3.
}

النتائج المتوقعة والخرج الحرفي

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
parse-float-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

fn start_main() -> i64 {
    print("first: ");
    let سيئ: result[f64] = parse_f64(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; }
        print(format_f64(جيد::value + 1.0));
        print("\n");
        return 0;
    }
    return 3;
}

النتائج المتوقعة والخرج الحرفي

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
parse-float-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

fn ابدأ_الرئيسية() -> ص64 {
    اطبع("first: ").
    let سيئ: نتيجة[f64] = parse_f64(اقرأ_سطر()).
    إذا (سيئ::ok) { أرجع 1. }
    print(سيئ::الخطأ::code).
    print("\nsecond: ").
    دع جيد: result[ع64] = حلل_ع64(read_line()).
    if (جيد::نجاح) {
        إذا (format_f64(0.5) != "0.5") { return 2. }
        اطبع(نسق_ع64(جيد::value + 1.0)).
        print("\n").
        أرجع 0.
    }
    return 3.
}

النتائج المتوقعة والخرج الحرفي

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] خطأ وقتي الترجمة، وتبقى رموز الأخطاء نصوصا ثابتة منفصلة عن الرسائل.

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

results-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة حي(الاسم: نص) -> نتيجة[نص] {
    إذا (الاسم يطابق "") {
        أرجع إخفاق("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
results-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
results-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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 عدد العناصر بزمن ثابت. الفهرس السالب أو الخارج عن النطاق يوقف التنفيذ. يضيف أضف / append عنصرا من نوع العنصر نفسه ويعيد unit، ويستبدل الإسناد المفهرس xs[i] = v عنصرا واحدا. تتطلب كلتا العمليتين ربط var جذرا، وتحسم الفهارس من اليسار إلى اليمين مرة واحدة قبل قيمة الإسناد. نسخ القوائم مستقلة: تغيير نسخة، بما فيها القوائم المتداخلة، لا يغير الأصل.

مقبول: ليترال فارغ بنوع متوقع وفاصلة أخيرة وقوائم متداخلة وتمرير القوائم وإرجاعها وقراءة العناصر وطولها وإضافة العناصر واستبدالها عبر جذر var ونسخ مستقلة. مرفوض: ليترال فارغ بلا نوع متوقع أو خلط أنواع العناصر أو عناصر unit أو مساواة قائمتين أو فهرس سالب أو خارج النطاق أو التغيير عبر ربط let أو معامل أو قيمة مؤقتة.

lists-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة المجموع(القيم: قائمة[ص64]) -> ص64 {
    أرجع القيم[0] + القيم[1] + القيم[2].
}
دالة ابدأ_الرئيسية() -> ص64 {
    دع القيم: قائمة[ص64] = [3, 4, 5].
    إذا (طول(القيم) != 3) { أرجع 1. }
    إذا (المجموع(القيم) != 12) { أرجع 2. }
    اطبع("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
lists-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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; }
    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
lists-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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. }
    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
list-mutation-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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. }
    اطبع("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
list-mutation-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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; }
    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
list-mutation-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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. }
    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 غير محدود.

records-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

سجل رمز { نوع: ص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
records-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
records-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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 بلا خرج.

مقبول: دالة معرفة لاحقا أو استدعاء ذاتي. مرفوض: تحميل زائد، دالة متداخلة، عدد معاملات خاطئ أو مسار بلا إرجاع.

functions-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة مضروب(القيمة: ص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
functions-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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

الحدود المعيارية للإصدار

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

يحمل التشخيص مفتاح سبب ثابت وشدة ومعاملات ذات أنواع ومواضع مصدر وتعديلا اختياريا. اللغة تغير الصياغة فقط. التحذير لا يمنع التشغيل. يربط التشغيل المباشر التشخيص بالمصدر؛ البرامج المبنية لا تحتوي خريطة المصدر. المثال الأول يحاول تعديل رابط ثابت. يستبدل المثال الثاني دع / let بـمتغير / var ويعيد الحالة 1 بصورة طبيعية.

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

diagnostic-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
diagnostic-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
corrected-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
corrected-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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; success / start_main 1

تطبيق المضيف: shared

الحدود المعيارية للإصدار

الطباعة الآمنة

توقيع الطباعة المدمجة هو اطبع / print: (string) -> unit. يكتب بايتات النص بالترتيب، بما فيها NUL، بلا سطر جديد أو تفريغ تلقائي. أضف \n صراحة. لا يمكن إعادة تعريف أي من الاسمين. يعرض المتصفح بايتات الخرج بأمان ولا يفسرها كترميز صفحة.

مقبول: نص واحد، بما فيه النص الفارغ. مرفوض: عدد أو معاملات متعددة أو تخزين النتيجة.

الكتابة متزامنة، والنص الفارغ لا يلمس المضيف. يعيد المضيف الأصلي محاولة الكتابات المقطوعة ويتابع الكتابات القصيرة. يبقى أي خرج مقبول قبل الفشل ظاهرا. لا توجد معالجة خاصة لإشارة SIGPIPE؛ قد ينهي الأنبوب المغلق العملية بها. إذا تجاهلت البيئة الإشارة أو حجبتها وأعادت الكتابة EPIPE، تكون النتيجة فشل مضيف بالحالة 8.

output-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
output-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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.

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

input-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
input-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
input-mixed · ASPL 0.3.0

المتصفح والمضيف الأصلي

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

الحدود المعيارية للإصدار

أوامر Linux ومراحلها

تقبل الأداة ملف مصدر واحدا. يفحص check المصدر، ويشغّل run داخل العملية، وينشر build برنامج ELF باستبدال ذري بعد التحقق. لا يفتح الفحص والبناء مكتبات البرنامج. لا يستدعي البناء مترجم 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
اقرأ المثال وافحصه الحدود المعيارية للإصدار

الإدخال في Linux والبرامج المبنية

يقرأ aspl run من stdin الموروث، سواء أكان طرفية أم أنبوبا أم ملفا معادا توجيهه. يعمل القارئ نفسه داخل برنامج مبني بـaspl build من نوع ELF. يحتوي البرنامج المبني البايت كود وإصدار الآلة 3، ويعمل بعد إزالة المترجم ووقت التشغيل من 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 من قائمة الملفات وأجب عن الأسئلة نفسها، فيظهر الملف المولد كملف افتراضي جاهز للتنزيل دون أن يترجم المتصفح النص المولد في التشغيل نفسه. وحدة التحكم المكتبية تشغل المثال نفسه بدليل عمل ملف المصدر المختار وإدخال الأسطر المعتاد.

read-file-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
read-file-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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
write-file-ar · ASPL 0.3.0

المتصفح والمضيف الأصلي

دالة ابدأ_الرئيسية() -> ص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
write-file-en · ASPL 0.3.0

المتصفح والمضيف الأصلي

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 MiB1 MiB
الوحدات المعجمية1048576131072
عقد الصياغة1048576131072
عمق الصياغة256128
ذاكرة المترجم العاملة512 MiB128 MiB
بايتات البايت كود64 MiB8 MiB
الدوال655364096
الاستيرادات الخارجية40960
ثوابت الأعداد الصحيحة1048576131072
ثوابت الأعداد العائمة1048576131072
مراجع النصوص1048576131072
بايتات النصوص16 MiB2 MiB
حمولة سطر الإدخال65536 bytes65536 bytes
تعليمات البايت كود4194304524288
السجلات لكل دالة655368192
التعليمات المنفذةnone10000000
إطارات وقت التشغيل4096512
مواضع قيم وقت التشغيل1048576131072
ذاكرة التنفيذ المملوكة للآلة256 MiB64 MiB
الخرج الملتقطnone256 KiB
زمن الفحصnone2 s
زمن التنفيذnone3 s
الذاكرة الخطيةn/a256 MiB
وظائف العامل المتزامنةn/a1

يشمل المصدر كل بايت مقروء بما فيه علامة بداية النص. تشمل ذاكرة المترجم كل تخصيص حي للترجمة. تشمل ذاكرة التنفيذ الإطارات ومواضع القيم وإعارة النص والنصوص الحية المملوكة للتنفيذ، وتستبعد البرنامج الثابت والمكتبات وتخصيصات الشيفرة الخارجية. يتقدم فشل الحد البنيوي على حد الذاكرة عند العملية نفسها. فشل التخصيص دون السقف هو host-failure / allocation-failed.

يبدأ مؤقت الفحص حين يقبل العامل المحمّل المهمة، ومؤقت التنفيذ حين يقبل التشغيل بعد نجاح الفحص. لا يدخل التحميل في المؤقتين، ولا يدخل انتظار إدخال المستخدم في مؤقت التنفيذ. أول حد ملحوظ يحدد النتيجة؛ بلوغ الموعد ينهي العامل بسبب time-limit. يرفض حد الخرج الاستدعاء الذي يتجاوزه بأكمله ويبقي الخرج السابق جزئيا. ليس للتنفيذ الأصلي سقف منتج للتعليمات أو الوقت أو الخرج، مع بقاء الحد التمثيلي لعداد التعليمات.

تستخدم ASPL 0.3.0 صيغة البايت كود الخاصة بالإصدار 3. لا تقبل البنى الحالية البايت كود للإصدار 2. ليست الصيغة واجهة توافق عامة.

limit-ar · ASPL 0.3.0

المتصفح فقط

دالة ابدأ_الرئيسية() -> ص64 {
    طالما صواب {}
    أرجع 0.
}

النتائج المتوقعة والخرج الحرفي

browser: check success; limit-stop / execution-instruction-limit / ceiling 10000000; stdout ""
نزّل المصدر افتح في المحرر
limit-en · ASPL 0.3.0

المتصفح فقط

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.3.0.

ASPL-SEMANTIC-0403
يقتصر إصدار ASPL الأدنى على خمسة أنواع قابلة للتخزين، وتبقى النصوص ثابتة ومنشأة من القيم الحرفية فقط.
ASPL-SEMANTIC-0404
يقتصر إصدار ASPL الأدنى على خمسة أنواع قابلة للتخزين، وتبقى النصوص ثابتة ومنشأة من القيم الحرفية فقط.
ASPL-SEMANTIC-0405
يقتصر إصدار ASPL الأدنى على خمسة أنواع قابلة للتخزين، وتبقى النصوص ثابتة ومنشأة من القيم الحرفية فقط.
ASPL-SEMANTIC-0406
يقتصر إصدار ASPL الأدنى على خمسة أنواع قابلة للتخزين، وتبقى النصوص ثابتة ومنشأة من القيم الحرفية فقط.
ASPL-SEMANTIC-0407
يقتصر إصدار ASPL الأدنى على خمسة أنواع قابلة للتخزين، وتبقى النصوص ثابتة ومنشأة من القيم الحرفية فقط.
ASPL-SEMANTIC-0189
يقبل إصدار ASPL الأدنى ملف مصدر واحداً ولا يوفر الوحدات أو نظام حزم أو معاملات للبرنامج.
ASPL-BYTECODE-0531
صيغة ASPL bytecode خاصة ومتطابقة الإصدار وليست ABI عامة مستقرة.
ASPL-BYTECODE-0532
صيغة ASPL bytecode خاصة ومتطابقة الإصدار وليست ABI عامة مستقرة.
ASPL-BYTECODE-0533
صيغة ASPL bytecode خاصة ومتطابقة الإصدار وليست ABI عامة مستقرة.
ASPL-BYTECODE-0534
صيغة ASPL bytecode خاصة ومتطابقة الإصدار وليست ABI عامة مستقرة.
ASPL-BYTECODE-0535
صيغة ASPL bytecode خاصة ومتطابقة الإصدار وليست ABI عامة مستقرة.
ASPL-CLI-0605
لا يعزل التنفيذ الأصلي الشفرة الأجنبية غير الآمنة.
ASPL-CLI-0606
لا يعزل التنفيذ الأصلي الشفرة الأجنبية غير الآمنة.
ASPL-CLI-0607
لا يعزل التنفيذ الأصلي الشفرة الأجنبية غير الآمنة.
ASPL-CLI-0608
لا يعزل التنفيذ الأصلي الشفرة الأجنبية غير الآمنة.
ASPL-BROWSER-0347
لا تنشئ دالة إخراج المتصفح استيرادًا خارجيًا.
ASPL-BROWSER-0348
لا تضيف دالة إخراج المتصفح جسرًا لنظام الملفات.
ASPL-BROWSER-0349
لا تضيف دالة إخراج المتصفح جسرًا للشبكة.
ASPL-BROWSER-0350
لا تضيف دالة إخراج المتصفح جسرًا للخادم.
ASPL-DIST-0109
يستهدف الإصدار الأصلي الأول Linux x86-64 مع glibc 2.34 أو أحدث فقط.
ASPL-DIST-0144
يوفر SHA-256 فحص سلامة فقط، من دون مصادقة للناشر أو توقيع للإصدار.
ASPL-PERF-0161
تقتصر ادعاءات أداء البناء والمتصفح على الجهاز والبروتوكول والمتصفحات المثبتة في المواصفة.
ASPL-CONFORMANCE-0672
لا يدّعي إصدار ASPL الأدنى الجاهزية للإنتاج.
ASPL-CONFORMANCE-0673
لا يدّعي إصدار ASPL الأدنى الاستبدال الكامل للغة C.
ASPL-CONFORMANCE-0674
لا يَعِد إصدار ASPL الأدنى بمدة دعم أمني محددة.
ASPL-CONFORMANCE-0675
لا يدّعي إصدار ASPL الأدنى ثبات صيغة البايت كود العامة.

اعرف حدود C

المحوّلان وإعارة النص

على x86-64 Linux مع glibc، يستطيع برنامج ASPL أصلي تحميل أي مكتبة مشتركة يقبلها المحمّل الديناميكي لـglibc واستدعاء دالة مسماة حين يطابق نوعها الدقيق في C أحد محوّلات الاستدعاء الخارجي المدعومة. يدعم الإصدار الأدنى int(const char *) وdouble(double). تبقى إتاحة المكتبة وصلاحية المؤشر وسلوك الدالة الخارجية مسؤولية البرنامج.

مقبول: مكتبة ورمز حرفيان غير فارغين وبلا 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، نزّل المصدر وافحصه ثم شغّله على المضيف الأصلي. تضيف دالة المكتبة السطر الجديد. افحص النتيجة السالبة بنفسك ولا تستخدم القيمة الموجبة غير المحددة كحالة العملية. فشل تخصيص الإعارة فشل مضيف؛ ولا يضمن النظام تحويل انهيار الدالة الخارجية أو احتفاظها بالمؤشر إلى توقف مضبوط.

puts-ar · ASPL 0.3.0

المضيف الأصلي فقط

خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف 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
puts-en · ASPL 0.3.0

المضيف الأصلي فقط

خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف 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
double-ar · ASPL 0.3.0

المضيف الأصلي فقط

خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف 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
double-en · ASPL 0.3.0

المضيف الأصلي فقط

خاص بالمضيف الأصلي. يرفض المتصفح هذا الاستيراد بالصنف 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

تحقق من المضيف أولا

الهدف Linux x86-64 الأساسي مع glibc 2.34 أو أحدث. يجب أن تكون النتائج Linux وx86_64 وglibc 2.34 أو أحدث. فشل تحديد مكتبة GNU libc لا يثبت التوافق. راجع الحدود المعيارية للمضيف.

uname -s
uname -m
getconf GNU_LIBC_VERSION
الحدود المعيارية للإصدار

الأرشيف والتحقق

إصدار ASPL الحالي هو 0.3.0. نزّل أرشيف Linux x86-64 وملف البصمة، ثم افحصهما قبل الفك. هذا إصدار مشروع معلن ولا يدعي المطابقة الرسمية الكاملة لـASPL MVP.

يتضمن مجلد التنزيل الأرشيف وSHA256SUMS والتراخيص. يحتوي المجلد المطابق داخل الأرشيف على aspl, LICENSE-MIT, LICENSE-APACHE وTHIRD-PARTY-NOTICES فقط. الترخيص باختيار MIT OR Apache-2.0.

نزّل أرشيف 0.3.0 وملف البصمة إلى المجلد نفسه. يحتوي ملف البصمة سطرا واحدا من 64 رقما سداسيا صغيرا ومسافتين ثم اسم الملف وسطر جديد. يجب أن يبلغ الفحص aspl-0.3.0-x86_64-linux-gnu.tar.xz: OK قبل الفك. البصمة تحقق سلامة المحتوى ولا تثبت هوية الناشر.

يتضمن هذا الأرشيف إشعارات Unicode لأن الأداة تحتوي جداول مشتقة منه. اقرأ النصوص الكاملة: MIT وApache-2.0 وإشعارات الطرف الثالث.

اعمل في مجلد تنزيل جديد لكل إصدار. افحص القائمة قبل الفك؛ يجب أن تطابق المجلد والملفات والصلاحيات المذكورة. توقف عند فشل أي أمر أو اختلاف القائمة أو النسخة، ولا تنفذ أوامر التثبيت التالية.

يحافظ إصدار 0.3.0 على القراءة التفاعلية بالسميتين اقرأ_سطر / read_line ويستخدم صيغة البايت كود الخاصة بالإصدار 3. صيغة البايت كود داخلية وليست واجهة توافق عامة.

sha256sum --check SHA256SUMS &&
tar -tvJf aspl-0.3.0-x86_64-linux-gnu.tar.xz

tar -xJf aspl-0.3.0-x86_64-linux-gnu.tar.xz &&
./aspl-0.3.0-x86_64-linux-gnu/aspl --version
الحدود المعيارية للإصدار

ثبّت الأداة وتحقق من PATH

بعد التحقق، ضع أداة إصدار 0.3.0 المستخرجة في مسارك أو ثبّت بناء المصدر محليا. يجب أن تطبع aspl 0.3.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.

test "$(./build/aspl --version)" = "aspl 0.3.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
الحدود المعيارية للإصدار

الترقية والتراجع والإزالة

للترقية أعد فحص المضيف وتنزيل الإصدار الجديد والتحقق والفك وفحص النسخة المستخرجة ثم استبدل الأداة بأمر التثبيت نفسه. للتراجع اتبع الخطوات نفسها مع إصدار مؤرشف مختار وبصمته. كل إصدار منشور ثابت ولا يتغير تحت الاسم نفسه. لا توجد نسخة احتياطية آلية؛ احتفظ بالأرشيف إن أردت التراجع دون اتصال. أحدث إصدار فقط يتلقى الإصلاحات قبل 1.0.

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

بعد الإزالة شغّل command -v aspl لاكتشاف نسخة أخرى ما زالت على المسار.

rm -- "$HOME/.local/bin/aspl"

للموضع الذي يديره المسؤول فقط: sudo rm -- /usr/local/bin/aspl

الحدود المعيارية للإصدار
ارجع إلى المحرر