Введение

BPL (Bot programming language) - это встроенный язык выражений для конструктора ботов версии 3. Программа на этом языке размещается в блоках операций, условных блоках, триггерах и т.д. и представляет собой запись одного или нескольких выражений разделённых между собой символом новой строки или, опционально, точкой с запятой ";".

Каждое выражение языка представляет собой вычисляемую (или исполняемую) инструкцию (или инструкции) для бота. Любое выражение при этом имеет значение и может быть включено в качестве подвыражения в любое другое выражение по желанию программиста.

BPL не содержит каких-либо конструкций отвечающих за поток управления программой. За это отвечает графическая составляющая конструктора ботов.

Кодировка кода

Текст на BPL это Unicode текст в кодировке UTF-8. Строковые литералы могут содержать произвольные символы Unicode. Идентификаторы (см. ниже) могут включать в себя русские буквы.

Символы

Далее в описании грамматики языка будут использоваться следующие термы:

newline        = /* символ Юникода U+000A */ .
unicode_char   = /* произвольный символ Юникода, за исключением newline */ .
unicode_letter = /* символ Юникода обозначаемый букву */ .
unicode_digit  = /* символ Юникода обозначаемый цифру */ .

Буквы и цифры

Символ подчёркивания считается буквой в нижнем регистре:

letter        = unicode_letter | "_" .
decimal_digit = "0" … "9" .
hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" .

Лексические элементы

Токены

Любое выражение состоит из одного или нескольких слов или лексических элементов которые также называются токенами. В BPL выделяется пять групп токенов:

  • Пробельные символы
  • Комментарии
  • Идентификаторы
  • Операторы и символы пунктуации
  • Литералы

Пробельные символы

Пробельными считаются символы пробела (U+0020), новой строки ()U+000A), возврата каретки (U+000D), а также горизонтальной табуляции (U+0009). Обычно пробельные символы игнорируются кроме случаев когда они разделяют два токена с тем чтобы предотвратить их трактовку в качестве другого токена. 

Комментарии

При записи выражений можно указывать комментарии – участки программы, которые не участвуют в вычислениях, а выполняют лишь информационную функцию. Есть два вида комментариев:

  • Однострочные. Такие комментарии начинаются с символов "//" и заканчиваются окончанием строки.
  • Многострочные. Начало многострочного комментария начинается с символов "/*" и заканчивается символами "*/".
Пример комментариев
// Это однострочный комментарий
$x = time()

/**
 * А это уже
 * многострочный
 * комментарий
 */
say("Time is " + $x)

Идентификаторы

Идентификаторами являются названия функций, типов и переменных. Идентификатор состоит из букв (letter) и цифр (unicode_digit). Первым символом идентификатора должна быть буква.

identifier = letter { letter | unicode_digit } .

Примеры идентификаторов:

Пример идентификаторов
xyz
_x9
someBigIdentifier
тоже_идентификатор

Некоторые идентификаторы являются предопределёнными.

Операторы и символы пунктуации

Следующие символы представляют собой операторы: 

Математические

и строковые

+-*/%\**&|^>><<<<<>>>::~!
Комбинированные с присваиванием+=-=*=/=%=\=**=&=|=^=>>=<<=<<<=>>>=::=

Сравнение==!=><>=<=&&||








Преобразование и проверка типовis!isas?asto?to










Обращение к переменным$@#













Безопасное выполнение???














Инкремент и декремент++--














Присваивание =:=














Создание итератора...















Пунктуационные знаки:

()[]{}
.,:;

'"



_




Точка с запятой

Символ ";" используется в качестве разделителя BPL выражений находящихся на одной строке. Его можно опустить, если последний токен выражения является одним из следующих:

  • идентификатор;
  • числовой, строковый, булев литерал или nil;
  • знаки ")", "]" и "}".

Литералы

Литералы это значения разных типов данных встречающихся в тексте программы в качестве констант.

Пустой литерал

Специальный литерал обозначающий отсутствие значения. Представлен словом nil.

Булевы литералы

Булевы или логические литералы это значения двух видов: ИСТИНА и ЛОЖЬ. Представлены они соответственно двумя специальными словами: true и false.

Целочисленные литералы

Это последовательность цифр представляющая собой целое число. Целочисленный литерал может быть представлен в шестнадцатеричном формате, если имеет префикс "0x" или "0X".

