لغة لوا

لغة لوا ( تُلفظ /ˈluː.ə/ ، LOO؛ من البرتغالية : lua [ ˈlu(w)ɐ ] وتعني القمر ) هي لغة برمجة خفيفة الوزن وعالية المستوى ومتعددة الأنماط ، مصممة أساسًا للاستخدام في التطبيقات المدمجة . [ 2 ] تُعد لوا برنامجًا متعدد المنصات ، نظرًا لأن مُفسِّر الشفرة البايتية المُجمَّعة مكتوب بلغة ANSI C ، [ 3 ] كما أن لوا تمتلك واجهة برمجة تطبيقات ( API ) بسيطة نسبيًا مكتوبة بلغة C لتضمينها في التطبيقات. [ 4 ]

ظهرت لغة Lua في عام 1993 كلغة لتطوير تطبيقات البرمجيات لتلبية الطلب المتزايد على التخصيص في ذلك الوقت. وقد وفرت الإمكانيات الأساسية لمعظم لغات البرمجة الإجرائية ، لكنها لم تتضمن ميزات أكثر تعقيدًا أو خاصة بمجالات محددة ؛ بل تضمنت آليات لتوسيع اللغة، مما يسمح للمبرمجين بتنفيذ هذه الميزات. ولأن Lua صُممت لتكون لغة توسيع عامة قابلة للتضمين، فقد ركز مصمموها على تحسين سرعتها وقابليتها للنقل والتوسيع وسهولة استخدامها في التطوير.

تاريخ

تم إنشاء لغة Lua في عام 1993 بواسطة روبرتو إيروساليمسكي ولويز هنريكي دي فيغيريدو ووالديمار سيليس، أعضاء مجموعة تكنولوجيا رسومات الحاسوب ( Tecgraf ) في الجامعة البابوية الكاثوليكية في ريو دي جانيرو ، في البرازيل .

منذ عام 1977 وحتى عام 1992، انتهجت البرازيل سياسة فرض حواجز تجارية صارمة (تُعرف باسم "احتياطي السوق") على أجهزة وبرامج الحاسوب ، انطلاقًا من إيمانها بقدرة البرازيل على إنتاج أجهزتها وبرامجها محليًا، بل وضرورة ذلك. في ظل هذه الظروف، لم يكن بمقدور عملاء شركة تيكغراف، سياسيًا أو ماليًا، شراء برامج مُخصصة من الخارج؛ ففي ظل "احتياطي السوق"، كان على العملاء المرور بإجراءات بيروقراطية معقدة لإثبات عدم قدرة الشركات البرازيلية على تلبية احتياجاتهم. دفعت هذه الأسباب شركة تيكغراف إلى تطوير الأدوات الأساسية التي تحتاجها من الصفر. [ 5 ]

كانت لغتا وصف البيانات وتكوينها، وهما لغة الكائنات البسيطة (SOL) ولغة إدخال البيانات (DEL)، من اللغات السابقة للغة Lua. [ 6 ] وقد طُوِّرتا بشكل مستقل في شركة Tecgraf خلال الفترة 1992-1993 لإضافة بعض المرونة إلى مشروعين مختلفين (كلاهما عبارة عن برامج رسومية تفاعلية لتطبيقات هندسية في شركة بتروبراس ). كانت لغتا SOL وDEL تفتقران إلى أي هياكل للتحكم في التدفق، وشعرت بتروبراس بحاجة متزايدة إلى إضافة إمكانيات برمجة كاملة إليهما.

في كتاب "تطور لغة لوا" ، كتب مؤلفو اللغة: [ 5 ]

في عام ١٩٩٣، كان المنافس الحقيقي الوحيد هو لغة Tcl ، المصممة خصيصًا لتُدمج في التطبيقات. مع ذلك، تميزت Tcl ببنية غير مألوفة، ودعم ضعيف لوصف البيانات، واقتصار عملها على أنظمة يونكس. لم نُفكر في لغتي LISP أو Scheme لصعوبة استخدامهما. كانت لغة بايثون لا تزال في بداياتها. في ظل بيئة التطوير الحرّ التي سادت آنذاك في Tecgraf، كان من الطبيعي أن نسعى لتطوير لغة برمجة نصية خاصة بنا  ... ولأن العديد من المستخدمين المحتملين لم يكونوا مبرمجين محترفين، كان لا بد من تجنّب البنية والدلالات المُبهمة. كما كان من الضروري أن تكون اللغة الجديدة قابلة للنقل بسهولة، نظرًا لتنوع منصات الحوسبة التي يستخدمها عملاء Tecgraf. وأخيرًا، ولأننا توقعنا أن تحتاج منتجات Tecgraf الأخرى إلى تضمين لغة برمجة نصية، كان لا بد من أن تحذو اللغة الجديدة حذو SOL وتُقدّم كمكتبة بواجهة برمجة تطبيقات C.

