Передать RECURSIVE внутрь другого слова?

Обсуждение программ nnCron и nnCron LITE

Передать RECURSIVE внутрь другого слова?

Postby VK » Thu, 30 Sep 2004, 14:54

Суть задачи: я пытаюсь написать для плагина слово, которое бы по маске возвращало пользователю (псевдо)случайный файл. Ну, т. е. пользователь указывает, например:

S" c:\temp\*.bmp" PICK-RANDOM-FILE

и при каждом вызове получает какой-либо из bmp-файлов, хранящихся в 'c:\temp\'.

Алгоритм пока такой. Сначала "пробегаюсь" циклом FOR-FILES: по указанному каталогу и считаю общее количество файлов, подпадающих под маску. Потом генерирую случайное число в диапазоне количества файлов и запускаю еще один цикл FOR-FILES:, прерывая его на найденном случайном числе.

Все работает отменно. Вот код:
Code: Select all
<%
0 VALUE BMP_COUNT
0 VALUE BMP_COUNT_RANDOM

: GET-FILE-COUNT ( a u -- )
    0 TO BMP_COUNT
    FOR-FILES
        BMP_COUNT 1+ TO BMP_COUNT   
    ;FOR-FILES
;

: GET-RANDOM-FILE ( a u -- a u )
    \ this word selects the random file
    \ from the specified folder
    BMP_COUNT RANDOM TO BMP_COUNT_RANDOM
    0 TO BMP_COUNT
    FOR-FILES
        BMP_COUNT BMP_COUNT_RANDOM =
        IF
            FOUND-FULLPATH
            FF-EXIT
        ELSE
        THEN
        BMP_COUNT 1+ TO BMP_COUNT
    ;FOR-FILES
;

: PICK-RANDOM-FILE ( a u -- a u )
    2DUP GET-FILE-COUNT
    GET-RANDOM-FILE
;

%>


Однако теперь хочется приделать к слову 'PICK-RANDOM-FILE' возможность рекурсии. Но как? Напрашивается примерно такая же реализация, как и в самом FOR-FILES: -

RECURSIVE PICK-RANDOM-FILE: "file"

Однако, "внутри" слова 'PICK-RANDOM-FILE' "крутятся" два цикла FOR-FILES: и каждому из них надо передать информацию о том, нужна рекурсия или нет... Как тут надо поступить? (Или я вообще пошел по неправильному пути и есть более простой способ реализовать выбор случайного файла?)
CU
VK
User avatar
VK
 
Posts: 680
Joined: Wed, 14 Jul 2004, 19:17

Postby Nicholas_Nemtsev » Fri, 01 Oct 2004, 10:30

Не совсем понимаю проблему. Дело в том, что признак recursive сбрасывается после завершения FOR-FILES. Т.е. одним махом передать этот признак двум циклам не получится. Надо запоминать это значение и восстанавливать перед каждым циклом, если нужно. Т.е. примерно так:
Code: Select all
USER SAVE-RECURSIVE
: GET-FILE-COUNT ( a u -- )
    0 TO BMP_COUNT
   \ тут не надо
    FOR-FILES
        BMP_COUNT 1+ TO BMP_COUNT   
    ;FOR-FILES
;

: GET-RANDOM-FILE ( a u -- a u )
    \ this word selects the random file
    \ from the specified folder
    BMP_COUNT RANDOM TO BMP_COUNT_RANDOM
    0 TO BMP_COUNT
    SAVE-RECURSIVE @ IF RECURSIVE THEN
    FOR-FILES
        BMP_COUNT BMP_COUNT_RANDOM =
        IF
            FOUND-FULLPATH
            FF-EXIT
        ELSE
        THEN
        BMP_COUNT 1+ TO BMP_COUNT
    ;FOR-FILES
;

: PICK-RANDOM-FILE ( a u -- a u )
    FF-RECURSIVE? @ SAVE-RECURSIVE !
    2DUP GET-FILE-COUNT
    GET-RANDOM-FILE
;
Nicholas Nemtsev
User avatar
Nicholas_Nemtsev
Site Admin
 
Posts: 857
Joined: Thu, 01 Jul 2004, 22:25
Location: Псков

Postby VK » Fri, 01 Oct 2004, 10:36

Ага, понятно. Спасибо!
CU
VK
User avatar
VK
 
Posts: 680
Joined: Wed, 14 Jul 2004, 19:17


Return to nnCron forum (Russian)

Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests