http://tonnys.kiev.ua

FileSync 2 - интерпретатор скриптов


Оглавление


Запуск

FileSync2.exe <имя файла со скриптом>

Синтаксис

Команды разделяются переводом строки или ";". В некоторых случаях допустимы пробелы, например:

if(..) begin
...
end else begin
...
end

Синтаксис регистрово-зависим. Внимание! Пробелы между именем функции и скобкой "(" - недопустимы!

Переменные (см Приложение 5) всегда начинаются с знака $, например $my_var

Выражения всегда заключаются в квадратные скобки: [выражение], например: [4+$my_var]

Операции выражений: + - * / ^ ( ) - стандартные, % - целочисленное деление, @ - остаток от деления

логические:  =  <=  >=  !=

бинарные: & (and),  | (or), ! (not)

Логических переменных нет, используется значение целого типа: 0 = False, иначе - True. 

Внимание! Операция ! (not) не является логической, поэтому в условных выражениях следует использовать булеву функцию not()

Директивы прекомпилятора

Перечень функций

действие параметры пример
примечание: $ перед параметром означает, что обязательна переменная: $int - целочисленная, $str - строковая, $hwnd - содержащая хэндл (целочисленная), $var - любого типа.

Встроенные переменные FileSync2

$prog_dir путь к FileSync2.exe
$tt03_port, $tt03_host порт и хост для соединения с TT03
$tt03_from от имени кого сообщение
$tt03_msg сообщение, которое будет отправлено
$err код ошибки или 0 если ошибки не было. Устанавливается некоторыми командами.
dir.test("c:\temp1")
if($err)
    print("не удалось создать")

Базовые команды

new($имя_переменной,тип,значение) создать переменную типы: int, int64 - целые, float - действительное, string - строковой
new($st) - создать строковую переменную

new($i,int,"0") - целая переменная

set($var,<выражение>) установить значение переменной
set($st,"hello")
set($i,[12+$i])
begin, {, end, } начало и конец блока
begin
...
end
if(<выражение>) [begin...end] else [begin...end] условный блок
if([$i<5])
  print("<")
else
  print("> or =")
 
if($i)
begin
    inc($i)
    print($i)
end else begin
    print("$i = 0")
end
for($int,<max>,<инкремент>) цикл $int - переменная целого типа, берётся её текущее значение

[max] - условие выхода из цикла

[inc] - инкремент переменной

set($i,[5])
for($i,15,1) {
    print($i)
}
while(<условие>) условный цикл
while([$i>15])
begin
    print($i)
    dec($i)
end
inc($int) увеличить переменную
dec($int) уменьшить переменную
break выход из цикла
sub($имя подпрограммы)...endsub подпрограмма см. Приложение 4
sub($my_sub)
    print("Sub called...")
endsub
gosub($подпрограмма) перейти в подпрограмму gosub($my_sub)
return выход из подпрограммы
exit выход из текущего блока begin...end
halt прервать скрипт 

Процедуры (команды) FileSync2

общие

print(...) вывод в лог
print("hello")
print($i)
print(["value = "+$i])
wait(<delay>) задержка <delay> - задержка в мс wait(2000)
app.timeout(<delay>) таймаут приложения <delay> - задержка в секундах, по завершению которого скрипт прерывается и приложение закрывается

INI-файлы: ini.

ini.open(<имя файла>) открыть ini-файл для работы ini.open([$prog_dir+"my.ini"])
ini.close закрыть ini-файл
ini.readstr($var,<секция>,<параметр>,<значение по умолчанию>) прочитать значение в строковую переменную ini.readstr($st,"main","value","")
ini.writestr($var,<секция>,<параметр>) записать строковую переменную ini.writestr($st,"main","value")
ini.readint, ini.writeint, ini.readfloat, ini.writefloat запись и чтение целочисленных и действительных значений

Реестр: reg.

reg.open(<раздел>,<ключ>,cancreate=0,readonly=0) открыть ключ реестра <разделы>: CU=HKEY_CURRENT_USER, LM=HKEY_LOCAL_MACHINE, CR=HKEY_CLASSES_ROOT, US=HKEY_USERS, CC=HKEY_CURRENT_CONFIG

<ключ> - имя ключа; cancreate - создавать ключ, если отсутствует; readonly - открыть только для чтения 

new($st,string)

