Макроязык

Для анализа данных в Galaxy Communicator реализован анализатор и выполнитель выражений и макросов. Он используется для фильтрования, выполнения запросов над таблицами, а так же для написания макро- функций, которые можно выполнять над таблицами, которые доступны макроязыку.

На данный момент доступны 3 таблицы:

Обращение к таблицам возможно с помощью префикса – имени таблицы. Например: Race.Wpn или ShipGroup.Weight.

Для запросов и фильтров нужно указывать выражение. Выражение может состоять из операндов и операций.

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

Кроме этого операндом может быть вызов функции реализованной в макроязыке.

Операции делятся на унарные и бинарные.

Унарных операций две: унарный минус, и отрицание(not). Все остальные операции бинарные(+,-,*,/, and, or, >, <, >=, <=, <>, =, ==, &, |). Операция == применяется для сравнения строк без учета регистра.

Стоит отдельно рассмотреть операцию разыменовывания '^' - это операция позволяет формировать обращение к нужной планете. Имя планеты является левым операндом, правым может быть произвольное выражение, которое может обращаться к полям данной планеты. Например, для определения размера нужной планеты можно написать '#1'^.size или var1^.size, если значение переменной var1 во время выполнения будет равно названию или номеру планеты, то результат выражения будет равен размеру этой планеты. В списке кораблей так же можно обращаться к полям dest и from с помощью операции разыменовывания. Например, что бы отфильтровать корабли, которые находятся вместе с кораблями нужной вам расы на одной планете нужно достаточно установить фильтр dest^.fleet('RaceName')>0.

Кроме операции разыменования есть альтернативная возможность обращения не только к планете, но и к расе и к кораблю. Для этого в макроязык встроены операторы выборки одной записи из таблицы WinRace, WinPlanet, WithGroup, имеющие следующий синтаксис:

WithRace <expression> [ as 'name'] do {<operator>;} EndWith;

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

Например, макрос:

macro GetDrive;
begin 
  WithRace me  as 'mytable' do
     result:=mytable.drv;
  EndWith;
end;

Будет возвращать значение технологии двигателей главной расы.

Если нужно сформировать таблицу из нескольких записей, удовлетворяющих определенному условию, то нужно воспользоваться операторами WithRaces, WithPlanets, WithGroups. Синтаксис аналогичный оператору выборки одной записи. Различие в том, что выражение является фильтром, который будет применен к данной таблице. Т.е. более медленный аналог макроса GetDrive можно написать в таком виде:

macro GetDrive;
begin 
  WithRaces 'name="'+me+'"' do do
     result:=drv;
  EndWith;
end;

Стоковые константы указываются в кавычках (одинарных или двойных), возможно вложение одних кавычек в другие. Стоит учитывать, что все операции сравнения над стоками производится с учетом регистра. Т.е. 'World'<>'WorLD'. Это обусловлено тем, что все без исключения сервера Galaxy, так же различают регистры, и вполне возможно некорректная работа выполнителя в случаях, когда у Вас в галактике, кто-то этим пользуется.

Пример: “Normal 'string' constant”

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

Пример: 1e-3, 0.001

Поле таблицы совпадает с его названием при отображении.

Поле может быть написано без учета регистра.

Кроме этого есть константы:

#NL – константа перевода на новую строку

Но для 3 таблиц (Расы, Планеты, Список Групп) есть дополнительные вычислимые поля.

Все поля этих таблиц перечислены ниже.

Поля расы

Name

имя расы

Drv

Технология по двигателям

Wpn

Технология по оружию

Shld

Технология по защите

Crg

Технология по перевозке

Pop

общее население

Ind

общая индустрия

#

число планет

State

Статус

Votes

число голосов

Rating

Простой рейтинг расы

Level

Комплексный рейтинг расы

Team

Команда, для игры серии Team

VisiblePlanets

равно 1, если Вы видите, хотя бы одну планету данной расы, иначе 0

VisibleShips

равно 1, если Вы видите, хотя бы один корабль данной расы, иначе 0

DDrv

прирост технологии двигателей за этот ход

DWpn

прирост технологии оружия за этот ход

DShld

прирост технологии защиты за этот ход

DCrg

прирост технологии перевозок за этот ход

DPop

прирост населения за этот ход

DInd

прирост индустрии за этот ход

D#

прирост планет за этот ход

DVotes

прирост голосов за этот ход

Поля планеты

Num

номер планеты для Galaxy Plus

Name

имя планеты

Size

Размер планеты

Pop

Население планеты

Ind

Индустрия планеты

Res

Ресурс планеты

Production

Установленное производство

$

Промышленность

Mat

Материалы

Col

Колонисты

L

Свободный производственный потенциал

Race

Владелец расы или Uninhabited или Unidentified

Qlty

вес корабля, производимый планетой при POP=Size и IND=Size

OutCap

Количество промышленности планетой за ход

OutWgt

вес корабля, производимый планетой за ход

Battle

Размер битвы на планете, если битвы не было, то значение 0

BestETA

через сколько ходов прилетит на планету наблюдатель. Имеет значение 0, при наличии наблюдателя и -1, при отсутствии летящих кораблей на данную планету

