unit MethodAddrDemoUParser;
interface
uses Dialogs, Classes, SysUtils,
Variants, StrUtils, Grids,
DateUtils, StdCtrls ;
type
PParsedLine = ^TParsedLine;
TParsedLine = Record
lnMethodName: String;
lnArguments: Variant;
lnIsValide: Boolean;
End;
TPointedRec = Record
anInteger: Integer;
aSender: TObject;
End;
PPointedRec = ^TPointedRec;
PProcMethod = ^TProcMethod;
TProcMethod = procedure(V: Variant) of object;
PFuncMethod = ^TFuncMethod;
TFuncMethod = function (V: Variant): variant of object;
TLittleParser = Class
Private
function ParseArgs (aLine: String): Variant;
public
procedure ExecProcByName(aMethodName: string; _args: Variant);
Function ExecFuncByName(aMethodName: string; _args: Variant): Variant;
Function ShowDuration (Const duration: Double; intro: String): Variant;
function GetParsedLine (aLine: String): TParsedLine;
Published
constructor Create;
destructor Destroy; override;
procedure LineSummary (Const value: Variant);
procedure TotalAccess (Const value: Variant);
procedure AverageAccess (Const value: Variant);
procedure Duration (Const value: Variant);
procedure TotalDuration (Const value: Variant);
procedure AverageDuration (Const value: Variant);
procedure UserShowMessage (Const value: Variant);
function AddIntegers (Const value: Variant): Variant;
function AddStrings (Const value: Variant): Variant;
function HandlePointerValues(Const value: Variant): Variant;
end;
implementation
constructor TLittleParser.Create;
Begin inherited; End;
destructor TLittleParser.Destroy;
Begin Inherited; End;
function TLittleParser.ParseArgs(aLine: String): Variant;
var i, cutter,
argsCount: integer;
Begin
If (aLine = '') Then
Begin
result := Null;
exit;
End Else If (aLine[Length(aLine)] <> ')') Then
Begin
result := 'Missing final parenthesis...' ;
Exit;
End;
If aLine[1] = '(' Then aLine := RightStr(aLine,Length(aLine)-1);
aLine := LeftStr(aLine,Length(aLine)-1);
argsCount := 1;
For i := 1 To Length(aLine) -1 Do
If aLine[i] = ','
Then inc(argsCount);
If ArgsCount > 1 Then
Begin
result := VarArrayCreate([0,argsCount-1],varVariant);
For i := 0 To ArgsCount -2 Do
Begin
cutter := Pos(',',aLine)-1;
result[i] := LeftStr(aLine, cutter);
aLine := RightStr(aLine, Length(aLine) - (cutter +1) );
End;
result[argsCount -1] := aLine;
End Else result := aLine;
End;
function TLittleParser.GetParsedLine(aLine: String): TParsedLine;
Begin
TRY
result.lnIsValide := Not( Pos ('//',aLine) = 1 );
If result.lnIsValide Then
Begin
result.lnMethodName := LeftStr(aLine, Pos('(',aLine)-1);
result.lnArguments := Self.ParseArgs( RightStr(aLine,
Length(aLine) - Length(result.lnMethodName) ));
result.lnIsValide := Length(result.lnMethodName) > 0;
End;
EXCEPT
result.lnIsValide := False;
END;
End;
procedure TLittleParser.ExecProcByName(aMethodName: string; _args: Variant);
var
PAddr: PProcMethod;
M: TMethod;
begin
TRY
PAddr := MethodAddress(aMethodName);
If PAddr <> Nil then
Begin
M.Code := PAddr;
M.Data := Self;
TProcMethod(M)(_args);
End;
EXCEPT;END;
end;
function TLittleParser.ExecFuncByName(aMethodName: string; _args: Variant): Variant;
var PAddr: PFuncMethod;
M: TMethod;
begin
result := '';
TRY
PAddr := MethodAddress(aMethodName);
If PAddr <> Nil then
Begin
M.Code := PAddr;
M.Data := Self;
result := TFuncMethod(M)(_args);
End Else result := Null;
EXCEPT; END;
end;
function TLittleParser.HandlePointerValues(Const value: Variant): Variant;
var v: Variant;
i: Integer;
s: String;
Begin
i := StrToInt( varToStr( value ));
If PPointedRec(i).aSender is TButton
Then s := TButton(PPointedRec(i).aSender).Caption
Else s := '(Sender is not a button)';
v := 'This function has been called '
+ VarToStr( PPointedRec(i).anInteger ) + ' times.'
+ #13#10
+ ' The caller is this time : '
+ s;
result := v;
End;
function TLittleParser.AddIntegers(Const value: Variant): Variant;
var i: Integer;
v, vt, min, max: Variant;
Begin
v := 0;
If Not( VarIsArray( value )) then
Begin
result := 'Invalid arg( ' + value + ' ) : array wanted.';
exit;
End;
TRY
min := '0';
max := '9';
For i := 0 To VarArrayHighBound(value, 1) Do
TRY
If ( VarInRange( value[i] , min, max )) Then
Begin
vt := VarAsType(value[i], varInteger);
v := v + vt;
End;
EXCEPT;END;
result := v;
EXCEPT
result := -1;
END;
End;
function TLittleParser.AddStrings(Const value: Variant): Variant;
var i: Integer;
v: Variant;
Begin
v := '';
If Not( VarIsArray( value )) then
Begin
result := value;
exit;
End;
TRY
For i := 0 To VarArrayHighBound(value, 1) Do
v := v + value[i];
result := v;
EXCEPT
result := 'Failed to Concat';
END;
End;
procedure TLittleParser.LineSummary(Const value: Variant);
var v: Variant;
i, aRow: Integer;
Begin
If ( VarArrayHighBound( value, 1 ) < 2 ) then exit;
i := varAsType(value[0],varInteger);
aRow := varAsType(value[2],varInteger);
v := varArrayCreate([0,3],varOleStr);
v[0] := 'The event "' + TStringGrid(i).Cells[0,aRow] + '"';
v[1] := 'started : ' + TStringGrid(i).Cells[1,aRow];
v[2] := 'ended : ' + TStringGrid(i).Cells[2,aRow];
v[3] := 'and occured ' + TStringGrid(i).Cells[3,aRow] + ' times in this period.';
Self.UserShowMessage(v);
End;
procedure TLittleParser.TotalAccess(Const value: Variant);
var i,j,k, aCol: Integer;
Begin
If ( VarArrayHighBound( value, 1 ) < 2 ) then exit;
i := varAsType(value[0],varInteger);
aCol := varAsType(value[1],varInteger);
k := 0;
For j := 1 To TStringGrid(i).RowCount -1 Do
k := k + StrToInt( TStringGrid(i).Cells[aCol,j] );
Self.UserShowMessage('Total number of access observed : ' + IntToStr(k));
End;
procedure TLittleParser.AverageAccess(Const value: Variant);
var i, j, k, aCol: Integer;
Begin
If ( VarArrayHighBound( value, 1 ) < 2 ) then exit;
i := varAsType(value[0],varInteger);
aCol := varAsType(value[1],varInteger);
k := 0;
For j := 1 To TStringGrid(i).RowCount -1 Do
k := k + StrToInt( TStringGrid(i).Cells[aCol,j] );
Self.UserShowMessage('Average number of access observed : '
+ FloatToStr(k / TStringGrid(i).RowCount-1 ));
End;
function TLittleParser.ShowDuration(Const duration: Double; intro: String): Variant;
var hh, mn, ss, ms: Word;
Begin
DecodeTime(duration, hh, mn, ss, ms);
Self.UserShowMessage( intro
+ IntToStr(hh) + ':'
+ IntToStr(mn) + ':'
+ IntToStr(ss) );
End;
procedure TLittleParser.Duration(Const value: Variant);
var i, aRow: Integer;
evStart, evStop : TDateTime;
duration : Double;
Begin
If ( VarArrayHighBound( value, 1 ) < 2 ) then exit;
i := varAsType(value[0],varInteger);
aRow := varAsType(value[2],varInteger);
evStart := StrToDateTime( TStringGrid(i).Cells[1,aRow] );
evStop := StrToDateTime( TStringGrid(i).Cells[2,aRow] );
duration := DaySpan(evStop, evStart) ;
Self.ShowDuration( duration, 'The event '
+ TStringGrid(i).Cells[0,aRow]
+ ' lasted (h:m:s): ' )
End;
procedure TLittleParser.TotalDuration(Const value: Variant);
var i,j: Integer;
evStart, evStop : TDateTime;
d : Array of Double;
Begin
If ( VarArrayHighBound( value, 1 ) < 2 ) then exit;
i := varAsType(value[0],varInteger);
SetLength(d, TStringGrid(i).RowCount);
For j := 1 To TStringGrid(i).RowCount -1 Do
Begin
evStart := StrToDateTime( TStringGrid(i).Cells[1,j] );
evStop := StrToDateTime( TStringGrid(i).Cells[2,j] );
d[j] := DaySpan(evStop, evStart) ;
End;
For j := 1 To Length(d)-1 Do
d[0] := d[0] + d[j];
Self.ShowDuration( d[0], 'The whole observations lasted in total (h:m:s): ' )
End;
procedure TLittleParser.AverageDuration(Const value: Variant);
var i,j: Integer;
evStart, evStop : TDateTime;
d : Array of Double;
Begin
If ( VarArrayHighBound( value, 1 ) < 2 ) then exit;
i := varAsType(value[0],varInteger);
SetLength(d, TStringGrid(i).RowCount);
For j := 1 To TStringGrid(i).RowCount -1 Do
Begin
evStart := StrToDateTime( TStringGrid(i).Cells[1,j] );
evStop := StrToDateTime( TStringGrid(i).Cells[2,j] );
d[j] := DaySpan(evStop, evStart) ;
End;
For j := 1 To Length(d)-1 Do
d[0] := d[0] + d[j];
d[0] := d[0] / (TStringGrid(i).RowCount-1);
Self.ShowDuration( d[0], 'These events lasts on average (h:m:s): ' )
End;
procedure TLittleParser.UserShowMessage(Const value: Variant);
var i: integer;
s: String;
begin
s := '';
If varIsNull(value) Then s := 'No message to show...'
Else If ( VarIsArray( value ) ) then
Begin
For i := 0 To VarArrayHighBound(value,1) Do
s := s + value[i] + #13#10;
End Else s := Value;
MessageDlg(s, mtInformation, [mbOK], 0);
end;
end.
|