اکس‌ال (زبان برنامه‌نویسی)

تاریخچه

زبان XL حدوداً از سال 1992 به وجود آمد و نتیجه زحمات دراز مدت یک تیم طراحی زبان است. شایان ذکر است که سازنده و طراح اصلی این زبان Christophe de Dinechin می‌باشد. کامپایلر XL با زبان ++C نوشته شده‌است. نکته‌ای که در این زبان وجود داشت این بود که همه ویژگی‌هایی که بالا توصیف شده بود، درست کار می‌کرد؛ اما نوشتن plug-in برای آن یک کابوس بود، چون ++C خودش توسعه پذیر نیست بنابراین پیاده‌سازی ترجمه غیرممکن بود.

درخت پارس با انواع زیادی از گره‌ها خیلی پیچیده بود. چون برای پشتیبانی زبان متقاطع طراحی شده بود.

Moka یک کامپایلر توسعه پذیر Java-to-Java بود که از همین ساختار استفاده می‌کرد.

در سال 2003 یک کامپایلر جدید با اصلاح کامل کامپایلر قبلی و ساده کردن درخت پارس آن معرفی شد. در سال 2004 کامپایلر ساده‌تری راه اندازی شد که سادگی درخت پارس آن در حدی بود که گره‌هایش به اندازه 7 نوع گره XL0 رسید و همه توسعه‌های امروزی در XL نوشته می‌شود.

قواعد

در سطح XL0 قواعد زبان تعریف می‌شوند. در فاز XL0 کامپایلر ویژگی‌هایی نظیر نحوه نمایش متن، اولویت عملگرها و ... با استفاده از فایل توصیف قواعد، می‌تواند توصیف می‌شود. به عنوان مثال: فایل قواعد اصلی، نمادگذاری‌های ریاضی رایج مانند "+" برای عمل "جمع" و اولویت آن‌ها را تعریف می‌کند.

درخت پارس:

از 7 نوع گره تشکیل می‌شود. 4 تا مربوط به (integer، real، text و symbol) که برگ‌های درخت هم هستند و 3 تای دیگر هم گره‌های داخلی مربوط به (prefix، infix و block) هستند.

integer: برای نمایش اعداد صحیح مثلاً عدد 2 به کار می‌رود. علامت # هم برای نمایش مبنای اعداد استفاده می‌شود. مثلاً: (101001 # 2). همچنین علامت خط تیره هم برای جداسازی بین اعداد بزرگ و افزایش خوانایی می‌باشد. مثلاً: 100_110_011

real: برای نمایش اعداد غیر صحیح مثلاً 2.5 به کار می‌رود. موارد مربوط به مبنای اعداد و خط تیره‌گذاری هم وجود دارد. مثلاً: 16#F.FFF#E-10

Text: داده‌های متنی را نمایش می‌دهد. عبارات متنی در بین double quotes و کاراکترها با single quotes محصور می‌شوند.

Symbol: نمایش اسامی یا عملگرها را بر عهده دارد. اسامی شامل دنباله‌ای از حروف الفبا می‌باشد که با یک حرف شروع می‌شوند مثل Hello. بد نیست بدانید که XL1 بر خلاف XL0، بزرگ و کوچکی و خط تیره را نادیده نمی‌گیرد و مثلاً بین JohnDoe و john_doe تفاوت قائل می‌شود. و اما نمادها دنباله‌ای از کاراکترهای غیر الفبایی مثل *، =/= و ... می‌باشد.

infix: دو گره مرتبط به هم را با یک نماد میانوندی نمایش می‌دهد. مثلاً A and B یا 2 + 3. یکی دیگر از کاربردهای گره‌های میانوند، حضور در بین خطوط با نماد new-line برای جداسازی خط‌ها می‌باشد.

Prefix: برای نمایش دو گره متوالی مثل: write “Hello” استفاده می‌شود.

