суббота, 24 июня 2017 г.

Ещё про функторы

PROCEDURE EnumWindowChildren
  nWnd IN aWindow
  FUNCTOR IN aLambda
 
 aWindow aLambda DO
 // - вызываем aLambda на aWindow
 aWindow .EnumChildren ( aLambda call.me )
 // - вызываем себя рекурсивно
; // EnumWindowChildren

FunctorToIterator Desktop EnumWindowChildren .for .Out
// - перебираем все окна от Desktop рекурсивно

А теперь с анонимной функцией:

FunctorToIterator Desktop (
  nWnd IN aWindow
  FUNCTOR IN aLambda
 
 aWindow aLambda DO
 // - вызываем aLambda на aWindow
 aWindow .EnumChildren ( aLambda call.me )
 // - вызываем себя рекурсивно
) .for .Out
// - перебираем все окна от Desktop рекурсивно

Про функторы и итераторы. Простой пример

PROCEDURE .To
  IN aLowBound
  IN aHighBound
  FUNCTOR IN aLambda
 if ( aLowBound <= aHighBound ) then
 // - граничное условие
 begin
  aLowBound aLambda DO // - вызываем aLambda на aLowBound 
  Inc aLowBound // - увеличиваем aLowBound 
  aLowBound aHighBound aLambda call.me
  // - вызываем себя рекурсивно  
 end // ( aLowBound <= aHighBound )
; // .To

FunctorToIterator ( 1 10 ) .To .for .Out 
// - печатает числа от 1 до 10

FunctorToIterator ( 1 10 ) .To 
.filter ( <> 2 ) 
.for .Out 
// - печатает числа от 1 до 10, исключая 2

FunctorToIterator ( 1 10 ) .To 
.filter ( <> 2 ) 
.map ( 1 + ) 
.for .Out 
// - печатает числа от 2 до 11, исключая 3

То же самое, но с параметром справа:
PROCEDURE To
  IN aLowBound
  FUNCTOR IN aLambda
  Right IN aHighBound
 if ( aLowBound <= aHighBound ) then
 // - граничное условие
 begin
  aLowBound aLambda DO // - вызываем aLambda на aLowBound 
  Inc aLowBound // - увеличиваем aLowBound 
  aLowBound aLambda call.me aHighBound
  // - вызываем себя рекурсивно  
 end // ( aLowBound <= aHighBound )
; // To

FunctorToIterator 1 To 10 .for .Out 
// - печатает числа от 1 до 10

FunctorToIterator 1 To 10
.filter ( <> 2 ) 
.for .Out 
// - печатает числа от 1 до 10, исключая 2

FunctorToIterator 1 To 10
.filter ( <> 2 ) 
.map ( 1 + ) 
.for .Out 
// - печатает числа от 2 до 11, исключая 3

Немножко косметики:

ARRAY FUNCTION To
  IN aLowBound
  Right IN aHighBound

 PROCEDURE InnerTo
   IN aLowBound
   FUNCTOR IN aLambda
   Right IN aHighBound
  if ( aLowBound <= aHighBound ) then
  // - граничное условие
  begin
   aLowBound aLambda DO // - вызываем aLambda на aLowBound 
   Inc aLowBound // - увеличиваем aLowBound 
   aLowBound aLambda call.me aHighBound
   // - вызываем себя рекурсивно  
  end // ( aLowBound <= aHighBound )
 ; // InnerTo

 FunctorToIterator aLowBound InnerTo aHighBound
 >>> Result
; // To 

1 To 10 .for .Out 
// - печатает числа от 1 до 10

1 To 10
.filter ( <> 2 ) 
.for .Out 
// - печатает числа от 1 до 10, исключая 2

1 To 10
.filter ( <> 2 ) 
.map ( 1 + ) 
.for .Out 
// - печатает числа от 2 до 11, исключая 3

