ТОМ2: функции: различия между версиями

Материал из IFВики
Перейти к навигации Перейти к поиску
м (Секции в выражениях)
м (Секции в фактах)
Строка 157: Строка 157:
  
 
===Секции в фактах===
 
===Секции в фактах===
В фактах используются секции ==parsing== (парсинг), ==check== (проверка), и ==execute== (выполнение).
+
В фактах используются секции parsing (парсинг), check (проверка), и execute (выполнение).
====Секция ==parsing== в фактах====
+
====Секция parsing (парсинг) в фактах====
====Секция ==check== в фактах====
+
====Секция check (проверка) в фактах====
====Секция ==execute== в фактах====
+
====Секция execute (выполнение) в фактах====
  
 
===Секции в действиях===
 
===Секции в действиях===

Версия 14:33, 25 января 2014

Назначение

Функции используются в командной строке и в коде игры. В отличие от других языков, функции ТОМа не имеют имён и подбираются исключительно по аргументам.

Пример вызова фукции:

Дай мяч Маше

Строка кода может содержать несколько функций, вызываемых последовательно. При этом результат одной функции может являться аргументом для другой функции.

Подбор функций, их подчиненность и порядок вызова в строке определяется парсером самостоятельно.

Синтаксис

fn_type ( arg_list ) { code }

Где:

  • fn_type - ключевое слово, определяющее тип функции: expression (выражение), action (действие), fact (факт);
  • arg_list - список аргументов;
  • code - код тела функции, разделённый на секции.

список аргументов

arg_list

Синтаксис:

arg_type [arg_name] [#arg_key] [, arg_type [arg_name] [#arg_key]] ...

Аргументы в списке разделяются запятой или точкой с запятой.

Описание аргумента состоит из типа, имени и ключа, обязательным является только тип, остальные элементы могут быть опущены.

arg_type

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

  • Тип значения: bool, string, number, course, spcvalue, object, attribute, class, location, word, preposition, and-list, or-list.
  • Класс значения. Например, "предмет", "существо" и т.п.
  • Имя значения. Для значений, имеющих уникальные имена, в качестве типа можно указывать имя конкретного значения - имена объектов, локаций и т.д.
  • Произвольный литерал - должен в точности совпасть со словом, введенным игроком. Пример: "трах-тибидох"

arg_name

Имя переменной, которой будет передано значение аргумента в контексте выполнения функции.

Если имя переменной не указано, значение в функцию не передаётся, но по-прежнему влияет на подбор функций.

arg_key

Ключ, которому должно соответствовать значение аргумента.

Пример: #ВпЕч - значение должно находиться в винительном падеже единственного числа.

В состав ключа могут входить шаблоны '!' и '*'.

  • * - подходит любое свойство ключа;
  •  ! - в ключе не должно быть указанного свойства.

Пример: #*п!е - у значения должен быть любой падеж, и не должно быть отрицания.

Если ключ не указан, проверка значения на соответствие ключу не проводится.

Типы функций

Существует три типа функций – выражения, факты, действия.

Строка кода или команды в ТОМе обрабатывается в 2 этапа:

  1. Парсинг
  2. Выполнение строки

Вычисления и выполнение различных секций функций могут происходить как на 1м, так и на 2м этапах. На этапе парсинга происходит перебор вариантов, поэтому код, участвующий в парсинге, может вызываться множество раз.

Ели строка однозначно разобрана, она выполняется. Выполняется строка только один раз.

Любая строка, обработанная без ошибок, всегда возвращает значение, являющееся результатом её выполнения.

Зачем нужно деление функций на три типа:

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

Функции типа expression (выражение)

Выражения вычисляются на этапе разбора (парсинга) строки и не приводят к изменениям состояния игры.

Выражения могут входить в состав других сложных выражений, фактов или действий.

Выражение возвращает вычисленное значение. Если вся строка является одним выражением, то вычисленное значение будет финальным результатом всей строки.

Примеры выражений:

цвет стен
количество людей в комнате
некто, взявший 3 рубля
2 + 2
X + 3

Пример функции выражения:

expression(attribute Atr, object Ob) 
{ == parsing ==
  if :Ob.key != :Atr.key then fail, "несогласовано"
  Ok
  == execute ==
  if :Ob.:Atr then return :Ob
  fail, "тут такого нет"
}

Функции типа action (действие)

Действия изменяют состояние игры.

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

На этапе парсинга определяется необходимое действие и подготавливаются его аргументы.

Выполнение действий происходит после однозначного разбора строки.

Примеры действий:

покрась стены в зелёный цвет
возьми 3 рубля

Пример функции действия:

action(иди#Пф, location напр#Ап)
{ == check ==
  if loc = напр then fail, "ты уже здесь"
  if нельзя_пройти loc :напр then fail, "туда нет прохода"
  Ok
  == execute ==
  goto :напр
}

Функции типа fact (факт)

Факты применяются в качестве условий или вопросов, а так же как утверждения:

Если цвет стен зеленый, то … // условие
Цвет стен зеленый? // вопрос
Цвет стен зеленый. // утверждение

Факты могут входить в состав логических выражений, а также как условия в состав условных конструкций.

На этапе парсинга строки происходит проверка факта. Результат проверки - всегда логическое значение. Для условий результат проверки влияет на дальнейшее выполнение условной конструкции, для вопросов результат проверки является финальным результатом строки, для утверждений результат не важен.

После однозначного разбора строки с утверждением происходит выполнение этого утверждения (в нашем примере стенам будет присвоен зелёный цвет). Выполнение утверждения изменяет состояние игры.

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

Цвет стен зеленый
в комнате 5 человек
X = 3

Пример функции факта:

fact(нельзя_пройти, локация, локация)
{ == check ==
  yes //по умолчанию никуда нельзя пройти
}

Секции в функциях

Код функции делится на секции. Каждая секция имеет своё имя и выполняется на определённом этапе парсинга.

Начало секции обозначается знаками ==, после которых идёт имя секции.

Пример:

== parsing ==
... код секции ...

Код, размещенный перед первой секцией является общим и выполняется всегда.

Секции в выражениях

В выражениях используются секции parsing (парсинг) и execute (выполнение).

Секция parsing (парсинг) в выражениях

Секция execute (выполнение) в выражениях

Секции в фактах

В фактах используются секции parsing (парсинг), check (проверка), и execute (выполнение).

Секция parsing (парсинг) в фактах

Секция check (проверка) в фактах

Секция execute (выполнение) в фактах

Секции в действиях

Секция ==parsing== (==парсинг==) в действиях

Секция ==check== (==проверка==) в действиях

Секция ==execute== (==выполнение==) в действиях