Поиск дочернего окна

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

Re: Поиск дочернего окна

Postby Burunduk » Wed, 20 Nov 2013, 10:41

Такая конструкция тоже не работает

Code: Select all
: Тест ( Sec Min Hour ) S" %N>S%:%N>S%:%N>S%" EVAL-SUBST ;
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby VoidVolker » Wed, 20 Nov 2013, 23:34

Обнаружил, что строк 3 вида. Но не понятно, где они живут, сколько времни живут, как удаляются(есть ли сборщик мусора).

Скомпилированные в код строки живут вперемешку с кодом в кодофайле. При сложении, новым строкам выдается память из хипа, и там же они остаются до момента уничтожения потока. Сборщика мусора нет.
Code: Select all
S>D <# # # #> ( Sec Min Ha Hu )
  2SWAP           ( Ha Hu Sec Min )
  S>D <# # # #> ( Ha Hu Sec Ma Mu )
  ROT               ( Ha Hu Ma Mu Sec )
  S>D <# # # #> ( Ha Hu Ma Mu Sa Su )

А дело в том, что буфер-то для преобразования используется всего лишь один(в каждой задаче свой). Тут же в него три раза подряд записывается строка.
S" Первая" S" Вторая" S+
и что в итоге получилось - 1 и 2 строка еще живы в памяти или есть только третья строка?

Получился результат на стеке в виде адреса и длины строки, при этом для новой строки был выделен новый буфер. Две предыдущие строки остались без изменения лежать в кодофайле — если это был режим компиляции. И были затерты во входном буфере после перехода интерпретатора на следующую строку — если был режим выполнения.
Можно ли вместо выделения массива и PLACE просто запомнить a1, u1, a2, u2, в четырёх обычных переменных?
Что бы потом, например, склеить строки в обратном порядке?

Да. Можно даже делать строковые константы:
Code: Select all
: StringConst S" any text" ;


Code: Select all
: Тест ( Sec Min Hour ) S" %N>S%:%N>S%:%N>S%" EVAL-SUBST ;

Code: Select all
\ Sec Min Hour
N>S \ Sec Min a u
N>S \ Sec Min a a u
N>S \ Sec Min a a a u

a — адрес строки в буфере преобразования чисел
u — длина этой строки

(Так, я обычно добрый, но могу внезапно начать карать за код без тега code).
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 04:31

VoidVolker wrote:А дело в том, что буфер-то для преобразования используется всего лишь один(в каждой задаче свой). Тут же в него три раза подряд записывается строка.


Получается, что конструкция S>D <# # # #> использует один статический буфер(какой-то конечной длины), а слово S" каждый раз выделяет новую память? Независимо от режима выполнения кода?

Следовательно:

1. Без использования CREATE , ALLOT и PLACE не обойтись даже в таком простом случае. :(
2. Если буфер, который использует S>D, используют и другие подобные слова, то будут побочные эффекты.
Поиск которых будет затруднён без отладчика. :cry:

Burunduk wrote:Можно ли вместо выделения массива и PLACE просто запомнить a1, u1, a2, u2, в четырёх обычных переменных?Что бы потом, например, склеить строки в обратном порядке?

VoidVolker wrote:Да. Можно даже делать строковые константы:


Но в случае конструкции S>D <# # # #> мне поможет только PLACE ?

Использование конструкции
Code: Select all
: StringConst S" any text" ;


похоже может привести к большому расходу памяти, а в бесконечном цикле вообще приведёт к полному исчерпанию памяти?!!

А динамическое выделение памяти вообще недоступно для программирования задач?
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby AlikasS » Thu, 21 Nov 2013, 05:24

Burunduk wrote:А динамическое выделение памяти вообще недоступно для программирования задач?

Для работы с "большими" объемами данных использовать ALLOCATE, FREE, RESIZE.
если не найдешь примеров, пиши
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 05:55

Наконец-то получилось преобразовать секунды в строку:

Code: Select all
#( Отладка
NoActive
RunOnce
NoDel
Time: 11 12 20 11 * 2013


: СТРОКА-ВРЕМЕНИ-В-СЕКУНДЫ SH:M:S>Sec ;

CREATE MinBuf 2 ALLOT
CREATE SecBuf 2 ALLOT

: СЕКУНДЫ-В-СТРОКА-ВРЕМЕНИ ( Sec  ) 60 /MOD 60 /MOD ( Sec Min Hour )
  ROT           ( Min Hour Sec )
  ROT           ( Hour Sec Min )
  S>D <# # # #> ( Hour Sec Ma Mu )
  MinBuf PLACE  ( Hour Sec )
  S>D <# # # #> ( Hour Sa Su )
  SecBuf PLACE  ( Hour)
  S>D <# # # #> ( Ha Hu )
  S" :" S+      ( a u )       \ накапливаем результирующую строку HH:
  MinBuf COUNT  ( a u Ma Mu)
  S+ S" :" S+   ( a u )       \ накапливаем результирующую строку HH:MM:
  SecBuf COUNT  ( a u Sa Su )
  S+            ( a u )
;

Action:

S" 12:45:59" СТРОКА-ВРЕМЕНИ-В-СЕКУНДЫ
 СЕКУНДЫ-В-СТРОКА-ВРЕМЕНИ
 MsgBox
 
)#


