Перейти к основному содержимому

Синтаксемы и спецсимволы

Определение

В контексте программирования синтаксема может рассматриваться как минимальная единица синтаксиса, которая определяет структуру и правила написания кода.

Так синтаксемой может быть переменная, оператор, функция, ключевое слово объявления, или специальные символы, с помощью которых мы структурируем код.

Здесь представлены синтаксемы/спецсимволы, не вошедшие в остальные разделы с ключевыми словами и системными переменными.

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 используются в трёх случаях:

  1. В различных выражениях скобки повышают приоритет операций (операции в скобках выполняются в первую очередь):

    ! повышение приоритета арифметических операций

    (256 + 789) * (789 - 256)
    ! повышение приоритета операций сравнения

    if A = (A <> B): ...
  2. Если нужно передать функции более одного аргумента следует помещать всю группу аргументов в скобки:

    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))
  3. Если нужно организовать кортеж значений:

    %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, поэтому:

  1. если ваша локация-функция возвращает результат, неявный вызов такой локации будет работать точно так же, как явный вызов через func;
  2. если же локация-функция не возвращает результат, то при использовании её с неявным оператором она будет работать, как явный вызов через 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]>>]'
! На экране увидим '[,]'