Block: گره‌هایی را که توسط گروهی از نمادها احاطه شده اند، نشان می‌دهد. مثلاً (A) یا (index)

با فایل قواعد پیش فرض، عبارت زیر صرف نظر از معنی، یک جمله معتبر در سطح XL0 است:
A = B + "Hello"
و به این صورت تجزیه می‌شود:
infix("=",
      symbol("A"),
      infix("+",
            symbol("B"), text("Hello")))

معانی

فاز XL1 به عنوان دنبالی ای از عملیات روی درخت پارس XL0 است. این عملیات که توسط plug-inهای گوناگون کامپایلر فراهم می‌شوند، با توجه به شکل درخت پارس به وجود می‌آیند.

ساختار ویژه translate توسط یک plug-in فراهم شده‌است تا نوشتن Plug-inهای دیگر را آسان نماید. ساختار quote هم یک درخت پارس را تولید می‌کند.

در زیر نمونه‌ای از این نمادگذاری‌ها را می‌بینیم که چگونه در پیاده‌سازی یک plug-in به اسم ZeroRemoval نقش دارد.
translation ZeroRemoval
  when
    'X' + 0
  then
    return X
  when
    'X' * 0
  then
    return parse_tree(0)
فاز XL1 شامل مجموعه عظیمی از plug-inها می‌شود که abstractionهای رایجی نظیر subroutine، تایپ داده‌ای و تعریف متغیرها و همچنین اساس برنامه نویسی ساخت یافته مانند جملات شرطی یا حلقه‌ها را نیز فراهم می‌کند.

سیستم تایپ

فرایند چک کردن تایپ در XL1، به صورت ایستا با قابلیت برنامه‌نویسی عمومی نظیر ++C یا Ada می‌باشد. تایپ‌هایی مانند آرایه‌ها و اشاره گرها که در زبانی مثل ++C به عنوان تایپ اولیه تلقی می‌شود، در کتابخانه XL وجود دارد. به عنوان مثال، یک تایپ آرایه یک بعدی می‌تواند به صورت زیر تعریف شود:
generic [Item : type; Size : integer] type array
تایپ عمومی معتبر، تایپ عمومی ای می‌باشد که توسط شرطی مشخص می‌کند، چه تایپی می‌تواند استفاده شود. یک تایپ منظم است، اگر یک ارتباط کمتری داشته باشد مانند:
// A type is ordered if it has a less-than relationshipgeneric type ordered if
  A, B : ordered
  Test : boolean := A <B
در زبان XL این قابلیت وجود دارد تا تابعی را تعریف کنید که تلویحاً عمومی می‌باشد چون تایپ منظم خودش عمومی است.
// Generic function for the minimum of one itemfunction Min(X : ordered) return ordered is
  return X
همچنین این موضوع، برای تایپ‌های عمومی ای که پارامترهایی را دارند، مانند آرایه‌ها به کار می‌رود. یک تابعی که مجموع عناصر در هر آرایه را محاسبه می‌کند، به صورت زیر نوشته می‌شود:
function Sum(A : array) return array.Item is
  for I in 0..array.Size-1 loop
    result += A[I]

لیست‌های آرگومان متغیر امن-تایپ

توابع می‌توانند overload شوند. یک تابع با استفاده از لغت کلیدی other در لیست پارامترها یش می‌تواند با تعداد متغیری آرگومان تعریف شود. در چنین تابعی، other استفاده می‌شود تا تعداد متغیر آرگومان‌ها را به یک subroutine دیگر بفرستد.
// Generic function for the minimum of N itemfunction Min(X : ordered; ...) return ordered is
  result := Min(...)
  if X <result then
    result := X
هنگامی که یک چنین تابعی صدا زده می‌شود، کامپایلر به‌طور بازگشتی توابع را معرفی می‌کند تا لیست پارامترها را تطبیق دهد.
// Examples of use of the Min just declaredX : real := Min(1.3, 2.56, 7.21)Y : integer := Min(1, 3, 6, 7, 1, 2)

کاهش عبارت (Operator Overloading)

عملگرها با استفاده از فرم written تعریف توابع بیان می‌شوند. در زیر کدی که جمع دو عدد صحیح را تعریف می‌کند، می‌بینیم:
function Add(X, Y: integer)
return integer written X+Y
فرم written می‌تواند بیشتر از دو پارامتر هم داشته باشد. به عنوان مثال یک ماتریس انتقال خطی به صورت زیر است:
function Linear(A, B, C : matrix) return matrix written A+B*C
فرم written همچنین می‌تواند از عدد ثابت‌ها نیز استفاده کند. نظیر:
function Equal(A, B : matrix) return boolean written A=Bfunction IsNull(A : matrix) return boolean written A=0function IsUnity(A : matrix) return boolean written A=1
مکانیزم مذکور برای پیاده‌سازی همه عملگرهای اساسی استفاده می‌شود.

Iterators

XL Iteratorها به برنامه نویسان اجازه پیاده‌سازی generatorها و iteratorها را می‌دهند.
import IO = XL.UI.CONSOLEiterator IntegerIterator (var out Counter : integer; Low, High : integer) written Counter in Low..High is
    Counter := Low
    while Counter <= High loop
        yield
        Counter += 1// Note that I needs not be declared, because declared 'var out' in the iterator// An implicit declaration of I as an integer is therefore made herefor I in 1..5 loop
   IO.WriteLn "I=", I

دودمان

XL توسط تعداد زیادی از زبان‌های دیگر الهام بخشیده شد، که عبارتند از:

Ada: پشتوانه‌های برنامه‌های با مقیاس بزرگ، مدیریت انتظارات، وظایف و جنبه‌های حمایتی.

Basic: نشان می‌دهد که چگونه قواعد یک زبان برنامه‌سازی می‌تواند ساده باشد. basic یکی از اولین زبان‌های پیشرفته‌ای است که پرانتزهای دور فراخوانی subroutineها را اجباری نمی‌کرد.

C: اساس برخی از زبان‌ها می‌باشد و به عنوان استانداردی بر حسب routineها و پشتیبانی‌های سطح ماشین می‌باشد، پس XL یک ماشین مجازی برای اجرا کردن نمی‌خواهد.

++C: کتابخانه template استاندارد، نیاز برای پشتیبانی از تایپ‌های عمومی را نشان می‌دهد که با معرفی صریح generic ها(بر خلاف Ada که در این زمینه دچار نقصان بود) صورت می‌گیرد.
Fortran: عملکرد پیوسته این زبان، باعث به وجود آمدن زبان‌های C و ++C شد و در شناسایی ساختارهای زبان که مانع بهینه سازی مفید می‌باشد، کمک شایانی نمود.

Java: اهمیت یک کتابخانه بزرگ و قابل جابجایی را شرح داد. اتصال با کد java به عنوان یک چالش برای XL باقی‌ماند.

Lisp: به عنوان یه فاکتور کلیدی در بقا و ارتباط XL با عصر حاضر می‌باشد. زبان Lisp اولین زبانی بود که ویژگی‌های شی گرایی را به صورت عادی و معمولی درآورد و در این زمینه خیلی به XL کمک کرد.

Prolog: مدل‌های گوناگون برنامه‌نویسی را شرح داد. همچنین تلاش‌های بسیاری هم صورت گرفت تا تضمین کند که یک plug-in استیل prolog می‌تواند برای XL هم نوشته شود.

Visual Basic: نشان می‌دهد که چگونه نمایش منطقی درخت پارس از نمایش دیدنی اش می‌تواند متمایز شود. اندکی از مردم VB را ویرایش کردند. انتظار می‌رود که plug-inهای ویرایشی XL توانایی‌های شبیهی را با استفاده مستقیم از درخت پارس به دست آورند.