You've already forked lazarus-ccr
356 lines
13 KiB
Plaintext
356 lines
13 KiB
Plaintext
![]() |
|
||
|
This file documents the TStExpression and TStExpressionEdit components.
|
||
|
|
||
|
|
||
|
TStExpression
|
||
|
=============
|
||
|
|
||
|
TStExpression is a non-visual component that provides expression evaluation
|
||
|
at several different levels. At the lowest level, simple mathematical
|
||
|
expressions can be evaluated and the resulting value obtained. On a higher
|
||
|
level, you can define alpha-numeric constants that can then be used within
|
||
|
expressions; You can add user-defined functions (and even methods of a class)
|
||
|
so that the names of these routines can be used in expressions; You can
|
||
|
define variables that relate directly to variables in your program and even
|
||
|
use them in expressions.
|
||
|
|
||
|
Note: TStExpression replaces AnalyzeExpr that SysTools version 2.00 provided,
|
||
|
but a version of that routine is still provided for backward compatibility.
|
||
|
|
||
|
The TStExpression expression parser implements the following grammar, similar
|
||
|
to a subset of Pascal:
|
||
|
|
||
|
expression: term | expression+term | expression-term
|
||
|
term: factor | term*factor | term/factor
|
||
|
factor: base | base^factor
|
||
|
base: unsigned_num | (expression) | sign factor | func_call
|
||
|
unsigned_num: digit_seq | digit_seq.digit_seq | digit_seq scale_fac |
|
||
|
digit_seq.digit_seq scale_fac
|
||
|
sign: + | -
|
||
|
func_call: identifier | identifier(params)
|
||
|
params: expression | params,expression
|
||
|
scale_fac: E digit_seq | E sign digit_seq
|
||
|
digit_seq: digit | digit_seq digit
|
||
|
identifier: starts with A..Z,_ continues with A..Z,_,0..9
|
||
|
digit: 0..9
|
||
|
|
||
|
Case is not significant when matching characters.
|
||
|
|
||
|
The grammar follows normal rules of arithmetic precedence, with ^ highest, *
|
||
|
and / in the middle, and + and - lowest. Thus, 1+2*3^4 means 1+(2*(3^4)).
|
||
|
Parentheses can be used to force non-default precedence.
|
||
|
|
||
|
Note that the power operator x^y is right-associative. This means that
|
||
|
2^0.5^2 is equivalent to 2^(0.5^2). All other arithmetic operators are left
|
||
|
associative: 1-2-3 is equivalent to (1-2)-3.
|
||
|
|
||
|
The following functions are supported in 16-bit and 32-bit applications:
|
||
|
|
||
|
abs, arctan, cos, exp, frac, int(trunc), ln, pi, round, sin, sqr,
|
||
|
sqrt
|
||
|
|
||
|
If the VCL Math unit is available and you define the "UseMathUnit" define in
|
||
|
STDEFINE.INC, the following are also available:
|
||
|
|
||
|
arccos, arcsin, arctan2, tan, cotan, hypot, cosh, sinh, tanh,
|
||
|
arccosh, arcsinh, arctanh, lnxp1, log10, log2, logn, ceil, floor
|
||
|
|
||
|
The calling conventions for all functions match those of the VCL runtime
|
||
|
library or Math unit. The acceptable parameter ranges and output values also
|
||
|
match thoses of the VCL runtime library or MATH unit.
|
||
|
|
||
|
When the input expression contains an error, TStExpression raises an
|
||
|
exception of type EStExprError. Its ErrorCode property provides more detail
|
||
|
about the error. Its ErrorColumn property gives the string index of the start
|
||
|
of the token where the error was detected.
|
||
|
|
||
|
TStExpression is very flexible. You can add support for your own functions
|
||
|
easily. For example, to add support for the Sin() function, first write a
|
||
|
function to provide the proper number and type of parameters (the "far" can
|
||
|
be omitted with 32-bit compilers):
|
||
|
|
||
|
function _Sin(Value : TStFloat) : TStFloat; far;
|
||
|
begin
|
||
|
Result := Sin(Value);
|
||
|
end;
|
||
|
|
||
|
and then add it to the TStExpression component:
|
||
|
|
||
|
MyStExpression.AddFunction1Param('sin', _Sin);
|
||
|
|
||
|
Or, if you wanted to use a method of the form (or any other class) that you
|
||
|
were working in, you could do the same thing this way:
|
||
|
|
||
|
function MyForm._Sin(Value : TStFloat) : TStFloat;
|
||
|
begin
|
||
|
Result := Sin(Value);
|
||
|
end;
|
||
|
|
||
|
and then add it to the TStExpression component:
|
||
|
|
||
|
MyStExpression.AddMethod1Param('sin', _Sin);
|
||
|
|
||
|
TStExpression supports user-defined functions with 0 to 3 parameters. The
|
||
|
parameters and function result must be the TStFloat type (defined in the
|
||
|
STBASE unit). In the example above, that's why we didn't just add
|
||
|
the Sin() function directly, in the call to AddFunction1Param -- The
|
||
|
TStExpression component must know the data types of parameters and return
|
||
|
values. If the function you are adding has no parameters, use the
|
||
|
AddFunction0Parm() method. AddFunction2Param for functions with two
|
||
|
parameters, etc.
|
||
|
|
||
|
The following function and method types define all possible user-defined
|
||
|
function and method types accepted by the TStExpression component:
|
||
|
|
||
|
{user-defined functions with up to 3 parameters}
|
||
|
TStFunction0Param =
|
||
|
function : TStFloat;
|
||
|
TStFunction1Param =
|
||
|
function(Value1 : TStFloat) : TStFloat;
|
||
|
TStFunction2Param =
|
||
|
function(Value1, Value2 : TStFloat) : TStFloat;
|
||
|
TStFunction3Param =
|
||
|
function(Value1, Value2, Value3 : TStFloat) : TStFloat;
|
||
|
|
||
|
{user-defined methods with up to 3 parameters}
|
||
|
TStMethod0Param =
|
||
|
function : TStFloat
|
||
|
of object;
|
||
|
TStMethod1Param =
|
||
|
function(Value1 : TStFloat) : TStFloat
|
||
|
of object;
|
||
|
TStMethod2Param =
|
||
|
function(Value1, Value2 : TStFloat) : TStFloat
|
||
|
of object;
|
||
|
TStMethod3Param =
|
||
|
function(Value1, Value2, Value3 : TStFloat) : TStFloat
|
||
|
of object;
|
||
|
|
||
|
Add predefined constant values by using the AddConstant method:
|
||
|
|
||
|
AddConstant('X', 50)
|
||
|
|
||
|
Then, in any expression that uses the identifier "X", the value 50 will be
|
||
|
used when the expression is evaluated.
|
||
|
|
||
|
Add references to variables in your program by using the AddVariable method:
|
||
|
|
||
|
var
|
||
|
MyVar : TStFloat;
|
||
|
|
||
|
AddVariable('MyVar', @MyVar);
|
||
|
|
||
|
Whenever an expression is evaluated that contains the "MyVar" identifier,
|
||
|
the actual value of the variable (in your program) is retrieved and used
|
||
|
to compute the expression result. Changes to variable's value in your
|
||
|
program will be reflected when the expression is next evaluated.
|
||
|
|
||
|
Two things to note: First, the variable must be a TStFloat type and second,
|
||
|
the variable must remain in "scope". In general, this means that the variable
|
||
|
must either be defined globally or as a class variable. You normally would not
|
||
|
use AddVariable for variables defined local to a procedure or function (a
|
||
|
stack variable).
|
||
|
|
||
|
TStExpression offers a way to dynamically determine the value of an variable
|
||
|
or function that is being used in an expression -- the OnGetIdentValue event.
|
||
|
This event is fired if the expression parser is unable to locate the identifier
|
||
|
in its internal list of identifier names. In response to the event, you should
|
||
|
assign a value to the Value parameter that corresponds to the identifier name
|
||
|
passed to the event as the Identifier parameter. If no event handler is
|
||
|
assigned to this even and the expression parser is unable to locate a match for
|
||
|
an identifier used in an expression, an exception is raised.
|
||
|
|
||
|
|
||
|
Reference Section
|
||
|
-----------------
|
||
|
|
||
|
methods
|
||
|
-------
|
||
|
|
||
|
function AnalyzeExpression : TStFloat;
|
||
|
-> AnalyzeExpression causes the expression contained in the Expression property
|
||
|
to be evaluated and returns the resulting value as the function result.
|
||
|
|
||
|
|
||
|
procedure AddConstant(const Name : string; Value : TStFloat);
|
||
|
-> AddConstant adds named constant values for use within expressions.
|
||
|
|
||
|
Example: AddConstant('X', 50)
|
||
|
|
||
|
|
||
|
procedure AddFunction0Param(const Name : string; FunctionAddr : TStFunction0Param);
|
||
|
procedure AddFunction1Param(const Name : string; FunctionAddr : TStFunction1Param);
|
||
|
procedure AddFunction2Param(const Name : string; FunctionAddr : TStFunction2Param);
|
||
|
procedure AddFunction3Param(const Name : string; FunctionAddr : TStFunction3Param);
|
||
|
-> AddFunctionXParam adds support for user-defined functions within expressions.
|
||
|
|
||
|
The four variations allow defining functions with no parameters, or, with one,
|
||
|
two, or three parameters. Name is the identifier that is entered into the
|
||
|
expression. The name does not need to be the same as the actual function name.
|
||
|
|
||
|
Parameter and function results must be defined as TStFloat.
|
||
|
|
||
|
|
||
|
procedure AddInternalFunctions;
|
||
|
-> AddInternalFunctions adds support for all of the predefined internal
|
||
|
functions.
|
||
|
|
||
|
Since AddInternalFunctions is called by default, calling this routine without
|
||
|
first calling ClearIdentifiers will result in duplicate identifier exceptions.
|
||
|
|
||
|
|
||
|
procedure AddMethod0Param(const Name : string; MethodAddr : TStMethod0Param);
|
||
|
procedure AddMethod1Param(const Name : string; MethodAddr : TStMethod1Param);
|
||
|
procedure AddMethod2Param(const Name : string; MethodAddr : TStMethod2Param);
|
||
|
procedure AddMethod3Param(const Name : string; MethodAddr : TStMethod3Param);
|
||
|
-> AddMethodXParam adds support for user-defined methods within expressions.
|
||
|
|
||
|
The four variations allow defining methods with no parameters, or, with one,
|
||
|
two, or three parameters. Name is the identifier that is entered into the
|
||
|
expression. The name does not need to be the same as the actual method name.
|
||
|
|
||
|
Parameter and function results must be defined as TStFloat.
|
||
|
|
||
|
|
||
|
procedure AddVariable(const Name : string; VariableAddr : PStFloat);
|
||
|
-> Adds Name as a reference to a variable in your program.
|
||
|
|
||
|
Name is the identifier used in expressions.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
var
|
||
|
X : TStFloat;
|
||
|
...
|
||
|
AddVariable('X', @X)
|
||
|
|
||
|
|
||
|
procedure ClearIdentifiers;
|
||
|
-> ClearIdentifiers removes all function, method, constant, and variable identifiers.
|
||
|
|
||
|
|
||
|
procedure GetIdentList(S : TStrings);
|
||
|
-> GetIdentList fills S with a list of identifiers current recognized.
|
||
|
|
||
|
|
||
|
procedure RemoveIdentifier(const Name : string);
|
||
|
-> RemoveIdentifier removes support for the identifier Name.
|
||
|
|
||
|
If Name is not found, no action is taken.
|
||
|
|
||
|
|
||
|
properties
|
||
|
----------
|
||
|
property AsFloat : TStFloat (run-time read-only)
|
||
|
-> AsFloat evaluates the expression and returns the value as a TStFloat
|
||
|
value;
|
||
|
|
||
|
property AsInteger : Integer (run-time read-only)
|
||
|
-> AsInteger evaluates the expression and returns the value as a whole number
|
||
|
using the Round() function to convert the TStFloat value.
|
||
|
|
||
|
property AsString : string (run-time read-only)
|
||
|
-> AsString evaluates the expression and returns the value as a string using
|
||
|
the FloatToStr() function to format the TStFloat value.
|
||
|
|
||
|
property LastError : Integer (run-time read-only)
|
||
|
-> LastError returns the error code (zero if no error).
|
||
|
|
||
|
property ErrorPosition : Integer (run-time read-only)
|
||
|
-> ErrorPosition returns the position of the error within the expression.
|
||
|
|
||
|
ErrorPosition is valid only if LastError is non-zero.
|
||
|
|
||
|
property Expression : string (run-time)
|
||
|
-> Expression defines the expression that should be evaluated.
|
||
|
|
||
|
property AllowEqual : Boolean
|
||
|
default: True
|
||
|
-> AllowEqual determines if the use of the "=" symbol in the expression will
|
||
|
add constant declarations.
|
||
|
|
||
|
If true, expressions like X = 5 will cause the identifer "X" to be added and
|
||
|
associated with the value 5. This expression will also return a value of 5
|
||
|
when analyzed. If false, a bad character exception is raised.
|
||
|
|
||
|
|
||
|
events
|
||
|
------
|
||
|
property OnAddIdentifier : TNotifyEvent
|
||
|
-> OnAddIdentifier defines an event that is fired when a new identifier
|
||
|
is added.
|
||
|
|
||
|
This event is fired for additions of function, method, constant, and variable
|
||
|
identifiers.
|
||
|
|
||
|
property OnGetIdentValue : TGetIdentValueEvent
|
||
|
TGetIdentValueEvent =
|
||
|
procedure(Sender : TObject; const Identifier : string; var Value : TStFloat)
|
||
|
of object;
|
||
|
-> OnGetIdentValue defines an event handler that is fired to obtain the value
|
||
|
for an identifier that was not found in the internal list of known identifiers.
|
||
|
|
||
|
|
||
|
TStExpressionEdit
|
||
|
=================
|
||
|
The TStExpressionEdit component is a simple descendant of a TEdit component
|
||
|
that adds one new method, two properties, and two new events. In all other
|
||
|
respects, this control is the same as the standard VCL TEdit control.
|
||
|
|
||
|
The TStExpressionEdit uses an instance of the TStExpression component to do
|
||
|
most of the work. Any expression that is valid for the TStExpression
|
||
|
component can be entered into the component or assigned to the Text property.
|
||
|
The expression is evaluated when the component loses the focus (with AutoEval
|
||
|
true) or when the Evaluate method is called. Also, if AutoEval is true and
|
||
|
the control loses the focus, the resulting value is displayed in the control.
|
||
|
|
||
|
|
||
|
New properties and methods:
|
||
|
|
||
|
function Evaluate : TStFloat;
|
||
|
|
||
|
-> Evaluate evaluates the contents of the Text property as an expression
|
||
|
using the contained TStExpression component and returns the result of the
|
||
|
expression as the function result.
|
||
|
|
||
|
If an error occurs an exception is raised unless an event handler for the
|
||
|
OnError event is assigned. In which case, the event is fired instead.
|
||
|
|
||
|
Note: The AnalyzeExpr function (which is documented in the printed
|
||
|
manual and on-line help) is obsolete and is provided for backward
|
||
|
compatibility only.
|
||
|
|
||
|
|
||
|
property AutoEval : Boolean
|
||
|
|
||
|
-> AutoEval determines if the entered expression is automatically evaluated
|
||
|
when the control loses the focus.
|
||
|
|
||
|
If AutoEval is true, the Evaluate method is called automatically and the
|
||
|
Text of the edit control is set to the result of evaluating the expression.
|
||
|
If False, no additional action is taken.
|
||
|
|
||
|
|
||
|
property Expr : TStExpression (run-time)
|
||
|
|
||
|
-> Expr provides access to the contained TStExpression component and all of
|
||
|
its properties, methods, and events.
|
||
|
|
||
|
|
||
|
property OnAddIdentifier : TNotifyEvent
|
||
|
|
||
|
-> OnAddIdentifier defines an event that is fired when an identifier is
|
||
|
added to the internal TStExpression component.
|
||
|
|
||
|
This event is fired to notify you that a constant or function identifier has
|
||
|
been added to the contained TStExpression component.
|
||
|
|
||
|
|
||
|
property OnError : TStExprErrorEvent
|
||
|
|
||
|
TStExprErrorEvent =
|
||
|
procedure(Sender : TObject; ErrorNumber : LongInt; const ErrorStr : string)
|
||
|
of object;
|
||
|
|
||
|
-> OnError defines an event that is fired when an evaluation error occurs.
|