
@c ------------------------------------------------------------------
@chapter Скрипты MGL

@c TODO Translate it!

MathGL library supports the simplest scripts for data handling and plotting. These scripts can be used independently (with the help of UDAV, mglconv, mglview programs and others
@ifclear UDAV
, @pxref{Utilities}) or in the frame of the library using.
@end ifclear

@ifclear UDAV
@menu
* MGL definition::
* Program flow commands::
* mglParse class::
@end menu
@end ifclear

@ifset UDAV
@menu
* MGL definition::
* Program flow commands::
@end menu
@end ifset


@c ------------------------------------------------------------------
@external{}
@node MGL definition, Program flow commands, , MGL scripts
@section Основы MGL

Язык MGL достаточно простой. Каждая строка -- отдельная команда. Первое слово -- имя команды, а все остальные ее аргументы. Команда может иметь до 1000 аргументов (по крайней мере сейчас). Слова разделяются одно от другого пробелом или символом табуляции. Различий между верхним и нижним индексом нет, т.е. переменные @var{a} и @var{A} идентичны. Символ @samp{#} начинает комментарий -- все символы после него игнорируются до конца строки. Исключением является случай, когда @samp{#} входит в строку. Опции команды указываются после символа @samp{;} (@pxref{Command options}). Символ @samp{:} начинает новую команду (подобно переводу строки) если он расположен не внутри скобок или строки.

Если строка содержит ссылки на внешние параметры (@samp{$0}, @samp{$1} ... @samp{$9}) или макроопределения (@samp{$a}, @samp{$b} ... @samp{$z}), то текущие значения параметров/макроопределений подставляются в строку вместо ссылки до выполнением команды. Это позволяет использовать один и тот же скрипт при различных входных параметрах командной строки или вводить макроопределения по ходу исполнения команд скрипта.

Аргументы команды могут быть строками, переменными или числами.
@itemize @bullet
@item
Строка -- произвольный набор символов между метками @samp{'}. Длинные строки могут быть соединены из нескольких линий файла символом @samp{\}. Т.е. строки файла @samp{'a +'\<br>' b'} дадут строку @samp{'a + b'} (здесь @samp{<br>} -- перевод строки). Также можно использовать соединение строк и чисел, используя символ @samp{,} без пробелов (например, @samp{'max(u)=',u.max,' a.u.'}).

@item
Обычно переменная имеет имя, состоящее из букв и чисел (должно начинаться с буквы и не быть длиннее 64 символов). В качестве переменной можно использовать временные массивы, включающие в себя:
@itemize @bullet
@item
срезы (``подмассивы'') массивов данных (подобно команде @ref{subdata}). Например, @code{a(1)} или @code{a(1,:)} или @code{a(1,:,:)} -- вторая строка массива @var{a}, @code{a(:,2)} или @code{a(:,2,:)} -- третий столбец, @code{a(:,:,0)} -- первый срез и т.д. Также можно выделить часть массива с m-го по n-ый элемент @code{a(m:n,:,:)} или просто @code{a(m:n)}.

@item
произвольные комбинации столбцов данных (например, @code{a('n*w^2/exp(t)')}), если столбцы данных были именованы командой @ref{idset} или в файле данных (в строке начинающейся с @code{##}).

@item
произвольное выражение из существующих переменных и констант. Например, @samp{sqrt(dat(:,5)+1)} даст временный массив данных с элементами равными @code{tmp[i,j] = sqrt(dat[i,5,j]+1)}.

@item
массивы с элементами заданными в квадратных скобках [], разделенные @samp{,}. При этом внутри выражения не должно быть пробелов! Например, @samp{[1,2,3]} даст временный массив из 3 элементов @{1, 2, 3@}; @samp{[[11,12],[21,22]]} даст матрицу 2*2 и т.д. Элементами такой конструкции могут быть и массивы если их размерности одинаковые, например @samp{[v1,v2,...,vn]}.

@item
результат команд построения новых данных (@pxref{Make another data}), если они заключены в фигурные скобки @{@}. Например, @samp{@{sum dat 'x'@}} даст временный массив, который есть результат суммирования @var{dat} вдоль 'x'. Это такой же массив как и @var{tmp}, полученный командой @samp{sum tmp dat 'x'}. При этом можно использовать вложенные конструкции, например @samp{@{sum @{max dat 'z'@} 'x'@}}.
@end itemize
Временные массивы не могут стоять в качестве первого аргумента команд, создающих массивы (например, @samp{new}, @samp{read}, @samp{hist} и т.д.).

@item
К скалярным переменным, кроме собственно чисел, относятся: специальные переменные @code{nan=#QNAN, pi=3.1415926..., on=1, off=0, :=-1}, переменные с суффиксами (@pxref{Data information}), переменные определенные командой @ref{define}. Также массивы размером 1x1x1 считаются скалярами (например, @samp{pi/dat.nx}).
@end itemize
Перед первым использованием все переменные должны быть определены с помощью команд, создающих массивы (@ref{new}, @ref{var}, @ref{list}, @ref{copy}, @ref{read}, @ref{hist}, @ref{sum} и др., см. @ref{Data constructor}, @ref{Data filling} и @ref{Make another data}).

Команды могут иметь несколько наборов аргументов (например, @code{plot ydat} и @code{plot xdat ydat}). Все аргументы команды для выбранного набора должны быть указаны, однако часть из них могут иметь значения по умолчанию. Такие аргументы в описании команд будут помещены в квадратные скобки [], например @code{plot ydat ['stl'='' zval=nan]}. При этом запись @code{[arg1 arg2 arg3 ...]} подразумевает @code{[arg1 [arg2 [arg3 ...]]]}, т.е. опускать можно только аргументы с конца, если вы согласны с их значениями по умолчанию. Например, @code{plot ydat '' 1} или @code{plot ydat ''} правильно, а @code{plot ydat 1} не правильно (аргумент @code{'stl'} пропущен).



@c TODO Translate it!

@c ------------------------------------------------------------------
@external{}
@node Program flow commands, MGL definition, MGL scripts
@section Program flow commands

Below I show commands to control program flow, like, conditions, loops, define script arguments and so on. Other commands can be found in chapters @ref{MathGL core} and @ref{Data processing}. Note, that some of program flow commands (like @ref{define}, @ref{ask}, @ref{call}, @ref{for}, @ref{func}) should be placed alone in the string.

@cindex chdir
@anchor{chdir}
@deftypefn {MGL command} {} chdir 'path'
Changes the current directory to @var{path}.
@end deftypefn

@cindex ask
@anchor{ask}
@deftypefn {MGL command} {} ask $N 'question'
Sets @var{N}-th script argument to answer which give the user on the @var{question}. Usually this show dialog with question where user can enter some text as answer. Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn

@cindex define
@anchor{define}
@deftypefn {MGL command} {} define $N smth
Sets @var{N}-th script argument to @var{smth}. Note, that @var{smth} is used as is (with @samp{'} symbols if present). Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn
@deftypefn {MGL command} {} define name smth
Create scalar variable @code{name} which have the numeric value of @code{smth}. Later you can use this variable as usual number. Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn
@cindex defchr
@anchor{defchr}
@deftypefn {MGL command} {} defchr $N smth
Sets @var{N}-th script argument to character with value evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn
@cindex defnum
@anchor{defnum}
@deftypefn {MGL command} {} defnum $N smth
Sets @var{N}-th script argument to number with value evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn
@cindex defpal
@anchor{defpal}
@deftypefn {MGL command} {} defpal $N smth
Sets @var{N}-th script argument to palette character at position evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn

@cindex call
@anchor{call}
@deftypefn {MGL command} {} call 'fname' [ARG1 ARG2 ... ARG9]
Executes function @var{fname} (or script if function is not found). Optional arguments will be passed to functions. See also @ref{func}.
@end deftypefn
@cindex func
@anchor{func}
@deftypefn {MGL command} {} func 'fname' [narg=0]
Define the function @var{fname} and number of required arguments. The arguments will be placed in script parameters $1, $2, ... $9. Note, you should stop script execution before function definition(s) by command @ref{stop}. See also @ref{return}.
@end deftypefn
@cindex return
@anchor{return}
@deftypefn {MGL command} {} return
Return from the function. See also @ref{func}.
@end deftypefn


@cindex if
@anchor{if}
@deftypefn {MGL command} {} if dat 'cond'
Starts block which will be executed if @var{dat} satisfy to @var{cond}.
@end deftypefn
@deftypefn {MGL command} {} if @code{val}
Starts block which will be executed if @code{val} is nonzero.
@end deftypefn
@cindex elseif
@anchor{elseif}
@deftypefn {MGL command} {} elseif dat 'cond'
Starts block which will be executed if previous @code{if} or @code{elseif} is false and @var{dat} satisfy to @var{cond}.
@end deftypefn
@deftypefn {MGL command} {} elseif @code{val}
Starts block which will be executed if previous @code{if} or @code{elseif} is false and @code{val} is nonzero.
@end deftypefn
@cindex else
@anchor{else}
@deftypefn {MGL command} {} else
Starts block which will be executed if previous @code{if} or @code{elseif} is false.
@end deftypefn
@cindex endif
@anchor{endif}
@deftypefn {MGL command} {} endif
Finishes @code{if/elseif/else} block.
@end deftypefn

@cindex for
@anchor{for}
@deftypefn {MGL command} {} for $N @code{v1 v2 [dv=1]}
Starts cycle with $@var{N}-th argument changing from @var{v1} to @var{v2} with the step @var{dv}. Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn
@deftypefn {MGL command} {} for $N dat
Starts cycle with $@var{N}-th argument changing for @var{dat} values. Here @var{N} is digit (0...9) or alpha (a...z).
@end deftypefn
@cindex next
@anchor{next}
@deftypefn {MGL command} {} next
Finishes @code{for} cycle.
@end deftypefn

@cindex once
@anchor{once}
@deftypefn {MGL command} {} once @code{val}
The code between @code{once on} and @code{once off} will be executed only once. Useful for large data manipulation in programs like UDAV.
@end deftypefn
@cindex stop
@anchor{stop}
@deftypefn {MGL command} {} stop
Terminate execution.
@end deftypefn

@ifclear UDAV
@c ------------------------------------------------------------------
@external{}
@node mglParse class, , Program flow commands, MGL scripts
@section mglParse class
@cindex mglParse

Class for parsing and executing MGL script. This class is defined in @code{#include <mgl2/mgl.h>}.

Class mglParse is the interpreter for MGL scripts. The main function of mglParse class is @code{Execute()}. Exactly this function parses and executes the script string-by-string. Also there are subservient functions for the finding and creation of a variable. These functions can be useful for displaying values of variables (arrays) in some external program (in window, for example). Function @code{AllowSetSize()} allows one to prevent changing the size of the  picture inside the script (forbids the MGL command @code{setsize}).

@c Note an important feature -- if user defines function @var{func} in variable then it will be called before the destroying of this variable (@pxref{mglVar class}).

@deftypefn {Constructor on @code{mglParse}} @code{} mglParse (@code{bool} setsize=@code{false})
@deftypefnx {Constructor on @code{mglParse}} @code{} mglParse (@code{HMPR} pr)
@deftypefnx {Constructor on @code{mglParse}} @code{} mglParse (@code{mglParse &}pr)
@deftypefnx {C function} @code{HMPR} mgl_create_parser ()
Constructor initializes all values with zero and set @var{AllowSetSize} value.
@end deftypefn

@deftypefn {Destructor on @code{mglParse}} @code{} ~mglParse ()
@deftypefnx {C function} @code{void} mgl_delete_parser (@code{HMPR} p)
Destructor delete parser
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{HMPR} Self ()
Returns the pointer to internal object of type @code{HMPR}.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const char *}text)
@deftypefnx{Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const wchar_t *}text)
@deftypefnx {C function} @code{void} mgl_parse_text (@code{HMGL} gr, @code{HMPR} p, @code{const char *}text)
@deftypefnx {C function} @code{void} mgl_parse_textw (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}text)
Main function in the class. Function parse and execute line-by-line MGL script in array @var{text}. Lines are separated by newline symbol @samp{\n} as usual.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{FILE *}fp, @code{bool} print=@code{false})
@deftypefnx {C function} @code{void} mgl_parse_file (@code{HMGL} gr, @code{HMPR} p, @code{FILE *}fp, @code{int} print)
The same as previous but read script from the file @var{fp}. If @var{print}=@code{true} then all warnings and information will be printed in stdout.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const char *}str, @code{long} pos=@code{0})
@deftypefnx {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
@deftypefnx {C function} @code{int} mgl_parse_line (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
@deftypefnx {C function} @code{int} mgl_parse_linew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
Function parses the string @var{str} and executes it by  using @var{gr} as a graphics plotter. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long. Optional argument @var{pos} allows to save the string position in the document (or file) for using @code{for|next} command.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{mglData} Calc (@code{const char *}formula)
@deftypefnx {Method on @code{mglParse}} @code{mglData} Calc (@code{const wchar_t *}formula)
@deftypefnx {C function} @code{HMDT} mgl_parser_calc (@code{HMPR} p, @code{const char *}formula)
@deftypefnx {C function} @code{HMDT} mgl_parser_calcw (@code{HMPR} p, @code{const wchar_t *}formula)
Function parses the string @var{formula} and return resulting data array. In difference to @code{AddVar()} or @code{FindVar()}, it is usual data array which should be deleted after usage.
@end deftypefn


@deftypefn {Method on @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const char *}str)
@deftypefnx {Method on @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const wchar_t *}str)
@deftypefnx {C function} @code{void} mgl_parser_add_param (@code{HMPR} p, @code{int} id, @code{const char *}val)
@deftypefnx {C function} @code{void} mgl_parser_add_paramw (@code{HMPR} p, @code{int} id, @code{const wchar_t *}val)
Function set the value of @var{n}-th parameter as string @var{str} (@var{n}=0, 1 ... 'z'-'a'+10). String @var{str} shouldn't contain @samp{$} symbol.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{mglVar *} FindVar (@code{const char *}name)
@deftypefnx {Method on @code{mglParse}} @code{mglVar *} FindVar (@code{const wchar_t *}name)
@deftypefnx {C function} @code{HMDT} mgl_parser_find_var  (@code{HMPR} p, @code{const char *}name)
@deftypefnx {C function} @code{HMDT} mgl_parser_find_varw  (@code{HMPR} p, @code{const wchar_t *}name)
Function returns the pointer to variable with name @var{name} or zero if variable is absent. Use this function to put external data array to the script or get the data from the script. You must @strong{not delete} obtained data arrays!
@end deftypefn
@deftypefn {Method on @code{mglParse}} @code{mglVar *} AddVar (@code{const char *}name)
@deftypefnx {Method on @code{mglParse}} @code{mglVar *} AddVar (@code{const wchar_t *}name)
@deftypefnx {C function} @code{HMDT} mgl_parser_add_var (@code{HMPR} p, @code{const char *}name)
@deftypefnx {C function} @code{HMDT} mgl_parser_add_varw (@code{HMPR} p, @code{const wchar_t *}name)
Function returns the pointer to variable with name @var{name}. If variable is absent then new variable is created with name @var{name}. Use this function to put external data array to the script or get the data from the script. You must @strong{not delete} obtained data arrays!
@end deftypefn

@deftypefn{Method on @code{mglParse} (C++)} @code{void} DeleteVar (@code{const char *}name)
@deftypefnx{Method on @code{mglParse} (C++)} @code{void} DeleteVar (@code{const wchar_t *}name)
@deftypefnx {C function} @code{void} mgl_parser_del_var (@code{HMPR} p, @code{const char *}name)
@deftypefnx {C function} @code{void} mgl_parser_del_varw (@code{HMPR} p, @code{const wchar_t *}name)
Function delete the variable specified by its name or by its pointer.
@end deftypefn

@deftypefn{Method on @code{mglParse} (C++)} @code{void} DeleteAll ()
@deftypefnx {C function} @code{void} mgl_parser_del_all (@code{HMPR} p)
Function delete all variables in this parser.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{void} RestoreOnce ()
@deftypefnx {C function} @code{void} mgl_parser_restore_once (@code{HMPR} p)
Restore Once flag.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{void} AllowSetSize (@code{bool} a)
@deftypefnx {C function} @code{void} mgl_parser_allow_setsize (@code{HMPR} p, @code{int} a)
Allow to parse 'setsize' command or not.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{void} AllowFileIO (@code{bool} a)
@deftypefnx {C function} @code{void} mgl_parser_allow_file_io (@code{HMPR} p, @code{int} a)
Allow reading/saving files or not.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{void} Stop ()
@deftypefnx {C function} @code{void} mgl_parser_stop (@code{HMPR} p)
Sends stop signal which terminate execution at next command.
@end deftypefn


@deftypefn {Method on @code{mglParse}} @code{long} GetCmdNum ()
@deftypefnx {C function} @code{long} mgl_parser_cmd_num (@code{HMPR} p)
Return the number of registered MGL commands.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{const char *} GetCmdName (@code{long} id)
@deftypefnx {C function} @code{const char *} mgl_parser_cmd_name (@code{HMPR} p, @code{long} id)
Return the name of command with given @var{id}.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{int} CmdType (@code{const char *}name)
@deftypefnx {C function} @code{int} mgl_parser_cmd_type (@code{HMPR} p, @code{const char *}name)
Return the type of MGL command @var{name}. Type of commands are: 0 -- not the command, 1 - data plot, 2 - other plot, 3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program, 8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot, 13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{const char *} CmdFormat (@code{const char *}name)
@deftypefnx {C function} @code{const char *} mgl_parser_cmd_frmt (@code{HMPR} p, @code{const char *}name)
Return the format of arguments for MGL command @var{name}.
@end deftypefn

@deftypefn {Method on @code{mglParse}} @code{const char *} CmdDesc (@code{const char *}name)
@deftypefnx {C function} @code{const char *} mgl_parser_cmd_desc (@code{HMPR} p, @code{const char *}name)
Return the description of MGL command @var{name}.
@end deftypefn

@end ifclear

@external{}