reg.open("CU","\Software\Microsoft\Windows\CurrentVersion\Run")
if([ f_reg.valueexists("TSTools") ]) {
    reg.readstr($st,"tstools")
    print([ "TSTools="+$st ])
} else 
    print("Value not found!")

reg.close закрыть ключ реестра
reg.keycreate(<key>) создать ключ
reg.keydelete(<key>) удалить ключ

reg.readint($var,<name>)

reg.readbool($var,<name>)

reg.readstr($var,<name>)

reg.readfloat($var,<name>)

reg.readcurr($var,<name>)

reg.readdate($var,<name>)

reg.readtime($var,<name>)

reg.readdt($var,<name>)

прочитать значение в переменную из текущего ключа reg.readcurr читает в переменную типа float, reg.readbool - типа int 

reg.writeint(<name>,<value>)

reg.writebool(<name>,<value>)

reg.writestr(<name>,<value>)

reg.writefloat(<name>,<value>)

reg.writecurr(<name>,<value>)

reg.writedate(<name>,<value>)

reg.writetime(<name>,<value>)

reg.writedt(<name>,<value>)

записать значение в текущий ключ для reg.writebool передаётся int, для reg.writecurr - float
reg.keynames(<list_id>) прочитать имена ключей в список
reg.valuenames(<list_id>) прочитать имена параметров в список new($l,int)
list.create($l,"List1")
reg.valuenames($l)
reg.delvalue(<name>) удалить параметр

Реестр - функции: f_reg.

(int) f_reg.keyexists(<key>) проверяет существование ключа
(int) f_reg.valueexists(<name>) проверяет существование параметра в открытом ключе

Строки: ввод и шифрование

pw.crypt($str,<пароль>,<имя файла>) зашифровать пароль указанным файлом в $str помещается значение зашифрованного указанным файлом пароля. По работе с шифрованием и паролями см. соответствующий раздел.
cryptstr($str,<что>,<ключ>) зашифровать строку зашифровать <что> указанным ключом
uncryptstr($str,<что>,<ключ>) расшифровать строку
inputstr($str,<подсказка>,<макс длинна>) вызвать диалог ввода строки
inputpassw($str,<подсказка>,<минимальная длинна>) вызвать диалог ввода пароля

API-функции: api.

api.findwintext($int,<текст>) найти окно, содержащее в заголовке указанный текст в $int помещается хэндл найденного окна или 0 если не найдено
api.findwindow($int,<заголовок>,<класс>) найти окно если не требуется указание заголовка или класса, указать вместо них "nil" api.findwindow($i,"notepad","nil")
api.gettext($str,$hwnd) получить заголовок окна $hwnd - хэндл окна
api.sendstr($hwnd,<строка>) отправить строку на указанный хэндл 
api.sendkey($hwnd,<имя клавиши>) отправить указанную клавишу перечень клавиш см. Приложение 1 api.sendkey($hwnd,"F12")
api.findchildwin($int,<HWNDparent>,<name>,<class>) найти дочернее окно используется для поиска оконных элементов
tt03.send(<сообщение>) отправить сообщение на TT03 если <сообщение> пустое - будет отправлено значение переменной $tt03_msg
set($tt03_host,"director")
tt03.send("Превед!!! Кагдила?")

Лог-файл: log.

log.init(<имя файла>) подготовить текстовый файл для записи
log.mode(<режимы>) установить режим записи файла <режимы>="FD"

F - закрывать файл после каждой записи

D - дописывать дату и время в начало строки

log.mode("") //сброс режимов

log.mode("FD") //форсировать запись и дописывать дату/время

log.write(<строка>) дописать строку в файл при режиме F в начало строки добавляется дата/время
log.close закрыть файл
app.set(<строка>) изменить/задать установки приложения параметры указываются в виде перечня Параметр=Значение через запятую. Допустимые параметры см. Приложение 2. Внимание: без использования параметра SHOW=1 окно скрипта будет скрыто app.set("left=100,center=1,show=1")

Директории: dir.

dir.test(<имя директории>) проверить/создать директорию создаёт директорию, если такой не существует
dir.cd(<имя директории>) сменить директорию
dir.rd(<имя директории>) удалить директорию

Файлы: file.

file.exec(<имя файла>, <параметры>, <директоря>, <ждать завершения=0|1>) выполнить внешнее приложение параметры кроме <имя файла> могут быть не заданы или пустыми (""). Если задан  <ждать завершения> то скрипт останавливается до завершения вызванного приложения или по таймауту.
file.exec("notepad.exe","script.txt")
file.exec("d:\work","")
file.exec("notepad.exe","","",1)
file.copy(<src.filename>,<dest.filename>) скопировать одиночный файл если dest.filename не содержит имени файла то должна заканчиваться на "\"
file.copy("c:\temp\text1.txt","c:\temp1\text1.txt")
file.copy("c:\temp\text1.txt","c:\temp1\")
file.del(<имя файла>) удалить файл
file.move(<src.filename>,<dest.filename>,safe=0) переместить файл safe=1 - "безопасный" режим, файл сначала копируется, потом удаляется после проверки на наличие
file.rename(<old.filename>,<new.filename>) переименовать файл new.filename - можно указать только имя, без директории

Диски: disk.

disk.free($var,<name>,num=-1) свободное место на диске в байтах указывается или имя диска в виде "c:\" или номер. Результат помещается в $var (тип int64)
new($i,int64)
disk.free($i,"c:\")
disk.free($i,"",3)
disk.size($var,<name>,num=-1) размер диска
disk.type($int,<name>,num=-1) тип устройства
  • DRIVE_REMOVABLE = 2
  • DRIVE_FIXED = 3
  • DRIVE_REMOTE = 4
  • DRIVE_CDROM = 5
  • DRIVE_RAMDISK = 6

Сеть: net.

net.ping($int,<хост>,echo=1,mode=0) пинг echo=1 - выводить эхо в лог, 0 - не выводить.

mode=0 - 5 пингов, первый отбрасывается, остальные усредняются. mode=1 - одиночный пинг. mode=2 - то же, что и 0, но с прерыванием при первой ошибке.

Количество ошибок сохраняется в $err с отрицательным знаком

new($i,int)
net.ping($i,"google.com")

Списки

см. Приложение 3
list.create($var,"name",<тип>) создаёт список переменная $var должна быть обьявлена заранее. <тип>=0 - обычный, 1 - файловый
list.clear(id) очистить список
list.add(id,<строка>) добавить строку
list.insert(id,<строка>,<позиция>) вставить строку
list.set(id,<строка>,<позиция>) изменить элемент списка
list.del(id,<позиция>) удалить строку из списка
list.save(id,<filename>) сохранить список в файл сохраняет только основную часть, для сохранения файловых списков следует использовать list.filessave
list.load(id,<filename>) прочитать список из файла
list.loadex(id,num,<filename>,skip=0,count=-1) ïðî÷èòàòü ÷àñòü òåêñòîâîãî ôàéëà ÷èòàåò çàäàííîå êîëè÷åñòâî ñòðîê:

id - ñïèñîê, num - ïîçèöèÿ, êóäà âñòàâèòü ïðî÷èòàííîå (-1 = äîáàâèòü), skip = ñêîëüêî ïðîïóñòèòü ñòðîê, count = ñêîëüêî ñ÷èòàòü.

new($list,int)

list.create($list,"ñïèñîê1")

list.loadex($list,-1,"c:\temp\1.txt",0,3)

list.getid($var,"имя") получить индекс списка по имени имя - присвоенное при list.create
list.getfiles(id,<dir>,<attr=ra>,<subdirs=0>,<add=0>) заполнить список именами файлов из указанной директории <add>=1 - дополнить список

<attr>="r a h v s l", <subdirs> - задаёт уровень вложенности для поиска в поддиректориях

list.count($count,id) получить размер списка
list.filessave(id,<filename>) сохранить список файлов
list.filesload(id,<filename>,<add=0>) прочитать список файлов считывает размер файла, дату и директорию
list.copyitem(src_id,src_num,dest_id,dest_num=-1) копировать элемент в другой список dest_num=-1 - добавить, иначе - вставить
list.copy(src_id,src_num,dest_id,cnt=-1,add=0) копировать список cnt=-1 - все элементы до конца списка, add=0 - очистить список dest_id, иначе - дополнить.
 list.applyfilter(id,filter,oper=0,res_id=-1) применить на список фильтр фильтр - список с масками файлов. При res_id<>-1 результат фильтра помещается в него. Детальнее см. приложение
list.compare(id,etalon,res_id=-1,flag=7) сравнить списки Детальнее см. Приложение 3
list.sort(id,<тип сортировки>) сортировать список <тип сортировки>: положительный - по возрастанию, отрицательный: по убыванию.

Коды: 1 - по имени, 2 - по расширению, 3 - по размеру, 4 - по дате и времени, 5 - по времени.

list.findstr(id,$var,<текст>,start=0) ищет <текст> в списке, начиная со строки start. Возвращает номер строки или -1, если не найдено.

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

базовые

функции применяются исключительно в выражениях, заключённых в квадратные скобки [...выражение...] print([f_nows(0)])
(int64) not(<выражение>) логическое "НЕ" функция от любого параметра, не равного нулю возвращает 0, иначе 1 not(1) = 0, not(237) = 0, not(0) = 1
(datetime) f_date(<дата-время>) выделяет дату из переменной типа datetime
new($dt,datetime,"01.01.2007 11:00") 
set($dt,[f_date($dt)])
print($dt) //01.01.2007
(datetime) f_time(<дата-время>) выделяет время из переменной типа datetime set($dt,[f_time($dt)])
(string)  f_times(<дата-время>) преобразует время в строку print( [f_times($dt)] )
(string)  f_dts(<дата-время>) преобразует дату и время в строку print( [f_dts($dt)] )
(datetime) f_std("дата время") преобразует строку в дата-время new($d,datetime)

set($d,[f_std("01.01.2009 09:00"])

(datetime) f_now(0) текущая дата print([ f_nows(0) ])
(string) f_nows(0) текущая дата в виде строки print([ f_dts(f_now(0)) ])
(int64) f_round(<float>) округление
new($i,int)
new($f,float,"5.67")
set($i,[f_round($f)]) //$i=6
(int64) f_int(<float>) целая часть set($i,[f_int($f)]) //$i=5
(float) f_frac(<float>) дробная часть set($f,[f_frac($f)]) //$f=0.67
(int64) f_len(<строка>) длинна строки
(int64) f_pos(<подстрока>,<строка>) позиция подстроки в строке
(string) f_copy(<строка>,<позиция>,<количество>) выделить подстроку
(string) f_del(<строка>,<позиция>,<количество>) удалить из строки
(string) f_chr(<код символа>) возвращает символ с указанным кодом
(int64) f_ord(<строка>,<позиция>) возвращает код указанного символа
(string) f_sl(<строка>,<длинна>) сдвиг строки влево
(string) f_sr(<строка>,<длинна>) сдвиг строки вправо
(string) f_str.replace(<строка>, <подстрока1>, <подстрока2>) заменить в строке подстроку1 на подстроку2
(string) f_up(<строка>) перевод строки в верхний регистр
(string) f_low(<строка>) перевод строки в нижний регистр

  Функции - общие

f_findinstance функция, ищет уже запущенную копию FileSync2 с таким же скриптом.
if( [f_findinstance] )
    halt
(int) f_file.exist(<имя файла>) проверяет существование файла
if( [f_fileexist("myfile.txt")] )
    print("File found!")
(int) f_dir.exist(<имя директории>) проверяет существование директории
 (str) f_pf(path,file) обьединяет путь и имя файла
 (str) f_dir.current(0) текущая директория
 (str) f_file.name(<filename>) выделяет имя файла
 (str) f_file.dir(<filename>) выделяет директорию из полного имени файла
 (str) f_file.path(<filename>) выделяет путь
 (str) f_file.ext(<filename>) выделяет расширение
 (str) f_file.chext(<filename>,<.new ext>) меняет расширение
 (datetime) f_file.dt(<filename>) получить дату/время файла print([f_dts(f_file.dt("c:\temp\text.txt"))])
 (int64) f_file.size(<filename>) получить размер файла print([f_file.size("c:\temp\text.txt")])
 (str) f_app.paramcount(0) получить количество параметров командной строки
 (str) f_app.paramstr(<index>) получить параметр коммандной строки с указанным индексом обычно, параметр №1 содержит путь к файлу скрипта
 (str) f_strpart(str,div,num) делит строку str по разделителю div и возвращает подстроку номер num 

//для строки

// $str="aaa,bbb,ccc"

print([ f_strpart($str,",",0) ]) // aaa

print([ f_strpart($str,",",2) ]) // ccc

Функции - списки

 (str) f_list.get(id,num) возвращает элемент num списка id print([f_list.get($id,0)])
 (str) f_list.fn(id,num) возвращает элемент в виде полного имени файла (с путём) file.copy( [f_list.fn($id,$i1)],["c:\temp\"+f_list.get($id,$i1)] )
 (int) f_list.testmask(id,<filename>) проверить имя файла на соответствие списку масок (id) список id может состоят как из имён файлов так и из масок (*.exe). Функция возвращает номер строки списка, соответствующий указанному имени файла или -1 если соответствия нет.
 (int) f_list.indexof(id, <строка>) ищет строку в списке
 (int64) f_list.fsize(id,num,refresh) возвращает размер файла refresh=1 - обновить информацию
 (datetime) f_list.fdt(id,num,refresh) возвращает датувремя
 (int) f_list.ftag(id,num) возвращает тэг списка  для операции compare
 (str) f_list.name(id,num) возвращает левую часть параметра вида name=value
 (str) f_list.value(id,num,name) возвращает правую часть параметра вида name=value если num=-1 то поиск происходит по строковому параметру name  print([ f_list.value($l,2,"" ])

print([ f_list.value($l,-1,"name2" ])

 

Приложение 0. Работа с шифрованием

Функции cryptstr и uncryptstr шифруют/расшифровывают указанное выражение заданным ключом, результат в виде base-64 кодровки помещается в строковую переменную.

Если ключ не указан то шифрование/расшифровка выполняются ключом на основе текста текущего исполняемого скрипта.

Для реализации простого варианта защиты пароля от просмотра используется комбинация функций: pw.crypt и uncryptstr без ключа.

Функция pw.crypt вместо ключа использует указанный текстовый файл. Обратной функции нет, т.е. расшифровать возможно только из текущего скрипта.

Таким образом реализуется схема:

1. делается скрипт (main.txt), читающий пароль из ini-файла и использующий его. (при желании - хоть на экран выводящий). Скрипт использует uncryptstr без ключа.

2. делается скрипт для ввода и шифрования пароля (setpassw.txt) который введённый пароль шифрует текстом скрипта main.txt и записывает в ini-файл

пример:

main.txt:


new($st) //строковая переменная
new($hwnd,int,"0") //целочисленная переменная
ini.open([$prog_dir+"main.ini"]) //открываем ini-файл
ini.readstr($st,"main","passw","error") //читаем строку из ini-файла
uncryptstr($st,$st,"") //расшифровываем ключом на основе текущего скрипта
if([$st!=""])
begin
    print("password ok")
    api.findwindow($hwnd,"Password box","nil") //найдём окно ввода пароля
    api.sendstr($hwnd,$st) //отправить пароль какому-нибудь окну
    api.sendkey($hwnd,"enter") //нажать Enter
end else
    print("uncrypt error")

setpassw.txt


new($st,string,"<empty>")
inputpassw($st,"введите пароль",0) //диалог ввода пароля
ini.open([$prog_dir+"main.ini"])
pw.crypt($st,$st,"main.txt") //зашифровать текстом скрипта из main.txt
ini.writestr($st,"mail","passw")
ini.close
close //закрыть окно скрипта

Приложение 1. Перечень названий клавиш для api.sendkey()

enter, win, menu, bs (BackSpace), tab, F1..F12

 

Приложение 2. Параметры команды app.set()

SHOW=1|0 - 1 = показать окно. Иначе будет скрыто. 0 = свернуть

left, top, width, height - размеры и положение. Пример: app.set("left=100,top=120,width=400")

center=0|1 - центрировать окно. Пример: app.set("width=400, height=200, center=1")

log_cmd=0|1 - разрешить/запретить лог каждой команды*

log_file - имя файла, в который будет сохранён лог текущего скрипта (отображаемый в окне приложения). По-умолчанию FileSync2_log.txt

log_append=0|1 - дописывать/перезаписывать лог

caption="заголовок окна" - установить заголовок окна

*примечание - перечень установок лога относится к логу основного окна програмы и никак не пересекается с групой команд log.

Приложение 3. Списки. Фильтры и сравнение списков

В общем случае список - набор строк (TStringList). Основной элемент списка - строка. Для файлового списка к строкам, хранящим имена файлов,  дополнительно привязываются параметры файла.

Для создания списка требуется ранее обьявленная переменная типа int, в которую помещается индекс (идентификатор) списка. Если идентификатор был утерян (переменная была изменена), то получить его значение можно командой list.getid(<переменная>,<имя списка>)

Команды фильтрации:

list.applyfilter($id, $filter, oper=0, $res_id=-1) - выделяет элементы списка $id в соответствии с фильтром $filter и операцией oper

$id, $filter - списки.

Если $res_id не задан: 

    oper=0 - удалить из $id элементы, не соответствующие фильтру

    oper=1 - удалить из $id элементы, соответствующие фильтру

Если $res_id задан: 

    oper=1 - копировать из $id элементы, соответствующие фильтру в список $res_id

    oper=11 - переместить из $id элементы, соответствующие фильтру в список $res_id

    oper=0 - копировать из $id элементы, НЕ соответствующие фильтру в список $res_id

    oper=10 - переместить из $id элементы, НЕ соответствующие фильтру в список $res_id

list.compare($id, $etalon, $res_id=-1, flag=14) - сравнивает список $id со списком $etalon по параметрам: размер файла и дата изменения и заполняет поле tag списка $id следующей битовой маской:

    бит 0 (значение 1)  -  файл отсутствует в эталоне (удалён)

    бит 1 (значение 2)  -  файл отсутствует в $id (новый)

    бит 2 (значение 4)  -  отличается размер

    бит 3 (значение 8)  -  отличается дата изменения

    бит 4 (значение 16)  -  дата изменения эталона новее 

$id, $etalon - файловые списки. Если $res_id задан то сравниваемые элементы помещаются в него согласно битовому параметру flag.

для проверки тэга следует использовать функцию f_list.ftag($id, <номер элемента>)

list.getfiles($id, <путь и маска файлов>, subdirs=0, attr="ra", add=0) - поместить перечень файлов в список. 

attr: r - ReadOnly, a - Archive, h - Hidden, v - VolumeID, s - SysFile, l - SymLink

add=0 - очистить список, add=1 - добавить в список

subdirs - уровень вложенности для поиска в поддиректориях. 0 - искать только в текущей.


//обьявление обычного списка
new($id,int)
list.create($id,"id")
//обьявление файлового списка
new($files,int)
list.create($files,"filelist",1)
//заполняем файловый список содержимым директории C:\temp\. Атрибуты - по умолчанию
list.getfiles($files,"c:\temp\*.*")
//мы хотим убрать из списка все jpg и exe файлы, для этого добавляем указанные маски в первый список:
list.add($id,"*.jpg")
list.add($id,"*.exe")
//и применяем фильтр из полученного списка масок ($id) на список файлов ($files): list.applyfilter(id,filter,oper=0,res_id=-1)
//если третий параметр (oper) = 0 то будут удалены элементы списка, не соответствующие фильтру (по умолчанию)
list.applyfilter($files,$id,1)
//ещё один список:
new($files2,int)
list.create($files2,"files2")
//заполняем файловый список содержимым директории C:\temp\1\ Атрибуты - по умолчанию
list.getfiles($files2,"c:\temp\1\*.*")
//сравнить списки
list.compare($files2,$files)
//вывести результат с указанием изменений
new($st,string)
new($i1,int,"0")
new($cnt,int)
new($tag,int)
list.count($cnt, $files2) //получить количество строк списка в переменную $cnt
while([ $i1<$cnt ])
begin
    set($tag,[ f_list.ftag($files2, $i1) ]) //получить тэг элемента
    if([ $tag = 1 ])
        set($st,"удалён")
    if([ ($tag & 2)>0 ])
        set($st,[ $st+" новый," ] )
    if([ ($tag & 4)>0 ])
        set($st,[ $st+" изменён размер," ] )
    if([ ($tag & 8)>0 ])
        set($st,[ $st+" изменена дата," ] )
    if([ ($tag & 16)>0 ])
        set($st,[ $st+" новее" ] )
    print([ " " + f_list.get($files2,$i1) + $st ])
    inc($i1)
end

Приложение 4. Подпрограммы

Вложенных подпрограмм не допускается.

Подпрограммы реализуются операторами:

sub(имя_подпрограммы) - начало блока подпрограммы

endsub - конец блока подпрограммы

gosub($имя_подпрограммы) - перейти в подпрограмму

return - немедленный возврат из подпрограммы, эквивалентен достижению endsub

Видимость переменных

Все переменные в скрипте - глобальные, включая переменные в подпрограммах. Тем не менее реализована "локализация" переменных, т.е. в подпрограмме можно создавать переменные с таким же именем как и в основной программе. Обратиться к глобальной переменной (должна быть ранее определена) можно через удвоенный символ $$:

if($i<$$i) ...

Пример: использование подпрограммы для вывода списка


//обьявление глобальных переменных

new($icnt,int);
new($id,int)

sub(outlist)
    new($i1,int,"0");
    set($i1,[0]);    
//обязательно обнулить, несмотря на значение, заданное в new(), так как переменная - глобальна
    while( [$i1<$$icnt] ) {    
//сравнение локальной и глобальной переменных
        print([ f_sr(""+f_list.fsize($$id,$i1,0),12) + " " + f_list.get($$id,$i1) ] )
//обратить внимание на ""+ перед функцией - чтоб результат был строкой
        inc($i1)
    }
endsub

app.set("show=1")

//создать списки и привязать к переменным
list.create($id,"id",1)

//получить список файлов для целевой директории
list.getfiles($id,"c:\temp\*.*")

list.count($icnt,$id)
//размер списка, в глобальную переменную

list.sort($id,1)   
//сортировка с типом 1 - по имени
gosub($outlist)  
//напечатать список

list.sort($id,3)  
  //сортировка с типом 3 - по размеру
gosub($outlist) 
//напечатать список


Так как переменные из подпрограммы - глобальные то к ним можно обратиться через $имя_подпрограммы.$имя_переменной

Приложение 5. Типы переменных, приведение типов

Переменная обьявляется оператором:

new($имя_переменной, <тип>, <значение по умолчанию="">)

   $имя_переменной - символьное имя, начинающееся с знака $

    <тип> - для переменных поддерживаются следующие типы:

тип описание типы, приводимые к указанному
string строка все типы
int целое int64 с обрезанием старших битов
int64 большое целое int
datetime дата и время float, int, int64
float действительное datetime, int, int64

Логический тип отсутствует. В логических выражениях используется значение типа int: 0 = False, иначе True

Выражения, записываемые в квадратных скобках, имеют свою специфику. Прежде всего, в выражениях участвуют только 3 типа данных: int64, float, string. Остальные типы приводятся к ним. Восновном операции с выражениями выполняются по стандартным правилам.

Со строками допустимы операции сложения и логические. Для операции сложения с участием строк результат всегда строка, если один из операндов - строка. Этот момент следует использовать для приведения типов в выражениях, например:

print([ f_sr( f_list.fsize($list_id,$item_id) , 10 ) ])   //вывод размера файла c выравниванием по правому краю

указанный оператор выведет <null> так как возникнет ошибка преобразования типов:

f_sr() - возвращает строку, первый аргумент должен так же быть строкой, но f_list.fsize() возвращает int64. Для корректной работы следует записать:

print([ f_sr( "" + f_list.fsize($list_id,$item_id) , 10 ) ])

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

Задать значение переменной можно оператором

set($имя_переменной, <значение>)

set($имя_переменной, [выражение])

Примеры:

set($i, 0)

set($str, "Привет")

 

Приложение 6. Прекомпилятор

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

поддерживаемые директивы:

#include <имя файла> - конструкция вставляет в текущий скрипт содержимое указанного файла. Файл ищется или в директории программы или в поддиректории \lib. При использовании данной конструкции номера строк при ошибках выводятся с учётом вставленного файла, т.е. смещаются.

#define <значение1> <значение2> - задаёт замену для текста скрипта, т.е. во всём скрипте <значение1> будет заменено на <значение2>. Основное использование - именованные константы, но может использоваться и для синтаксических конструкций. позиция в коде не имеет значения. Если в значениях содержатся пробелы, их следует брать в кавычки. Кавычка внутри кавычек ставится путём удвоения символа.

Пример:


//добавить содержимое файла const.txt
#include const.txt
//определим константу
#define PI 3.14
//определим замену для выражения в скобках:
#define { ([
#define } ])
#define MSG0 """Число Pi = """
#define MSG1 "Число Pi = "
 
//оба оператора выведут одинаковый результат. Обратите внимние на используемые фигурные скобки
print{MSG0 + PI}  // print(["Число Pi = " + 3.14])
print("MSG1 PI")    // print("Число Pi = 3.14")