YourFleet

масса вашего флота на орбите планеты

FriendFleet

масса союзного флота на орбите планеты

AlienFleet

масса вражеского флота на орбите планеты

DestTo(Pl)

Расстояние от данной планеты до указанной (параметр - строка)

Ships(Race),

Fleet(Race)

Масса флота расы, на орбите планете (параметр срока)

Team

Команда, для игры серии Team

CanSendTo(Pl)

Находится ли данная планета в области доступных для перелета планет

StrName

Строковое представление имени планеты, равно name, если имя не пустое, иначе #<num>

Поля для кораблей

Grp

группа, или -1, если корабль не Ваш

#

Количество кораблей в группе

Name

имя типа корабля

Drv

Технология по двигателям

Gun

Характеристика корабля по количеству пушек

Wpn

Технология по оружию

Shld

Технология по защите

Crg

Технология по перевозкам

Attack

Эффективная атака

Defence

Эффективная защита

Cargo

Размер трюма

Q

Количество загруженного груза в трюм

Typ

тип загруженного груза

Dest

Планета назначения

From

Планета, откуда летит корабль

R

Расстояние до планеты назначения, либо 0, если корабль не летит

Weight

вес корабля

Fleet

Название флота, либо пустая строка

State

статус корабля

Speed

Скорость корабля

ESpeed

Скорость пустого корабля

CSpeed

Скорость полностью загруженного корабля

D

Характеристика корабля по двигателю

W

Характеристика корабля по мощности пушек

S

Характеристика корабля по защите

C

Характеристика корабля по трюму

Race

имя расы владельца

Bomb

Бомбардировка одного корабля в группе

WarShip

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

Waitl

Имеет значение 1, если группа готова к запуску (находится на орбите, имеет двигатель, и это не группа общей массой менее 2).

ETA

Количество ходов, необходимое для преодоления расстояния R до планеты назначения

CanSendTo(Planet)

Имеет значение количество ходов, требуемое для полета до Planet, если группа может быть отправлена на данную планету, иначе -1

Team

Команда, для игры серии Team

DestTo(Pl)

Расстояние от планеты назначения до указанной (параметр - строка)

Кроме этих полей каждая таблица имеет поле Count  и функцию Current(NewPos). Count - возвращает количество записей в таблице, нумерация идет от 0 до count. Функция Current позволяет менять текущую запись в таблице в значение NewPos. Например, sum(#*Weight) может быть переписана на макроязыке следующим образом:

macro mysum;
var
  summa, i;
begin
  summa:=0;
  for i:=0 to shipgroup.count do
     shipgroup.current(i);
     summa:=summa+shipgroup.#*shipgroup.Weight;
  endfor;
  result:=summa;
end;

Причем, этот макрос может быть выполнен в любом окне запроса, так как содержит обращение к shipgroup и не зависит от текущей активной таблицы.

 

Синтаксис макроязыка

Для написания полноценных макросов разработан макроязык. Для этого нужно создать файл gcomm.mac в каталоге расположения gcomm.exe и в этот файл вставляются все описания макросов.

Синтаксис описан ниже:

Макрос объявляется следующим образом:

Macro <ident>[(<ident>{,<ident>})];

Var <ident>{,<ident>};

Begin

{<operator>;}

End;

,где в части VAR указывается список переменных, тип переменных определяется во время выполнения и может динамически меняться.

Кроме этого всегда есть зарезервированная переменная result, значение которой определяет результат функции.

Ниже приведен синтаксис операторов языка

<operator> ::=

if <expression> then {<operator>;} [else {<operator>;}] endif

for <ident>:= <expression> to <expression> do {<operator>;} endfor

while <expression> do {<operator>;} endwhile

<ident>:=<expression>

<function call>

 

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

Функции макроязыка

PlanetDest("планета1", "планета2")

Результат функции - расстояние между двумя планетами

sum(<выражение>)

Агрегационная функция, выполняет <выражение> для каждой строки таблицы, и вычисляет сумму этих выражений

avg(<выражение>)

Агрегационная функция, выполняет <выражение> для каждой строки таблицы, и вычисляет среднее этих выражений

count

возвращает количество строк в данной таблице

me

возвращает имя расы, за которую был загружен отчет

FloatToStr(<число>[,<N>,<D>])

Преобразование числа в строковое представление, при этом можно указать общее число чисел (N), и число знаков после запятой(D).

По умолчанию N=10, D=2.

sqrt, sqr, sin, cos, ln, exp, round, trunc

математические функции с вещественным аргументом

AddCommand("команда")

добавление команды в приказ, при этом команда выполняется

StrPos(<подстрока>,<строка>)

Нахождение первого вхождения подстроки в строке, результат позиция в строке, иначе 0

StrChar(<строка>, N)

Быстрое получение N символа из строки

StrCopy(<строка>, P,N)

Выделение подстроки из строки с позиции P и длиной N символов

StrLen(<строка>)

Получение длины строки

StrCut(<строка>, P,N)

Удаление подстроки из строки с позиции P и длиной N символов

 

обратно

Hosted by uCoz