Hopeless - функциональное программирование на языке HOPE

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

http://shabarshin.com/funny/

02-September-2007 hopeless-v0.2.tar.bz2 (98K)

* функция "read" теперь может запускать команды (если в начале имени файла стоит !)
* новый пример test/_run.hop который демонстрирует #!/..., argv и read("!...")
Last edited by Shaos on 09 Aug 2009 15:22, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Code: Select all

#!/usr/local/bin/hopeless -f
uses lines;
write argv to "argv.txt";
lines(read("!hopeless -f io.in"));
Пример показывает как делать из Hope-программ запускаемые скрипты, выводит аргументы в файл argv.txt (по одному в строку), а также создаёт список строк, которые получаются на выходе после запуска Hope-программы io.in (из каталога test) на исполнение (стандартный выход такого запуска посылается в файл и содержимое этого файла возвращается как результат функции read).
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

а вообще интересно получается:

lines(read("!arch")) возвращает список из одной строки с именем архитектуры компьютера (у меня ["i686"])

lines(read("!ls")) возвращает список строк - имён файлов в текущем каталоге
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Сегодня я впервые написал полезный скрипт на языке Hope!

Задача: имеем AVI и список эпизодов с указанием номера первого и последнего кадра , а также названия эпизода:

1000 1100 name_1
2000 2200 name_2

и т.д. - требуется с помощью менкодера по данному списку слить указанные эпизоды в отдельные файлы:

episodes.hop

Code: Select all

#!/usr/local/bin/hopeless -f

! episodes.hop - Alexander Shabarshin
! http://www.funnylang.org
! argv@0 - name
! argv@1 - fps
! script is loaded from file "name"
! movie is loaded from file "name.avi"
! episodes saved to "name_second_suffix.avi"
! format of script:
! start_frame end_frame suffix_name
! comment starts with #

uses list,lines,words;

type string == list(char);
data script_entry == make_script_entry(num,num,string);

dec script_line : list(string) # num -> script_entry;
--- script_line(t1::t2::ss::nil,fps) <=  
    let t_beg == (str2num(t1))/fps in
    let t_end == (str2num(t2)+1)/fps in
    let t_duration == t_end - t_beg in
	if t_duration =< 0 then error("end time smaller than begin time in " <> ss)
        else make_script_entry(t_beg,t_duration,ss);

dec parse_script : num # list(string) -> list(script_entry);
--- parse_script(_,nil) <= nil;
--- parse_script(fps,h::l) <= script_line(words(h),fps) :: parse_script(fps,l);
--- parse_script(fps,('#'::_)::l) <= parse_script(fps,l);

dec run_script : string # list(script_entry) -> list(string);
--- run_script(_, nil) <= "Ok" :: nil;
--- run_script(name, h::l) <=
    let make_script_entry(ss,endpos,suffix) == h in
	lines(read(unwords(["!episodes ", name,
	    name <> "_" <> num2str(floor(ss)) <> "_" <> suffix, 
	    num2str(ss), num2str(endpos)])))
		<> run_script(name,l);

run_script(argv@0,parse_script(str2num(argv@1),lines(read(argv@0))));
Вышеизложенный скрипт в процессе работы вызывает вот этот консольный скриптик (упрощено 11 сентября):

episodes

Code: Select all

mencoder -oac copy -ovc copy $1.avi -o $2.avi -ss $3 -endpos $4 >>stdout.out 2>>stderr.out
Имея список эпизодов в файле с именем test, а видео в файле с именем test.avi (предположим с частотой кадров 50) вызываем скрипт так:

./episodes.hop test 50
Last edited by Shaos on 11 Sep 2007 19:26, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Чтобы ещё покодить такого, чтобы поюзать новую функциональность Hopeless по запуску внешних приложений? ;)

P.S. У этой реализации Hope отсутствует полное описание встроенных библиотек - может сделать веб-сайт на эту тему с уроками, блогом/форумом и т.д.?
Я тут за главного - если что шлите мыло на me собака shaos точка net
Mac Buster
Retired
Posts: 1474
Joined: 03 Aug 2003 22:37
Location: Moscow

Post by Mac Buster »

Shaos wrote:P.S. У этой реализации Hope отсутствует полное описание встроенных библиотек - может сделать веб-сайт на эту тему с уроками, блогом/форумом и т.д.?
Уроки и примеры были бы очень кстати :D
Extreme Entertainment
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Пользовательский ввод оказывается можно также через read сделать (причём в оригинальной версии эта возможность уже была) - путём чтения файла /dev/stdin (чтение файлов тут ленивое, поэтому функции принимающие список будут получать строчку за строчкой по мере поступления) - вот пример простого скрипта, который переставляет введённое с клавиатуры в обратном порядке:

Code: Select all

