لغة BASIC
لهجة BASIC الكلاسيكية في aukimi، الأنواع، والبُنى، والاختصاران، والقواعد التي يقع فيها الجميع. 2,237 أمرًا وراءها.
باختصار#
يشحن Aukimi لهجة BASIC كلاسيكية: لغة كاملة، لا نظام وحدات ماكرو لعبة،
بأرقام مُنمَّطة (typed numerics)، وسجلات (records)، وطرائق (methods)، ومراجع
(references)، وأخطاء مُهيكَلة، وروتينات مشتركة (coroutines)، وحوسبة WebGPU.
تعيش في وضع منفذ عرض TXT في Engine وفي عرض BASIC في محرر السكريبت.
يبقى JavaScript واجهة السكريبت المرجعية (canonical). BASIC واجهة أمامية اختيارية: يُترجَم كلاهما إلى الموزِّع (dispatcher) الخاص نفسه، لذا يصل برنامج BASIC وبرنامج JavaScript إلى المحرك نفسه بالضبط. لا شيء درجة ثانية، ولا شيء بيئة تشغيل منفصلة.
القاعدة التي يقع فيها الجميع#
استدعاء الأمر يحمل أقواسًا دائمًا.
mode = ClipSpaceMode()
SpritePosition(player, 320, 180)
هذا ليس أسلوبًا. إنه ما يتيح للمُصرِّف (compiler) التمييز بين أمر ومتغيّر، وهذا هو سبب اكتشاف خطأ إملائي الآن وقت التصريف (compile time):
| ما تكتبه | ما كان يحدث سابقًا | ما يحدث الآن |
|---|---|---|
SpritePositon(1, 10, 20) | يُصرَّف بنظافة، ولا يتحرك sprite، ويظهر الفشل لاحقًا كـ... is not defined | خطأ تصريف، مع اقتراح أقرب تهجئة في الكتالوج |
Blorp(1, 2) | يُمرَّر حرفيًا إلى JavaScript المُولَّد | خطأ تصريف |
ceci nest pas du basic | يُصدَر كجملة (statement) | خطأ تصريف |
كان خطأ كتابة يقدِّم نفسه كخلل في المحرك. قِيسَ مقابل مجموعة الـ84 عرضًا توضيحيًا، وأنتج الحارس (guard) صفر إيجابيات كاذبة ووجد فشلين صامتين حقيقيين،
SetMusicSystemVolumeوGetLightSensorExists، واللذين لا يعرفهما الكتالوج إلا كـMusicSystemVolumeوLightSensorExists.
بابان مفتوحان عن قصد: لا يزال console.log("x") وwindow.x = 1 ينجحان. كُتب
حارس لهما، وقِيسَ، وسُحب: يعمل BASIC داخل سياق يوفِّر أسماء لا يستطيع
المُصرِّف تعدادها، لذا كان رفض جذر مجهول يرفض برامج صالحة. إيجابية كاذبة هناك
أسوأ من التسرب.
Print يرسم. Console يسجِّل.#
المفاجأة الأكثر شيوعًا على الإطلاق:
Print(...) | يرسم على الشاشة، ويستدعيه برنامج كل إطار |
Console(...) | يكتب في طرفية المحرر، ولا يفعل شيئًا آخر |
Debug(...) | الأمر نفسه باسم PureBasic، لذاكرة العضلات |
ConsoleWarning، ConsoleError، ClearConsole | بقية السجل |
سيغرق Print في حلقة إطار أي خطأ حقيقي في الطرفية، ولهذا السبب هما أمران
منفصلان بدلًا من واحد بعلَم (flag).
الأنواع#
الأنواع الرقمية حقيقية، وتتصرف بشكل مطابق على كل هدف: المحرر، وتصدير HTML، وبناء Bevy/الأصلي (native):
- أعداد صحيحة موقَّعة وغير موقَّعة بـ8 و16 و32 و64 بت، مع تحويل قسري
(coercion) حتمي، و
DIVصحيح، وفيضان (overflow) بالتفاف (wrapping). - float32 وfloat64.
- الرموز (sigils) الكلاسيكية لا تزال تعمل:
name$نص، وspeed#عدد عشري (float).
OPTION EXPLICIT اختياري (opt-in)، وتبقى المتغيرات الضمنية الكلاسيكية
هي الافتراضية بحيث تستمر البرامج المستوردة في العمل. تفعيله شرط مسبق للميزتين
اللتين لا يمكن أن تكونا آمنتين بدونه، التنميط الرقمي والمراجع، لأن تعيينًا
خاطئ الإملاء ينشئ متغيرًا بصمت يهزم كليهما.
البُنى#
Records#
يعلن TYPE عن سجل (record). تتداخل بشكل عشوائي، ولها دلالة قيمة (value
semantics): تعيين واحد ينسخه نسخًا عميقًا، بما في ذلك المصفوفات والمجموعات
المتداخلة.
Methods#
يربط METHOD دالة بنسخة (instance)، مع SELF بداخلها، وNew للبناء
وDelete للتدمير. تبقى النسخ العميقة آمنة مع الطرائق (method-safe).
References#
REF وBYREF هما الشيء نفسه بتهجئتين، ويمنح كلاهما معاملًا حيًا
للقراءة/الكتابة، لعدد قياسي (scalar)، أو سجل، أو حقل واحد، أو مصفوفة، أو مؤشر
قائمة (list cursor)، أو مدخل خريطة (map entry). تُمرَّر المراجع عبر
الاستدعاءات، وتُحوَّل قسريًا إلى أنواع ثابتة العرض عند الحدود.
Handles#
يأخذ @target مرجعًا من الدرجة الأولى. HANDLE وPOINTER هما الشكلان
المُنمَّطان، بقراءة وكتابة وصلاحية وتحرير مُتحقَّق منها، ومقبض (handle) إلى
سجل محذوف يُبطَل بدلًا من أن يُترَك معلَّقًا (dangling).
التحكم والأمان#
أخطاء مُهيكَلة: TRY / CATCH / FINALLY، متداخلة، مع THROW،
وRETHROW محميّ، والتقاط (catch) مُهيكَل ونصي معًا.
التصريف الشرطي: #IF / #ELSEIF / #ELSE / #ENDIF، متداخل، مع أعلام
ميزات (feature flags) وملفات تعريف صريحة للمحرر، وHTML، وBevy، وnative/wasm،
وdebug/release. يُحلّ قبل عمليات الإدراج (includes)، على كل هدف.
دوال غنية: قيم افتراضية، وOPTIONAL، وPARAMARRAY أخيرة (أو ...)،
وتحميل زائد آمن للعدد (arity overloads)، وتحويل قسري مُنمَّط للقيمة المُعادة،
وإعادة سجلات ومصفوفات مستنسخة.
البرامج متعددة الملفات#
تجعل #INCLUDE و#INSERT وIncludeFile البرنامج عدة ملفات. ينشئ المحرر
وحدات المشروع ويستوردها، ويكمل مسارات الإدراج (include paths)، ويحفظ الرسم
البياني للاعتماديات، وكل هدف تشغيل مُهيَّأ لذلك.
Coroutines، والشيء المتروك عمدًا#
المهام التعاونية (cooperative) قائمة على التسميات (labels)، بمقابض مُنمَّطة، وحالة نتيجة وخطأ، وإلغاء عند نقاط yield، وانتظار (await) على مهمة واحدة أو مجموعة. تشترك في جدولة اللعبة (game scheduler) على كل هدف.
الخيوط (threads) ذات الذاكرة المشتركة مستبعدة عمدًا. ليست مستبعدة «ليس بعد». جدولة تعاونية يمكنك فهمها أفضل من سباق بيانات (data race) لا يمكنك إعادة إنتاجه.
حوسبة WebGPU#
مخازن تخزين (storage buffers) مُنمَّطة f32 / i32 / u32، وخطوط أنابيب
(pipelines) WGSL خام، وإرسال (dispatch) مرتَّب حسب الإطار، وقراءة memblock
مرة أخرى، حوسبة GPU حقيقية من BASIC.
⚠️ Engine فقط. يرفع هدف HTML خطأ قدرة (capability) صريحًا، ويُبلِّغ هدف Bevy بعدم التوافق قبل البناء بدلًا من إنتاج ثنائي (binary) يفشل عند أول إرسال (dispatch).
اختصاران لمشكلة واحدة#
597 أمرًا مُسمَّاة Set/Get<الكائن><الخاصية>: Sprite بـ66، وTween
بـ58، وText بـ32، وEdit بـ29. اسم الكائن داخل اسم الدالة ومعرِّفه أول معامل
في كل سطر. يزيل كلا الاختصارين أدناه ذلك التكرار، ولا يمثِّل أيٌّ منهما واجهة
(API) جديدة: يعيد المُصرِّف بناء اسم الأمر الحقيقي ويبحث عنه في الكتالوج.
WITH <family>، داخل كتلة#
WITH SPRITE s
\position 100, 200 ` SpritePosition(s, 100, 200)
\size 64, 64 ` SpriteSize(s, 64, 64)
x# = \x ` SpriteX(s)
ENDWITH
في رأس الجملة \prop يكتب؛ في أي مكان آخر يقرأ. الموضع هو ما يقرِّر،
لذا لا توجد ترميز ثانٍ لتعلُّمه. WITH hero، رمز واحد، لا تزال كتلة السجل؛
وWITH SPRITE s تختار عائلة من الكتالوج.
s.position(...)، في أي مكان آخر#
s = CreateSprite(img) ` the family is DEDUCED from the creation command
s.position(100, 200) ` SpritePosition(s, 100, 200)
s.visible = 1 ` SpriteVisible(s, 1)
x# = s.x ` SpriteX(s)
تأتي العائلة من Create<F> / Load<F> / Clone<F>، أو من s AS Sprite
صريحة عندما يصل المعرِّف من مكان آخر. تُعاد كتابة المتغيرات التي عائلتها
معروفة فقط: تحتفظ السجلات بحقولها، وتحتفظ القوائم بطرائقها، وSELF.field
تبقى دون مساس.
⚠️ المعامل المُنمَّط لا يُتعرَّف عليه. FUNCTION move(s AS Sprite) لا
يمنح s عائلة، فالمرور يقرأ التصريحات والتعيينات على مستوى الجملة فقط. ذُكر
هذا هنا لأنه حد حقيقي، لا خلل يجب أن تطارده.
⚠️ يُسقط الكتالوج الفعل على الخصائص، ويبقيه على دورة الحياة. يكتب
SpritePosition، ويقرأ SpriteX، ولا يحمل أيٌّ منهما Set أو Get:
4 أوامر فقط في الكتالوج بأكمله تبدأ بـSet، ولا شيء يبدأ بـGet.
ينجو الفعل حيث يوجَد شيء أو ينتهي: CreateSprite، وLoadImage،
وDeleteSprite.
هذا يستحق المعرفة لأن الخطأ الإملائي خطأ تصريف، وSet… هو الخطأ الإملائي
الذي يصل به الناس. الكتالوج هو المرجعية،
والمرجع مُولَّد منه.
استيفاء النصوص (string interpolation)، اختياري#
Print($"score: {points}") ` "score: " + Str(points)
تكتب {{ و}} أقواسًا حرفية (literal braces).
⚠️ بادئة $ إلزامية، وهي ليست زخرفة. استيفاء كل نص حرفي كان يكسر JSON
مكتوبًا يدويًا، وهو ما تأخذه واجهة العالم (world API) بشكل روتيني:
CreateTerrain("island", "{\"preset\":\"island\",\"size\":256}")
هناك الأقواس بيانات، لا فجوات (holes). يُترَك نص بلا بادئة دون مساس أيًّا كان محتواه.
التسمية هي الإظهار#
يصنع برنامج كلاسيكي مئات الكائنات. فقط ما يُسمِّيه يدخل Scene Graph،
SpriteName(id, "player") وأشقاؤها هي ما يضع كائنًا في الشجرة حيث يمكن لبقية
Engine رؤيته. تفعل LightName وParticlesName الشيء نفسه لضوء ومُصدِر
(emitter).
يشرح الدرس سمِّ ما ينشئه برنامجك ذلك خطوة بخطوة: المشهد نفسه، مرة والشجرة فارغة، ومرة بثلاثة مدخلات فيها.
كتالوج الأوامر#
2,237 أمرًا، و2,550 تحميلًا زائدًا عامًا (overloads)، و43 فئة. الأكبر:
| 3D | 286 | Studio | 106 | File | 61 |
| Core | 200 | Input | 95 | Memblock | 43 |
| Tweening | 149 | Input-Raw | 94 | 3D Particles | 41 |
| 3D Physics | 144 | Multiplayer | 91 | World | 40 |
| Sprite | 135 | Text | 68 | Particles | 38 |
| Platform | 111 | 2D Physics | 66 | Sound | 37 |
إضافةً إلى JSON (36)، وImage (35)، وSkeleton (34)، وXML (34)، وMusic (29)، وPreference (27)، وExtras (21)، وHTTP (21)، وString (21)، وMath (19)، وRegular Expression (19)، وVideo (18)، وDictionary (17)، وBenchmarking (15)، وCompute (14)، وDate (13)، وMaths (12)، وTime (12)، وStringBuilder (9)، وCompression (7)، وFont (8)، وError (4)، وArray (3)، وCipher (2)، وSort (2).
Studio وCompute إضافتا Aukimi الخاصتان إلى اللهجة الكلاسيكية: أوامر الطرفية، وتسمية الكائنات، وخط أنابيب WebGPU.
المرجع الكامل للأوامر يسردها جميعًا، بكل معامل وكل تحميل زائد، مع بحث خاص به، مُولَّد من الكتالوج نفسه الذي تعدُّه هذه الصفحة، لذا لا يمكن أن يتخلف عنه. تقرأ لوحة الواجهة (API) في المحرر ذلك الكتالوج أيضًا.
هذه الصفحة توثِّق اللغة؛ وتلك توثِّق الأوامر.
القيود والمشاكل الشائعة#
- الأقواس ليست اختيارية على أمر. يُرفَض شكل PureBasic العاري (
Debug "x")، لأنه يعيد فتح الالتباس بين المتغيّر والأمر الذي يعتمد عليه حارس وقت التصريف. - تفوز دالة المستخدم على أمر مُكتلَج بالاسم نفسه، ويمكن لمتغيّر أن يشارك اسم أمر في تصريح مُنمَّط، أو على يسار تعيين، أو كجذر مسار.
- المتغيرات ودوال المستخدم غير حساسة لحالة الأحرف، ومساحات رموزها منفصلة فعليًا عن مساحة الكتالوج.
Printليس سجلًا. انظر أعلاه؛ إنه الخطأ الذي يملأ طرفية.- Compute لا يُصدَّر. اكتب المسار الاحتياطي قبل أن تعتمد عليه.