Новость из категории: Информация

Взаимодействие ChaiScript с C++

Содержание:
1. Идеология взаимодействия ChaiScript и С++ и язык ChaiScript (Вы читаете данный раздел);
2. Контейнеры, модули и многопоточность.
Идеология взаимодействия ChaiScript и С++

Взаимодействие ChaiScript с C++

Скриптовый язык 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; i<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] // Интервальный синтаксис

Полный список всех встроенных функций для массивов доступных в скрипте во время выполнения приведен в документации (http://chaiscript.com/doxygen/namespace chai script language.html).

В ChaiScript есть примитивная реализация классов. Поля задаются ключевым словом attr, а методы - обычным def:
attr Rectangle::height attr Rectangle::width
def Rectangle::Rectangle() { this.height = 10; this.width = 20 } def Rectangle::area() { this.height * this.width }
var rect = Rectangle() rect.height = 30 print(rect.area())

Никаких механизмов наследования и полиморфизма нет, так что они, строго говоря, являются этаким «синтаксическим сахаром», а не полноценными классами.



Вы не программист и взаимодействие ChaiScript с C++ Вас совершенно не интересует! Ну, а единственное ваше желание в данный момент - установить в своем доме спутниковое телевидение (http://www.tvcentre.ru/), которое будет принимать качественный сигнал даже на большом удалении от города.

Приобрести комплект спутникового ТВ на самых выгодных для себя условиях Вы сможете на сайте www.tvcentre.ru.

Рейтинг статьи

Оценка
4/5
голосов: 6
Ваша оценка статье по пятибальной шкале:
 
 
   

Поделиться

Похожие новости

Комментарии

^ Наверх