صُممت لغة Lua 1.0 بحيث تضمنت دوال إنشاء الكائنات فيها، والتي كانت آنذاك مختلفة قليلاً عن الأسلوب الحالي الخفيف والمرن، صيغة وصف البيانات الخاصة بلغة SOL (ومن هنا جاء اسم Lua: Sol تعني "الشمس" بالبرتغالية، و Lua تعني "القمر"). استُعيرت صيغة Lua لهياكل التحكم في الغالب من لغة Modula ( if, while, repeat/ until)، ولكنها تأثرت أيضًا بلغة CLU (الإسنادات المتعددة والإرجاع المتعدد من استدعاءات الدوال، كبديل أبسط لمعاملات المراجع أو المؤشرات الصريحة )، ولغة C++ ("فكرة رائعة تسمح بتعريف متغير محلي فقط عند الحاجة إليه" [ 5 ]ولغتي SNOBOL و AWK ( المصفوفات الترابطية ). في مقال نُشر في مجلة Dr. Dobb's Journal ، ذكر مبتكرو Lua أيضًا أن لغتي LISP وScheme، بآلية هيكل البيانات الموحدة والمنتشرة فيهما ( القائمة )، كان لهما تأثير كبير على قرارهم بتطوير الجدول كهيكل البيانات الأساسي في Lua. [ 7 ]

تأثرت دلالات لغة Lua بشكل متزايد بلغة Scheme مع مرور الوقت، [ 5 ] وخاصة مع إدخال الدوال المجهولة والنطاق المعجمي الكامل . وقد أُضيفت العديد من الميزات في إصدارات Lua الجديدة.

صدرت إصدارات Lua السابقة للإصدار 5.0 بموجب ترخيص مشابه لترخيص BSD . أما بدءًا من الإصدار 5.0، فقد تم ترخيص Lua بموجب ترخيص MIT . كلا الترخيصين هما ترخيصان مفتوحان للبرمجيات الحرة ، وهما متطابقان تقريبًا.

سمات

تُوصَف لغة لوا عادةً بأنها لغة " متعددة الأنماط "، إذ توفر مجموعة صغيرة من الميزات العامة التي يمكن توسيعها لتناسب أنواعًا مختلفة من المشكلات. لا تدعم لوا التوريث بشكل صريح ، ولكنها تسمح بتنفيذه باستخدام الجداول الوصفية . وبالمثل، تسمح لوا للمبرمجين بتنفيذ مساحات الأسماء والفئات وغيرها من الميزات ذات الصلة باستخدام تطبيقها ذي الجدول الواحد؛ وتتيح الدوال من الدرجة الأولى استخدام العديد من تقنيات البرمجة الوظيفية ، كما يتيح النطاق المعجمي الكامل إخفاء المعلومات بدقة عالية لفرض مبدأ أقل الامتيازات .

بشكل عام، تسعى لغة لوا إلى توفير ميزات أساسية بسيطة ومرنة قابلة للتوسيع حسب الحاجة، بدلاً من تقديم مجموعة ميزات خاصة بنموذج برمجي واحد. ونتيجة لذلك، تتميز اللغة الأساسية بخفتها ؛ إذ يبلغ حجم المفسر المرجعي الكامل حوالي 293 كيلوبايت فقط بعد التجميع [ 3 ] ، وهو قابل للتكيف بسهولة مع نطاق واسع من التطبيقات. 

باعتبارها لغة برمجة ديناميكية الكتابة، مصممة للاستخدام كلغة إضافية أو لغة برمجة نصية ، تتميز لغة Lua بصغر حجمها بما يكفي لتناسب مجموعة متنوعة من منصات التشغيل. وهي تدعم عددًا محدودًا من هياكل البيانات الأساسية، مثل القيم المنطقية ، والأعداد ( أعداد عشرية مزدوجة الدقة وأعداد صحيحة 64 بت افتراضيًا)، والسلاسل النصية . أما هياكل البيانات الشائعة ، مثل المصفوفات والمجموعات والقوائم والسجلات ، فيمكن تمثيلها باستخدام هيكل البيانات الأصلي الوحيد في Lua، وهو الجدول، الذي يُعدّ في جوهره مصفوفة ترابطية غير متجانسة .

تُنفذ لغة Lua مجموعة صغيرة من الميزات المتقدمة مثل الدوال من الدرجة الأولى ، وجمع البيانات المهملة ، والإغلاقات ، واستدعاءات الذيل المناسبة ، والتحويل (التحويل التلقائي بين قيم السلسلة والرقم في وقت التشغيل)، والروتينات الفرعية (تعدد المهام التعاوني) وتحميل الوحدات النمطية الديناميكي .

بناء الجملة

يمكن كتابة برنامج "Hello, World!" الكلاسيكي على النحو التالي، مع أو بدون أقواس: [ 8 ] [ a ]

print ( "مرحباً بالعالم!" )
اطبع "مرحباً بالعالم!"

تعريف متغير بدون قيمة.

متغير محلي

تعريف متغير بقيمة 1000 (ألف)

عدد الطلاب المحليين = 1000

يبدأ التعليق في لغة لوا بشرطتين متتاليتين ويمتد إلى نهاية السطر، على غرار لغات آدا وإيفل وهاسكل وإس كيو إل وفي إتش دي إل . وتُعلّم السلاسل النصية والتعليقات متعددة الأسطر بأقواس مربعة مزدوجة.

-- تعليق من سطر واحد --[[ تعليق متعدد الأسطر --]]

يتم تطبيق دالة المضروب في هذا المثال :

دالة مضروب ( ن ) محلي س = 1 من أجل i = 2 ، ن افعل س = س * i نهاية إرجاع س نهاية

تدفق التحكم

تحتوي لغة Lua على نوع واحد من الاختبارات الشرطيةif then end : مع بنيات اختيارية elseوبنيات elseif thenللتحكم في التنفيذ.

if then endيتطلب البيان العام الكلمات المفتاحية الثلاث جميعها:

إذا تحقق الشرط ، فـ -- نهاية نص العبارة

مثال على ifبيان

إذا كانت قيمة x لا تساوي 10 ، فاطبع ( x ) .

يمكن إضافة الكلمة elseالمفتاحية مع كتلة عبارات مصاحبة للتحكم في التنفيذ عندما ifيكون الشرط كالتالي false:

إذا تحقق الشرط ، فسيتم تنفيذ نص العبارة، وإلا فسيتم تنفيذ نص العبارة.

مثال على if elseبيان

إذا كانت قيمة x تساوي 10 ، فاطبع ( 10 وإلا فاطبع ( x ) .

يمكن أيضًا التحكم في التنفيذ وفقًا لشروط متعددة باستخدام elseif thenالكلمات المفتاحية:

إذا تحقق الشرط ، فسيتم تنفيذ نص العبارة. وإذا تحقق الشرط ، فسيتم تنفيذ نص العبارة. وإلا ، فسيتم تنفيذ نص العبارة الافتراضي ( اختياري).

مثال على if elseif elseبيان

إذا كانت قيمة x تساوي y ، فاطبع "x = y" . وإذا كانت قيمة x تساوي z ، فاطبع "x = z" . وإلا ، فاطبع ( اختياري ) "x لا تساوي أي متغير آخر " .

تحتوي لغة Lua على أربعة أنواع من الحلقات الشرطية: whileالحلقة ، repeatوالحلقة (مشابهة للحلقة do while) ، forوالحلقة العددية ، والحلقة العامة for.

الشرط = صحيحبينما الشرط do --العبارات endكرر --العبارات حتى يتحقق الشرطfor i = first , last , delta do -- قد تكون قيمة delta سالبة، مما يسمح لحلقة for بالعد تنازليًا أو تصاعديًا -- التعليمات -- مثال: print(i) end

forستتكرر هذه الحلقة العامة على الجدول _Gباستخدام دالة التكرار القياسية pairs، حتى تعود إلى nil:

for key , value in pairs ( _G ) do print ( key , value ) end

يمكن أيضًا تداخل الحلقات (وضعها داخل حلقة أخرى).

الشبكة المحلية = { { 11 , 12 , 13 }, { 21 , 22 , 23 }, { 31 , 32 , 33 } }لكل y ، صف في أزواج ( الشبكة ) نفّذ لكل x ، قيمة في أزواج ( الصف ) نفّذ اطبع ( x ، y ، القيمة ) نهاية نهاية

الوظائف

يوضح المثال التالي كيفية تعامل لغة Lua مع الدوال كقيم من الدرجة الأولى ، حيث تم تعديل سلوك دالة الطباعة:

do local oldprint = print -- تخزين دالة الطباعة الحالية كدالة oldprint function print ( s ) --[[ إعادة تعريف دالة الطباعة. لا يزال من الممكن استخدام دالة الطباعة المعتادة  من خلال oldprint. الدالة الجديدة لها وسيط واحد فقط.]] oldprint ( s == "foo" and "bar" or s ) end end

سيتم الآن توجيه أي مكالمات مستقبلية printإلى الوظيفة الجديدة، وبسبب نطاق Lua المعجمي ، لن تكون وظيفة الطباعة القديمة متاحة إلا من خلال وظيفة الطباعة الجديدة المعدلة.

يدعم Lua أيضًا عمليات الإغلاق ، كما هو موضح أدناه:

دالة addto ( x ) -- تُعيد دالة جديدة تُضيف x إلى الوسيط return function ( y ) --[[عندما نشير إلى المتغير x، وهو خارج  النطاق الحالي وعمره أقصر من عمر هذه  الدالة المجهولة، تُنشئ Lua إغلاقًا.]] return x + y end end fourplus = addto ( 4 ) print ( fourplus ( 3 )) -- يطبع 7يمكن تحقيق ذلك أيضًا عن طريق استدعاء الدالة بالطريقة التالية: print ( addto ( 4 )( 3 )) --[[ وذلك لأننا نستدعي الدالة المُعادة من 'addto(4)' مع الوسيط '3' مباشرةً.  وهذا يساعد أيضًا على تقليل تكلفة البيانات وتحسين الأداء عند استدعائها بشكل تكراري.]]

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

الجداول

تُعدّ الجداول أهمّ هياكل البيانات (وهي، بحكم تصميمها، النوع الوحيد من البيانات المركبة المدمجة ) في لغة لوا، وهي أساس جميع أنواع البيانات التي يُنشئها المستخدم. وهي عبارة عن مصفوفات ترابطية مع إضافة مفتاح رقمي تلقائي وبنية خاصة.

الجدول عبارة عن مجموعة من أزواج المفاتيح والبيانات، حيث تتم الإشارة إلى البيانات بواسطة المفتاح؛ بعبارة أخرى، هو عبارة عن مصفوفة ترابطية غير متجانسة مجزأة .

يتم إنشاء الجداول باستخدام {}صيغة المُنشئ.

a_table = {} -- إنشاء جدول جديد فارغ

يتم تمرير الجداول دائمًا عن طريق المرجع (انظر الاستدعاء عن طريق المشاركة ).

يمكن أن يكون المفتاح (الفهرس) أي قيمة باستثناء nilNaN ، بما في ذلك الدوال.

a_table = { x = 10 } -- إنشاء جدول جديد، مع إدخال واحد يربط "x" بالرقم 10. print ( a_table [ "x" ]) -- طباعة القيمة المرتبطة بمفتاح السلسلة، في هذه الحالة 10. b_table = a_table b_table [ "x" ] = 20 -- تم تغيير القيمة في الجدول إلى 20. print ( b_table [ "x" ]) -- طباعة 20. print ( a_table [ "x" ]) -- طباعة 20 أيضًا، لأن a_table و b_table يشيران إلى نفس الجدول.

يُستخدم الجدول غالبًا كبنية (أو سجل ) باستخدام السلاسل النصية كمفاتيح. ولأن هذا الاستخدام شائع جدًا، فإن لغة Lua توفر صيغة خاصة للوصول إلى هذه الحقول. [ 10 ]

point = { x = 10 , y = 20 } -- إنشاء جدول جديد print ( point [ "x" ]) -- يطبع 10 print ( point . x ) -- له نفس معنى السطر أعلاه تمامًا. تدوين النقطة الأسهل قراءةً هو مجرد اختصار برمجي.

باستخدام جدول لتخزين الوظائف ذات الصلة، يمكن أن يعمل كمساحة اسم.

النقطة = {}Point.new = function ( x , y ) return { x = x , y = y } -- return {["x"] = x, ["y"] = y } endPoint.set_x = function ( point , x ) point.x = x -- point [ " x" ] = x ; end

يتم تعيين مفتاح رقمي للجداول تلقائيًا، مما يتيح استخدامها كنوع بيانات مصفوفة . يكون الفهرس التلقائي الأول هو 1 بدلاً من 0 كما هو الحال في العديد من لغات البرمجة الأخرى (على الرغم من أنه يُسمح بفهرس صريح بقيمة 0).

المفتاح الرقمي 1يختلف عن المفتاح النصي "1".

array = { "a" , "b" , "c" , "d" } -- يتم تعيين الفهارس تلقائيًا. print ( array [ 2 ]) -- يطبع "b". يبدأ الترقيم التلقائي في Lua من 1. print ( # array ) -- يطبع 4. # هو عامل الطول للجداول والسلاسل النصية. array [ 0 ] = "z" -- الصفر فهرس صالح. print ( # array ) -- لا يزال يطبع 4، لأن مصفوفات Lua تبدأ من 1.

tيُعرَّف طول الجدول بأنه أي فهرس صحيح nبحيث t[n]لا يكون صفرًا nilويكون t[n+1]صفرًا nil؛ علاوة على ذلك، إذا t[1]كان صفرًا nil، nفيمكن أن يكون صفرًا. بالنسبة للمصفوفة العادية، التي تحتوي على قيم غير فارغة من 1 إلى قيمة معينة n، فإن طولها هو بالضبط صفر n، وهو فهرس آخر قيمة فيها. إذا كانت المصفوفة تحتوي على "فجوات" (أي قيم فارغة بين قيم غير فارغة أخرى)، #tفيمكن أن يكون صفرًا أيًا من الفهارس التي تسبق nilقيمةً مباشرةً (أي أنه قد يعتبر أي قيمة فارغة من هذا القبيل نهايةً للمصفوفة). [ 11 ]

ExampleTable = { { 1 , 2 , 3 , 4 }, { 5 , 6 , 7 , 8 } } print ( ExampleTable [ 1 ][ 3 ]) -- يطبع "3" print ( ExampleTable [ 2 ][ 4 ]) -- يطبع "8"

يمكن أن يكون الجدول عبارة عن مصفوفة من الكائنات.

دالة Point ( x , y ) -- مُنشئ كائن "Point" return { x = x , y = y } -- تُنشئ وتُعيد كائنًا جديدًا (جدولًا) end array = { Point ( 10 , 20 ), Point ( 30 , 40 ), Point ( 50 , 60 ) } -- تُنشئ مصفوفة من النقاط -- array = { { x = 10, y = 20 }, { x = 30, y = 40 }, { x = 50, y = 60 } }; print ( array [ 2 ]. y ) -- تطبع 40

استخدام خريطة التجزئة لمحاكاة مصفوفة يكون عادةً أبطأ من استخدام مصفوفة فعلية؛ ومع ذلك، فإن جداول Lua مُحسَّنة للاستخدام كمصفوفات للمساعدة في تجنب هذه المشكلة. [ 12 ]

الجداول الفوقية

تُعدّ الدلالات القابلة للتوسيع سمةً أساسيةً في لغة Lua، وتتيح الجداول الوصفية تخصيصًا قويًا للجداول. يوضح المثال التالي جدولًا "لانهائيًا". لأي قيمة n، fibs[n]سيعطي الجدول nالعدد الفيبوناتشي رقم باستخدام البرمجة الديناميكية والتخزين المؤقت .

fibs = { 1 , 1 } -- القيم الأولية لـ fibs[1] و fibs[2]. setmetatable ( fibs , { __index = function ( values ​​, n ) --[[__index هي دالة معرفة مسبقًا في Lua،  ويتم استدعاؤها إذا لم يكن المفتاح "n" موجودًا.]] values ​​[ n ] = values ​​[ n - 1 ] + values ​​[ n - 2 ] -- حساب وتخزين fibs[n]. return values ​​[ n ] end })

البرمجة الكائنية التوجه

على الرغم من أن لغة Lua لا تتضمن مفهومًا مُدمجًا للفئات ، إلا أنه يُمكن محاكاة البرمجة كائنية التوجه باستخدام الدوال والجداول. يُنشأ الكائن بوضع الدوال والحقول في جدول. يُمكن تطبيق الوراثة (الفردية والمتعددة) باستخدام الجداول الوصفية ، وذلك بتفويض الدوال والحقول غير الموجودة إلى الكائن الأصل.

لا يوجد مفهوم "فئة" في هذه التقنيات؛ بل تُستخدم النماذج الأولية ، على غرار مفهوم "الذات" أو لغة جافا سكريبت . تُنشأ الكائنات الجديدة إما باستخدام دالة مصنع (تقوم بإنشاء كائنات جديدة من الصفر) أو عن طريق استنساخ كائن موجود.

إنشاء كائن متجه أساسي :

local Vector = {} local VectorMeta = { __index = Vector }دالة Vector.new ( x , y , z ) -- الدالة البانية تُرجع setmetatable ( { x = x , y = y , z = z } , VectorMeta ) endدالة Vector.magnitude ( self ) -- طريقة أخرى تُرجع math.sqrt ( self.x ^ 2 + self.y ^ 2 + self.z ^ 2 ) endlocal vec = Vector.new ( 0 , 1 , 0 ) -- إنشاء متجه print ( vec.magnitude ( vec ) ) -- استدعاء دالة (الناتج: 1) print ( vec.x ) -- الوصول إلى متغير عضو (الناتج: 0 )

هنا، setmetatableيُخبر Lua بالبحث عن عنصر في Vectorالجدول إذا لم يكن موجودًا فيه vec. وهو ما يُعادل ، حيث يبحث أولًا في الجدول عن العنصر. لا يحتوي الجدول على عنصر، ولكن جدول البيانات الوصفية الخاص به يُحيل البحث إلى الجدول للعثور على العنصر عندما لا يكون موجودًا فيه .vec.magnitudevec["magnitude"]vecmagnitudevecmagnitudeVectormagnitudevec

توفر لغة Lua بعض التسهيلات النحوية لدعم البرمجة الكائنية. لتعريف الدوال الأعضاء داخل جدول النموذج الأولي، يمكن استخدام `<format>` ، وهو ما يعادل `<format> `. كما أن استدعاء توابع الصنف يستخدم النقطتين الرأسيتين: ` <format>`، وهو ما يعادل `<format> `.functiontable:func(args)functiontable.func(self,args)object:func(args)object.func(object,args)

مع أخذ ذلك في الاعتبار، إليك فئة مقابلة مع :اختصار برمجي:

المتجه المحلي = {} المتجه .__ index = المتجهدالة Vector : new ( x , y , z ) -- الدالة البانية بما أن تعريف الدالة يستخدم نقطتين رأسيتين، فإن وسيطها الأول هو "self" الذي يشير إلى "Vector" return setmetatable ({ x = x , y = y , z = z }, self ) endدالة Vector : magnitude () -- طريقة أخرى -- الإشارة إلى الكائن الضمني باستخدام self return math.sqrt ( self.x ^ 2 + self.y ^ 2 + self.z ^ 2 ) endlocal vec = Vector : new ( 0 , 1 , 0 ) -- إنشاء متجه print ( vec : magnitude ()) -- استدعاء دالة (الناتج: 1) print ( vec . x ) -- الوصول إلى متغير عضو (الناتج: 0)

الميراث

من الممكن استخدام الجداول الوصفية لمحاكاة سلوك وراثة الفئات في لغة لوا. [ 13 ] في هذا المثال، نسمح بضرب قيم المتجهات بثابت في فئة مشتقة.

المتجه المحلي = {} المتجه .__ index = المتجهدالة Vector : new ( x , y , z ) -- الدالة البانية هنا، يشير self إلى دالة "new" الخاصة بالفئة التي نستدعيها. في الفئة المشتقة، سيكون self هو الفئة المشتقة؛ في فئة Vector، سيكون self هو Vector. return setmetatable ({ x = x , y = y , z = z }, self ) endدالة Vector : magnitude () -- طريقة أخرى -- الإشارة إلى الكائن الضمني باستخدام self return math.sqrt ( self.x ^ 2 + self.y ^ 2 + self.z ^ 2 ) end-- مثال على وراثة الصنف الزائف local VectorMult = {} VectorMult .__ index = VectorMult setmetatable ( VectorMult , Vector ) -- اجعل VectorMult صنفًا فرعيًا من Vectorدالة VectorMult : ضرب ( القيمة ) self.x = self.x * القيمة self.y = self.y * القيمة self.z = self.z * القيمة return self endlocal vec = VectorMult : new ( 0 , 1 , 0 ) -- إنشاء متجه print ( vec : magnitude ()) -- استدعاء دالة (الناتج: 1) print ( vec.y ) -- الوصول إلى متغير عضو (الناتج: 1) vec : multiply ( 2 ) -- ضرب جميع مكونات المتجه في 2 print ( vec.y ) -- الوصول إلى العضو مرة أخرى ( الناتج : 2)

من الممكن أيضًا تطبيق التوريث المتعدد ؛ __indexحيث يمكن أن يكون دالة أو جدولًا. [ 14 ] كما يمكن تطبيق تحميل المعاملات الزائد ؛ إذ يمكن أن تحتوي جداول البيانات الوصفية في لغة لوا على عناصر مثل __add، __subوما إلى ذلك. [ 15 ]

تطبيق

لا تُفسَّر برامج Lua مباشرةً من ملف Lua النصي، بل تُجمَّع إلى بايت كود، ثم يُشغَّل على آلة Lua الافتراضية . عادةً ما تكون عملية التجميع غير مرئية للمستخدم وتُنفَّذ أثناء وقت التشغيل ، خاصةً عند استخدام مُجمِّع JIT، ولكن يُمكن إجراؤها دون اتصال بالإنترنت لزيادة سرعة التحميل أو تقليل استهلاك الذاكرة في بيئة التشغيل عن طريق الاستغناء عن المُجمِّع. كما يُمكن إنتاج بايت كود Lua وتنفيذه من داخل Lua، باستخدام الدالة dumpمن مكتبة السلاسل النصية والدوال load/loadstring/loadfileالأخرى. تم تنفيذ Lua الإصدار 5.5.0 بحوالي 32000 سطر من كود C. [ 3 ]

على غرار معظم وحدات المعالجة المركزية، وعلى عكس معظم الآلات الافتراضية (التي تعتمد على بنية المكدس )، تعتمد آلة Lua الافتراضية على بنية المسجلات ، وبالتالي فهي أقرب إلى تصميم معظم الأجهزة. تتجنب بنية المسجلات النسخ المفرط للقيم، وتقلل من إجمالي عدد التعليمات لكل دالة. تُعد الآلة الافتراضية لـ Lua 5 من أوائل الآلات الافتراضية النقية القائمة على المسجلات والتي حظيت باستخدام واسع النطاق. [ 16 ] وتُعد Parrot و Dalvik من Android مثالين آخرين معروفين على الآلات الافتراضية القائمة على المسجلات. كما كانت آلة PCScheme الافتراضية قائمة على المسجلات أيضًا. [ 17 ]

هذا المثال هو قائمة بايت كود لدالة المضروب المحددة أعلاه (كما هو موضح بواسطة luacالمترجم 5.1): [ 18 ]

دالة <factorial.lua:1,7> (9 تعليمات، 36 بايت في 0x8063c60) معامل واحد، 6 خانات، 0 قيم علوية، 6 متغيرات محلية، ثابتان، 0 دوال 1 [2] LOADK 1 -1 ; 1 2 [3] LOADK 2 -2 ; 2 3 [3] نقل 3 0 4 [3] LOADK 4 -1 ; 1 5 [3] FORPREP 2 1 ; إلى 7 6 [4] MUL 1 1 5 7 [3] FORLOOP 2 -2 ; إلى 6 8 [6] إرجاع 1 2 9 [7] إرجاع 0 1

واجهة برمجة تطبيقات C

صُممت لغة Lua لتُدمج في تطبيقات أخرى، وتوفر واجهة برمجة تطبيقات (API) بلغة C لهذا الغرض. تنقسم واجهة برمجة التطبيقات إلى جزأين: نواة Lua ومكتبة Lua المساعدة. [ 19 ] يُغني تصميم واجهة برمجة تطبيقات Lua عن الحاجة إلى عدّ المراجع (إدارتها) يدويًا في كود C، على عكس واجهة برمجة تطبيقات Python . تتميز واجهة برمجة التطبيقات، مثل اللغة نفسها، ببساطتها. توفر المكتبة المساعدة وظائف متقدمة، وتتكون في معظمها من وحدات ماكرو للمعالجة المسبقة تُساعد في عمليات الجداول المعقدة.

تعتمد واجهة برمجة تطبيقات Lua C على بنية المكدس . توفر Lua دوالًا لإضافة وحذف معظم أنواع بيانات C البسيطة (الأعداد الصحيحة، والأعداد العشرية، وما إلى ذلك) من وإلى المكدس، بالإضافة إلى دوال لمعالجة الجداول عبر المكدس. يختلف مكدس Lua نوعًا ما عن المكدس التقليدي؛ إذ يمكن فهرسة المكدس مباشرةً، على سبيل المثال. تشير الفهارس السالبة إلى الإزاحات من أعلى المكدس. على سبيل المثال، -1 هو الأعلى (أحدث قيمة أُضيفت)، بينما تشير الفهارس الموجبة إلى الإزاحات من الأسفل (أقدم قيمة). يتم أيضًا نقل البيانات بين دوال C و Lua باستخدام المكدس. لاستدعاء دالة Lua، تُضاف الوسائط إلى المكدس، ثم lua_callيُستخدم المكدس لاستدعاء الدالة الفعلية. عند كتابة دالة C ليتم استدعاؤها مباشرةً من Lua، تُقرأ الوسائط من المكدس.

فيما يلي مثال على استدعاء دالة Lua من لغة C:

#include <stdio.h> #include <lua.h> // مكتبة Lua الرئيسية (lua_*) #include <lauxlib.h> // مكتبة Lua المساعدة (luaL_*)int main ( void ) { // إنشاء حالة Lua lua_State * L = luaL_newstate ( );// تحميل وتنفيذ سلسلة نصية إذا ( luaL_dostring ( L , "function foo (x,y) return x+y end" )) { lua_close ( L ); return -1 ; }// دفع قيمة المتغير العام "foo" (الدالة المعرفة أعلاه) // إلى المكدس، متبوعة بالعددين الصحيحين 5 و3 lua_getglobal ( L , "foo" ); lua_pushinteger ( L , 5 ); lua_pushinteger ( L , 3 ); lua_call ( L , 2 , 1 ); // استدعاء دالة ذات وسيطين وقيمة إرجاع واحدة printf ( "النتيجة: %d \n " , lua_tointeger ( L , -1 )); // طباعة القيمة الصحيحة للعنصر الموجود في أعلى المكدس lua_pop ( L , 1 ); // إعادة المكدس إلى حالته الأصلية lua_close ( L ); // إغلاق حالة Lua return 0 ; }

تشغيل هذا المثال يعطي:

$ cc -o example example.c -llua $ ./example النتيجة: 8

توفر واجهة برمجة تطبيقات C أيضًا بعض الجداول الخاصة، الموجودة في "مؤشرات وهمية" مختلفة ضمن بنية Lua. قبل LUA_GLOBALSINDEXالإصدار 5.2 من Lua [ 20 ] ، يوجد جدول المتغيرات العامة، _Gوهو جزء من Lua، ويمثل مساحة الاسم الرئيسية . كما يوجد سجلٌّ حيث LUA_REGISTRYINDEXيمكن لبرامج C تخزين قيم Lua لاسترجاعها لاحقًا.

الوحدات

إلى جانب وحدات المكتبة القياسية (الأساسية)، يُمكن كتابة إضافات باستخدام واجهة برمجة تطبيقات Lua. وحدات الإضافة هي كائنات مشتركة تُستخدم لتوسيع وظائف المفسر من خلال توفير إمكانيات أصلية لبرامج Lua النصية. يُمكن لبرامج Lua النصية تحميل وحدات الإضافة باستخدام [ 19 require تمامًا مثل الوحدات المكتوبة بلغة Lua نفسها، أو باستخدام [ 21] . عند تحميل مكتبة C عبر [ 21 ] ، يبحث Lua عن الدالة ويستدعيها، والتي تعمل كأي دالة C قابلة للاستدعاء من Lua، وعادةً ما تُعيد جدولًا مليئًا بالأساليب. تتوفر مجموعة متنامية من الوحدات تُسمى "Rocks" من خلال نظام إدارة الحزم LuaRocks [ 22 ] ، على غرار CPAN و RubyGems و Python eggs . توجد روابط Lua جاهزة لمعظم لغات البرمجة الشائعة، بما في ذلك لغات البرمجة النصية الأخرى [ 23 ] . بالنسبة للغة C++، يوجد عدد من الأساليب القائمة على القوالب وبعض مولدات الربط التلقائي.package.loadlibrequire('foo')luaopen_foo

التطبيقات

في تطوير ألعاب الفيديو ، تُستخدم لغة Lua على نطاق واسع كلغة برمجة نصية ، ويعود ذلك أساسًا إلى سهولة تضمينها وسرعة تنفيذها وقصر مدة تعلمها . [ 24 ] ومن أبرز الألعاب التي تستخدم Lua: Roblox ، [ 25 ] و Garry's Mod و World of Warcraft و Payday 2 و Project Zomboid و Phantasy Star Online 2 و Dota 2 و Crysis ، [ 26 ] وغيرها الكثير. كما تُستخدم Lua في برامج أخرى غير برامج ألعاب الفيديو، مثل Adobe Lightroom و Moho و iClone و Aerospike ، وبعض برامج النظام في FreeBSD و NetBSD ، وتُستخدم كلغة برمجة نصية للقوالب في MediaWiki باستخدام إضافة Scribunto. [ 27 ]

في عام 2003، أظهر استطلاع رأي أجرته GameDev.net أن لغة Lua هي لغة البرمجة النصية الأكثر شيوعًا لبرمجة الألعاب. [ 28 ] وفي 12 يناير 2012، أُعلن عن فوز Lua بجائزة Front Line لعام 2011 من مجلة Game Developer في فئة أدوات البرمجة. [ 29 ]

تستخدم العديد من التطبيقات غير المتعلقة بالألعاب أيضًا لغة Lua من أجل قابلية التوسع، مثل LuaTeX ، وهي تطبيق للغة TeX لتنسيق النصوص؛ وRedis ، وهي قاعدة بيانات مفتاح-قيمة ؛ وScyllaDB ، وهي مخزن أعمدة واسع ؛ وNeovim ، وهو محرر نصوص؛ وNginx ، وهو خادم ويب ؛ وWireshark ، وهو محلل حزم الشبكة؛ وDiscordia، وهي مكتبة واجهة برمجة تطبيقات Discord ؛ و Pure Data ، وهي لغة برمجة صوتية مرئية (من خلال امتداد pdlua).

اللغات المشتقة

اللغات التي تُترجم إلى لغة لوا

اللهجات

  • LuaJIT ، وهو مترجم فوري للغة Lua 5.1. [ 36 ] [ 37 ]
  • لغة Luau، التي طورتها شركة Roblox ، هي مشتقة من لغة Lua 5.1 ومتوافقة معها، وتتميز بنظام كتابة تدريجي ، وميزات إضافية، وتركيز على الأداء. [ 38 ] وقد حسّنت Luau من خاصية الحماية (sandboxing) للسماح بتشغيل التعليمات البرمجية غير الموثوقة في التطبيقات المدمجة. [ 39 ]
  • رافي، لغة لوا 5.3 تدعم تقنية الترجمة الفورية (JIT) مع إمكانية تحديد الأنواع الثابتة. وتعتمد تقنية الترجمة الفورية على معلومات الأنواع. [ 40 ]
  • Shine، وهو نسخة معدلة من LuaJIT مع العديد من الإضافات، بما في ذلك نظام الوحدات ونظام الماكرو. [ 41 ]
  • Glua، وهي نسخة معدلة مضمنة في لعبة Garry's Mod كلغة برمجة نصية. [ 42 ]
  • Teal، وهي لهجة Lua ذات كتابة ثابتة مكتوبة بلغة Lua. [ 43 ]
  • يستخدم جهاز PICO-8 ، وهو "جهاز ألعاب فيديو خيالي"، مجموعة فرعية من لغة Lua تُعرف باسم PICO-8 Lua.
  • بلوتو، وهي مجموعة فرعية من لغة لوا 5.4 تقدم بنية محسّنة ومكتبات وتجربة تطوير أفضل، مع الحفاظ على التوافق مع لغة لوا العادية. [ 44 ]

بالإضافة إلى ذلك، يقدم مجتمع مستخدمي لغة Lua بعض التصحيحات القوية فوق تطبيق C المرجعي. [ 45 ]

انظر أيضاً

ملحوظات

  1. يُعدّ استخدام الاختصارات النحوية ، أو بنية الجدول، أو السلسلة النصية الحرفية التي تلي المعرّف، استدعاءً صحيحًا للدالة. [ 9 ]

مراجع

  1. https://lua.org/versions.html#5.5 .{{cite web}}: مفقود أو فارغ |title=( مساعدة )
  2. ^ إيروساليمشي، روبرتو. دي فيغيريدو، لويز هنريكي؛ فيلهو فالديمار سيليس (يونيو 1996). "Lua - لغة ملحقة قابلة للتوسيع" . البرمجيات: الممارسة والخبرة . 26 (6): 635–652 . دوى : 10.1002/(SICI)1097-024X(199606)26:6 < 635::AID-SPE26 > 3.0.CO ; 2-ف . S2CID 61066194 . تم الاسترجاع 24 أكتوبر 2015 . 
  3. 1 2 3 "حول لغة لوا" . Lua.org . تم الاطلاع عليه بتاريخ 26 مايو 2026 .
  4. ^ تختييف ، يوري (21 أبريل 2013). "من البرازيل إلى ويكيبيديا" . الشؤون الخارجية . تم الاسترجاع 25 أبريل 2013 .
  5. 1 2 3 4 إيروساليمسكي، ر .؛ فيغيريدو، ل.هـ؛ سيليس، و. (2007). "تطور لغة لوا" (ملف PDF) . وقائع المؤتمر الثالث لجمعية ACM SIGPLAN حول تاريخ لغات البرمجة . الصفحات 2-1-2-26. doi : 10.1145/1238844.1238846 . ISBN  978-1-59593-766-7. S2CID 475143 . 
  6. "تطور لغة الامتداد: تاريخ لغة لوا" . 2001. تم الاطلاع عليه بتاريخ 18 ديسمبر 2008 .
  7. ^ فيغيريدو، LH؛ إيروسالمشي، ر. سيليس دبليو. (ديسمبر 1996). "Lua: لغة مدمجة قابلة للتوسيع. تحل بعض الآليات الفوقية محل مجموعة من الميزات" . مجلة الدكتور دوب . المجلد. 21، لا. 12. ص 26 – 33.   
  8. "البرمجة بلغة لوا : 1" . 
  9. "دليل مرجع Lua 5.0، 2.5.7، استدعاءات الوظائف" .
  10. "دليل مرجع Lua 5.1" . 2014. تم الاطلاع عليه بتاريخ 27 فبراير 2014 .
  11. "دليل مرجع Lua 5.1" . 2012. تم الاطلاع عليه بتاريخ 16 أكتوبر 2012 .
  12. "شفرة مصدر Lua 5.1" . 2006. تم الاطلاع عليه بتاريخ 24 مارس 2011 .
  13. ^ روبرتو إيروساليمشي. البرمجة في لوا، الطبعة الرابعة ص. 165. 
  14. "البرمجة بلغة لوا : 16.3" . لوا . تم الاطلاع عليه بتاريخ 16 سبتمبر 2021 . 
  15. "دليل استخدام الأساليب الوصفية" . ويكي مستخدمي لغة لوا . مؤرشف من الأصل بتاريخ 16 سبتمبر 2021. تم الاطلاع عليه بتاريخ 16 سبتمبر 2021 .
  16. إيروساليمسكي، ر.؛ فيغيريدو، ل.هـ.؛ سيليس، و. (2005). "تطبيق لغة لوا 5.0" . مجلة علوم الحاسوب الشاملة . 11 (7): 1159-1176 . doi : 10.3217/jucs-011-07-1159 .
  17. شركة تكساس إنسترومنتس (1990). برنامج PC Scheme: دليل المستخدم ودليل اللغة المرجعي، الطبعة التجارية . دار نشر MIP. رقم ISBN 0-262-70040-9.
  18. مان، كين-هونغ (2006). "مقدمة بسيطة لتعليمات الآلة الافتراضية في لغة لوا 5.1" (ملف PDF) .
  19. 1 2 "دليل مرجعي للغة Lua 5.2" . Lua.org . تم الاطلاع عليه بتاريخ 23 أكتوبر 2012 .
  20. ^ إيروساليمشي، روبرتو. دي فيغيريدو، لويز هنريكي؛ سيليس، فالديمار (2011-2013). التغييرات في API . لوا.org . تم الاسترجاع 9 مايو 2014 .{{cite book}}تم |work=تجاهله ( مساعدة )
  21. ^ إيروساليمشي، روبرتو. دي فيغيريدو، لويز هنريكي؛ سيليس، فالديمار. "الدليل المرجعي لوا 5.4" . لوا . تم الاسترجاع في 1 يونيو 2022 .
  22. "LuaRocks" . luarocks.org . تم الاطلاع عليه بتاريخ 24 مايو 2009 .
  23. "ربط الكود بلغة لوا" . ويكي مستخدمي لوا. مؤرشف من الأصل بتاريخ 27 يوليو 2009. تم الاطلاع عليه بتاريخ 24 مايو 2009 .
  24. "لماذا تُعتبر لغة Lua لغة برمجة ألعاب؟" . موقع Stack Overflow . مؤرشف من الأصل بتاريخ 20 أغسطس 2013. تم الاطلاع عليه بتاريخ 22 أبريل 2017 .
  25. "لماذا لواو ؟ " . لواو . تم الاطلاع عليه بتاريخ 6 أبريل 2026 .
  26. "مقدمة لتعديل لعبة كرايسس من جانب الخادم" . تم الاطلاع عليه بتاريخ 23 مارس 2022 .
  27. "وظائف Lua" . wow.gamepedia.com . تم الاطلاع عليه في 1 مارس 2021 .
  28. "نتائج الاستطلاع" . مؤرشف من الأصل في 7 ديسمبر 2003. تم الاطلاع عليه في 22 أبريل 2017 .{{cite web}}: CS1 maint: bot: حالة عنوان URL الأصلي غير معروفة ( رابط )
  29. "الإعلان عن الفائزين بجوائز الخط الأمامي" . مؤرشف من الأصل بتاريخ 15 يونيو 2013. تم الاطلاع عليه بتاريخ 22 أبريل 2017 .
  30. "دليل اللغة - مون سكريبت 0.5.0" . moonscript.org . تم الاطلاع عليه بتاريخ 25 سبتمبر 2020 .
  31. ليف (23 سبتمبر 2020). "leafo/moonscript" . جيت هاب . تم الاسترجاع في 25 سبتمبر 2020 .
  32. 1 2 جارزيا، أندريه ألفيس. "اللغات التي يتم تجميعها إلى Lua" . AndreGarzia.com . تم الاسترجاع في 25 سبتمبر 2020 .
  33. "Urn: تطبيق Lisp للغة Lua | Urn" . urn-lang.com . تم الاطلاع عليه بتاريخ 12 يناير 2021 .
  34. "Amulet ML" . amulet.works . تم الاطلاع عليه بتاريخ 12 يناير 2021 .
  35. "LunarML، مُترجم لغة ML القياسي الذي يُنتج Lua/JavaScript" . GitHub .
  36. "LuaJIT" . LuaJIT .
  37. "الإضافات" . LuaJIT .
  38. " لماذا لواو؟" . لواو . تم الاطلاع عليه في 3 أغسطس 2024. كل هذه العوامل دفعتنا إلى إعادة صياغة لغة Lua 5.1 التي بدأنا بها، وتحويلها إلى لغة جديدة مشتقة أطلقنا عليها اسم لواو. ينصب تركيزنا على جعل اللغة أكثر كفاءة وغنى بالميزات، وتسهيل كتابة أكواد قوية من خلال الجمع بين التدقيق اللغوي والتحقق من الأنواع باستخدام نظام أنواع تدريجي.
  39. "التجربة المعزولة" . لواو . تم الاطلاع عليه بتاريخ 27 مارس 2025 .
  40. "لغة برمجة رافي" . جيت هاب .
  41. ^ هاندت ، ريتشارد (22 أبريل 2021). "ريتشاردهونت / شاين" . جيثب .
  42. "ويكي Garry's Mod" . wiki.facepunch.com .
  43. "teal-language/tl" . لغة Teal . 23 ديسمبر 2024. تم الاطلاع عليه بتاريخ 23 ديسمبر 2024 .
  44. "ما هو بلوتو؟" . بلوتو . تم الاطلاع عليه بتاريخ 27 يونيو 2025 .
  45. "Lua Power Patches" . lua-users.org . مؤرشف من الأصل بتاريخ 18 مايو 2021. تم الاطلاع عليه بتاريخ 18 مايو 2021 .

للمزيد من القراءة