Онлайн-справочник по самым часто задаваемым вопросам из темы "Как сделать?" на форуме QSP.su

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

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

Круглые скобки ()

Круглые скобки `()` в 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]=('Петров','Пётр','Петрович')

Квадратные скобки []

Квадратные скобки `[]` в 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[]

Фигурные скобки {}

Фигурные скобки `{}` в 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]=args[0]-1:
    result=result+args[0]
end
-----summ-----


! пример вызова локации "summ", как функции
*pl @summ(19) ! выведет на экран 190

Обратите внимание, неявный вызов локации-функции заменяет и `gosub`, и `func`, поэтому, если ваша локация-функция возвращает результат, неявный вызов такой локации будет работать точно так же, как явный вызов через `func`; если же локация-функция не возвращает результат, то при использовании её с неявным оператором она будет работать, как явный вызов через `gosub`.