TDAExpressionEvaluator
Overview
The TDAExpressionEvaluator class allows you to use Pascal Script expressions in a script-like approach.
For example: The TDADataTable class uses the TDAExpressionEvaluator in InternalOnCalcFields to do evaluations based on the values of the fields of a current record.
Use Case
You are free to use the functionality of the TDAExpressionEvaluator class for your own purposes. There are some examples of the TDAExpressionEvaluator's usage (please also refer to the TDAStdExpressionEvaluator Use case)):
program ExpressionEvaluatorDemo;
{$APPTYPE CONSOLE}
uses
Classes, SysUtils, Math, Variants, uDAExpressionEvaluator;
type
TEvaluationContext = class
public
procedure ValueSupplier(Sender: TDAExpressionEvaluator; const aIdentifier: string; out aValue: Variant);
procedure FunctionSupplier (Sender: TDAExpressionEvaluator; const aIdentifier: string; const Args: array of Variant; out aValue: Variant);
end;
{ TEvaluationContext }
procedure TEvaluationContext.FunctionSupplier(
Sender: TDAExpressionEvaluator; const aIdentifier: string;
const Args: array of Variant; out aValue: Variant);
begin
if aIdentifier = 'FVAL' then begin
aValue := FutureValue (Args [0], Args [1], Args [2], Args [3], Args [4]);
end
else if aIdentifier = 'DDB' then begin
aValue := DoubleDecliningBalance (Args [0], Args [1], Args [2], Args [3]);
end
else if aIdentifier = 'DateToStr' then begin
aValue := DateToStr (Args [0]);
end
else
raise Exception.Create ('Unknown function ' + QuotedStr (aIdentifier));
end;
procedure TEvaluationContext.ValueSupplier(Sender: TDAExpressionEvaluator;
const aIdentifier: string; out aValue: Variant);
var
i : integer;
tmp : TStrings;
begin
if aIdentifier = 'null' then aValue := null
else if aIdentifier = 'ptEndOfPeriod' then aValue := ord (ptEndOfPeriod)
else if aIdentifier = 'ptStartOfPeriod' then aValue := ord (ptStartOfPeriod)
else if aIdentifier [1] = '[' then begin
tmp := TStringList.Create;
try
tmp.DelimitedText := Copy (aIdentifier, 2, Length (aIdentifier) - 2);
aValue := VarArrayCreate([0, tmp.Count -1], varVariant);
for i := 0 to tmp.Count -1 do
aValue [i] := tmp [i];
finally
tmp.Free;
end;
end
else
raise Exception.Create ('Unknown value ' + QuotedStr (aIdentifier));
end;
procedure doCalculation (evaluator : TDAExpressionEvaluator; const expression : string);
begin
Write (QuotedStr (expression), ' -> ');
WriteLn (QuotedStr (evaluator.Evaluate (expression)));
end;
procedure doDemo;
var
evaluator : TDAExpressionEvaluator;
context : TEvaluationContext;
begin
evaluator := TDAExpressionEvaluator.Create;
context := TEvaluationContext.Create;
evaluator.OnGetValue := context.ValueSupplier;
evaluator.OnUnknownFunctionCall := context.FunctionSupplier;
doCalculation (evaluator, '((1 + 2) * 3) / 4'); //'2.25'
doCalculation (evaluator, '31 > $1F'); //'False'
doCalculation (evaluator, '15 % 4 { % is remainder (mod)}'); //'3'
doCalculation (evaluator, '1 in [1, 2, 3]'); //'True'
doCalculation (evaluator, **abc` LIKE `*c**); //'True'
doCalculation (evaluator, 'DateToStr (#12/31/2010#)'); //'31.12.2010'
doCalculation (evaluator, 'FVAL (0.1, 1, 5, 1000, ptStartOfPeriod)'); //'-1105.5'
doCalculation (evaluator, 'FVAL (0.1, 1, 5, 1000, ptEndOfPeriod)'); //'-1105'
doCalculation (evaluator, 'DDB (1000, 100, 5, 1)'); //'400'
evaluator.Free;
context.Free;
end;
begin
try
doDemo;
except on E : Exception do
WriteLn ('Exception: ', E.Message);
end;
end.
Location
- Unit: uDAExpressionEvaluator.pas
constructor Create
Creates a new instance.
constructor Create
Evaluate
Performs Pascal Script from aString
(see the Use Case).
function Evaluate(const aString: string): Variant
Parameters:
- aString: Script text
FunctionList
Holds the set of known functions (see the Use Case).
property FunctionList: TDAEEFunctionList read
OnGetValue
Fires when the script engine encounters an unkown variable (see the Use Case).
property OnGetValue: TDAEEGetValue read write
delegate: procedure OnGetValue(Sender: TDAExpressionEvaluator; const aIdentifier: string; out aValue: Variant)
OnUnknownFunctionCall
Fires when the script engine encounters an unkown a call of an unknown function (not present in FunctionList)(see the Use Case).
property OnUnknownFunctionCall: TDAEEFunctionCall read write
delegate: procedure OnUnknownFunctionCall(Sender: TDAExpressionEvaluator; const aIdentifier: string; const Args: array of Variant; out aValue: Variant)
StringCaseInsensitive
Controls if Pascal
rules for identifier name distinguishing is used (True
) or
not (False
, default).
property StringCaseInsensitive: Boolean read write
UseTrueFalseinVariableName
Controls if the name of a variable (True
and false) presents a Boolean
value (False
, default)
or a variable (True
).
property UseTrueFalseinVariableName: Boolean read write
UseWildcardsInEqual
Controls if a Like
style (symbol "*") is used in string comparison (True
) or
not (False
, default).
property UseWildcardsInEqual: Boolean read write
FunctionList
Holds the set of known functions (see the Use Case).
property FunctionList: TDAEEFunctionList read
StringCaseInsensitive
Controls if Pascal
rules for identifier name distinguishing is used (True
) or
not (False
, default).
property StringCaseInsensitive: Boolean read write
UseTrueFalseinVariableName
Controls if the name of a variable (True
and false) presents a Boolean
value (False
, default)
or a variable (True
).
property UseTrueFalseinVariableName: Boolean read write
UseWildcardsInEqual
Controls if a Like
style (symbol "*") is used in string comparison (True
) or
not (False
, default).
property UseWildcardsInEqual: Boolean read write
constructor Create
Creates a new instance.
constructor Create
Evaluate
Performs Pascal Script from aString
(see the Use Case).
function Evaluate(const aString: string): Variant
Parameters:
- aString: Script text
OnGetValue
Fires when the script engine encounters an unkown variable (see the Use Case).
property OnGetValue: TDAEEGetValue read write
delegate: procedure OnGetValue(Sender: TDAExpressionEvaluator; const aIdentifier: string; out aValue: Variant)
OnUnknownFunctionCall
Fires when the script engine encounters an unkown a call of an unknown function (not present in FunctionList)(see the Use Case).
property OnUnknownFunctionCall: TDAEEFunctionCall read write
delegate: procedure OnUnknownFunctionCall(Sender: TDAExpressionEvaluator; const aIdentifier: string; const Args: array of Variant; out aValue: Variant)
- Pascal Script
- TDAStdExpressionEvaluator