Необходимость использовать глобальные переменные для буферов строк чревата ошибками в сложных задачах. Решить эту проблему можно было бы двумя способами:

1. Использовать локальные переменные. Если такие есть в Форте
2. Удалять имена переменных(и даже слов) из словаря после компиляции. Такую фишку я видел в Фортоподобной системе, разработанной в МГУ в 80-е годы.
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 06:01

AlikasS wrote:
Burunduk wrote:А динамическое выделение памяти вообще недоступно для программирования задач?

Для работы с "большими" объемами данных использовать ALLOCATE, FREE, RESIZE.
если не найдешь примеров, пиши


Спасибо! Пока-бы с "маленькими" строками разобраться. :D
А сколько памяти доступно на задачу? Кодофайл 16 разрядный?

Вот для полноты понимания почитать бы что-нибудь про EVAL-SUBST
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 07:30

Переделал процедуру что бы обойтись без глобальных буферов

Code: Select all
: СЕКУНДЫ-В-СТРОКА-ВРЕМЕНИ2 ( Sec  ) 60 /MOD 60 /MOD ( Sec Min Hour )
  ROT           ( Min Hour Sec )
  ROT           ( Hour Sec Min )
  SWAP          ( Hour Min Sec )
  2>R           ( Hour )      \ Используем стек возвратов для Sec и Min
  S>D <# # # #> ( Ha Hu )
  S" :" S+      ( a u )       \ накапливаем результирующую строку HH:
  R>            ( a u Min )   \ Достаём Min из стека возвратов
  S>D <# # # #> ( a u Ma Mu )
  S+ S" :" S+   ( a u )       \ накапливаем результирующую строку HH:MM:
  R>            ( a u Sec )   \ Достаём Sec из стека возвратов
  S>D <# # # #> ( a u Sa Su )
  S+            ( a u )
;


Получается, что слово S+ каждый раз хоронит какую-то часть памяти? Таким образом, создаются утечки памяти!!! :(
А если задача будет работать непрерывно?
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby AlikasS » Thu, 21 Nov 2013, 09:43

Code: Select all
: СЕКУНДЫ-В-СТРОКА-ВРЕМЕНИ2 ( Sec  ) 60 /MOD 60 /MOD ( Sec Min Hour )
S" %0 esPICK%:%1 esPICK%:%2 esPICK%" EVAL-SUBST
;
и еще несколько вариантов :-)
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 10:59

AlikasS wrote:
Code: Select all
: СЕКУНДЫ-В-СТРОКА-ВРЕМЕНИ2 ( Sec  ) 60 /MOD 60 /MOD ( Sec Min Hour )
S" %0 esPICK%:%1 esPICK%:%2 esPICK%" EVAL-SUBST
;
и еще несколько вариантов :-)


Но решил проверить на "закладки"

Выяснил, что:

1. В Вашем коде всё хорошо. Sec Min Hour удаляются из стека.

2. Параметры для esPICK можно задавать в любом порядке. Стек не изменяется до полного завершения работы EVAL-SUBST. И это замечательно! :D
Если вдруг надо сделать строку SS:MM:HH , то ниже приведённый код тоже работает нормально
Code: Select all
S" %2 esPICK%:%1 esPICK%:%0 esPICK%" EVAL-SUBST

Стек очищается.

3. Но если используются не все параметры, то за стеком надо следить!
Код вида
Code: Select all
S"Минута %1 esPICK%" EVAL-SUBST

оставит в стеке только Sec

Вывод - Конструкция вида
Code: Select all
S" %0 esPICK%:%1 esPICK%:%2 esPICK%   бла-бла-бла   %n esPICK%" EVAL-SUBST

удаляет из стека n элементов.
Включая и те, что не выбираются из стека словом esPICK
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 11:19

AlikasS wrote:и еще несколько вариантов


Что означают фигурные скобки?
Изучая работу строк нашёл на форуме такой код

