RTCalcExpress


1. Overview.

RTCalcExpress is a Delphi component for calculating expressions, entered in Run-Time.
It can be installed into Delphi4, 5, 6, 7 and higher.

The expressions can contain numbers, arithmetic ('+', '-', '*', '/') and
logic ('=', '>', '<', '<>', '>=', '<=', 'AND', 'OR') operators and functions,
defined by user (FDU).
A priority of the arithmetic calculations is usual - at first multiplication and division,
then addition and subtraction.
It is possible to change the priority of calculations by the standard way - through parentheses.

It is possible to add any quantity of the FDU functions.
These functions can be as without arguments and to have the unlimited quantity of the arguments.
The arguments suppose any level of an enclosure i.e. these can consist of the expressions,
other functions etc. A list of the arguments consists in parentheses.
A name of the FDU function is not case sensitivity.

A maximal length of the expression corresponds to the length of the Delphi data type AnsiString.
The expression can be divided on substrings, which will be calculated one after another.
In this case return value will be a result of calculating the last substring.
The break-symbol is semicolon.
In this case, it is possible to calculate the intermediate meanings,
which can be saved in global variables.
These variables can be use as the arguments of the FDU functions or as elements of the expressions.

The component has 20 global variables.
- Data type INTEGER: ttInt1..ttInt5;
- Data type STRING: ttStr1..ttStr5;
- Data type NUMERIC (DOUBLE): ttNum1..ttNum5;
- Data type DATE (TDateTime): ttDate1..ttDate5.

The character pair ':=' is the operator of assignment a value to the global variables.
Examples:

ttNum1 := Date;
ttNum2 := Date + 3;
Max(ttNum1, ttNum2)

ttNum1 := Date;
ttDate5 := Round(Date / 7);
ttNum1 > ttDate5

