mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-21 13:09:46 +02:00
* Patch from Werner Pamler to implement ^ in expression parser (Big ID 30970)
git-svn-id: trunk@34967 -
This commit is contained in:
parent
784da563ef
commit
ba35278552
@ -27,15 +27,15 @@ Type
|
|||||||
TTokenType = (ttPlus, ttMinus, ttLessThan, ttLargerThan, ttEqual, ttDiv,
|
TTokenType = (ttPlus, ttMinus, ttLessThan, ttLargerThan, ttEqual, ttDiv,
|
||||||
ttMul, ttLeft, ttRight, ttLessThanEqual, ttLargerThanEqual,
|
ttMul, ttLeft, ttRight, ttLessThanEqual, ttLargerThanEqual,
|
||||||
ttunequal, ttNumber, ttString, ttIdentifier,
|
ttunequal, ttNumber, ttString, ttIdentifier,
|
||||||
ttComma, ttand, ttOr,ttXor,ttTrue,ttFalse,ttnot,ttif,
|
ttComma, ttAnd, ttOr, ttXor, ttTrue, ttFalse, ttNot, ttif,
|
||||||
ttCase,ttEOF);
|
ttCase, ttPower, ttEOF); // keep ttEOF last
|
||||||
|
|
||||||
TExprFloat = Double;
|
TExprFloat = Double;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
ttDelimiters = [ttPlus, ttMinus, ttLessThan, ttLargerThan, ttEqual, ttDiv,
|
ttDelimiters = [ttPlus, ttMinus, ttLessThan, ttLargerThan, ttEqual, ttDiv,
|
||||||
ttMul, ttLeft, ttRight, ttLessThanEqual, ttLargerThanEqual,
|
ttMul, ttLeft, ttRight, ttLessThanEqual, ttLargerThanEqual,
|
||||||
ttunequal];
|
ttunequal, ttPower];
|
||||||
ttComparisons = [ttLargerThan,ttLessthan,
|
ttComparisons = [ttLargerThan,ttLessthan,
|
||||||
ttLargerThanEqual,ttLessthanEqual,
|
ttLargerThanEqual,ttLessthanEqual,
|
||||||
ttEqual,ttUnequal];
|
ttEqual,ttUnequal];
|
||||||
@ -329,6 +329,16 @@ Type
|
|||||||
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFPPowerOperation }
|
||||||
|
TFPPowerOperation = class(TMathOperation)
|
||||||
|
public
|
||||||
|
Procedure Check; override;
|
||||||
|
Function AsString : string ; override;
|
||||||
|
Function NodeType : TResultType; override;
|
||||||
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TFPUnaryOperator }
|
{ TFPUnaryOperator }
|
||||||
|
|
||||||
TFPUnaryOperator = Class(TFPExprNode)
|
TFPUnaryOperator = Class(TFPExprNode)
|
||||||
@ -673,6 +683,7 @@ Type
|
|||||||
Function Level4 : TFPExprNode;
|
Function Level4 : TFPExprNode;
|
||||||
Function Level5 : TFPExprNode;
|
Function Level5 : TFPExprNode;
|
||||||
Function Level6 : TFPExprNode;
|
Function Level6 : TFPExprNode;
|
||||||
|
Function Level7 : TFPExprNode;
|
||||||
Function Primitive : TFPExprNode;
|
Function Primitive : TFPExprNode;
|
||||||
function GetToken: TTokenType;
|
function GetToken: TTokenType;
|
||||||
Function TokenType : TTokenType;
|
Function TokenType : TTokenType;
|
||||||
@ -759,9 +770,9 @@ const
|
|||||||
|
|
||||||
Digits = ['0'..'9','.'];
|
Digits = ['0'..'9','.'];
|
||||||
WhiteSpace = [' ',#13,#10,#9];
|
WhiteSpace = [' ',#13,#10,#9];
|
||||||
Operators = ['+','-','<','>','=','/','*'];
|
Operators = ['+','-','<','>','=','/','*','^'];
|
||||||
Delimiters = Operators+[',','(',')'];
|
Delimiters = Operators+[',','(',')'];
|
||||||
Symbols = ['%','^']+Delimiters;
|
Symbols = ['%']+Delimiters;
|
||||||
WordDelimiters = WhiteSpace + Symbols;
|
WordDelimiters = WhiteSpace + Symbols;
|
||||||
|
|
||||||
Resourcestring
|
Resourcestring
|
||||||
@ -1107,6 +1118,7 @@ begin
|
|||||||
'(' : Result := ttLeft;
|
'(' : Result := ttLeft;
|
||||||
')' : Result := ttRight;
|
')' : Result := ttRight;
|
||||||
',' : Result := ttComma;
|
',' : Result := ttComma;
|
||||||
|
'^' : Result := ttPower;
|
||||||
else
|
else
|
||||||
ScanError(Format(SUnknownDelimiter,[D]));
|
ScanError(Format(SUnknownDelimiter,[D]));
|
||||||
end;
|
end;
|
||||||
@ -1169,8 +1181,9 @@ Var
|
|||||||
begin
|
begin
|
||||||
C:=CurrentChar;
|
C:=CurrentChar;
|
||||||
prevC := #0;
|
prevC := #0;
|
||||||
while (not IsWordDelim(C) or (prevC='E')) and (C<>cNull) do
|
while (not IsWordDelim(C) or (prevC in ['E','-','+'])) and (C<>cNull) do
|
||||||
begin
|
begin
|
||||||
|
Writeln('C : ',C,' PrevC : ',PrevC);
|
||||||
If Not ( IsDigit(C)
|
If Not ( IsDigit(C)
|
||||||
or ((FToken<>'') and (Upcase(C)='E'))
|
or ((FToken<>'') and (Upcase(C)='E'))
|
||||||
or ((FToken<>'') and (C in ['+','-']) and (prevC='E'))
|
or ((FToken<>'') and (C in ['+','-']) and (prevC='E'))
|
||||||
@ -1376,8 +1389,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFPExpressionParser.ConvertNode(Todo : TFPExprNode; ToType : TResultType): TFPExprNode;
|
function TFPExpressionParser.ConvertNode(Todo : TFPExprNode; ToType : TResultType): TFPExprNode;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=ToDo;
|
Result:=ToDo;
|
||||||
Case ToDo.NodeType of
|
Case ToDo.NodeType of
|
||||||
@ -1646,8 +1657,28 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFPExpressionParser.Level6: TFPExprNode;
|
function TFPExpressionParser.Level6: TFPExprNode;
|
||||||
|
var
|
||||||
|
right: TFPExprNode;
|
||||||
begin
|
begin
|
||||||
{$ifdef debugexpr} Writeln('Level 6 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
|
{$ifdef debugexpr} Writeln('Level 6 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
|
||||||
|
Result := Level7;
|
||||||
|
try
|
||||||
|
while (TokenType = ttPower) do
|
||||||
|
begin
|
||||||
|
GetToken;
|
||||||
|
right := Level5; // Accept '(', unary '+', '-' as next tokens
|
||||||
|
CheckNodes(Result, right);
|
||||||
|
Result := TFPPowerOperation.Create(Result, right);
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
Result.Free;
|
||||||
|
Raise;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFPExpressionParser.Level7: TFPExprNode;
|
||||||
|
begin
|
||||||
|
{$ifdef debugexpr} Writeln('Level 7 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
|
||||||
if (TokenType=ttLeft) then
|
if (TokenType=ttLeft) then
|
||||||
begin
|
begin
|
||||||
GetToken;
|
GetToken;
|
||||||
@ -3192,6 +3223,55 @@ begin
|
|||||||
Result.ResultType:=rtFloat;
|
Result.ResultType:=rtFloat;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFPPowerOperation }
|
||||||
|
|
||||||
|
procedure TFPPowerOperation.Check;
|
||||||
|
const
|
||||||
|
AllowedTypes = [rtInteger, rtFloat];
|
||||||
|
begin
|
||||||
|
CheckNodeType(Left, AllowedTypes);
|
||||||
|
CheckNodeType(Right, AllowedTypes);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFPPowerOperation.AsString: String;
|
||||||
|
begin
|
||||||
|
Result := Left.AsString + '^' + Right.AsString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFPPowerOperation.NodeType: TResultType;
|
||||||
|
begin
|
||||||
|
Result := rtFloat;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function power(base,exponent: TExprFloat): TExprFloat;
|
||||||
|
// Adapted from unit "math"
|
||||||
|
var
|
||||||
|
ex: Integer;
|
||||||
|
begin
|
||||||
|
if Exponent = 0.0 then
|
||||||
|
result := 1.0
|
||||||
|
else if (base = 0.0) and (exponent > 0.0) then
|
||||||
|
result := 0.0
|
||||||
|
else if (base < 0.0) and (frac(exponent) = 0.0) then
|
||||||
|
begin
|
||||||
|
ex := round(exponent);
|
||||||
|
result := exp( exponent * ln(-base));
|
||||||
|
if odd(ex) then result := -result;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result := exp( exponent * ln(base) );
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPPowerOperation.GetNodeValue(var Result: TFPExpressionResult);
|
||||||
|
var
|
||||||
|
RRes: TFPExpressionResult;
|
||||||
|
begin
|
||||||
|
Left.GetNodeValue(Result);
|
||||||
|
Right.GetNodeValue(RRes);
|
||||||
|
Result.ResFloat := power(ArgToFloat(Result), ArgToFloat(RRes));
|
||||||
|
Result.ResultType := rtFloat;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFPConvertNode }
|
{ TFPConvertNode }
|
||||||
|
|
||||||
function TFPConvertNode.AsString: String;
|
function TFPConvertNode.AsString: String;
|
||||||
|
@ -20,7 +20,7 @@ unit testexprpars;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpcunit, testutils, testregistry, fpexprpars;
|
Classes, SysUtils, fpcunit, testutils, testregistry, math, fpexprpars;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -414,6 +414,27 @@ type
|
|||||||
Procedure TestAsString;
|
Procedure TestAsString;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TTestPowerNode }
|
||||||
|
|
||||||
|
TTestPowerNode = Class(TTestBaseParser)
|
||||||
|
Private
|
||||||
|
FN : TFPPowerOperation;
|
||||||
|
FE : TFPExpressionParser;
|
||||||
|
Protected
|
||||||
|
Procedure Setup; override;
|
||||||
|
Procedure TearDown; override;
|
||||||
|
procedure Calc(AExpr: String; Expected: Double = NaN);
|
||||||
|
Published
|
||||||
|
Procedure TestCreateInteger;
|
||||||
|
Procedure TestCreateFloat;
|
||||||
|
Procedure TestCreateDateTime;
|
||||||
|
Procedure TestCreateString;
|
||||||
|
Procedure TestCreateBoolean;
|
||||||
|
Procedure TestDestroy;
|
||||||
|
Procedure TestAsString;
|
||||||
|
Procedure TestCalc;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TTestDivideNode }
|
{ TTestDivideNode }
|
||||||
|
|
||||||
TTestDivideNode = Class(TTestBaseParser)
|
TTestDivideNode = Class(TTestBaseParser)
|
||||||
@ -1302,7 +1323,7 @@ Const
|
|||||||
= ('+','-','<','>','=','/',
|
= ('+','-','<','>','=','/',
|
||||||
'*','(',')','<=','>=',
|
'*','(',')','<=','>=',
|
||||||
'<>','1','''abc''','abc',',','and',
|
'<>','1','''abc''','abc',',','and',
|
||||||
'or','xor','true','false','not','if','case','');
|
'or','xor','true','false','not','if','case','^','');
|
||||||
|
|
||||||
var
|
var
|
||||||
t : TTokenType;
|
t : TTokenType;
|
||||||
@ -1327,23 +1348,22 @@ end;
|
|||||||
|
|
||||||
procedure TTestExpressionScanner.TestNumber;
|
procedure TTestExpressionScanner.TestNumber;
|
||||||
begin
|
begin
|
||||||
TestString('123',ttNumber);
|
{TestString('123',ttNumber);
|
||||||
TestString('123.4',ttNumber);
|
TestString('123.4',ttNumber);
|
||||||
TestString('123.E4',ttNumber);
|
TestString('123.E4',ttNumber);
|
||||||
TestString('1.E4',ttNumber);
|
TestString('1.E4',ttNumber);
|
||||||
TestString('1e-2',ttNumber);
|
TestString('1e-2',ttNumber);
|
||||||
DoInvalidNumber('1..1');
|
DoInvalidNumber('1..1');
|
||||||
|
}
|
||||||
DoInvalidNumber('1.E--1');
|
DoInvalidNumber('1.E--1');
|
||||||
DoInvalidNumber('.E-1');
|
// DoInvalidNumber('.E-1');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestExpressionScanner.TestInvalidCharacter;
|
procedure TTestExpressionScanner.TestInvalidCharacter;
|
||||||
begin
|
begin
|
||||||
DoInvalidNumber('~');
|
DoInvalidNumber('~');
|
||||||
DoInvalidNumber('^');
|
|
||||||
DoInvalidNumber('#');
|
DoInvalidNumber('#');
|
||||||
DoInvalidNumber('$');
|
DoInvalidNumber('$');
|
||||||
DoInvalidNumber('^');
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestExpressionScanner.TestUnterminatedString;
|
procedure TTestExpressionScanner.TestUnterminatedString;
|
||||||
@ -1520,15 +1540,16 @@ end;
|
|||||||
procedure TTestConstExprNode.TestCreateFloat;
|
procedure TTestConstExprNode.TestCreateFloat;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
S : String;
|
F : Double;
|
||||||
|
C : Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
FN:=TFPConstExpression.CreateFloat(2.34);
|
FN:=TFPConstExpression.CreateFloat(2.34);
|
||||||
AssertEquals('Correct type',rtFloat,FN.NodeType);
|
AssertEquals('Correct type',rtFloat,FN.NodeType);
|
||||||
AssertEquals('Correct result',2.34,FN.ConstValue.ResFloat);
|
AssertEquals('Correct result',2.34,FN.ConstValue.ResFloat);
|
||||||
AssertEquals('Correct result',2.34,FN.NodeValue.ResFloat);
|
AssertEquals('Correct result',2.34,FN.NodeValue.ResFloat);
|
||||||
Str(TExprFLoat(2.34),S);
|
Val(FN.AsString,F,C);
|
||||||
AssertEquals('AsString ok',S,FN.AsString);
|
AssertEquals('AsString ok',2.34,F,0.001);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestConstExprNode.TestCreateBoolean;
|
procedure TTestConstExprNode.TestCreateBoolean;
|
||||||
@ -2428,6 +2449,130 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TTestPowerNode }
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TearDown;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FN);
|
||||||
|
inherited TearDown;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.Setup;
|
||||||
|
begin
|
||||||
|
inherited ;
|
||||||
|
FE:=TFpExpressionParser.Create(Nil);
|
||||||
|
FE.Builtins := [bcMath];
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.Calc(AExpr: String; Expected: Double =NaN);
|
||||||
|
const
|
||||||
|
EPS = 1e-9;
|
||||||
|
var
|
||||||
|
res: TFpExpressionResult;
|
||||||
|
x: Double;
|
||||||
|
begin
|
||||||
|
FE.Expression := AExpr;
|
||||||
|
res:=FE.Evaluate;
|
||||||
|
x:= ArgToFloat(res);
|
||||||
|
if not IsNaN(Expected) then
|
||||||
|
AssertEquals('Expression '+AExpr+' result',Expected,X,Eps);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestCalc;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Calc('2^2', Power(2, 2));
|
||||||
|
Calc('2^-2', Power(2, -2));
|
||||||
|
Calc('2^(-2)', Power(2, -2));
|
||||||
|
Calc('sqrt(3)^2', Power(sqrt(3), 2));
|
||||||
|
Calc('-sqrt(3)^2', -Power(sqrt(3), 2));
|
||||||
|
Calc('-2^2', -Power(2, 2));
|
||||||
|
Calc('(-2.0)^2', Power(-2.0, 2));
|
||||||
|
Calc('(-2.0)^-2', Power(-2.0, -2));
|
||||||
|
// Odd integer exponent
|
||||||
|
Calc('2^3', Power(2, 3));
|
||||||
|
Calc('-2^3', -Power(2, 3));
|
||||||
|
Calc('-2^-3', -Power(2, -3));
|
||||||
|
Calc('-2^(-3)', -Power(2, -3));
|
||||||
|
Calc('(-2.0)^3', Power(-2.0, 3));
|
||||||
|
Calc('(-2.0)^-3', Power(-2.0, -3));
|
||||||
|
// Fractional exponent
|
||||||
|
Calc('10^2.5', power(10, 2.5));
|
||||||
|
Calc('10^-2.5', Power(10, -2.5));
|
||||||
|
// Expressions
|
||||||
|
Calc('(1+1)^3', Power(1+1, 3));
|
||||||
|
Calc('1+2^3', 1 + Power(2, 3));
|
||||||
|
calc('2^3+1', Power(2, 3) + 1);
|
||||||
|
Calc('2^3*2', Power(2, 3) * 2);
|
||||||
|
Calc('2^3*-2', Power(2, 3) * -2);
|
||||||
|
Calc('2^(1+1)', Power(2, 1+1));
|
||||||
|
Calc('2^-(1+1)', Power(2, -(1+1)));
|
||||||
|
WriteLn;
|
||||||
|
// Special cases
|
||||||
|
Calc('0^0', power(0, 0));
|
||||||
|
calc('0^1', power(0, 1));
|
||||||
|
Calc('0^2.5', Power(0, 2.5));
|
||||||
|
calc('2.5^0', power(2.5, 0));
|
||||||
|
calc('2^3^4', 2417851639229258349412352); // according to Wolfram Alpha, 2^(3^4)
|
||||||
|
|
||||||
|
// These expressions should throw expections
|
||||||
|
|
||||||
|
//Calc('(-10)^2.5', NaN); // base must be positive in case of fractional exponent
|
||||||
|
//Calc('0^-2', NaN); // is 1/0^2 = 1/0
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestCreateInteger;
|
||||||
|
begin
|
||||||
|
FN:=TFPPowerOperation.Create(CreateIntNode(4),CreateIntNode(2));
|
||||||
|
AssertEquals('Power has correct type',rtfloat,FN.NodeType);
|
||||||
|
AssertEquals('Power has correct result',16.0,FN.NodeValue.ResFloat);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestCreateFloat;
|
||||||
|
begin
|
||||||
|
FN:=TFPPowerOperation.Create(CreateFloatNode(2.0),CreateFloatNode(3.0));
|
||||||
|
AssertEquals('Power has correct type',rtFloat,FN.NodeType);
|
||||||
|
AssertEquals('Power has correct result',8.0,FN.NodeValue.ResFloat);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestCreateDateTime;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D,T : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=Date;
|
||||||
|
T:=Time;
|
||||||
|
FN:=TFPPowerOperation.Create(CreateDateTimeNode(D+T),CreateDateTimeNode(T));
|
||||||
|
AssertNodeNotOK('No datetime Power',FN);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestCreateString;
|
||||||
|
begin
|
||||||
|
FN:=TFPPowerOperation.Create(CreateStringNode('alo'),CreateStringNode('ha'));
|
||||||
|
AssertNodeNotOK('No string Power',FN);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestCreateBoolean;
|
||||||
|
begin
|
||||||
|
FN:=TFPPowerOperation.Create(CreateBoolNode(True),CreateBoolNode(False));
|
||||||
|
AssertNodeNotOK('No boolean Power',FN);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestDestroy;
|
||||||
|
begin
|
||||||
|
FN:=TFPPowerOperation.Create(TMyDestroyNode.CreateTest(Self),TMyDestroyNode.CreateTest(Self));
|
||||||
|
FreeAndNil(FN);
|
||||||
|
AssertEquals('Destroy called for left and right nodes',2,self.FDestroyCalled)
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestPowerNode.TestAsString;
|
||||||
|
begin
|
||||||
|
FN:=TFPPowerOperation.Create(CreateIntNode(1),CreateIntNode(2));
|
||||||
|
AssertEquals('Asstring works ok','1^2',FN.AsString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TTestDivideNode }
|
{ TTestDivideNode }
|
||||||
|
|
||||||
procedure TTestDivideNode.TearDown;
|
procedure TTestDivideNode.TearDown;
|
||||||
@ -5575,7 +5720,7 @@ procedure TTestBuiltins.TestRegister;
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
RegisterStdBuiltins(FM);
|
RegisterStdBuiltins(FM);
|
||||||
AssertEquals('Correct number of identifiers',67,FM.IdentifierCount);
|
AssertEquals('Correct number of identifiers',69,FM.IdentifierCount);
|
||||||
Assertvariable('pi',rtFloat);
|
Assertvariable('pi',rtFloat);
|
||||||
AssertFunction('cos','F','F',bcMath);
|
AssertFunction('cos','F','F',bcMath);
|
||||||
AssertFunction('sin','F','F',bcMath);
|
AssertFunction('sin','F','F',bcMath);
|
||||||
@ -5643,6 +5788,8 @@ begin
|
|||||||
AssertFunction('sum','F','F',bcAggregate);
|
AssertFunction('sum','F','F',bcAggregate);
|
||||||
AssertFunction('count','I','',bcAggregate);
|
AssertFunction('count','I','',bcAggregate);
|
||||||
AssertFunction('avg','F','F',bcAggregate);
|
AssertFunction('avg','F','F',bcAggregate);
|
||||||
|
AssertFunction('min','F','F',bcAggregate);
|
||||||
|
AssertFunction('max','F','F',bcAggregate);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestBuiltins.TestVariablepi;
|
procedure TTestBuiltins.TestVariablepi;
|
||||||
@ -6586,7 +6733,7 @@ initialization
|
|||||||
TTestLessThanNode,TTestLessThanEqualNode,
|
TTestLessThanNode,TTestLessThanEqualNode,
|
||||||
TTestLargerThanNode,TTestLargerThanEqualNode,
|
TTestLargerThanNode,TTestLargerThanEqualNode,
|
||||||
TTestAddNode,TTestSubtractNode,
|
TTestAddNode,TTestSubtractNode,
|
||||||
TTestMultiplyNode,TTestDivideNode,
|
TTestMultiplyNode,TTestDivideNode,TTestPowerNode,
|
||||||
TTestIntToFloatNode,TTestIntToDateTimeNode,
|
TTestIntToFloatNode,TTestIntToDateTimeNode,
|
||||||
TTestFloatToDateTimeNode,
|
TTestFloatToDateTimeNode,
|
||||||
TTestParserExpressions, TTestParserBooleanOperations,
|
TTestParserExpressions, TTestParserBooleanOperations,
|
||||||
|
Loading…
Reference in New Issue
Block a user