Code: Select all
: NUM>BLS   \ ( num len -- a u ) \ Конвертировать число num в строку длиной len, пустое место заполнить пробелами
  { \ f -- }  \ Флаг для вставки знака или пробела
  0 MAX                       \ Фильтруем отрицательные числа
  DUP IF                      \ Фильтруем ноль
    OVER 0 <
    IF OVER ELSE 0 THEN TO f    \ Включаем флаг, если число отрицательное
    >R ABS S>D <#
      R> 0 DO                   \ Цикл по длине строки
        OVER IF                   \ Есть что преобразовывать?
          #                             \ Преобразовываем очередной разярд
        ELSE                      \ Все число преобразовано - вставляем знак или пробел и оставшиеся пробелы
          f IF                      \ Число отрицательное?
            f SIGN 0 TO f             \ Вставляем знак числа и выключаем флаг
          ELSE
            BL HOLD                 \ Вставляем пробелы
          THEN
        THEN
      LOOP
    #>
  ELSE                          \ Строка нулевой длины - значит пустая
    2DROP S" "
  THEN
;


{ \ f -- } \ Флаг для вставки знака или пробела Это локальная переменная так задаётся?
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby AlikasS » Thu, 21 Nov 2013, 11:43

да.
и признаться, мой вариант не сильно удачный, надо нули дополнять
если число меньше 10
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 11:55

AlikasS wrote:да.


Это на какой вопрос?

У меня вопросов много.
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby Burunduk » Thu, 21 Nov 2013, 16:34

Burunduk wrote:{ \ f -- } \ Флаг для вставки знака или пробела Это локальная переменная так задаётся?


Эксперимент в консоли показал, что это действительно локальная переменная.

Code: Select all
: test { \ LocalX  -- } 12 TO LocalX LocalX LocalX * . ;


test выводит 144
Непонятен смысл вот этих слов { \ LocalX -- }
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

Re: Поиск дочернего окна

Postby AlikasS » Fri, 22 Nov 2013, 01:19

локальные переменные
Spoiler: show
Объявление временных переменных, видимых только внутри
текущего слова и ограниченных временем вызова данного
слова выполняется с помощью слова "{". Внутри определения
слова используется конструкция, подобная стековой нотации Форта
{ список_инициализированных_локалов \ сп.неиниц.локалов -- что угодно }
Например:

{ a b c d \ e f -- i j }

Или { a b c d \ e f[ EVALUATE_выражение ] -- i j }
Это значит что для переменной f[ будет выделен на стеке возвратов участок
памяти длиной n байт. Использование переменной f[ даст адрес начала этого
участка. \В стиле MPE\

Или { a b c d \ e [ 12 ] f -- i j }
Это значит что для переменной f будет выделен на стеке возвратов участок
памяти длиной 12 байт. Использование переменной f даст адрес начала этого
участка.

Часть "\ сп.неиниц.локалов" может отсутствовать, например:

{ item1 item2 -- }

Это заставляет СП-Форт автоматически выделять место в
стеке возвратов для этих переменных в момент вызова слова
и автоматически освобождать место при выходе из него.

Обращение к таким локальным переменным - как к VALUE-переменным
по имени. Если нужен адрес переменной, то используется "^ имя"
или "AT имя".


Вместо \ можно использовать |
Вместо -> можно использовать TO

Примеры:

: TEST { a b c d \ e f -- } a . b . c . b c + -> e e . f . ^ a @ . ;
Ok
1 2 3 4 TEST
1 2 3 5 0 1 Ok

: TEST { a b -- } a . b . CR 5 0 DO I . a . b . CR LOOP ;
Ok
12 34 TEST
12 34
0 12 34
1 12 34
2 12 34
3 12 34
4 12 34
Ok

: TEST { a b } a . b . ;
Ok
1 2 TEST
1 2 Ok

: TEST { a b \ c } a . b . c . ;
Ok
1 2 TEST
1 2 0 Ok

: TEST { a b -- } a . b . ;
Ok
1 2 TEST
1 2 Ok

: TEST { a b \ c -- d } a . b . c . ;
Ok
1 2 TEST
1 2 0 Ok

: TEST { \ a b } a . b . 1 -> a 2 -> b a . b . ;
Ok
TEST
0 0 1 2 Ok

Имена локальных переменных существуют в динамическом
временном словаре только в момент компиляции слова, а
после этого вычищаются и более недоступны.

Использовать конструкцию "{ ... }" внутри одного определения можно
только один раз
уже не помню от куда цитата, но общий принцип работы понять можно
User avatar
AlikasS
 
Posts: 1434
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Поиск дочернего окна

Postby Burunduk » Fri, 22 Nov 2013, 04:23

AlikasS wrote:локальные переменные


Спасибо! :D
Burunduk
 
Posts: 73
Joined: Thu, 03 Oct 2013, 06:57

PreviousNext

Return to nnCron forum (Russian)

Who is online

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

cron