Before calculation all symbols of the expression are converted to upper case and 
all blanks are excluded.
If the fragment of the expression, for example, the argument of the FDU function,
is concluded in unary inverted commas, the blanks are not excluded from this fragment.
If the argument of function - a symbolical image of the date, then it is necessary 
to conclude it in the unary inverted commas (test #12).

2. Public Properties.

tt_arglist: TargList - A dynamic array (string data type) for storage previously 
calculated arguments of the FDU functions.
The quantity elements in this array corresponds to the quantity of the arguments;

tt_Int: array[1..5] of integer - An array for storage the meanings of the global variables
ttInt1...ttInt5;
tt_Str: array[1..5] of string - An array for storage the meanings of the global variables 
ttStr1...ttStr5;

tt_Num: array[1..5] of double - An array for storage the meanings of the global variables 
ttNum1...ttNum5;

tt_Date: array[1..5] of TDateTime - An array for storage the meanings of the global variables 
ttDate1...ttDate5;


3. Published Properties	.

ReturnType - ttString or ttNumeric. A data type of the expression;
MessLanguage - ttRussian or ttEnglish. A language of error messages.


4. Public Methods.

constructor Create(AOwner: Tcomponent); override;
destructor Destroy; override;

function CheckIsAlpha(s_check: string): Boolean - Checks all characters of a string.
It returns true if the characters are English or Russian letters, '_', blank, '0'...'9' 
(except for the first character);

function CheckIsDigit(s_check: string): Boolean - Checks all characters of a string.
It returns true if the characters are '0'...'9';

function CheckIsNumeric(s_check: string): Boolean - Checks all characters of a string.
It returns true if the characters are '0'...'9', character DecimalSeparator 
and '-' as first character.

function CheckIsDate(s_check: string): Boolean - Checks all characters of a string.
It returns true if the characters are '0'...'9', 
character '.' or ',' or '/' as a delimiter (quantity no more than two);

function StrFilter(s: string; n: Byte): string - Cuts out from a string a character, 
which numerical meanings is equal to the second argument and returns result of this transformation;

function Evaluate(s_arg: PChar; var n_arg1: integer; var code_err: integer; p_adr: PChar): double. 
The main method of the component - calculating of the expression. 
s_arg - a pointer to a string (AnsiString), which containing the expression for the calculating; 
n_arg1 - a variable parameter (for an additional opportunity of the function); 
code_err - a variable parameter, accepts meaning of a code of the error, at its occurrence, 
and 0 at a correct performance; 
p_adr - a buffer, allocated for a result of the calculating (if the property ReturnType is ttString);
The function returns a result of the calculating, if the property ReturnType is ttNumeric.


5. Published Events.

OnCalcFunction(s_name: string; n_kolarg: integer; is_check: Boolean; var n_arg1: integer; 
var code_err: integer; var s_rslt: string) - An event for adding the FDU functions;
s_name - a name of the function; 
n_kolarg - a number of the arguments of the function;
is_check - accepts true, when the call of the function is only for check, 
whether the function with such name is defined, and false, if the function called for the calculating;
n_arg1 and code_err - the variable parameters, described in the method Evaluate;
s_rslt - a variable parameter for the result of the calculating FDU function;
The meanings of the arguments FDU functions contain in the dynamic array tt_arglist;
A pattern of the function - in an example project.

OnErrorFunction(t_lang: TtLang; s_title: string; code_err: integer) - An event for adding 
error messages, which caused of the FDU functions; 
t_lang - a meaning of the property MessLanguage (ttRussian or ttEnglish);
s_title - a title of error message;
code_err - a code of the error. A meaning of the code_err must be more than 200.


6. Codes and error messages.

Code	Message
-------------------------------------------------------------------
101	Empty argument
102	Error in argument
103	Empty expression
104	The expression contains an inadmissible symbol
105	The expression contains odd quantity of unary inverted commas
106	The expression contains a superfluous symbol
107	The expression contains an inadmissible first symbol
108	Division by zero
109	Error in expression
110	Unknown name of variable
111	The list of arguments belongs to unknown function
112	Argument of unknown function
113	A place for result is not defined
114	The expression contains odd quantity of parentheses
-------------------------------------------------------------------


7. FDU functions of Demo - program.

Function	Quantity of		Description
		arguments
-------------------------------------------------------------------
DATE		0			Returns the current date
STRADD	2			Concatenates two strings into one
STREQUAL	2			Compares two strings without case sensitivity and 					returns 1 if they are equal and 0 otherwise
ROUND		1			Returns the value rounded to two digit after a 						point
MAX		2			Returns the greater of two numeric values
MIN		2			Returns the lesser of two numeric values
-------------------------------------------------------------------


9. Tests for Demo - program.

#	Expression							Result
-------------------------------------------------------------------
1	Date								Current date
2	StrAdd('xx', 'yy')					XXYY
3	StrAdd(xx, yy)						XXYY
4	StrAdd('xx', 'y  y')					XXY  Y
5	StrEqual(StrAdd('xx', 'yy'), 'xxyy')		1
6	StrEqual(StrAdd(xx, yy), xxYY)			1
7	StrEqual(StrAdd(xx, yy), xx YY)			1
8	StrEqual(StrAdd(xx, yy), 'xx YY')			0
9	Round(Date / 13)						Depends on the current
									date
10	Max(Round(Date / 13), Date)				Result #1
11	Min(Round(Date / 13), Date)				Result #6
12	Max('06.09.03', Date)					Result #1
13	(Date / 13) > (Date / 7)				0
14	(Date / 13) >= (Date / 7)				0
15	(Date / 13) = (Date / 7)				0
16	(Date / 13) <= (Date / 7)				1
17	Round(Date / 2) = Round(Date / 4 + Date / 4)	1
18	((Date / 13) = (Date / 7)) AND
 	((Date / 13) <= (Date / 7))				0
19	((Date / 13) = (Date / 7)) OR
	 ((Date / 13) <= (Date / 7))				1
20	ttNum1 := Date; ttNum2 := Date + 3;
 	Min(ttNum1, ttNum2)					Result #1
21	ttNum1 := Date; ttDate5 := Round(Date / 7);
 	ttNum1 > ttDate5						1
-------------------------------------------------------------------




Copyright (c) 2003 A.Storozhko.