Ещё косметики:
ARRAY FUNCTION To
  IN aLowBound
  Right IN aHighBound

 PROCEDURE InnerTo
   IN aLowBound
   FUNCTOR IN aLambda
   Right IN aHighBound
  if ( aLowBound <= aHighBound ) then
  // - граничное условие
  begin
   aLowBound aLambda DO // - вызываем aLambda на aLowBound 
   Inc aLowBound // - увеличиваем aLowBound 
   aLowBound aLambda call.me aHighBound
   // - вызываем себя рекурсивно  
  end // ( aLowBound <= aHighBound )
 ; // InnerTo

 FunctorToIterator aLowBound InnerTo aHighBound
 >>> Result
; // To 

PROCEDURE for
  ARRAY Right anArray
  FUNCTOR Right aLambda
 anArray .for> aLambda  
; // for

for ( 1 To 10 ) 
.Out 
// - печатает числа от 1 до 10

for
( 1 To 10
.filter ( <> 2 ) 
)
.Out 
// - печатает числа от 1 до 10, исключая 2

for 
( 1 To 10
.filter ( <> 2 ) 
.map ( 1 + ) 
)
.Out 
// - печатает числа от 2 до 11, исключая 3


Ещё про скипты


Также это в некотором смысле - аналог json.

Можно написать:

Elem A
 Elem B
 ; // B
 Elem C
 ; // C
; // A

PROCEDURE .Print
  IN anElement
 anElement .Stereotype .Out // - печатаем стереотип элемента
 anElement .Name .Out // - печатаем имя элемента
 anElement .MembersIterator .for call.me
 // - итерируем вложенные элементы и вызываем себя рекурсивно
; // .Print

@ A .Print

Будет напечатано:

Elem
A
Elem
B
Elem
C

А можно написать так:

STRING VAR S
S :=
'
Elem A
 Elem B
 ;
 Elem C
 ;
;
' 
>>> S // - кладём "код в строку"
// Да - строки в кавычках могут содержать в себе и переводы строк тоже 

S
.CompileStringAndDo .Print
// - компилируем строку и вызываем для построенного кода функцию .Print

Результат будет тот же.

А можно написать так:

: .ToStack
  IN anElement
 anElement // - это кладём на стек
 anElement .MembersIterator .for call.me
 // - итерируем вложенные элементы и вызываем себя рекурсивно
; // .ToStack

STRING VAR S
S :=
'
Elem A
 Elem B
 ;
 Elem C
 ;
;
' 
>>> S // - кладём "код в строку"
// Да - строки в кавычках могут содержать в себе и переводы строк тоже 

ARRAY VAR A
[ // - открываем массив
S .CompileStringAndDo .ToStack
] // - закрываем массив
>>> A // - кладём массив в переменную A

A .for .Out // - печатаем массив полностью
A .filter ( .Name <> 'B' ) .for .Out // - печатаем из массива элементы имя которых НЕ РАВНО B

Ну и всякие подобные штучки.

А можно без копирования:

PROCEDURE .Unfold
  IN anElement
  FUNCTOR IN aLambda
 anElement aLambda DO // - вызываем функтор aLambda на элементе anElement
 anElement .MembersIterator .for ( aLambda call.me )
 // - итерируем вложенные элементы и вызываем себя рекурсивно
; // .Unfold

STRING VAR S
S :=
'
Elem A
 Elem B
 ;
 Elem C
 ;
;
' 
>>> S // - кладём "код в строку"
// Да - строки в кавычках могут содержать в себе и переводы строк тоже 

VAR A
S .CompileStringAndDo ( >>> A ) // - компилируем код из строки S и кладём результат в переменную A

FunctorToIterator 
// - преобразование функтора в итератор
A 
// - параметр функтора
.Unfold 
// - сам функтор
.for .Out // - печатаем массив полностью

FunctorToIterator A .Unfold .filter ( .Name <> 'B' ) .for .Out // - печатаем из массива элементы имя которых НЕ РАВНО B

четверг, 22 июня 2017 г.

ToDo

Try..finally..end заменить на:

Try_finally ( a ) ( b )
Try_except ( a ) ( b )

И пихать begin в поток токенов.

Чтобы try a finally b end разворачивалось в:

Try_finally begin a end begin b end

Ну и try a except b end соответственно:

Try_except begin a end begin b end

Убрать FirstHalf и DualCompilingWord.

ToDo

Для слов сделать экземпляры, а не классы.

С event'ами.