Що таке ELI?

Extern Logic Interpreter або ELI (англійською читається як "ілай") – це спеціальний засіб у вигляді динамічно зв'язаної бібліотеки, що підключається до користувацької аплікації. Його безпосереднє призначення – максимально абстрагувати програму від логічних операцій, які до того ж можна було б з легкістю модифікувати без перекомпіляції основної програми. В ідеальному варіанті користувацька аплікація взагалі може обійтись без визначеного алгоритму роботи, все що від неї потрібно – надати певний функціонал для взаємодії з оточенням, наприклад читання або збереження файлів, вивід інформації для користувача тощо. Логіку роботи цих уособлених механізмів та алгоритм за яким буде працювати програма побудує ELI.

Уявіть, що у Вас є клієнт-серверна аплікація, яка приймає та розсилає певні файли за певною схемою. Завдяки ELI Ви зможете не тільки змінювати схему розсилки (наприклад, включати та виключати з неї робочі станції, чи визначати перелік файлів, що надсилаються на кожну станцію), але й змінювати сам алгоритм передачі. Припустимо, змінився розмір буферу для передачі даних. Вам не потрібно заново компілювати аплікацію, достатньо лише змінити значення однієї змінної у скрипті ELI. А якщо аплікація виконується в циклі, то завдяки директиві #include можна змінювати логіку роботи програми взагалі "на льоту".

Наприклад, я використовую скрипти ELI, щоб коригувати параметри утиліти обміну з ftp-сервером на більш ніж сотні комп'ютерів. При цьому можливості ELI дають мені змогу змінювати різні параметри в залежності від налаштувань кожного робочого місця. І все це одним скриптом.

Більше того, ELI сам може відігравати роль аплікації, розширюючи свої можливості за рахунок підключення зовнішніх бібліотек. Все, що потрібно для того, аби створити свою власну програму, користуючись можливостями ELI, це файл скрипта та маленька аплікація, що під'єднає до себе бібліотеку інтерпретатора та запустить трансляцію скрипту. Ця аплікація входить до складу дистрибутива ELI.

Можливості

Extern Logic Interpreter має достатньо розвинутий функціонал для створення простих аплікацій. Він підтримує (хоча в дещо обмеженому вигляді) два з основних приципів ООП: наслідування та інкапсуляцію. Внутрішня мова інтерпретатора оперує такими поняттями як числові та символьні змінні, цикли й умови, користувацькі процедури та функції, об'єкти та класи. Крім того, ELI може підключати динамічно зв'язані бібліотеки і оперувати функціоналом, що міститься в них.

Детальніше про ELI та його мову можна прочитати у документації на сторінці завантажень

Як все було

Історія створення ELI почалась з цілком іншого проекту: калькулятора математичних виразів, що мав форму динамічної бібліотеки. Остання версія могла розбирати та підраховувати досить довгі ланцюжки математичних операцій, але до робочого виду доведена так і не була. Зате залишилась концепція парсера, що розбирав рядок текстових символів, перетворював їх на числа, аналізував записані знаки операцій і, відповідно до їх пріорітету, проводив розрахунок. Потім була гра (також не реалізована до речі), логікою роботи якої повинні були керувати зовнішні скрипти. Так з'явився ELI, хоча тоді проект називався просто: "Script Compiler".

Перша робоча версія з функціоналу мала лише прості умови if-else та дороблений парсер математичних виразів, у якому нарешті з'явилася підтримка операції пріорітету "()". Функції хост-аплікації визначались простим перебором зі спеціального вектору std::string. Аргументи передавались через інший вектор, що грав роль такого собі стека. Така реалізація була вкрай незручною до того ж погано масштабувалась, бо список функцій основної аплікації постійно змінювався. Потрібен був інструмент, що не просто запускав би функції, базуючись на істинності умов, але й мав власну логіку роботи. Так з'явились змінні та стек функцій, яким могла керувати хост-аплікація.

Проект ріс та ширився, випливали на лікувалися помилки у логіці роботи, функціонал збагатився користувацькими процедурами, а принцип взаємодії з хост-аплікацією був переглянутий на користь віртуального інтерфейсу, що надавав доступ до методів класу, замість експортних функцій DLL. Також змінилась назва, бо слово "compiler" не відповідало принципу роботи. Таким чином народився Extern Logic Interpreter, або "Інтерпретатор Зовнішньої Логіки". Згодом стало зрозуміло, що для продуктивної обробки даних, отриманих від хост-аплікації (тепер проект вже не було орієнтовано на взаємодію з грою), потрібні структуровані одиниці даних, тож ELI отримав об'єкти, а згодом і класи.

Іронія долі: на тестах однієї з останніх предрелізних версій виявилось, що аби створити простенький текстовий квест (а саме такою повинна була бути гра, з якої почався проект) ELI не потребує безпосередньо аплікації гри, він цілком здатен на таке самотужки.