#!/usr/local/bin/hopeless -f
uses lines,list;
write "Press Ctrl-D to quit\n";
write (map reverse (lines(read("/dev/stdin"))));
Пример работы (жирным показано что было введено юзером):
Press Ctrl-D to quit
123
321
abc
cba
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Mac Buster wrote:
Shaos wrote:P.S. У этой реализации Hope отсутствует полное описание встроенных библиотек - может сделать веб-сайт на эту тему с уроками, блогом/форумом и т.д.?
Уроки и примеры были бы очень кстати :D
Ну на оригинальном сайте есть ref_man и hope_tut так сказать для первоначального погружения (как я и говорил - далеко не полные)
Ну и Филда читаем (правда например функция map тут юзается не как map(f,list), а как map f list - т.е. не по Филду и reduce тут нету - вместо неё foldl)
P.S. Поправочка - map и reduce по Филду имеются в hope_tut.in (тестовый скрипт по туториалу - НЕ либа)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Обновил версию для винды:

http://shabarshin.com/funny/hopeless_cygwin.zip (845K)

Включил туда пример _input.hop для Windows:

Code: Select all

#!./hopeless -f
uses lines,list;
write "Press Ctrl-C to quit!\r\n";
write map reverse (lines(read("con")));
А также поправил lines.hop, чтобы игнорировало '\r'
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Скрипт для покадровой обработки видео, разбитого на PNG-файлы (непосредственно обработкой занимается программа bluescreen, написанная на Си):

Code: Select all

#!/usr/local/bin/hopeless -f

uses lines,list;

dec process1 : list(char) -> list(char);
--- process1(p) <= read("!bluescreen " <> p <> " video/" <> p <> " a6b9f7 50");

dec process : list(list(char)) -> list(list(char));
--- process([]) <= [];
--- process(h::l) <= process1(h)::process(l);

write process(lines(read("!ls *.png")));
По видимому надо написать платформонезависимую функцию получения списка файлов в текущем каталоге по маске
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote: По видимому надо написать платформонезависимую функцию получения списка файлов в текущем каталоге по маске
Я ещё в прошлом году создал либу system.hop, специфичную для платформы. Например вот так она выглядит для Linux:

Code: Select all

uses lines,string;

dec getc : list(char);
--- getc <= read("/dev/stdin");

dec gets : list(string);
--- gets <= lines(getc);

dec dir : string -> list(string);
--- dir(s) <= lines(read("!ls " <> s));
а так для Windows:

Code: Select all

uses lines,string;

dec getc : list(char);
--- getc <= read("con");

dec gets : list(string);
--- gets <= lines(getc);

dec dir : string -> list(string);
--- dir(s) <= words(read("!dir /w " <> s));
А сейчас я пробую применять Hopeless в качестве скриптового языка CGI :dj:

P.S. "dir" под виндой пока глючит...
Last edited by Shaos on 21 Jun 2008 20:16, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

http://shabarshin.com/funny/

21-Jun-2008 hopeless-v0.3.tar.bz2 (99K)

* новый пример test/_input.hop который показывает ввод с клавиатуры (stdin)
* поправлена либа lib/lines.hop чтобы пропускать символ '\r'
* новые либы lib/system.hop и lib/system_win.hop (функции "getc" и "gets")
* новая либа lib/string.hop (сейчас там только определение типа "string")
* в либы lib/system.hop и lib/system_win.hop добавлена функция "dir"
* новый предопределённый список "env" с некоторыми переменными окружения для CGI
Last edited by Shaos on 09 Aug 2009 15:23, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

http://shabarshin.com/funny/

22-Jun-2008 hopeless-v0.4.tar.bz2 (99K)

* отдельный файл version.h для APPNAME и VERSION макросов
* поддержка более длинных имён файлов (сейчас 256 против 100)
* поддержка большего количества одновременных стримов (сейчас 100 против 20)
* ограниченный режим (-r) теперь разрешает чтение, но запрещает запуск команд ("!...")
* сейчас функция "mktemp" используется для создания имён временных файлов для запуска команд
* больше доступных переменных в "env" для CGI режима
Last edited by Shaos on 09 Aug 2009 15:23, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Пример простого CGI-скрипта на языке HOPE:

Code: Select all

#!/usr/local/bin/hopeless -f
uses lines,system;
write "Content-type: text/html\n\n";
write "<html><body>\n";
write "<h1>Hello, Input!</h1>\n";
write gets;
write "<h1>Hello, Args!</h1>\n";
write argv;
write "<h1>Hello, Envs!</h1>\n";
write env;
write "</body></html>\n";
вот как он себя ведёт:

при простом вызове без параметров будут напечатаны только переменные окружения с пустой переменной QUERY_STRING

при вызове с одним параметром (без символа '=' внутри) передаваемая строка появится в аргументах и в переменной QUERY_STRING (метод GET)

при вызове с параметрами вида name=value (более одной пары разделяются символом &) пары попадут только в QUERY_STRING (метод GET)

при посылке через метод POST (например из формы) параметры в виде пар name=value разделенных символом & попадут во входной поток, а переменная QUERY_STRING останется пустой
Last edited by Shaos on 21 Nov 2012 17:46, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24087
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote:P.S. "dir" под виндой пока глючит...
Пофиксил "dir" в виндовом варианте - скоро ждите обновления! ;)
Я тут за главного - если что шлите мыло на me собака shaos точка net