TFatExpression 1.0
a component by Gasper Kozak, June 2001
This component is completely free for any (ab)use. I do not promise any support or new updates.
The component probably includes bugs. If you find any, please let me know.
check for a new version on
Delphi pages.
this is an expression-calculation component. Simply by passing an string-expression to it, you can evaluate
its value. It uses a very simple parser and a syntax-tree approach.
FEATURES
operations: + - * / ^ !
parenthesis: ( )
functions:
In the TFatExpression component, there is a Functions: TStringList property, which holds a list of
user-defined functions. These can be entered at design-time, or assigned at run-time (see demo).
Functions without parameters can also serve as constants (see bellow for function Pi).
the function format is as follows:
function = function_name [ "(" argument_name [";" argument_name ... ] ")" ] "=" expression
valid function_name (and also argument_name) consists of:
first character = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_
every next character = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$#@&0123456789
here are a few examples of valid functions:
no parameter: Pi=3.14
one parameter: f(t) = 4*t*t + 2*t + 1
one parameter: sqr(x)=x*x
one parameter: sqrt(x)=x^(1/2)
see how functions can include each other
one parameter: circle_area(radius)=Pi*sqr(radius)
two parameters: add(x;y)=x + y
note: in function definition and also in expression, multiple parameters must be separated
with a ";" character.
When calculating, you would use some of these functions like this:
FatExpression1.Text := 'sqr(2) + sqrt(16) + add(4; 4)';
in this case, function FatExpression1.Value should return 16
Another type of function-implementing is available. If the component, while evaluating the expression,
comes along an unknown function, it generates an OnEvaluate event. It passes the function name, argument
count and argument list to the event, expecting the programer to provide it's result value. This can be
used for variables, arrays and constants that are application-dependant.
Here is some code showing how you could make the "add(x;y)=x+x" function the other way, by not adding it
to the Functions property.
The event handler first checks the Eval argument, and if is the right function (add), it returns a
result of "first argument plus second argument" to the Value. Argument list is zero-based, meaning the
first argument is Args[0], second is Args[1], ... and the last is Args[ArgCount - 1]. ArgCount tells
you how many arguments are in the Args array.
procedure TForm1.FatExpression1Evaluate(Sender: TObject; Eval: String;
Args: array of Double; ArgCount: Integer; var Value: Double);
begin
if UpperCase(Eval) = 'ADD' then
Value := Args[0] + Args[1];
end;
This code is equal to writing "add(x;y)=x+y" function in the Functions property, although it is probably
faster, since it is compiled and optimized by Delphi. There is also one big advantage using this approach.
it has a dynamic number of arguments.
Imagine this:
you add this function to the FatExpression1.Functions property: "add(a;b;c;d;e;f;g;h)=a+b+c+d+e+f+g+h".
In expression, you can pass less or more arguments (than there are specified in the function-definition)
to the function-call, for example:
FatExpression1.Text := 'add(1;2;3)'; // returns 6
FatExpression1.Text := 'add(1;1;1;1;1;1;1;1;1;1;1;1;1)'; // returns 8, because the function definition
only includes 8 parameters
If you pass less arguments, than the parser expects, the missing parameter are treated as zeros.
As you can see in demo, I handle the ADD function through OnEvaluate event. This way, I can take care of any
number of arguments passed to the function-call:
var I: Integer;
if UpperCase(Eval) = 'ADD' then
for I := 0 to ArgCount - 1 do
Value := Value + Args[I];
This code will add any number of arguments and return the value. So now, a call to
FatExpression1.Text := 'add(1;1;1;1;1;1;1;1;1;1;1;1;1)';
returns 13.
Function-calls in expression can also be nested within each other:
add(add(1; 1); add(1; 1))
add(add(add(add(1); 1); 1); 1))
add(add(add(add(4))))
All these functions return 4.
properties
-
EvaluateOrder: TEvaluateOrder = (eoInternalFirst, eoEventFirst)
Sets the order of evaluating functions. eoInternalFirst means the Functions property is checked
first. If the function is found, it is evaluated and no event is triggered. If the function is not
found, the event is triggered.
-
Functions: TStringList
A list of functions in specified format.
-
Text: String
The mathematical expression in string. This cannot be an equation.
-
Value: Double
Returns the value of "Text", using Functions property and OnEvaluate event for evaluating
unknown functions.
events
-
OnEvaluate(Sender: TObject; Eval: String; Args: array of Double; ArgCount: Integer; var Value: Double; var Done: Boolean)
Eval is the name of the evaluated function. Args is the array of values, presenting the called function's
arguments. ArgCount is number of elements in Args. Args is zero-based array. The Value argument is
the result value that should be filled. If you handle the function and return the result, you
should set Done to TRUE.
so... this is the basic info. For more, you should see demo, dig into the source or email me
(in this order).
eof