Синтаксемы и спецсимволы
Определение
В контексте программирования синтаксема может рассматриваться как минимальная единица синтаксиса, которая определяет структуру и правила написания кода.
Так синтаксемой может быть переменная, оператор, функция, ключевое слово объявления, или специальные символы, с помощью которых мы структурируем код.
Здесь представлены синтаксемы/спецсимволы, не вошедшие в остальные разделы с ключевыми словами и системными переменными.
END
Ключевое слово (оператор), отмечающее окончание многострочной конструкции. Многострочными могут быть действия, конструкции условий, циклов. Примеры:
! открываем условие
if obj "Кувшин":
*pl "У вас есть кувшин."
! закрываем условие
end
! открываем действие
act "Взять яблоко":
яблоко += 1
addobj "Яблоко"
! закрываем действие
end
loop local i = 0 while i < 10 step i += 1:
*pl "Проход <<i+1>>: i=<<i>>"
end
Каждая многострочная конструкция должна завершаться ключевым словом end
. Однако здесь работают такие же правила, как для HTML-тегов или скобок: если мы вкладываем одну конструкцию в другую, сначала необходимо закрывать последнюю открытую конструкцию:
! открываем условие
if obj "Пустой кувшин":
! код, который относится к условию
*pl "У вас есть пустой кувшин."
! открываем действие
act "Наполнить кувшин":
! код который относится к действию
delobj "Пустой кувшин"
addobj "Полный кувшин"
! закрываем ДЕЙСТВИЕ
end
*pl "Кувшин можно наполнить из колодца."
! закрываем УСЛОВИЕ
end
Можно использовать не просто end
, а end if
, end act
и end loop
:
! открываем действие
act "Купить 10 стрел по 5 рублей":
! открываем условие 1 уровня
if money >= 10 * 5:
arrow += 10
money -= 10 * 5
! открываем условие 2 уровня
if no (obj "Стрелы"):
addobj "Стрелы"
! закрываем условие 2 уровня
end if
else
*pl "Вам не хватает денег."
! закрываем условие 1 уровня
end if
! закрываем действие
end act
Вообще, после ключевого слова end
допускается, но не одобряется, запись любого текста. При этом игнорируется весь текст до следующей команды. Если команда записывается в той же строке, что и end
, то эта команда должна стоять после амперсанда (&
):
! открываем действие
act "Взять яблоко":
яблоко += 1
addobj "Яблоко"
! закрываем действие
end присутствие этого текста после end не одобряется & *pl "Новая команда"
Метки :
Метки — это особые синтаксические конструкции (а вернее меньше, чем конструкции, — синтаксемы), которые отмечают указанную строку кода и служат для быстрого перемещения к таким строкам с помощью оператора JUMP
. Общая запись:
:[название метки]
, где [название метки]
— теоретически любое сочетание символов, однако на практике желательно использовать лишь буквы, цифры, символы подчёркивания и пробелы. Перед двоеточием могут стоять символы пробелов и табуляции в любом количестве. Так же игнорируются прилегающие к названию метки символы пробелов и табуляций (однако ставить их не рекомендуется для удобства чтения кода).
! рекомендуемый вариант использования метки
jump 'метка'
! ...
:метка
! рабочий вариант с игнорированием прилегающих пробелов в метке
jump "метка с прилегающими пробелами"
! ...
: метка с прилегающими пробелами
! рабочий вариант с игнорированием прилегающих пробелов в jump
jump " метка с прилегающими пробелами "
! ...
:метка с прилегающими пробелами
Непосредственно после метки, в той же строке, через амперсанд (&
) могут идти любые другие команды, однако так делать не рекомендуется.
! метка с командами после неё
jump 'markdown'
! ...
:markdown & *pl "вывожу текст" & ! комментарий
Метки не чувствительны к регистру:
jump "FoR"
! ...
:for
Оператор jump
"видит" метки только внутри текущего блока кода. Иными словами метки локальны.
Метки с одинаковыми названиями могут располагаться на разных локациях (в разных блоках кода).
Если метки с одинаковыми названиями расположены в одном блоке кода, то все дублирующие метки, кроме самой первой, игнорируются плеером.
Отдельными блоками кода для меток считаются:
- код "Выполнить при посещении" конкретной локации (каждая локация — отдельный блок кода),
- код действия даже если действие добавлено программно,
- код в гиперссылке,
- код, передаваемый
DYNAMIC
/DYNEVAL
.
Метки внутри циклов относятся к тому же блоку кода, в котором расположен цикл.
Если действие добавлено программно, метки, размещённые в этом действии, становятся доступны из блока кода, в котором это действие было создано. Однако из действия невозможно совершить переход на метку, которая находится вне действия.
Случайные метки, то есть метки, на которые в текущем блоке кода нет перехода с помощью jump
, просто игнорируются интерпретатором.
Амперсанд &
&
— символ амперсанда служит для перечисления команд в одной строке. Общая запись:
[команда 1] & [команда 2] & ...
Данный символ не следует путать с операцией объединения строк (конкатенация), а использовать нужно с осторожностью.
Примеры:
*pl "Я сорвал с ветки яблоко." & addobj "Яблоко" & яблоко+=1
a = 3 & b = 7 & g = rand(1, 6) & ("26" & "27") & ! в скобках — конкатенация
Запятая ,
Запятая ,
в QSP используется для перечисления аргументов, передаваемых различным операторам и функциям:
rgb(25, 67, 250)
max(12, 45, 67, 89, 90, 122, 135, 168, 90)
addobj "Отвёртка", "img/screwdriver.png"
gosub "add_object", "Апельсин", 2, "Еда", 37
Так же запятая используется для перечисления значений в кортеже:
%personage = [26, 192, 85, 'Пётр', 'боксёр']
Круглые скобки ()
Круглые скобки ()
в QSP используются в трёх случаях:
-
В различных выражениях скобки повышают приоритет операций (операции в скобках выполняются в первую очередь):
! повышение приоритета арифметических операций
(256 + 789) * (789 - 256)
! повышение приоритета операций сравнения
if A = (A <> B): ... -
Если нужно передать функции более одного аргумента следует помещать всю группу аргументов в скобки:
rgb(25, 67, 250)
max(12, 45, 67, 89, 90, 122, 135, 168, 90)
rand(1, 1000)Будет хорошим тоном помещать даже один аргумент функции в скобки:
rand(999)
Не будет осуждаться, хотя так обычно не делают, если в скобки помещать и группу аргументов к операторам:
showinput(0)
addobj("Отвёртка", "img/screwdriver.png")
gosub("add_object", "Апельсин", 2, "Еда", 37)
gosub("add_object", "Рек", rand(23, 45), "Артефакт", max(36, 67, 90, a)) -
Если нужно организовать кортеж значений:
%tuple = (123, 234, 'string')
%mass[23] = ('Петров', 'Пётр', 'Петрович')
Для организации кортежей рекомендуется использовать квадратные скобки.
%tuple = [123, 234, 'string']
%mass[23] = ['Петров', 'Пётр', 'Петрович']
Квадратные скобки []
Квадратные скобки []
в QSP используются для указания индекса ячейки массива:
! присваиваем значение седьмой ячейке массива $mass
$mass[7] = "textstring"
Для индексации ячеек массивов можно использовать строковые значения:
$mass["x:4,y:6"] = "map-dot"
Так же для индексации ячеек массивов можно использовать кортежи. При этом дублировать скобки не обязательно:
$mass[4, 6] = "map_cell"
! эквивалентно
$mass[[4, 6]] = "map_cell"
Если квадратные скобки после названия массива не стоят, значит происходит работа с нулевой ячейкой массива:
$mass = "text"
! равнозначно
$mass[0] = "text"
Если индекс в квадратных скобках не указан, значит мы работаем с последней ячейкой массива:
! создаём новую ячейку в конце массива и присваиваем ей значение
$mass[] = "last_cell"
! получаем значение из последней ячейки массива:
$mass[]
Так же квадратные скобки используются для создания кортежей:
%tuple = [123, 234, 'string']
%mass[23] = ['Петров', 'Пётр', 'Петрович']
Фигурные скобки {}
Фигурные скобки {}
в QSP выступают как спецсимволы, отмечающие начало и конец строковых значений. Иными словами, по наличию таких скобок плеер может понять, где начинается и где кончается строковое значение:
*pl {Текст, который будет выведен на экран.}
Особенностью указания текстового значения с помощью фигурных скобок является то, что в таких строках не раскрываются подвыражения:
health = 150
*pl {Здоровье: <<health>>}
! на экран будет выведен текст 'Здоровье: <<health>>'
*pl "Здоровье: <<health>>"
! на экран будет выведен текст 'Здоровье: 150'
Для большей совместимости с различными версиями плееров, а так же для удобства чтения, фигурные скобки следует использовать в основном для записи кода, предназначенного для оператора dynamic
или функции dyneval
:
*pl $dyneval({$result = $mid("abcd", 2, 1) + "qwerty"})
dynamic {
$args[0]
addobj $args[1]
}, 'Текст', 'Вилка'
Так же фигурные скобки можно использовать для написания многострочных комментариев:
! {
многострочный
комментарий
}
Допустимо вложение любого количества фигурных скобок друг в друга.
Кавычка "
Кавычки "
(двойной апостроф) в QSP выступает как спецсимвол, отмечающий начало и конец строковых значений. Иными словами, по наличию кавычек плеер может понять, где начинается и где кончается строковое значение:
*pl "Текст, который будет выведен на экран."
Особенностью указания текстового значения с помощью кавычек является то, что в таких строках раскрываются подвыра жения:
health = 150
*pl "Здоровье: <<health>>"
! на экран будет выведен текст 'Здоровье: 150'
Кавычки внутри строки можно экранировать дублированием:
*pl "В кабачке ""У Мо"" сегодня весело и шумно."
Так же кавычки можно использовать для написания многострочных комментариев:
! "
многострочный
комментарий
"
Апостроф '
Апостроф '
в QSP выступает как спецсимвол, отмечающий начало и конец строковых значений. Иными словами, по наличию апострофов плеер может понять, где начинается и где кончается строковое значение:
*pl 'Текст, который будет выведен на экран.'
Особенностью указания текстового значения с помощью апострофов является то, что в таких строках раскрываются подвыражения:
health = 150
*pl 'Здоровье: <<health>>'
! на экран будет выведен текст 'Здоровье: 150'
Апостроф внутри строки можно экранировать дублированием:
*pl 'Руг''Ста''Раг сказал: — Что ты хочешь, мора? Хочешь мухомора?'
Так же апострофы можно использовать для написания многострочных комментариев:
! '
многострочный
комментарий
'
Символ "Коммерческое эт" @
Символ "Коммерческое эт" @
используется для организации неявного вызова локаций-функций, упрощая запись и заменяя собой оператор gosub
или функию func
. Общая запись:
@[$локация]([аргумент 0], [аргумент 1], ... , [аргумент 18])
, где [$локация]
— это название локации, код которой мы хотим выполнить без непосредственного перехода на неё. Аргументы [аргумент 0]
, [аргумент 1]
и т.д. могут использоваться на этой локации, их значения автоматически помещаются в переменные args[0]
, args[1]
, и т.д. соответственно. После обработки локации предыдущие значения args
восстанавливаются. Использование аргументов не обязательно, в этом случае скобки можно опускать.
При обращении к локации с помощью @
базовое описание локации добавляется к текущему описанию, базовые действия добавляются к текущим действиям, и происходит выполнение операторов в поле "Выполнить при посещении", затем возврат на исходную строку (продолжение выполнения кода после команды с @
).
Название локации при неявном вызове не должно содержать специальных символов, иначе это может привести к неработоспособности кода. Можно использовать буквы, цифры, символ подчёркивания и точку.
Примеры:
!обработка локации "ход". Массив args[] пуст.
@ход()
!обработка локации "ход" с передачей 3-х параметров.
! $args[0] = $var (значению), args[1] = 2,
! $args[2] = "данные". Обратите внимание на символы '$'.
@ход($var, 2, 'данные')
! это код вызова локации "переход"
@переход('локация')
! а это код самой локации "переход"
# переход
*pl $args[0] & ! на экран выведется текст 'локация'
! в окне дейс твий появится новое действие:
act 'перейти':
goto "улица"
end
- переход
! код локации для функции, получающей сумму ряда чисел от единицы до указанного значения
# summ
! в args[0] будет помещено число, которое мы укажем в качестве [аргумента 0]
loop while args[0] > 0 step args[0] -= 1:
result += args[0]
end
- summ
! пример вызова локации "summ", как функции
*pl @summ(19) & ! выведет на экран 190
Неявный вызов локации-функции заменяет и gosub
, и func
, поэтому:
- если ваша локация-функция возвращает результат, неявный вызов такой локации будет работать точно так же, как явный вызов через
func
; - если же локация-функция не возвращает результат, то при использовании её с неявным оператором она будет работать, как явный вызов через
gosub
.
Символ "Знак доллара" $
Выступает, как префикс типа для именования переменных и функций строкового типа. Его обязательно нужно указывать, если вы хотите присвоить переменной строковое значение:
$string = 'This is so long string. Very very long string'
Если не указать знак доллара перед названием переменной строкового типа при присвоении, это вызовет ошибку №101: "Несоответствие типов данных":
string = 'Short string'
Если вы присвоили переменной значение другого типа, и пытаетесь получить строковое, это не вызовет ошибку о несоответствии типов данных, но переменная вернёт значение, соответствующее значению по умолчанию для строковых значений, то есть пустую строку (''
).
number = 123
*pl 'Число ' + $number + '.'
! на экране увидим 'Число .', потому что $number вернёт пустую строку.
Символ "Знак процента" %
Выступает, как префикс типа для именования переменных и функций, содержащих или возвращающих кортежи. Его обязательно нужно указывать, если вы хотите присвоить переменной кортеж:
%tuple = [13, 37, 'string']
Если не указать знак процента перед названием переменной типа кортеж при присвоении, это вызовет ошибку №101: "Несоответствие типов данных":
tuple = [13, 37, 'string']
Если вы присвоили переменной значение другого типа, и пытаетесь получить кортеж, это не вызовет ошибку о несоответствии типов данных, но переменная вернёт значение, соответствующее значению по умолчанию, то есть пустые строки (''
), если извлекается текстовое значение, или нули (0
), если извлекается числовое значение.
number = 123
$var[0], $var[1] = %number
*pl '[<<$var[0]>>,<<$var[1]>>]'
! На экране увидим '[,]'