Предыдущая серия была тут - http://18delphi.blogspot.ru/2013/11/gui_5.html
Теперь хочется рассказать об устройстве TscriptCode и TscriptContext.
Для этого придётся вспомнить вот о чём:
Подсчёт ссылок и TRefcounted:
Абстрактные контейнеры:
Счастливы - "счастливые обладатели" ARC и generic'ов. Они могут сделать это по-другому. Но это (как говорил Фейнман (http://ru.wikipedia.org/wiki/%D0%A4%D0%B5%D0%B9%D0%BD%D0%BC%D0%B0%D0%BD,_%D0%A0%D0%B8%D1%87%D0%B0%D1%80%D0%B4_%D0%A4%D0%B8%D0%BB%D0%BB%D0%B8%D0%BF%D1%81)) - "читатели могут сделать это самостоятельно".
TscriptCode с одной стороны является наследником от TRefcounted, а с другой стороны - подмешивает в себя список ссылок на TscriptKeyWord.
Итак:
Про TscriptContext - нету уже сил писать. Отвлёкся я на RTTI. Время - позднее...
Продолжу про TscriptContext в следующей серии. В общем там банально всё конечно. "Стек значений". Но - не совсем...
Теперь хочется рассказать об устройстве TscriptCode и TscriptContext.
Для этого придётся вспомнить вот о чём:
Подсчёт ссылок и TRefcounted:
Абстрактные контейнеры:
Счастливы - "счастливые обладатели" ARC и generic'ов. Они могут сделать это по-другому. Но это (как говорил Фейнман (http://ru.wikipedia.org/wiki/%D0%A4%D0%B5%D0%B9%D0%BD%D0%BC%D0%B0%D0%BD,_%D0%A0%D0%B8%D1%87%D0%B0%D1%80%D0%B4_%D0%A4%D0%B8%D0%BB%D0%BB%D0%B8%D0%BF%D1%81)) - "читатели могут сделать это самостоятельно".
TscriptCode с одной стороны является наследником от TRefcounted, а с другой стороны - подмешивает в себя список ссылок на TscriptKeyWord.
Итак:
interface TscriptKeyWord = class(TRefcounted) procedure DoIt(aContext: TscriptContext); virtual; abstract; {* - собственно код выполнения слова. } end;//TscriptKeyWord _ItemType_ = TscriptKeyWord; _List_Parent_ = TRefcounted; {$Include _List_.imp.pas} TscriptCode = class(_List_) procedure CompileInteger(aValue: Integer); procedure CompileString(const aValue: String); procedure CompileKeyWord(aValue: TscriptKeyWord); procedure Run; // - выполняет скомпилированный код procedure RunInContext(aContext: TscriptContext); // - выполняет скомпилированный код в указанном контексте ... end;//TscriptCode implementation function IsSame(const A: _ItemType_; const B: _ItemType_): Boolean; begin Result := (A = B); end;//IsSame procedure FreeItem(var thePlace: _ItemType_); begin FreeAndNil(thePlace); end;//FreeItem procedure FillItem(var thePlace: _ItemType_; const aFrom: _ItemType_); begin thePlace := aFrom.Use; end;//FillItem {$Include List.imp.pas} procedure TscriptCode.CompileKeyWord(aValue: TscriptKeyWord); begin Self.Add(aValue); end; procedure TscriptCode.Run; var l_Context: TscriptContext; begin l_Context := TscriptContext.Create; try RunInContext(l_Context); finally FreeAndNil(l_Context); end;//try..finally end; procedure TscriptCode.RunInContext(aContext: TscriptContext); var l_Index : Integer; begin for l_Index := 0 to Pred(Self.Count) do Self.Items[l_Index].DoIt(aContext); // - выполняем каждое компилированное слово end; type TkwInteger = class(TscriptKeyWord) private f_Value : Integer; protected procedure DoIt(aContext: TscriptContext); override; public constructor Create(aValue : Integer); end;//TkwInteger procedure TkwInteger.DoIt(aContext: TscriptContext); begin aContext.PushInteger(f_Value); end; constructor TkwIntegerCreate(aValue : Integer); begin inherited Create; f_Value := aValue; end; procedure TscriptCode.CompileInteger(aValue: Integer); var l_Integer : TkwInteger; begin l_Integer := TkwInteger.Create(aValue); try CompileKeyWord(l_Integer); finally FreeAndNil(l_Integer); end;//try..finally end; type TkwString = class(TscriptKeyWord) private f_Value : String; protected procedure DoIt(aContext: TscriptContext); override; public constructor Create(const aValue : String); end;//TkwString procedure TkwString.DoIt(aContext: TscriptContext); begin aContext.PushString(f_Value); end; constructor TkwString.Create(const aValue : String); begin inherited Create; f_Value := aValue; end; procedure TscriptCode.CompileString(const aValue: String); var l_String : TkwString; begin l_String := TkwString.Create(aValue); try CompileKeyWord(l_String); finally FreeAndNil(l_String); end;//try..finally end;
Про TscriptContext - нету уже сил писать. Отвлёкся я на RTTI. Время - позднее...
Продолжу про TscriptContext в следующей серии. В общем там банально всё конечно. "Стек значений". Но - не совсем...
Комментариев нет:
Отправить комментарий