Скриптова мова ChaiScript унікальний тим, що в ньому по суті немає власних типів даних. Будь-яка змінна в ChaiScript представлена типом Boxed_value, який є варіантної «обгорткою» для абсолютно будь-якого допустимого в С ++ типу даних. Що саме буде зберігатися у змінній, визначається конструктором відповідного типу в момент її створення.
ChaiScript сам не виконує ніяких операції зі змінними, а просто намагається викликати функцію С ++ з сигнатурою, яка збігається з тією, що необхідна для поточної операції. Якщо підходящої функції в списку зареєстрованих в інтерпретаторі немає, він видає помилку. Інтерпретатор нічого не знає про внутрішню реалізації типів даних: все, що йому потрібно, - це зареєстровані функції С ++.
В результаті, ChaiScript може однаково легко працювати з абсолютно будь-якими типами даних, як би складні вони не були. Для їх ініціалізації викликаються відповідні конструктори С ++, для копіювання - конструктори копіювання, для присвоювання - оператори присвоювання. Будь-які методи об`єкта просто викликають однойменні методи класу в С ++ з потрібною сигнатурою.
Будь-яка змінна в ChaiScript може бути посиланням на змінну, певну в С ++. Будь-яка зміна такої змінної в С ++ відразу відображається в ChaiScript і навпаки. Це дозволяє нам уникати дублювання «важких» об`єктів в скрипті і основній програмі.
У ChaiScript немає ні самостійної стандартної бібліотеки, ні навіть будь-яких засобів файлового введення-виведення. Все, що може знадобитися для скрипті, має бути реалізовано на С ++ і зареєстровано в інтерпретаторі.
Важливо розуміти, що ChaiScript не можна використовувати без «материнської» програми на С ++ на відміну від Python, Ruby або Lua. Сила ChaiScript саме в надзвичайно легкому встановленні і прозорому взаємодії з С ++.
Мова ChaiScript
На жаль, синтаксис ChaiScript в документації вичерпно не описаний, так що вивчати його доводиться за прикладами і натхнення. На щастя, мова є вельми аскетичним - освоїти його нескладно.
Почнемо з азів:
# Коментар в скриптовій стилі // Коментар в стилі С ++ / * Коментар в стилі Сі * / # Оголошуємо дві змінні var pi = 3.14 var s = "Value of Pi is" # Виводимо на екран print (s + "" + to_string (pi)) # Оголошуємо змінну як посилання var s2: = s print ( "Посилання на s:" + to_string (s2)) # Міняємо початкове значення s = "Changed value" # Переконуємося, що посилання вказує на нове значення print ( "Посилання на s:" + to_string (s2))
На екрані очікувано буде:
Value of Pi is 3.1400000000000001 Посилання на s: Value of Pi is Посилання на s: Changed value
Числа за замовчуванням мають тип doubte або int, рядки - це звичайний std :: string в системній кодуванні. Оператор: = створює посилання на праву частину виразу.
Функції задаються ключовим словом def:
def add_square (a, b) { var a2 var b2 a2 = a * a b2 = b * b return a2 + b2 } print (add_square (2,3)) // Друкує 13
Є анонімні функції, що задаються ключовим словом fun:
var add_pi = fun (a) {return a + 3.14} print (add_pi (1)) // Друкує 4.14
Функції можна передавати в інші функції і повертати з них:
def gen_adder () { return fun (b) {return b + 1} }
var f = gen_adder () print (f (1)) // Друкує 2
Анонімні функції в ChaiScript не є замиканнями, і в функціональному стилі наChaiScript особливого не попрограмміруешь:
def gen_adder (a) { return fun (b) {return b + a} // Чи не працює! Зовнішня змінна a хоч я знаю! } // Error: "Can not find object: a" during evaluation
Конструкції for, while і if аналогічні таким в С ++ з двома нюансами: тіло конструкції обов`язково полягає в фігурні скобкі- для циклів немає оператора continue (є тільки break):
for (var i = 0 ilt; 10; if (i == 3) {break} else {print (i)} }
Конструкції switch немає. Всі логічні операції і арифметичні оператори - такі ж, як в С ++.
Є конструкція try-catch-finally і оператор throw. Винятки можна прозоро «прокидати» між скриптом і основною програмою на С ++:
void throwexception () {throw std :: runtime_error ( "err") -} int main () { // Генеруємо виключення в C ++, ловимо ChaiScript chaiscript :: ChaiScript chai; chai.add (chaiscript :: fun (throwexception), "throwexception") - chai ( "try {throwexception () -} catch (e) {print (e.what ()) -}") - // Друкує "err" // Генеруємо виключення в ChaiScript, ловимо в C ++ try { chai ( "throw (1)"); } Catch (chaiscript :: Boxed_Value bv) {// Ловимо об`єкт типу Boxed_Value int i = chaiscript :: boxed_cast(Bv) - // Перетворимо його в int // Тепер i == 1 } }
У ChaiScript є масиви, які технічно є типом std :: vector, і досить багато функцій в стилі алгоритмів STL для їх обробки. Є також асоціативні масиви з текстовими ключами.
var arr = [1,2,3, [ "a", "b", "c"], 5] // Масив з вкладеністю for_each (arr, print) // Роздруковуємо його поелементно в стилі STL print (arr [3] [1]) // Доступ до елементів var m = [ "a": 1, "b": 2] // Асоціативний масив // Роздруковуємо його for_each (m, fun (p) {// Створюємо анонімну функцію print ( "First = $ {p.first}, Second = $ {p.second}") // Просте перетворення в рядок в стилі скриптових мов за допомогою $ }) var r = [1..100] // Інтервальний синтаксис
Повний список всіх вбудованих функцій для масивів доступних в скрипті під час виконання наведено в документації (https://chaiscript.com/doxygen/namespace chai script language.html).
У ChaiScript є примітивна реалізація класів. Поля задаються ключовим словом attr, а методи - звичайним def:
Ніяких механізмів успадкування та поліморфізму немає, так що вони, строго кажучи, є таким собі «синтаксичним цукром», а не повноцінними класами.
Ви не програміст і взаємодія ChaiScript з C ++ Вас абсолютно не цікавить! Ну, а єдине ваше бажання в даний момент - встановити в своєму будинку супутникове телебачення (https://tvcentre.ru/), яке буде приймати якісний сигнал навіть на великій відстані від міста.
Придбати комплект супутникового ТБ на найвигідніших для себе умовах Ви зможете на сайті tvcentre.ru.