Для улучшения читабельности можно использовать символ "_" для разделения последовательных цифр в числе или для отделения префикса от числа:

Пример целочисленных литералов
42
4_2
0xBadFace
0xBad_Face
0x_67_7a_2f_cc_40_c6
170141183460469231731687303715884105727
170_141183_460469_231731_687303_715884_105727

_42         // идентификатор, но не литерал
42_         // ошибка: _ должен разделять последовательные цифры
4__2        // ошибка: два подряд идущих _
0_xBadFace  // ошибка: _ должен разделять последовательные цифры

Дробно-числовые литералы

Дробно-числовые литералы состоят из целой части (десятичные цифры), десятичной точки (.), дробной части (десятичные цифры) и экспоненты (буква "e" или "E" за которой следует опциональный знак (+ или -) и далее десятичные цифры). Целая часть, либо дробная часть могут быть опущены. Десятичная точка, либо экспонента могут быть опущены. Значение экспоненты exp увеличивает мантиссу в 10^exp раз.

Как и в случае с целочисленными литералами можно использовать "_" для улучшения читабельности:

Пример дробно-числовых литералов
0.
72.40
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5
1_5.         // == 15.0
0.15e+0_2    // == 15.0

1_.5         // ошибка: _ должен разделять последовательные цифры
1._5         // ошибка: _ должен разделять последовательные цифры
1.5_e1       // ошибка: _ должен разделять последовательные цифры
1.5e_1       // ошибка: _ должен разделять последовательные цифры
1.5e1_       // ошибка: _ должен разделять последовательные цифры

Строковые литералы

Строковый литерал представляет собой последовательность символов (unicde_char). Есть два вида строковых литеров: неинтерпретируемые и интерпретируемые.

Неинтерпретируемые строковые литералы представляют собой любую последовательность символов Юникода (unicode_char)? кроме newline, заключённую в одинарные кавычки. При этом символ одинарной кавычки и символ обратного слэша должны экранироваться.

Интерпретируемые строковые литералы создаются с помощью двойных кавычек и могут содержать любые символы Юникода (кроме newline), а также специальные последовательности символов. Экранированию подлежат символы двойной кавычки и обратный слэш.

Переменные

Для хранения данных в сценариях ботов применяются переменные. Переменная представляет собой именованный участок памяти бота. Она создаётся при первом своем использовании в каком-либо блоке операция. При этом значением по умолчанию для всех переменных является nil.

Существует три вида переменных, различающихся своей областью видимости:

  • Переменные, видимые в пределах одного модуля в одном потоке.
    Доступны для чтения и записи. Названия таких переменных начинаются с символа $. Такие переменные удобно использовать для хранения значений промежуточных операций и вычислений.
  • Переменные, видимые в пределах одного модуля в разных потоках.
    Доступны для чтения и записи. Названия переменных уровня модуля начинаются с символа #. Поскольку такие переменные видны во всех потоках бота их удобно использовать для взаимодействия между потоками. 
  • Глобальные переменные или переменные окружения.
    Автоматически задаваемые переменные, которые видны во всех потоках всех модулей бота. Эти переменные доступны только для чтения и хранят информацию о глобальном контексте работы бота. Их имена начинаются с символа @.
Примеры записей переменных разных видов
// Переменные $p и $r доступны только в потоке, в котором они определены
$p = 2 * 3.14 * $r

// Эта переменная доступна во всех потоках в пределах текущего модуля
// (модуля, в котором находится блок операций, в котором определена переменная).
#count = queue.size()

// @communicationType глобальная переменная только для чтения. Доступна везде.
$isChat = @communicationType == "TEXT"

Имена переменных могут содержать только цифры, английские и русские буквы, а также символ подчёркивания. Т.е. вы не можете назвать переменную каким-то словом, содержащим пробел или символ отличный от символов русского и английского языков. Тем не менее, существует способ использовать любое название. Для этого необходимо заключить название переменной в круглые скобки.

Пример использования
$('日本') = 123         // Создали переменную c именем 日本
$x = $('日本')          // $x теперь равна 123
$(math.rand(1, 2)) = 0 // Динамически создаём переменную с именем 1 или 2 и присваиваем ей значение 0
  • Нет меток