صِيَغٌ خَاْصَّةٌ Special forms

يُستَخدم الكائن specialForms لتعريف نحويَّاتٍ خاصَّة في Egg. فهي تربط الكلمات بالدوال مِمَّا يُقَدَّرُ كصيغٍ خاصَّة. وهي حاليًّا خالية. فلنقم إذًا بإضافة بعض الصيغ.

specialForms["if"] = function(args, env){

if (args.length != 3)

throw new SyntaxError("Bad number of args to if");

if (evaluate(args[0], env) !== false) return evaluate(args[1], env); else return evaluate(args[2], env); }; تَتَوَقَّع بُنية if الخاصَّة بِـ Egg ثلاثة جدليَّات arguments. فهي ستُقَيِّم الأولى، وإذا لم تكن النتيجة هي القيمة "خطأ" false، عندها ستُقَيِّم الثانية. وإلَّا، ستُقَيَّم الثالثة. إنَّ صيغة if هذه أشبه بثُلاثِيَّة الجافا سكرِبت ؟: فهي مُعَامِل operator أكثر من if الخاصَّة بِالجافا سكرِبت. وهي تعبير expression وليست إفادة statement، وَتنتج قيمة، ما يعني، نتيجة الجدليَّة الثانية أو الثالثة. تختلف Egg عن الجافا سكرِبت بطريقة إستيعاب قيمة الشَّرط if. فلن تعامل الأشياء مثل الصفر أو السلسلة النصيَّة الفارغة كَـخطأ false، بل تعامل هكذا القيمة خطأ المحدَّدة بدقَّة. سبب حاجتنا لتمثيل if كَصيغة خاصَّة special form، أكثر منه كَدالَّة إعتياديَّة، هو أنَّ كل جدليَّات الدَّوال تُقَيَّم evaluated قبل أن تُستدعى الدالَّة function، بينما يجب على if أن تقيِّم فقط إمَّا جدليَّتها الثانية أو الثالثة، إعتمادًا على قيمة الأولى. إنَّ صيغة "طالما" while مُشابهة. specialForms["while"] = function(args, env){ if (args.length != 2) throw new SyntaxError("Bad number of args to while"); while(evaluate(args[0], env) !== false) evaluate(args[1], env); // Since undefined does not exist in Egg, we return false, // for lack of a meaningful result. return false; }; طوبُ بِناءٍ أساسيٍّ آخر هو do، حيثُ يُنفِّذ كُلَّ جدليَّاتِه من القِمَّة لِلقاع. وتكون قيمته هي القيمة المُنتَجة من الجدليَّة الأخيرة. specialForms["do"] = function(args, env){ var value = false; args.forEach(function(arg){ value = evaluate(arg, env); }); return value; }; لِنكونَ قادِرين على إنشاء مُتَغَيِّرَات variables وإعطائها قيمًا جديدة، فإنَّنا نقوم أيضًا بإنشاء صيغة Form تُدعى "عَرِّفْ" define. تتوقَّع كلمة كَأوَّل جدليَّة وتعبيرٍ ما -كَثَانِ جدليَّاتِها- يُنتِج القيمة لِإسنادِها إلى تلك الكلمة. بما أنَّ define -كأيِّ شيءٍ آخر- هي تعبيرٌ expression، فيجب أن تعود بقيمة value. سنجعلها تعود بالقيمة الَّتي أُسْنِدَتْ (كَمُعامِل operator جافا سِكرِبت: = ). specialForms["define"] = function(args, env){ if (args.length != 2 || args[0].type != "word") throw new SyntaxError("Bad use of define");

var value = evaluate(args[1], env);

env[args[0].name] = value;

return value;

};