пятница, 8 ноября 2013 г.

GUI-тестировании "по-русски". Как всё это устроено №3. Как устроена работа с переменными, оператор равно и что такое WordWorker'ы.

Предыдущая серия была тут - http://18delphi.blogspot.com/2013/11/gui-2.html

Теперь хочется рассказать вот о чём.

Как устроена работа с переменными, оператор равно и что такое WordWorker'ы.

Рассмотрим пример:

VAR I
1 =: I

Что тут написано?
VAR I - определяет переменную с именем I в текущем контексте видимости (о контекстах позже поговорим отдельно).
1 - кладёт на стек значений целое число 1.
=: I - выбирает значение со стека и кладёт его в переменную I.

Как всё это устроено?

Сейчас попробую рассказать.

До сих пор нам встречались слова-наследники от TscriptKeyWord, которые умели выбирать значения из стека значений (TscriptContext) и работать с ними. Также они умели класть значения на стек. Пример тут - http://18delphi.blogspot.ru/2013/11/gui.html

Теперь хочется затронуть слова, которые не только умеют работать со значениями со стека ("параметры слева"), но и со словами, которые следуют в коде за ними ("параметры справа").

Одним из таких слов и является оператор равно - =:

Семантически он похож на оператор равно Паскаля, только "перевёрнут в другую сторону". Это "наследие" обратной польской записи, но это, поверьте мне, не так уж и важно.

Слова, которые умеют работать с "параметрами справа" я исторически называю WordWorker'ами.

И соответственно - наследуются они от класса TscriptWordWorker.

Разберём устройство этого класса:
interface

type
  TscriptWordWorker = class(TscriptKeyWord)
   protected
    procedure WorkTheWord(aWordToTheRight : TscriptKeyWord; aContext: TscriptContext); virtual; abstract;
  end;//TscriptWordWorker

Пока в дальнейшие детали этого слова вдаваться не будем.

Также есть ещё наследник от него TscriptVarWorker - слово, которое обрабатывает переменную.
Выглядит оно вот так:

interface

type
  IscriptVar = interface
   ['{39369047-E783-4A4B-9657-6C2450D737C3}']
   procedure PopFrom(aContext: TscriptContext);
   ...
  end;//IscriptVar

  TscriptVarWorker = class(TscriptWordWorker)
   protected
    procedure WorkTheWord(aWordToTheRight : TscriptKeyWord; aContext: TscriptContext); override;
    procedure WorkTheVar(aVarToTheRight : IscriptVar; aContext: TscriptContext); virtual; abstract;
  end;//TscriptVarWorker 

implementation

procedure TscriptVarWorker.WorkTheWord(aWordToTheRight : TscriptKeyWord; aContext: TscriptContext)
var
 l_Var : IscriptVar;
begin
 if Supports(aWordToTheRight, l_Var) then
  WorkTheVar(l_Var, aContext)
 else
  Assert(false);
end;

И тогда мы можем написать:

interface

type
  TkwPopToVar = class(TscriptVarWorker)
   protected
    procedure WorkTheVar(aVarToTheRight : IscriptVar; aContext: TscriptContext); override;
  end;//TkwPopToVar

implementation

procedure TkwPopToVar.WorkTheVar(aVarToTheRight : IscriptVar; aContext: TscriptContext);
begin
 aVarToTheRight.PopFrom(aContext);
end;

initialization
 ScriptEngine.RegisterKeyWord(TkwPopToVar, '=:');

Пока - всё.

Дальнейшие детали опишу в следующих сериях.

Комментариев нет:

Отправить комментарий