mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 10:39:18 +02:00
* Add support for currency type
git-svn-id: trunk@38523 -
This commit is contained in:
parent
3a78ff1ee4
commit
c3414c6100
@ -85,7 +85,7 @@ Type
|
|||||||
|
|
||||||
EExprScanner = Class(Exception);
|
EExprScanner = Class(Exception);
|
||||||
|
|
||||||
TResultType = (rtBoolean,rtInteger,rtFloat,rtDateTime,rtString);
|
TResultType = (rtBoolean,rtInteger,rtFloat,rtDateTime,rtString,rtCurrency);
|
||||||
TResultTypes = set of TResultType;
|
TResultTypes = set of TResultType;
|
||||||
|
|
||||||
TFPExpressionResult = record
|
TFPExpressionResult = record
|
||||||
@ -94,6 +94,7 @@ Type
|
|||||||
rtBoolean : (ResBoolean : Boolean);
|
rtBoolean : (ResBoolean : Boolean);
|
||||||
rtInteger : (ResInteger : Int64);
|
rtInteger : (ResInteger : Int64);
|
||||||
rtFloat : (ResFloat : TExprFloat);
|
rtFloat : (ResFloat : TExprFloat);
|
||||||
|
rtCurrency : (ResCurrency : Currency);
|
||||||
rtDateTime : (ResDateTime : TDatetime);
|
rtDateTime : (ResDateTime : TDatetime);
|
||||||
rtString : ();
|
rtString : ();
|
||||||
end;
|
end;
|
||||||
@ -389,12 +390,21 @@ Type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ TIntToFloatNode }
|
{ TIntToFloatNode }
|
||||||
|
|
||||||
TIntToFloatNode = Class(TIntConvertNode)
|
TIntToFloatNode = Class(TIntConvertNode)
|
||||||
Public
|
Public
|
||||||
Function NodeType : TResultType; override;
|
Function NodeType : TResultType; override;
|
||||||
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TIntToCurrencyNode }
|
||||||
|
|
||||||
|
TIntToCurrencyNode = Class(TIntConvertNode)
|
||||||
|
Public
|
||||||
|
Function NodeType : TResultType; override;
|
||||||
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TIntToDateTimeNode }
|
{ TIntToDateTimeNode }
|
||||||
|
|
||||||
TIntToDateTimeNode = Class(TIntConvertNode)
|
TIntToDateTimeNode = Class(TIntConvertNode)
|
||||||
@ -412,6 +422,34 @@ Type
|
|||||||
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFloatToCurrencyNode }
|
||||||
|
|
||||||
|
TFloatToCurrencyNode = Class(TFPConvertNode)
|
||||||
|
Public
|
||||||
|
Procedure Check; override;
|
||||||
|
Function NodeType : TResultType; override;
|
||||||
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCurrencyToDateTimeNode }
|
||||||
|
|
||||||
|
TCurrencyToDateTimeNode = Class(TFPConvertNode)
|
||||||
|
Public
|
||||||
|
Procedure Check; override;
|
||||||
|
Function NodeType : TResultType; override;
|
||||||
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCurrencyToFloatNode }
|
||||||
|
|
||||||
|
TCurrencyToFloatNode = Class(TFPConvertNode)
|
||||||
|
Public
|
||||||
|
Procedure Check; override;
|
||||||
|
Function NodeType : TResultType; override;
|
||||||
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TFPNegateOperation }
|
{ TFPNegateOperation }
|
||||||
|
|
||||||
TFPNegateOperation = Class(TFPUnaryOperator)
|
TFPNegateOperation = Class(TFPUnaryOperator)
|
||||||
@ -433,6 +471,7 @@ Type
|
|||||||
Constructor CreateDateTime(AValue : TDateTime);
|
Constructor CreateDateTime(AValue : TDateTime);
|
||||||
Constructor CreateFloat(AValue : TExprFloat);
|
Constructor CreateFloat(AValue : TExprFloat);
|
||||||
Constructor CreateBoolean(AValue : Boolean);
|
Constructor CreateBoolean(AValue : Boolean);
|
||||||
|
constructor CreateCurrency(AValue: Currency);
|
||||||
Procedure Check; override;
|
Procedure Check; override;
|
||||||
Function NodeType : TResultType; override;
|
Function NodeType : TResultType; override;
|
||||||
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
Procedure GetNodeValue(var Result : TFPExpressionResult); override;
|
||||||
@ -465,6 +504,7 @@ Type
|
|||||||
function GetAsBoolean: Boolean;
|
function GetAsBoolean: Boolean;
|
||||||
function GetAsDateTime: TDateTime;
|
function GetAsDateTime: TDateTime;
|
||||||
function GetAsFloat: TExprFloat;
|
function GetAsFloat: TExprFloat;
|
||||||
|
function GetAsCurrency : Currency;
|
||||||
function GetAsInteger: Int64;
|
function GetAsInteger: Int64;
|
||||||
function GetAsString: String;
|
function GetAsString: String;
|
||||||
function GetResultType: TResultType;
|
function GetResultType: TResultType;
|
||||||
@ -473,6 +513,7 @@ Type
|
|||||||
procedure SetAsBoolean(const AValue: Boolean);
|
procedure SetAsBoolean(const AValue: Boolean);
|
||||||
procedure SetAsDateTime(const AValue: TDateTime);
|
procedure SetAsDateTime(const AValue: TDateTime);
|
||||||
procedure SetAsFloat(const AValue: TExprFloat);
|
procedure SetAsFloat(const AValue: TExprFloat);
|
||||||
|
procedure SetAsCurrency(const AValue: Currency);
|
||||||
procedure SetAsInteger(const AValue: Int64);
|
procedure SetAsInteger(const AValue: Int64);
|
||||||
procedure SetAsString(const AValue: String);
|
procedure SetAsString(const AValue: String);
|
||||||
procedure SetName(const AValue: ShortString);
|
procedure SetName(const AValue: ShortString);
|
||||||
@ -487,6 +528,7 @@ Type
|
|||||||
Procedure Assign(Source : TPersistent); override;
|
Procedure Assign(Source : TPersistent); override;
|
||||||
Function EventBasedVariable : Boolean; Inline;
|
Function EventBasedVariable : Boolean; Inline;
|
||||||
Property AsFloat : TExprFloat Read GetAsFloat Write SetAsFloat;
|
Property AsFloat : TExprFloat Read GetAsFloat Write SetAsFloat;
|
||||||
|
Property AsCurrency : Currency Read GetAsCurrency Write SetAsCurrency;
|
||||||
Property AsInteger : Int64 Read GetAsInteger Write SetAsInteger;
|
Property AsInteger : Int64 Read GetAsInteger Write SetAsInteger;
|
||||||
Property AsString : String Read GetAsString Write SetAsString;
|
Property AsString : String Read GetAsString Write SetAsString;
|
||||||
Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean;
|
Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean;
|
||||||
@ -539,6 +581,7 @@ Type
|
|||||||
Function AddBooleanVariable(Const AName : ShortString; AValue : Boolean) : TFPExprIdentifierDef;
|
Function AddBooleanVariable(Const AName : ShortString; AValue : Boolean) : TFPExprIdentifierDef;
|
||||||
Function AddIntegerVariable(Const AName : ShortString; AValue : Integer) : TFPExprIdentifierDef;
|
Function AddIntegerVariable(Const AName : ShortString; AValue : Integer) : TFPExprIdentifierDef;
|
||||||
Function AddFloatVariable(Const AName : ShortString; AValue : TExprFloat) : TFPExprIdentifierDef;
|
Function AddFloatVariable(Const AName : ShortString; AValue : TExprFloat) : TFPExprIdentifierDef;
|
||||||
|
Function AddCurrencyVariable(Const AName : ShortString; AValue : Currency) : TFPExprIdentifierDef;
|
||||||
Function AddStringVariable(Const AName : ShortString; AValue : String) : TFPExprIdentifierDef;
|
Function AddStringVariable(Const AName : ShortString; AValue : String) : TFPExprIdentifierDef;
|
||||||
Function AddDateTimeVariable(Const AName : ShortString; AValue : TDateTime) : TFPExprIdentifierDef;
|
Function AddDateTimeVariable(Const AName : ShortString; AValue : TDateTime) : TFPExprIdentifierDef;
|
||||||
Function AddFunction(Const AName : ShortString; Const AResultType : Char; Const AParamTypes : String; ACallBack : TFPExprFunctionCallBack) : TFPExprIdentifierDef;
|
Function AddFunction(Const AName : ShortString; Const AResultType : Char; Const AParamTypes : String; ACallBack : TFPExprFunctionCallBack) : TFPExprIdentifierDef;
|
||||||
@ -576,6 +619,7 @@ Type
|
|||||||
FargumentParams : TExprParameterArray;
|
FargumentParams : TExprParameterArray;
|
||||||
Protected
|
Protected
|
||||||
Procedure CalcParams;
|
Procedure CalcParams;
|
||||||
|
function ConvertArgument(aIndex: Integer; aNode: TFPExprNode; aType: TResultType): TFPExprNode; virtual;
|
||||||
Public
|
Public
|
||||||
Procedure Check; override;
|
Procedure Check; override;
|
||||||
Constructor CreateFunction(AID : TFPExprIdentifierDef; Const Args : TExprArgumentArray); virtual;
|
Constructor CreateFunction(AID : TFPExprIdentifierDef; Const Args : TExprArgumentArray); virtual;
|
||||||
@ -622,6 +666,7 @@ Type
|
|||||||
|
|
||||||
TAggregateSum = Class(TAggregateExpr)
|
TAggregateSum = Class(TAggregateExpr)
|
||||||
Public
|
Public
|
||||||
|
function ConvertArgument(aIndex: Integer; aNode: TFPExprNode; aType: TResultType): TFPExprNode; override;
|
||||||
Procedure InitAggregate; override;
|
Procedure InitAggregate; override;
|
||||||
Procedure UpdateAggregate; override;
|
Procedure UpdateAggregate; override;
|
||||||
end;
|
end;
|
||||||
@ -679,10 +724,10 @@ Type
|
|||||||
FHashList : TFPHashObjectlist;
|
FHashList : TFPHashObjectlist;
|
||||||
FDirty : Boolean;
|
FDirty : Boolean;
|
||||||
procedure CheckEOF;
|
procedure CheckEOF;
|
||||||
function ConvertNode(Todo: TFPExprNode; ToType: TResultType): TFPExprNode;
|
|
||||||
function GetAsBoolean: Boolean;
|
function GetAsBoolean: Boolean;
|
||||||
function GetAsDateTime: TDateTime;
|
function GetAsDateTime: TDateTime;
|
||||||
function GetAsFloat: TExprFloat;
|
function GetAsFloat: TExprFloat;
|
||||||
|
function GetAsCurrency: Currency;
|
||||||
function GetAsInteger: Int64;
|
function GetAsInteger: Int64;
|
||||||
function GetAsString: String;
|
function GetAsString: String;
|
||||||
function MatchNodes(Todo, Match: TFPExprNode): TFPExprNode;
|
function MatchNodes(Todo, Match: TFPExprNode): TFPExprNode;
|
||||||
@ -693,6 +738,8 @@ Type
|
|||||||
procedure ParserError(Msg: String);
|
procedure ParserError(Msg: String);
|
||||||
procedure SetExpression(const AValue: String); virtual;
|
procedure SetExpression(const AValue: String); virtual;
|
||||||
Procedure CheckResultType(Const Res :TFPExpressionResult; AType : TResultType); inline;
|
Procedure CheckResultType(Const Res :TFPExpressionResult; AType : TResultType); inline;
|
||||||
|
Procedure CheckResultTypes(Const Res :TFPExpressionResult; ATypes : TResultTypes); inline;
|
||||||
|
Class function ConvertNode(Todo: TFPExprNode; ToType: TResultType): TFPExprNode;
|
||||||
class Function BuiltinsManager : TExprBuiltInManager;
|
class Function BuiltinsManager : TExprBuiltInManager;
|
||||||
Function Level1 : TFPExprNode;
|
Function Level1 : TFPExprNode;
|
||||||
Function Level2 : TFPExprNode;
|
Function Level2 : TFPExprNode;
|
||||||
@ -714,7 +761,7 @@ Type
|
|||||||
Destructor Destroy; override;
|
Destructor Destroy; override;
|
||||||
Function IdentifierByName(const AName : ShortString) : TFPExprIdentifierDef; virtual;
|
Function IdentifierByName(const AName : ShortString) : TFPExprIdentifierDef; virtual;
|
||||||
Procedure Clear;
|
Procedure Clear;
|
||||||
Procedure EvaluateExpression(Var Result : TFPExpressionResult);
|
Procedure EvaluateExpression(Out Result : TFPExpressionResult);
|
||||||
function ExtractNode(var N: TFPExprNode): Boolean;
|
function ExtractNode(var N: TFPExprNode): Boolean;
|
||||||
Function Evaluate : TFPExpressionResult;
|
Function Evaluate : TFPExpressionResult;
|
||||||
Function ResultType : TResultType;
|
Function ResultType : TResultType;
|
||||||
@ -722,6 +769,7 @@ Type
|
|||||||
Procedure InitAggregate;
|
Procedure InitAggregate;
|
||||||
Procedure UpdateAggregate;
|
Procedure UpdateAggregate;
|
||||||
Property AsFloat : TExprFloat Read GetAsFloat;
|
Property AsFloat : TExprFloat Read GetAsFloat;
|
||||||
|
Property AsCurrency : Currency Read GetAsCurrency;
|
||||||
Property AsInteger : Int64 Read GetAsInteger;
|
Property AsInteger : Int64 Read GetAsInteger;
|
||||||
Property AsString : String Read GetAsString;
|
Property AsString : String Read GetAsString;
|
||||||
Property AsBoolean : Boolean Read GetAsBoolean;
|
Property AsBoolean : Boolean Read GetAsBoolean;
|
||||||
@ -752,6 +800,7 @@ Type
|
|||||||
Function AddBooleanVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : Boolean) : TFPBuiltInExprIdentifierDef;
|
Function AddBooleanVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : Boolean) : TFPBuiltInExprIdentifierDef;
|
||||||
Function AddIntegerVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : Integer) : TFPBuiltInExprIdentifierDef;
|
Function AddIntegerVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : Integer) : TFPBuiltInExprIdentifierDef;
|
||||||
Function AddFloatVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : TExprFloat) : TFPBuiltInExprIdentifierDef;
|
Function AddFloatVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : TExprFloat) : TFPBuiltInExprIdentifierDef;
|
||||||
|
Function AddCurrencyVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : Currency) : TFPBuiltInExprIdentifierDef;
|
||||||
Function AddStringVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : String) : TFPBuiltInExprIdentifierDef;
|
Function AddStringVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : String) : TFPBuiltInExprIdentifierDef;
|
||||||
Function AddDateTimeVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : TDateTime) : TFPBuiltInExprIdentifierDef;
|
Function AddDateTimeVariable(Const ACategory : TBuiltInCategory; Const AName : ShortString; AValue : TDateTime) : TFPBuiltInExprIdentifierDef;
|
||||||
Function AddFunction(Const ACategory : TBuiltInCategory; Const AName : ShortString; Const AResultType : Char; Const AParamTypes : String; ACallBack : TFPExprFunctionCallBack) : TFPBuiltInExprIdentifierDef;
|
Function AddFunction(Const ACategory : TBuiltInCategory; Const AName : ShortString; Const AResultType : Char; Const AParamTypes : String; ACallBack : TFPExprFunctionCallBack) : TFPBuiltInExprIdentifierDef;
|
||||||
@ -877,6 +926,7 @@ begin
|
|||||||
'B' : Result:=rtBoolean;
|
'B' : Result:=rtBoolean;
|
||||||
'I' : Result:=rtInteger;
|
'I' : Result:=rtInteger;
|
||||||
'F' : Result:=rtFloat;
|
'F' : Result:=rtFloat;
|
||||||
|
'C' : Result:=rtCurrency;
|
||||||
else
|
else
|
||||||
RaiseParserError(SErrInvalidResultCharacter,[C]);
|
RaiseParserError(SErrInvalidResultCharacter,[C]);
|
||||||
end;
|
end;
|
||||||
@ -899,6 +949,39 @@ begin
|
|||||||
FreeAndNil(Builtins);
|
FreeAndNil(Builtins);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFloatToCurrencyNode }
|
||||||
|
|
||||||
|
procedure TFloatToCurrencyNode.Check;
|
||||||
|
begin
|
||||||
|
CheckNodeType(Operand,[rtFloat]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFloatToCurrencyNode.NodeType: TResultType;
|
||||||
|
begin
|
||||||
|
Result:=rtCurrency;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFloatToCurrencyNode.GetNodeValue(var Result: TFPExpressionResult);
|
||||||
|
begin
|
||||||
|
Operand.GetNodeValue(Result);
|
||||||
|
Result.ResultType:=rtCurrency;
|
||||||
|
Result.ResCurrency:=Result.ResFloat;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TIntToCurrencyNode }
|
||||||
|
|
||||||
|
function TIntToCurrencyNode.NodeType: TResultType;
|
||||||
|
begin
|
||||||
|
Result:=rtCurrency;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIntToCurrencyNode.GetNodeValue(var Result: TFPExpressionResult);
|
||||||
|
begin
|
||||||
|
Operand.GetNodeValue(Result);
|
||||||
|
Result.ResCurrency:=Result.ResInteger;
|
||||||
|
Result.ResultType:=rtCurrency;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFPModuloOperation }
|
{ TFPModuloOperation }
|
||||||
|
|
||||||
procedure TFPModuloOperation.Check;
|
procedure TFPModuloOperation.Check;
|
||||||
@ -936,47 +1019,16 @@ procedure TAggregateMax.InitAggregate;
|
|||||||
begin
|
begin
|
||||||
inherited InitAggregate;
|
inherited InitAggregate;
|
||||||
FFirst:=True;
|
FFirst:=True;
|
||||||
FResult.ResultType:=rtFloat;
|
FResult.ResultType:=FArgumentNodes[0].NodeType;
|
||||||
FResult.resFloat:=0;
|
Case FResult.ResultType of
|
||||||
|
rtFloat : FResult.resFloat:=0.0;
|
||||||
|
rtCurrency : FResult.resCurrency:=0.0;
|
||||||
|
rtInteger : FResult.resInteger:=0;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TAggregateMax.UpdateAggregate;
|
procedure TAggregateMax.UpdateAggregate;
|
||||||
|
|
||||||
Var
|
|
||||||
OK : Boolean;
|
|
||||||
N : TFPExpressionResult;
|
|
||||||
|
|
||||||
begin
|
|
||||||
FArgumentNodes[0].GetNodeValue(N);
|
|
||||||
if FFirst then
|
|
||||||
begin
|
|
||||||
FFirst:=False;
|
|
||||||
OK:=True;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Case N.ResultType of
|
|
||||||
rtFloat: OK:=N.ResFloat>FResult.ResFloat;
|
|
||||||
rtinteger: OK:=N.ResInteger>FResult.ResFloat;
|
|
||||||
end;
|
|
||||||
if OK then
|
|
||||||
Case N.ResultType of
|
|
||||||
rtFloat: FResult.ResFloat:=N.ResFloat;
|
|
||||||
rtinteger: FResult.ResFloat:=N.ResInteger;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TAggregateMin }
|
|
||||||
|
|
||||||
procedure TAggregateMin.InitAggregate;
|
|
||||||
begin
|
|
||||||
inherited InitAggregate;
|
|
||||||
FFirst:=True;
|
|
||||||
FResult.ResultType:=rtFloat;
|
|
||||||
FResult.resFloat:=0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TAggregateMin.UpdateAggregate;
|
|
||||||
|
|
||||||
Var
|
Var
|
||||||
OK : Boolean;
|
OK : Boolean;
|
||||||
N : TFPExpressionResult;
|
N : TFPExpressionResult;
|
||||||
@ -989,14 +1041,57 @@ begin
|
|||||||
FFirst:=False;
|
FFirst:=False;
|
||||||
OK:=True;
|
OK:=True;
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
Case N.ResultType of
|
||||||
|
rtFloat: OK:=N.ResFloat>FResult.ResFloat;
|
||||||
|
rtCurrency: OK:=N.ResCurrency>FResult.ResCurrency;
|
||||||
|
rtinteger: OK:=N.ResInteger>FResult.ResFloat;
|
||||||
|
end;
|
||||||
|
if OK then
|
||||||
|
Case N.ResultType of
|
||||||
|
rtFloat: FResult.ResFloat:=N.ResFloat;
|
||||||
|
rtinteger: FResult.ResFloat:=N.ResInteger;
|
||||||
|
rtCurrency: FResult.ResCurrency:=N.ResCurrency;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TAggregateMin }
|
||||||
|
|
||||||
|
procedure TAggregateMin.InitAggregate;
|
||||||
|
begin
|
||||||
|
inherited InitAggregate;
|
||||||
|
FFirst:=True;
|
||||||
|
FResult.ResultType:=FArgumentNodes[0].NodeType;
|
||||||
|
Case FResult.ResultType of
|
||||||
|
rtFloat : FResult.resFloat:=0.0;
|
||||||
|
rtCurrency : FResult.resCurrency:=0.0;
|
||||||
|
rtInteger : FResult.resInteger:=0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TAggregateMin.UpdateAggregate;
|
||||||
|
|
||||||
|
Var
|
||||||
|
OK : Boolean;
|
||||||
|
N : TFPExpressionResult;
|
||||||
|
|
||||||
|
begin
|
||||||
|
FArgumentNodes[0].GetNodeValue(N);
|
||||||
|
if FFirst then
|
||||||
|
begin
|
||||||
|
FFirst:=False;
|
||||||
|
OK:=True;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Case N.ResultType of
|
Case N.ResultType of
|
||||||
rtFloat: OK:=N.ResFloat<FResult.ResFloat;
|
rtFloat: OK:=N.ResFloat<FResult.ResFloat;
|
||||||
|
rtCurrency: OK:=N.ResCurrency<FResult.ResCurrency;
|
||||||
rtinteger: OK:=N.ResInteger<FResult.ResFloat;
|
rtinteger: OK:=N.ResInteger<FResult.ResFloat;
|
||||||
end;
|
end;
|
||||||
if OK then
|
if OK then
|
||||||
Case FResult.ResultType of
|
Case FResult.ResultType of
|
||||||
rtFloat: FResult.ResFloat:=N.ResFloat;
|
rtFloat: FResult.ResFloat:=N.ResFloat;
|
||||||
|
rtCurrency: FResult.ResCurrency:=N.ResCurrency;
|
||||||
rtinteger: FResult.ResFloat:=N.ResInteger;
|
rtinteger: FResult.ResFloat:=N.ResInteger;
|
||||||
end;
|
end;
|
||||||
inherited UpdateAggregate;
|
inherited UpdateAggregate;
|
||||||
@ -1007,7 +1102,6 @@ end;
|
|||||||
procedure TAggregateAvg.InitAggregate;
|
procedure TAggregateAvg.InitAggregate;
|
||||||
begin
|
begin
|
||||||
inherited InitAggregate;
|
inherited InitAggregate;
|
||||||
FCount:=0;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TAggregateAvg.UpdateAggregate;
|
procedure TAggregateAvg.UpdateAggregate;
|
||||||
@ -1019,15 +1113,30 @@ end;
|
|||||||
procedure TAggregateAvg.GetNodeValue(var Result: TFPExpressionResult);
|
procedure TAggregateAvg.GetNodeValue(var Result: TFPExpressionResult);
|
||||||
begin
|
begin
|
||||||
inherited GetNodeValue(Result);
|
inherited GetNodeValue(Result);
|
||||||
Result.ResultType:=rtFloat;
|
Result.ResultType:=FResult.ResultType;
|
||||||
if FCount=0 then
|
if FCount=0 then
|
||||||
Result.ResFloat:=0
|
Case FResult.ResultType of
|
||||||
|
rtInteger:
|
||||||
|
begin
|
||||||
|
Result.ResultType:=rtFloat;
|
||||||
|
Result.ResFloat:=0.0;
|
||||||
|
end;
|
||||||
|
rtFloat:
|
||||||
|
Result.ResFloat:=0.0;
|
||||||
|
rtCurrency:
|
||||||
|
Result.ResCurrency:=0.0;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Case FResult.ResultType of
|
Case FResult.ResultType of
|
||||||
rtInteger:
|
rtInteger:
|
||||||
|
begin
|
||||||
|
Result.ResultType:=rtFloat;
|
||||||
Result.ResFloat:=FResult.ResInteger/FCount;
|
Result.ResFloat:=FResult.ResInteger/FCount;
|
||||||
|
end;
|
||||||
rtFloat:
|
rtFloat:
|
||||||
Result.ResFloat:=FResult.ResFloat/FCount;
|
Result.ResFloat:=FResult.ResFloat/FCount;
|
||||||
|
rtCurrency:
|
||||||
|
Result.ResCurrency:=FResult.ResCurrency/FCount;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1058,12 +1167,20 @@ end;
|
|||||||
|
|
||||||
{ TAggregateSum }
|
{ TAggregateSum }
|
||||||
|
|
||||||
|
function TAggregateSum.ConvertArgument(aIndex: Integer; aNode: TFPExprNode; aType: TResultType): TFPExprNode;
|
||||||
|
begin
|
||||||
|
if not (aNode.NodeType in [rtFloat,rtInteger,rtCurrency]) then
|
||||||
|
RaiseParserError(SErrInvalidArgumentType,[aIndex,ResultTypeName(aType),ResultTypeName(aNode.NodeType)]);
|
||||||
|
Result:=aNode;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TAggregateSum.InitAggregate;
|
procedure TAggregateSum.InitAggregate;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
FResult.ResultType:=FArgumentNodes[0].NodeType;
|
FResult.ResultType:=FArgumentNodes[0].NodeType;
|
||||||
Case FResult.ResultType of
|
Case FResult.ResultType of
|
||||||
rtFloat: FResult.ResFloat:=0.0;
|
rtFloat: FResult.ResFloat:=0.0;
|
||||||
|
rtCurrency : FResult.ResCurrency:=0.0;
|
||||||
rtinteger: FResult.ResInteger:=0;
|
rtinteger: FResult.ResInteger:=0;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1077,6 +1194,7 @@ begin
|
|||||||
FArgumentNodes[0].GetNodeValue(R);
|
FArgumentNodes[0].GetNodeValue(R);
|
||||||
Case FResult.ResultType of
|
Case FResult.ResultType of
|
||||||
rtFloat: FResult.ResFloat:=FResult.ResFloat+R.ResFloat;
|
rtFloat: FResult.ResFloat:=FResult.ResFloat+R.ResFloat;
|
||||||
|
rtCurrency: FResult.ResCurrency:=FResult.ResCurrency+R.ResCurrency;
|
||||||
rtinteger: FResult.ResInteger:=FResult.ResInteger+R.ResInteger;
|
rtinteger: FResult.ResInteger:=FResult.ResInteger+R.ResInteger;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1468,7 +1586,7 @@ begin
|
|||||||
FIdentifiers.Assign(AValue)
|
FIdentifiers.Assign(AValue)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TFPExpressionParser.EvaluateExpression(var Result: TFPExpressionResult);
|
procedure TFPExpressionParser.EvaluateExpression(Out Result: TFPExpressionResult);
|
||||||
begin
|
begin
|
||||||
If (FExpression='') then
|
If (FExpression='') then
|
||||||
ParserError(SErrInExpressionEmpty);
|
ParserError(SErrInExpressionEmpty);
|
||||||
@ -1493,19 +1611,26 @@ begin
|
|||||||
Raise EExprParser.Create(Msg);
|
Raise EExprParser.Create(Msg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFPExpressionParser.ConvertNode(Todo : TFPExprNode; ToType : TResultType): TFPExprNode;
|
Class function TFPExpressionParser.ConvertNode(Todo : TFPExprNode; ToType : TResultType): TFPExprNode;
|
||||||
begin
|
begin
|
||||||
Result:=ToDo;
|
Result:=ToDo;
|
||||||
Case ToDo.NodeType of
|
Case ToDo.NodeType of
|
||||||
rtInteger :
|
rtInteger :
|
||||||
Case ToType of
|
Case ToType of
|
||||||
rtFloat : Result:=TIntToFloatNode.Create(Result);
|
rtFloat : Result:=TIntToFloatNode.Create(Result);
|
||||||
|
rtCurrency : Result:=TIntToCurrencyNode.Create(Result);
|
||||||
rtDateTime : Result:=TIntToDateTimeNode.Create(Result);
|
rtDateTime : Result:=TIntToDateTimeNode.Create(Result);
|
||||||
end;
|
end;
|
||||||
rtFloat :
|
rtFloat :
|
||||||
Case ToType of
|
Case ToType of
|
||||||
|
rtCurrency : Result:=TFloatToCurrencyNode.Create(Result);
|
||||||
rtDateTime : Result:=TFloatToDateTimeNode.Create(Result);
|
rtDateTime : Result:=TFloatToDateTimeNode.Create(Result);
|
||||||
end;
|
end;
|
||||||
|
rtCurrency :
|
||||||
|
Case ToType of
|
||||||
|
rtFloat : Result:=TCurrencyToFloatNode.Create(Result);
|
||||||
|
rtDateTime : Result:=TCurrencyToDateTimeNode.Create(Result);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1537,8 +1662,26 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
EvaluateExpression(Res);
|
EvaluateExpression(Res);
|
||||||
CheckResultType(Res,rtFloat);
|
CheckResultTypes(Res,[rtFloat,rtCurrency,rtInteger]);
|
||||||
Result:=Res.ResFloat;
|
case Res.ResultType of
|
||||||
|
rtInteger : Result:=Res.ResInteger;
|
||||||
|
rtFloat : Result:=Res.ResFloat;
|
||||||
|
rtCurrency : Result:=res.ResCurrency;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFPExpressionParser.GetAsCurrency: Currency;
|
||||||
|
var
|
||||||
|
Res: TFPExpressionResult;
|
||||||
|
|
||||||
|
begin
|
||||||
|
EvaluateExpression(Res);
|
||||||
|
CheckResultTypes(Res,[rtFloat,rtCurrency,rtInteger]);
|
||||||
|
case Res.ResultType of
|
||||||
|
rtInteger : Result:=Res.ResInteger;
|
||||||
|
rtFloat : Result:=Res.ResFloat;
|
||||||
|
rtCurrency : Result:=res.ResCurrency;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFPExpressionParser.GetAsInteger: Int64;
|
function TFPExpressionParser.GetAsInteger: Int64;
|
||||||
@ -1572,24 +1715,23 @@ end;
|
|||||||
function TFPExpressionParser.MatchNodes(Todo,Match : TFPExprNode): TFPExprNode;
|
function TFPExpressionParser.MatchNodes(Todo,Match : TFPExprNode): TFPExprNode;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
TT,MT : TResultType;
|
FromType,ToType : TResultType;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=Todo;
|
Result:=Todo;
|
||||||
TT:=Todo.NodeType;
|
FromType:=Todo.NodeType;
|
||||||
MT:=Match.NodeType;
|
ToType:=Match.NodeType;
|
||||||
If (TT<>MT) then
|
If (FromType<>ToType) then
|
||||||
begin
|
Case FromType of
|
||||||
if (TT=rtInteger) then
|
rtInteger:
|
||||||
begin
|
if (ToType in [rtFloat,rtCurrency,rtDateTime]) then
|
||||||
if (MT in [rtFloat,rtDateTime]) then
|
Result:=ConvertNode(Todo,toType);
|
||||||
Result:=ConvertNode(Todo,MT);
|
rtFloat:
|
||||||
end
|
if (ToType in [rtCurrency,rtDateTime]) then
|
||||||
else if (TT=rtFloat) then
|
Result:=ConvertNode(Todo,toType);
|
||||||
begin
|
rtCurrency:
|
||||||
if (MT=rtDateTime) then
|
if (ToType in [rtFloat,rtDateTime]) then
|
||||||
Result:=ConvertNode(Todo,rtDateTime);
|
Result:=ConvertNode(Todo,toType);
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1937,6 +2079,12 @@ begin
|
|||||||
RaiseParserError(SErrInvalidResultType,[ResultTypeName(Res.ResultType)]);
|
RaiseParserError(SErrInvalidResultType,[ResultTypeName(Res.ResultType)]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TFPExpressionParser.CheckResultTypes(const Res: TFPExpressionResult; ATypes: TResultTypes);
|
||||||
|
begin
|
||||||
|
If Not (Res.ResultType in ATypes) then
|
||||||
|
RaiseParserError(SErrInvalidResultType,[ResultTypeName(Res.ResultType)]);
|
||||||
|
end;
|
||||||
|
|
||||||
class function TFPExpressionParser.BuiltinsManager: TExprBuiltInManager;
|
class function TFPExpressionParser.BuiltinsManager: TExprBuiltInManager;
|
||||||
begin
|
begin
|
||||||
Result:=BuiltinIdentifiers;
|
Result:=BuiltinIdentifiers;
|
||||||
@ -2085,6 +2233,15 @@ begin
|
|||||||
Result.FValue.ResFloat:=AValue;
|
Result.FValue.ResFloat:=AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFPExprIdentifierDefs.AddCurrencyVariable(const AName: ShortString; AValue: Currency): TFPExprIdentifierDef;
|
||||||
|
begin
|
||||||
|
Result:=Add as TFPExprIdentifierDef;
|
||||||
|
Result.IdentifierType:=itVariable;
|
||||||
|
Result.Name:=AName;
|
||||||
|
Result.ResultType:=rtCurrency;
|
||||||
|
Result.FValue.ResCurrency:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFPExprIdentifierDefs.AddStringVariable(const AName: ShortString;
|
function TFPExprIdentifierDefs.AddStringVariable(const AName: ShortString;
|
||||||
AValue: String): TFPExprIdentifierDef;
|
AValue: String): TFPExprIdentifierDef;
|
||||||
begin
|
begin
|
||||||
@ -2172,6 +2329,7 @@ begin
|
|||||||
rtBoolean : FValue.ResBoolean:=FStringValue='True';
|
rtBoolean : FValue.ResBoolean:=FStringValue='True';
|
||||||
rtInteger : FValue.ResInteger:=StrToInt(AValue);
|
rtInteger : FValue.ResInteger:=StrToInt(AValue);
|
||||||
rtFloat : FValue.ResFloat:=StrToFloat(AValue, FileFormatSettings);
|
rtFloat : FValue.ResFloat:=StrToFloat(AValue, FileFormatSettings);
|
||||||
|
rtCurrency : FValue.ResFloat:=StrToCurr(AValue, FileFormatSettings);
|
||||||
rtDateTime : FValue.ResDateTime:=StrToDateTime(AValue, FileFormatSettings);
|
rtDateTime : FValue.ResDateTime:=StrToDateTime(AValue, FileFormatSettings);
|
||||||
rtString : FValue.ResString:=AValue;
|
rtString : FValue.ResString:=AValue;
|
||||||
end
|
end
|
||||||
@ -2180,6 +2338,7 @@ begin
|
|||||||
rtBoolean : FValue.ResBoolean:=False;
|
rtBoolean : FValue.ResBoolean:=False;
|
||||||
rtInteger : FValue.ResInteger:=0;
|
rtInteger : FValue.ResInteger:=0;
|
||||||
rtFloat : FValue.ResFloat:=0.0;
|
rtFloat : FValue.ResFloat:=0.0;
|
||||||
|
rtCurrency : FValue.ResCurrency:=0.0;
|
||||||
rtDateTime : FValue.ResDateTime:=0;
|
rtDateTime : FValue.ResDateTime:=0;
|
||||||
rtString : FValue.ResString:='';
|
rtString : FValue.ResString:='';
|
||||||
end
|
end
|
||||||
@ -2260,6 +2419,13 @@ begin
|
|||||||
FValue.ResFloat:=AValue;
|
FValue.ResFloat:=AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TFPExprIdentifierDef.SetAsCurrency(const AValue: Currency);
|
||||||
|
begin
|
||||||
|
CheckVariable;
|
||||||
|
CheckResultType(rtCurrency);
|
||||||
|
FValue.ResCurrency:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TFPExprIdentifierDef.SetAsInteger(const AValue: Int64);
|
procedure TFPExprIdentifierDef.SetAsInteger(const AValue: Int64);
|
||||||
begin
|
begin
|
||||||
CheckVariable;
|
CheckVariable;
|
||||||
@ -2283,6 +2449,7 @@ begin
|
|||||||
Result:='False';
|
Result:='False';
|
||||||
rtInteger : Result:=IntToStr(FValue.ResInteger);
|
rtInteger : Result:=IntToStr(FValue.ResInteger);
|
||||||
rtFloat : Result:=FloatToStr(FValue.ResFloat, FileFormatSettings);
|
rtFloat : Result:=FloatToStr(FValue.ResFloat, FileFormatSettings);
|
||||||
|
rtCurrency : Result:=CurrToStr(FValue.ResCurrency, FileFormatSettings);
|
||||||
rtDateTime : Result:=FormatDateTime('cccc',FValue.ResDateTime, FileFormatSettings);
|
rtDateTime : Result:=FormatDateTime('cccc',FValue.ResDateTime, FileFormatSettings);
|
||||||
rtString : Result:=FValue.ResString;
|
rtString : Result:=FValue.ResString;
|
||||||
end;
|
end;
|
||||||
@ -2304,7 +2471,7 @@ begin
|
|||||||
if RT2<>RT then
|
if RT2<>RT then
|
||||||
begin
|
begin
|
||||||
// Automatically convert integer to float.
|
// Automatically convert integer to float.
|
||||||
if (rt2=rtInteger) and (rt=rtFLoat) then
|
if (rt2=rtInteger) and (rt=rtFloat) then
|
||||||
begin
|
begin
|
||||||
FValue.ResultType:=RT;
|
FValue.ResultType:=RT;
|
||||||
I:=FValue.resInteger;
|
I:=FValue.resInteger;
|
||||||
@ -2340,6 +2507,13 @@ begin
|
|||||||
Result:=FValue.ResFloat;
|
Result:=FValue.ResFloat;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFPExprIdentifierDef.GetAsCurrency: Currency;
|
||||||
|
begin
|
||||||
|
CheckResultType(rtCurrency);
|
||||||
|
CheckVariable;
|
||||||
|
Result:=FValue.ResCurrency;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFPExprIdentifierDef.GetAsBoolean: Boolean;
|
function TFPExprIdentifierDef.GetAsBoolean: Boolean;
|
||||||
begin
|
begin
|
||||||
CheckResultType(rtBoolean);
|
CheckResultType(rtBoolean);
|
||||||
@ -2445,6 +2619,13 @@ begin
|
|||||||
Result.Category:=ACategory;
|
Result.Category:=ACategory;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TExprBuiltInManager.AddCurrencyVariable(const ACategory: TBuiltInCategory; const AName: ShortString; AValue: Currency
|
||||||
|
): TFPBuiltInExprIdentifierDef;
|
||||||
|
begin
|
||||||
|
Result:=TFPBuiltInExprIdentifierDef(FDefs.AddCurrencyVariable(AName,AValue));
|
||||||
|
Result.Category:=ACategory;
|
||||||
|
end;
|
||||||
|
|
||||||
function TExprBuiltInManager.AddStringVariable(
|
function TExprBuiltInManager.AddStringVariable(
|
||||||
const ACategory: TBuiltInCategory; const AName: ShortString; AValue: String
|
const ACategory: TBuiltInCategory; const AName: ShortString; AValue: String
|
||||||
): TFPBuiltInExprIdentifierDef;
|
): TFPBuiltInExprIdentifierDef;
|
||||||
@ -2621,6 +2802,13 @@ begin
|
|||||||
FValue.ResFloat:=AValue;
|
FValue.ResFloat:=AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
constructor TFPConstExpression.CreateCurrency(AValue: Currency);
|
||||||
|
begin
|
||||||
|
Inherited create;
|
||||||
|
FValue.ResultType:=rtCurrency;
|
||||||
|
FValue.ResCurrency:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TFPConstExpression.CreateBoolean(AValue: Boolean);
|
constructor TFPConstExpression.CreateBoolean(AValue: Boolean);
|
||||||
begin
|
begin
|
||||||
FValue.ResultType:=rtBoolean;
|
FValue.ResultType:=rtBoolean;
|
||||||
@ -2650,6 +2838,7 @@ begin
|
|||||||
rtDateTime : Result:=''''+FormatDateTime('cccc',FValue.resDateTime)+'''';
|
rtDateTime : Result:=''''+FormatDateTime('cccc',FValue.resDateTime)+'''';
|
||||||
rtBoolean : If FValue.ResBoolean then Result:='True' else Result:='False';
|
rtBoolean : If FValue.ResBoolean then Result:='True' else Result:='False';
|
||||||
rtFloat : Str(FValue.ResFloat,Result);
|
rtFloat : Str(FValue.ResFloat,Result);
|
||||||
|
rtCurrency : Str(FValue.ResCurrency,Result);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2659,7 +2848,7 @@ end;
|
|||||||
procedure TFPNegateOperation.Check;
|
procedure TFPNegateOperation.Check;
|
||||||
begin
|
begin
|
||||||
Inherited;
|
Inherited;
|
||||||
If Not (Operand.NodeType in [rtInteger,rtFloat]) then
|
If Not (Operand.NodeType in [rtInteger,rtFloat,rtCurrency]) then
|
||||||
RaiseParserError(SErrNoNegation,[ResultTypeName(Operand.NodeType),Operand.AsString])
|
RaiseParserError(SErrNoNegation,[ResultTypeName(Operand.NodeType),Operand.AsString])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2674,6 +2863,7 @@ begin
|
|||||||
Case Result.ResultType of
|
Case Result.ResultType of
|
||||||
rtInteger : Result.resInteger:=-Result.ResInteger;
|
rtInteger : Result.resInteger:=-Result.ResInteger;
|
||||||
rtFloat : Result.resFloat:=-Result.ResFloat;
|
rtFloat : Result.resFloat:=-Result.ResFloat;
|
||||||
|
rtCurrency : Result.resCurrency:=-Result.ResCurrency;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2917,7 +3107,8 @@ begin
|
|||||||
Case RT.ResultType of
|
Case RT.ResultType of
|
||||||
rtBoolean : B:=RT.ResBoolean=RV.ResBoolean;
|
rtBoolean : B:=RT.ResBoolean=RV.ResBoolean;
|
||||||
rtInteger : B:=RT.ResInteger=RV.ResInteger;
|
rtInteger : B:=RT.ResInteger=RV.ResInteger;
|
||||||
rtFloat : B:=RT.ResFloat=RV.ResFLoat;
|
rtFloat : B:=RT.ResFloat=RV.ResFloat;
|
||||||
|
rtCurrency : B:=RT.resCurrency=RV.resCurrency;
|
||||||
rtDateTime : B:=RT.ResDateTime=RV.ResDateTime;
|
rtDateTime : B:=RT.ResDateTime=RV.ResDateTime;
|
||||||
rtString : B:=RT.ResString=RV.ResString;
|
rtString : B:=RT.ResString=RV.ResString;
|
||||||
end;
|
end;
|
||||||
@ -3072,7 +3263,8 @@ begin
|
|||||||
Case Result.ResultType of
|
Case Result.ResultType of
|
||||||
rtBoolean : Result.resBoolean:=Result.ResBoolean=RRes.ResBoolean;
|
rtBoolean : Result.resBoolean:=Result.ResBoolean=RRes.ResBoolean;
|
||||||
rtInteger : Result.resBoolean:=Result.ResInteger=RRes.ResInteger;
|
rtInteger : Result.resBoolean:=Result.ResInteger=RRes.ResInteger;
|
||||||
rtFloat : Result.resBoolean:=Result.ResFloat=RRes.ResFLoat;
|
rtFloat : Result.resBoolean:=Result.ResFloat=RRes.ResFloat;
|
||||||
|
rtCurrency : Result.resBoolean:=Result.resCurrency=RRes.resCurrency;
|
||||||
rtDateTime : Result.resBoolean:=Result.ResDateTime=RRes.ResDateTime;
|
rtDateTime : Result.resBoolean:=Result.ResDateTime=RRes.ResDateTime;
|
||||||
rtString : Result.resBoolean:=Result.ResString=RRes.ResString;
|
rtString : Result.resBoolean:=Result.ResString=RRes.ResString;
|
||||||
end;
|
end;
|
||||||
@ -3109,7 +3301,8 @@ begin
|
|||||||
Right.GetNodeValue(RRes);
|
Right.GetNodeValue(RRes);
|
||||||
Case Result.ResultType of
|
Case Result.ResultType of
|
||||||
rtInteger : Result.resBoolean:=Result.ResInteger<RRes.ResInteger;
|
rtInteger : Result.resBoolean:=Result.ResInteger<RRes.ResInteger;
|
||||||
rtFloat : Result.resBoolean:=Result.ResFloat<RRes.ResFLoat;
|
rtFloat : Result.resBoolean:=Result.ResFloat<RRes.ResFloat;
|
||||||
|
rtCurrency : Result.resBoolean:=Result.resCurrency<RRes.resCurrency;
|
||||||
rtDateTime : Result.resBoolean:=Result.ResDateTime<RRes.ResDateTime;
|
rtDateTime : Result.resBoolean:=Result.ResDateTime<RRes.ResDateTime;
|
||||||
rtString : Result.resBoolean:=Result.ResString<RRes.ResString;
|
rtString : Result.resBoolean:=Result.ResString<RRes.ResString;
|
||||||
end;
|
end;
|
||||||
@ -3135,10 +3328,17 @@ begin
|
|||||||
rtInteger : case Right.NodeType of
|
rtInteger : case Right.NodeType of
|
||||||
rtInteger : Result.resBoolean:=Result.ResInteger>RRes.ResInteger;
|
rtInteger : Result.resBoolean:=Result.ResInteger>RRes.ResInteger;
|
||||||
rtFloat : Result.resBoolean:=Result.ResInteger>RRes.ResFloat;
|
rtFloat : Result.resBoolean:=Result.ResInteger>RRes.ResFloat;
|
||||||
|
rtCurrency : Result.resBoolean:=Result.ResInteger>RRes.resCurrency;
|
||||||
end;
|
end;
|
||||||
rtFloat : case Right.NodeType of
|
rtFloat : case Right.NodeType of
|
||||||
rtInteger : Result.resBoolean:=Result.ResFloat>RRes.ResInteger;
|
rtInteger : Result.resBoolean:=Result.ResFloat>RRes.ResInteger;
|
||||||
rtFloat : Result.resBoolean:=Result.ResFloat>RRes.ResFLoat;
|
rtFloat : Result.resBoolean:=Result.ResFloat>RRes.ResFloat;
|
||||||
|
rtCurrency : Result.resBoolean:=Result.ResFloat>RRes.ResCurrency;
|
||||||
|
end;
|
||||||
|
rtCurrency : case Right.NodeType of
|
||||||
|
rtInteger : Result.resBoolean:=Result.ResCurrency>RRes.ResInteger;
|
||||||
|
rtFloat : Result.resBoolean:=Result.ResCurrency>RRes.ResFloat;
|
||||||
|
rtCurrency : Result.resBoolean:=Result.ResCurrency>RRes.ResCurrency;
|
||||||
end;
|
end;
|
||||||
rtDateTime : Result.resBoolean:=Result.ResDateTime>RRes.ResDateTime;
|
rtDateTime : Result.resBoolean:=Result.ResDateTime>RRes.ResDateTime;
|
||||||
rtString : Result.resBoolean:=Result.ResString>RRes.ResString;
|
rtString : Result.resBoolean:=Result.ResString>RRes.ResString;
|
||||||
@ -3177,7 +3377,7 @@ end;
|
|||||||
procedure TFPOrderingOperation.Check;
|
procedure TFPOrderingOperation.Check;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
AllowedTypes =[rtInteger,rtfloat,rtDateTime,rtString];
|
AllowedTypes =[rtInteger,rtfloat,rtCurrency,rtDateTime,rtString];
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CheckNodeType(Left,AllowedTypes);
|
CheckNodeType(Left,AllowedTypes);
|
||||||
@ -3190,7 +3390,7 @@ end;
|
|||||||
procedure TMathOperation.Check;
|
procedure TMathOperation.Check;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
AllowedTypes =[rtInteger,rtfloat,rtDateTime,rtString];
|
AllowedTypes =[rtInteger,rtfloat,rtCurrency,rtDateTime,rtString];
|
||||||
|
|
||||||
begin
|
begin
|
||||||
inherited Check;
|
inherited Check;
|
||||||
@ -3223,7 +3423,8 @@ begin
|
|||||||
rtInteger : Result.ResInteger:=Result.ResInteger+RRes.ResInteger;
|
rtInteger : Result.ResInteger:=Result.ResInteger+RRes.ResInteger;
|
||||||
rtString : Result.ResString:=Result.ResString+RRes.ResString;
|
rtString : Result.ResString:=Result.ResString+RRes.ResString;
|
||||||
rtDateTime : Result.ResDateTime:=Result.ResDateTime+RRes.ResDateTime;
|
rtDateTime : Result.ResDateTime:=Result.ResDateTime+RRes.ResDateTime;
|
||||||
rtFloat : Result.ResFLoat:=Result.ResFLoat+RRes.ResFLoat;
|
rtFloat : Result.ResFloat:=Result.ResFloat+RRes.ResFloat;
|
||||||
|
rtCurrency : Result.ResCurrency:=Result.ResCurrency+RRes.ResCurrency;
|
||||||
end;
|
end;
|
||||||
Result.ResultType:=NodeType;
|
Result.ResultType:=NodeType;
|
||||||
end;
|
end;
|
||||||
@ -3233,7 +3434,7 @@ end;
|
|||||||
procedure TFPSubtractOperation.check;
|
procedure TFPSubtractOperation.check;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
AllowedTypes =[rtInteger,rtfloat,rtDateTime];
|
AllowedTypes =[rtInteger,rtfloat,rtCurrency,rtDateTime];
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CheckNodeType(Left,AllowedTypes);
|
CheckNodeType(Left,AllowedTypes);
|
||||||
@ -3257,7 +3458,8 @@ begin
|
|||||||
case Result.ResultType of
|
case Result.ResultType of
|
||||||
rtInteger : Result.ResInteger:=Result.ResInteger-RRes.ResInteger;
|
rtInteger : Result.ResInteger:=Result.ResInteger-RRes.ResInteger;
|
||||||
rtDateTime : Result.ResDateTime:=Result.ResDateTime-RRes.ResDateTime;
|
rtDateTime : Result.ResDateTime:=Result.ResDateTime-RRes.ResDateTime;
|
||||||
rtFloat : Result.ResFLoat:=Result.ResFLoat-RRes.ResFLoat;
|
rtFloat : Result.ResFloat:=Result.ResFloat-RRes.ResFloat;
|
||||||
|
rtCurrency : Result.resCurrency:=Result.resCurrency-RRes.ResCurrency;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3266,7 +3468,7 @@ end;
|
|||||||
procedure TFPMultiplyOperation.check;
|
procedure TFPMultiplyOperation.check;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
AllowedTypes =[rtInteger,rtfloat];
|
AllowedTypes =[rtInteger,rtCurrency,rtfloat];
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CheckNodeType(Left,AllowedTypes);
|
CheckNodeType(Left,AllowedTypes);
|
||||||
@ -3288,7 +3490,8 @@ begin
|
|||||||
Right.GetNodeValue(RRes);
|
Right.GetNodeValue(RRes);
|
||||||
case Result.ResultType of
|
case Result.ResultType of
|
||||||
rtInteger : Result.ResInteger:=Result.ResInteger*RRes.ResInteger;
|
rtInteger : Result.ResInteger:=Result.ResInteger*RRes.ResInteger;
|
||||||
rtFloat : Result.ResFLoat:=Result.ResFLoat*RRes.ResFLoat;
|
rtFloat : Result.ResFloat:=Result.ResFloat*RRes.ResFloat;
|
||||||
|
rtCurrency : Result.ResCurrency:=Result.ResCurrency*RRes.ResCurrency;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3296,7 +3499,7 @@ end;
|
|||||||
|
|
||||||
procedure TFPDivideOperation.check;
|
procedure TFPDivideOperation.check;
|
||||||
Const
|
Const
|
||||||
AllowedTypes =[rtInteger,rtfloat];
|
AllowedTypes =[rtInteger,rtCurrency,rtfloat];
|
||||||
|
|
||||||
begin
|
begin
|
||||||
CheckNodeType(Left,AllowedTypes);
|
CheckNodeType(Left,AllowedTypes);
|
||||||
@ -3310,8 +3513,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFPDivideOperation.NodeType: TResultType;
|
function TFPDivideOperation.NodeType: TResultType;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=rtFLoat;
|
if (Left.NodeType=rtCurrency) and (Right.NodeType=rtCurrency) then
|
||||||
|
Result:=rtCurrency
|
||||||
|
else
|
||||||
|
Result:=rtFloat;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure TFPDivideOperation.GetNodeValue(var Result : TFPExpressionResult);
|
Procedure TFPDivideOperation.GetNodeValue(var Result : TFPExpressionResult);
|
||||||
@ -3324,16 +3531,21 @@ begin
|
|||||||
Right.GetNodeValue(RRes);
|
Right.GetNodeValue(RRes);
|
||||||
case Result.ResultType of
|
case Result.ResultType of
|
||||||
rtInteger : Result.ResFloat:=Result.ResInteger/RRes.ResInteger;
|
rtInteger : Result.ResFloat:=Result.ResInteger/RRes.ResInteger;
|
||||||
rtFloat : Result.ResFLoat:=Result.ResFLoat/RRes.ResFLoat;
|
rtFloat : Result.ResFloat:=Result.ResFloat/RRes.ResFloat;
|
||||||
|
rtCurrency :
|
||||||
|
if NodeType=rtCurrency then
|
||||||
|
Result.ResCurrency:=Result.ResCurrency/RRes.ResCurrency
|
||||||
|
else
|
||||||
|
Result.ResFloat:=Result.ResFloat/RRes.ResFloat;
|
||||||
end;
|
end;
|
||||||
Result.ResultType:=rtFloat;
|
Result.ResultType:=NodeType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFPPowerOperation }
|
{ TFPPowerOperation }
|
||||||
|
|
||||||
procedure TFPPowerOperation.Check;
|
procedure TFPPowerOperation.Check;
|
||||||
const
|
const
|
||||||
AllowedTypes = [rtInteger, rtFloat];
|
AllowedTypes = [rtInteger, rtCurrency, rtFloat];
|
||||||
begin
|
begin
|
||||||
CheckNodeType(Left, AllowedTypes);
|
CheckNodeType(Left, AllowedTypes);
|
||||||
CheckNodeType(Right, AllowedTypes);
|
CheckNodeType(Right, AllowedTypes);
|
||||||
@ -3440,6 +3652,46 @@ begin
|
|||||||
Result.ResultType:=rtDateTime;
|
Result.ResultType:=rtDateTime;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TCurrencyToDateTimeNode }
|
||||||
|
|
||||||
|
procedure TCurrencyToDateTimeNode.Check;
|
||||||
|
begin
|
||||||
|
inherited Check;
|
||||||
|
CheckNodeType(Operand,[rtCurrency]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCurrencyToDateTimeNode.NodeType: TResultType;
|
||||||
|
begin
|
||||||
|
Result:=rtDateTime;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Procedure TCurrencyToDateTimeNode.GetNodeValue(var Result : TFPExpressionResult);
|
||||||
|
begin
|
||||||
|
Operand.GetNodeValue(Result);
|
||||||
|
Result.ResDateTime:=Result.ResCurrency;
|
||||||
|
Result.ResultType:=rtDateTime;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCurrencyToFloatNode }
|
||||||
|
|
||||||
|
procedure TCurrencyToFloatNode.Check;
|
||||||
|
begin
|
||||||
|
inherited Check;
|
||||||
|
CheckNodeType(Operand,[rtCurrency]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCurrencyToFloatNode.NodeType: TResultType;
|
||||||
|
begin
|
||||||
|
Result:=rtFloat;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Procedure TCurrencyToFloatNode.GetNodeValue(var Result : TFPExpressionResult);
|
||||||
|
begin
|
||||||
|
Operand.GetNodeValue(Result);
|
||||||
|
Result.ResFloat:=Result.ResCurrency;
|
||||||
|
Result.ResultType:=rtFloat;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFPExprIdentifierNode }
|
{ TFPExprIdentifierNode }
|
||||||
|
|
||||||
constructor TFPExprIdentifierNode.CreateIdentifier(AID: TFPExprIdentifierDef);
|
constructor TFPExprIdentifierNode.CreateIdentifier(AID: TFPExprIdentifierDef);
|
||||||
@ -3489,6 +3741,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Function TFPExprFunction.ConvertArgument(aIndex : Integer; aNode : TFPExprNode; aType : TResultType) : TFPExprNode;
|
||||||
|
|
||||||
|
Var
|
||||||
|
N : TFPExprNode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Automatically convert integers to floats for float/currency parameters
|
||||||
|
N:=TFPExpressionParser.ConvertNode(aNode,aType);
|
||||||
|
if (aNode=N) then
|
||||||
|
// No conversion was performed, raise error
|
||||||
|
RaiseParserError(SErrInvalidArgumentType,[aIndex,ResultTypeName(aType),ResultTypeName(aNode.NodeType)]);
|
||||||
|
Result:=N;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFPExprFunction.HasAggregate: Boolean;
|
function TFPExprFunction.HasAggregate: Boolean;
|
||||||
var
|
var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
@ -3515,22 +3781,13 @@ begin
|
|||||||
begin
|
begin
|
||||||
rtp:=CharToResultType(FID.ParameterTypes[i+1]);
|
rtp:=CharToResultType(FID.ParameterTypes[i+1]);
|
||||||
rta:=FArgumentNodes[i].NodeType;
|
rta:=FArgumentNodes[i].NodeType;
|
||||||
If (rtp<>rta) then begin
|
If (rtp<>rta) then
|
||||||
|
FArgumentNodes[i]:=ConvertArgument(I+1,FArgumentNodes[i],rtp);
|
||||||
// Automatically convert integers to floats in functions that return
|
|
||||||
// a float
|
|
||||||
if (rta = rtInteger) and (rtp = rtFloat) then begin
|
|
||||||
FArgumentNodes[i] := TIntToFloatNode.Create(FArgumentNodes[i]);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
RaiseParserError(SErrInvalidArgumentType,[I+1,ResultTypeName(rtp),ResultTypeName(rta)])
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFPExprFunction.CreateFunction(AID: TFPExprIdentifierDef;
|
constructor TFPExprFunction.CreateFunction(AID: TFPExprIdentifierDef; const Args: TExprArgumentArray);
|
||||||
const Args: TExprArgumentArray);
|
|
||||||
begin
|
begin
|
||||||
Inherited CreateIdentifier(AID);
|
Inherited CreateIdentifier(AID);
|
||||||
FArgumentNodes:=Args;
|
FArgumentNodes:=Args;
|
||||||
@ -3637,6 +3894,8 @@ function ArgToFloat(Arg: TFPExpressionResult): TExprFloat;
|
|||||||
begin
|
begin
|
||||||
if Arg.ResultType = rtInteger then
|
if Arg.ResultType = rtInteger then
|
||||||
result := Arg.resInteger
|
result := Arg.resInteger
|
||||||
|
else if Arg.ResultType = rtCurrency then
|
||||||
|
result := Arg.resCurrency
|
||||||
else
|
else
|
||||||
result := Arg.resFloat;
|
result := Arg.resFloat;
|
||||||
end;
|
end;
|
||||||
|
@ -506,6 +506,7 @@ type
|
|||||||
procedure DoEchoBoolean(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
procedure DoEchoBoolean(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
||||||
procedure DoEchoDate(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
procedure DoEchoDate(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
||||||
procedure DoEchoFloat(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
procedure DoEchoFloat(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
||||||
|
procedure DoEchoCurrency(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
||||||
procedure DoEchoInteger(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
procedure DoEchoInteger(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
||||||
procedure DoEchoString(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
procedure DoEchoString(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
||||||
procedure DoGetDate(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
procedure DoGetDate(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
|
||||||
@ -518,6 +519,7 @@ type
|
|||||||
Procedure AssertOperand(N : TFPExprNode; OperandClass : TClass);
|
Procedure AssertOperand(N : TFPExprNode; OperandClass : TClass);
|
||||||
Procedure AssertResultType(RT : TResultType);
|
Procedure AssertResultType(RT : TResultType);
|
||||||
Procedure AssertResult(F : TExprFloat);
|
Procedure AssertResult(F : TExprFloat);
|
||||||
|
Procedure AssertCurrencyResult(C : Currency);
|
||||||
Procedure AssertResult(I : Int64);
|
Procedure AssertResult(I : Int64);
|
||||||
Procedure AssertResult(S : String);
|
Procedure AssertResult(S : String);
|
||||||
Procedure AssertResult(B : Boolean);
|
Procedure AssertResult(B : Boolean);
|
||||||
@ -730,9 +732,10 @@ type
|
|||||||
FTest33 : TFPExprIdentifierDef;
|
FTest33 : TFPExprIdentifierDef;
|
||||||
procedure DoGetBooleanVar(var Res: TFPExpressionResult; ConstRef AName: ShortString);
|
procedure DoGetBooleanVar(var Res: TFPExpressionResult; ConstRef AName: ShortString);
|
||||||
procedure DoGetBooleanVarWrong(var Res: TFPExpressionResult; ConstRef AName: ShortString);
|
procedure DoGetBooleanVarWrong(var Res: TFPExpressionResult; ConstRef AName: ShortString);
|
||||||
procedure DoTestVariable33;
|
|
||||||
procedure TestAccess(Skip: TResultType);
|
procedure TestAccess(Skip: TResultType);
|
||||||
|
procedure TestAccess(Skip: TResultTypes);
|
||||||
Protected
|
Protected
|
||||||
|
procedure DoTestVariable33;
|
||||||
procedure AddVariabletwice;
|
procedure AddVariabletwice;
|
||||||
procedure UnknownVariable;
|
procedure UnknownVariable;
|
||||||
Procedure ReadWrongType;
|
Procedure ReadWrongType;
|
||||||
@ -775,6 +778,8 @@ type
|
|||||||
procedure TestVariable32;
|
procedure TestVariable32;
|
||||||
procedure TestVariable33;
|
procedure TestVariable33;
|
||||||
procedure TestVariable34;
|
procedure TestVariable34;
|
||||||
|
procedure TestVariable35;
|
||||||
|
procedure TestVariable36;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TTestParserFunctions }
|
{ TTestParserFunctions }
|
||||||
@ -814,6 +819,10 @@ type
|
|||||||
procedure TestFunction27;
|
procedure TestFunction27;
|
||||||
procedure TestFunction28;
|
procedure TestFunction28;
|
||||||
procedure TestFunction29;
|
procedure TestFunction29;
|
||||||
|
procedure TestFunction30;
|
||||||
|
procedure TestFunction31;
|
||||||
|
procedure TestFunction32;
|
||||||
|
procedure TestFunction33;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TAggregateNode }
|
{ TAggregateNode }
|
||||||
@ -851,6 +860,7 @@ type
|
|||||||
Procedure TestCountAggregate;
|
Procedure TestCountAggregate;
|
||||||
Procedure TestSumAggregate;
|
Procedure TestSumAggregate;
|
||||||
Procedure TestSumAggregate2;
|
Procedure TestSumAggregate2;
|
||||||
|
Procedure TestSumAggregate3;
|
||||||
Procedure TestAvgAggregate;
|
Procedure TestAvgAggregate;
|
||||||
Procedure TestAvgAggregate2;
|
Procedure TestAvgAggregate2;
|
||||||
Procedure TestAvgAggregate3;
|
Procedure TestAvgAggregate3;
|
||||||
@ -871,6 +881,7 @@ type
|
|||||||
procedure TestVariable4;
|
procedure TestVariable4;
|
||||||
procedure TestVariable5;
|
procedure TestVariable5;
|
||||||
procedure TestVariable6;
|
procedure TestVariable6;
|
||||||
|
procedure TestVariable7;
|
||||||
procedure TestFunction1;
|
procedure TestFunction1;
|
||||||
procedure TestFunction2;
|
procedure TestFunction2;
|
||||||
end;
|
end;
|
||||||
@ -895,6 +906,7 @@ type
|
|||||||
procedure AssertDateTimeExpression(Const AExpression : String; Const AResult : TDateTime);
|
procedure AssertDateTimeExpression(Const AExpression : String; Const AResult : TDateTime);
|
||||||
procedure AssertAggregateExpression(Const AExpression : String; AResult : Int64; AUpdateCount : integer);
|
procedure AssertAggregateExpression(Const AExpression : String; AResult : Int64; AUpdateCount : integer);
|
||||||
procedure AssertAggregateExpression(Const AExpression : String; AResult : TExprFloat; AUpdateCount : integer);
|
procedure AssertAggregateExpression(Const AExpression : String; AResult : TExprFloat; AUpdateCount : integer);
|
||||||
|
procedure AssertAggregateCurrExpression(Const AExpression : String; AResult : Currency; AUpdateCount : integer);
|
||||||
Published
|
Published
|
||||||
procedure TestRegister;
|
procedure TestRegister;
|
||||||
Procedure TestVariablepi;
|
Procedure TestVariablepi;
|
||||||
@ -962,6 +974,8 @@ type
|
|||||||
Procedure TestFunctionstrtodatetime;
|
Procedure TestFunctionstrtodatetime;
|
||||||
Procedure TestFunctionstrtodatetimedef;
|
Procedure TestFunctionstrtodatetimedef;
|
||||||
Procedure TestFunctionAggregateSum;
|
Procedure TestFunctionAggregateSum;
|
||||||
|
Procedure TestFunctionAggregateSumFloat;
|
||||||
|
Procedure TestFunctionAggregateSumCurrency;
|
||||||
Procedure TestFunctionAggregateCount;
|
Procedure TestFunctionAggregateCount;
|
||||||
Procedure TestFunctionAggregateAvg;
|
Procedure TestFunctionAggregateAvg;
|
||||||
Procedure TestFunctionAggregateMin;
|
Procedure TestFunctionAggregateMin;
|
||||||
@ -1004,6 +1018,7 @@ begin
|
|||||||
Case Result.ResultType of
|
Case Result.ResultType of
|
||||||
rtInteger : Result.ResInteger:=FVarValue;
|
rtInteger : Result.ResInteger:=FVarValue;
|
||||||
rtFloat : Result.ResFloat:=FVarValue / 2;
|
rtFloat : Result.ResFloat:=FVarValue / 2;
|
||||||
|
rtCurrency : Result.ResCurrency:=FVarValue / 2;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1163,6 +1178,40 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserAggregate.TestSumAggregate3;
|
||||||
|
Var
|
||||||
|
C : TAggregateSum;
|
||||||
|
V : TFPExprVariable;
|
||||||
|
I : Integer;
|
||||||
|
R : TFPExpressionResult;
|
||||||
|
A : TExprArgumentArray;
|
||||||
|
|
||||||
|
begin
|
||||||
|
FFunction.ResultType:=rtCurrency;
|
||||||
|
FFunction.ParameterTypes:='F';
|
||||||
|
FFunction.Name:='SUM';
|
||||||
|
FFunction2.ResultType:=rtCurrency;
|
||||||
|
C:=Nil;
|
||||||
|
V:=TFPExprVariable.CreateIdentifier(FFunction2);
|
||||||
|
try
|
||||||
|
SetLength(A,1);
|
||||||
|
A[0]:=V;
|
||||||
|
C:=TAggregateSum.CreateFunction(FFunction,A);
|
||||||
|
C.Check;
|
||||||
|
C.InitAggregate;
|
||||||
|
For I:=1 to 10 do
|
||||||
|
begin
|
||||||
|
FVarValue:=I;
|
||||||
|
C.UpdateAggregate;
|
||||||
|
end;
|
||||||
|
C.GetNodeValue(R);
|
||||||
|
AssertEquals('Correct type',rtCurrency,R.ResultType);
|
||||||
|
AssertEquals('Correct value',55/2,R.ResCurrency,0.1);
|
||||||
|
finally
|
||||||
|
C.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestParserAggregate.TestAvgAggregate;
|
procedure TTestParserAggregate.TestAvgAggregate;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
@ -1237,7 +1286,6 @@ procedure TTestParserAggregate.TestAvgAggregate3;
|
|||||||
Var
|
Var
|
||||||
C : TAggregateAvg;
|
C : TAggregateAvg;
|
||||||
V : TFPExprVariable;
|
V : TFPExprVariable;
|
||||||
I : Integer;
|
|
||||||
R : TFPExpressionResult;
|
R : TFPExpressionResult;
|
||||||
A : TExprArgumentArray;
|
A : TExprArgumentArray;
|
||||||
|
|
||||||
@ -1565,6 +1613,7 @@ begin
|
|||||||
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);
|
||||||
Val(FN.AsString,F,C);
|
Val(FN.AsString,F,C);
|
||||||
|
AssertEquals('Correct conversion',0,C);
|
||||||
AssertEquals('AsString ok',2.34,F,0.001);
|
AssertEquals('AsString ok',2.34,F,0.001);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2828,6 +2877,12 @@ begin
|
|||||||
AssertEquals('Correct float result',F,FP.Evaluate.ResFloat);
|
AssertEquals('Correct float result',F,FP.Evaluate.ResFloat);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestExpressionParser.AssertCurrencyResult(C: Currency);
|
||||||
|
begin
|
||||||
|
AssertEquals('Correct currency result',C,FP.ExprNode.NodeValue.ResCurrency);
|
||||||
|
AssertEquals('Correct currency result',C,FP.Evaluate.ResCurrency);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestExpressionParser.AssertResult(I: Int64);
|
procedure TTestExpressionParser.AssertResult(I: Int64);
|
||||||
begin
|
begin
|
||||||
AssertEquals('Correct integer result',I,FP.ExprNode.NodeValue.ResInteger);
|
AssertEquals('Correct integer result',I,FP.ExprNode.NodeValue.ResInteger);
|
||||||
@ -4439,6 +4494,7 @@ begin
|
|||||||
rtString : res.ResString:=FP.Identifiers[0].AsString;
|
rtString : res.ResString:=FP.Identifiers[0].AsString;
|
||||||
rtInteger : Res.ResInteger:=FP.Identifiers[0].AsInteger;
|
rtInteger : Res.ResInteger:=FP.Identifiers[0].AsInteger;
|
||||||
rtFloat : Res.ResFloat:=FP.Identifiers[0].AsFloat;
|
rtFloat : Res.ResFloat:=FP.Identifiers[0].AsFloat;
|
||||||
|
rtCurrency : Res.ResCurrency:=FP.Identifiers[0].AsCurrency;
|
||||||
rtDateTime : Res.ResDateTime:=FP.Identifiers[0].AsDateTime;
|
rtDateTime : Res.ResDateTime:=FP.Identifiers[0].AsDateTime;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -4455,6 +4511,7 @@ begin
|
|||||||
rtString : FP.Identifiers[0].AsString:=res.ResString;
|
rtString : FP.Identifiers[0].AsString:=res.ResString;
|
||||||
rtInteger : FP.Identifiers[0].AsInteger:=Res.ResInteger;
|
rtInteger : FP.Identifiers[0].AsInteger:=Res.ResInteger;
|
||||||
rtFloat : FP.Identifiers[0].AsFloat:=Res.ResFloat;
|
rtFloat : FP.Identifiers[0].AsFloat:=Res.ResFloat;
|
||||||
|
rtCurrency : FP.Identifiers[0].AsCurrency:=Res.ResCurrency;
|
||||||
rtDateTime : FP.Identifiers[0].AsDateTime:=Res.ResDateTime;
|
rtDateTime : FP.Identifiers[0].AsDateTime:=Res.ResDateTime;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -4540,14 +4597,12 @@ Var
|
|||||||
begin
|
begin
|
||||||
D:=Now;
|
D:=Now;
|
||||||
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
AssertException('Cannot add same name twice',EExprParser,@AddVariabletwice);
|
AssertException('Cannot add same name twice',EExprParser,@AddVariabletwice);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestParserVariables.TestVariable8;
|
procedure TTestParserVariables.TestVariable8;
|
||||||
|
|
||||||
Var
|
|
||||||
I : TFPExprIdentifierDef;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
FP.Identifiers.AddIntegerVariable('a',123);
|
FP.Identifiers.AddIntegerVariable('a',123);
|
||||||
FP.Identifiers.AddIntegerVariable('b',123);
|
FP.Identifiers.AddIntegerVariable('b',123);
|
||||||
@ -4564,6 +4619,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddIntegerVariable('a',123);
|
I:=FP.Identifiers.AddIntegerVariable('a',123);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='a';
|
FP.Expression:='a';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
||||||
@ -4578,6 +4634,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddStringVariable('a','a123');
|
I:=FP.Identifiers.AddStringVariable('a','a123');
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='a';
|
FP.Expression:='a';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
||||||
@ -4592,6 +4649,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddFloatVariable('a',1.23);
|
I:=FP.Identifiers.AddFloatVariable('a',1.23);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='a';
|
FP.Expression:='a';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
||||||
@ -4599,6 +4657,21 @@ begin
|
|||||||
AssertResult(1.23);
|
AssertResult(1.23);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserVariables.TestVariable36;
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : TFPExprIdentifierDef;
|
||||||
|
|
||||||
|
begin
|
||||||
|
I:=FP.Identifiers.AddCurrencyVariable('a',1.23);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
|
FP.Expression:='a';
|
||||||
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
|
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
||||||
|
AssertResultType(rtCurrency);
|
||||||
|
AssertCurrencyResult(1.23);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestParserVariables.TestVariable12;
|
procedure TTestParserVariables.TestVariable12;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
@ -4606,6 +4679,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddBooleanVariable('a',True);
|
I:=FP.Identifiers.AddBooleanVariable('a',True);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='a';
|
FP.Expression:='a';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
||||||
@ -4622,6 +4696,7 @@ Var
|
|||||||
begin
|
begin
|
||||||
D:=Date;
|
D:=Date;
|
||||||
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='a';
|
FP.Expression:='a';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPExprVariable, FP.ExprNode);
|
||||||
@ -4648,6 +4723,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.BuildHashList;
|
FP.BuildHashList;
|
||||||
S:=FP.IdentifierByName('A');
|
S:=FP.IdentifierByName('A');
|
||||||
AssertSame('Identifier found',I,S);
|
AssertSame('Identifier found',I,S);
|
||||||
@ -4660,6 +4736,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.BuildHashList;
|
FP.BuildHashList;
|
||||||
S:=FP.IdentifierByName('B');
|
S:=FP.IdentifierByName('B');
|
||||||
AssertNull('Identifier not found',S);
|
AssertNull('Identifier not found',S);
|
||||||
@ -4668,10 +4745,11 @@ end;
|
|||||||
procedure TTestParserVariables.TestVariable17;
|
procedure TTestParserVariables.TestVariable17;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
I,S : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.BuildHashList;
|
FP.BuildHashList;
|
||||||
AssertException('Identifier not found',EExprParser,@unknownvariable);
|
AssertException('Identifier not found',EExprParser,@unknownvariable);
|
||||||
end;
|
end;
|
||||||
@ -4683,6 +4761,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
I:=FP.Identifiers.AddIntegerVariable('a',1);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
S:=FP.Identifiers.FindIdentifier('B');
|
S:=FP.Identifiers.FindIdentifier('B');
|
||||||
AssertNull('Identifier not found',S);
|
AssertNull('Identifier not found',S);
|
||||||
end;
|
end;
|
||||||
@ -4711,18 +4790,24 @@ end;
|
|||||||
|
|
||||||
procedure TTestParserVariables.TestAccess(Skip : TResultType);
|
procedure TTestParserVariables.TestAccess(Skip : TResultType);
|
||||||
|
|
||||||
|
begin
|
||||||
|
TestAccess([Skip]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserVariables.TestAccess(Skip : TResultTypes);
|
||||||
|
|
||||||
Var
|
Var
|
||||||
rt : TResultType;
|
rt : TResultType;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
For rt:=Low(TResultType) to High(TResultType) do
|
For rt:=Low(TResultType) to High(TResultType) do
|
||||||
if rt<>skip then
|
if Not (rt in skip) then
|
||||||
begin
|
begin
|
||||||
FasWrongType:=rt;
|
FasWrongType:=rt;
|
||||||
AssertException('Acces as '+ResultTypeName(rt),EExprParser,@ReadWrongtype);
|
AssertException('Acces as '+ResultTypeName(rt),EExprParser,@ReadWrongtype);
|
||||||
end;
|
end;
|
||||||
For rt:=Low(TResultType) to High(TResultType) do
|
For rt:=Low(TResultType) to High(TResultType) do
|
||||||
if rt<>skip then
|
if Not (rt in skip) then
|
||||||
begin
|
begin
|
||||||
FasWrongType:=rt;
|
FasWrongType:=rt;
|
||||||
AssertException('Acces as '+ResultTypeName(rt),EExprParser,@WriteWrongtype);
|
AssertException('Acces as '+ResultTypeName(rt),EExprParser,@WriteWrongtype);
|
||||||
@ -4732,13 +4817,20 @@ end;
|
|||||||
procedure TTestParserVariables.TestVariable21;
|
procedure TTestParserVariables.TestVariable21;
|
||||||
begin
|
begin
|
||||||
FP.IDentifiers.AddIntegerVariable('a',1);
|
FP.IDentifiers.AddIntegerVariable('a',1);
|
||||||
TestAccess(rtInteger);
|
TestAccess([rtInteger]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestParserVariables.TestVariable22;
|
procedure TTestParserVariables.TestVariable22;
|
||||||
begin
|
begin
|
||||||
FP.IDentifiers.AddFloatVariable('a',1.0);
|
FP.IDentifiers.AddFloatVariable('a',1.0);
|
||||||
TestAccess(rtFloat);
|
TestAccess([rtFloat]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserVariables.TestVariable35;
|
||||||
|
|
||||||
|
begin
|
||||||
|
FP.IDentifiers.AddCurrencyVariable('a',1.0);
|
||||||
|
TestAccess([rtCurrency]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestParserVariables.TestVariable23;
|
procedure TTestParserVariables.TestVariable23;
|
||||||
@ -4886,6 +4978,7 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
B:=FTest33.AsBoolean;
|
B:=FTest33.AsBoolean;
|
||||||
|
AssertTrue(B in [true,False])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestParserVariables.TestVariable33;
|
procedure TTestParserVariables.TestVariable33;
|
||||||
@ -4947,6 +5040,12 @@ begin
|
|||||||
Result.resFloat:=Args[0].resFloat;
|
Result.resFloat:=Args[0].resFloat;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Procedure EchoCurrency(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result.resCurrency:=Args[0].resCurrency;
|
||||||
|
end;
|
||||||
|
|
||||||
Procedure EchoString(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
|
Procedure EchoString(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -4977,6 +5076,12 @@ begin
|
|||||||
Result.resFloat:=Args[0].resFloat;
|
Result.resFloat:=Args[0].resFloat;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Procedure TTestExpressionParser.DoEchoCurrency(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result.resCurrency:=Args[0].resCurrency;
|
||||||
|
end;
|
||||||
|
|
||||||
Procedure TTestExpressionParser.DoEchoString(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
|
Procedure TTestExpressionParser.DoEchoString(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -5011,6 +5116,7 @@ begin
|
|||||||
rtString : res.ResString:=FP.Identifiers[0].AsString;
|
rtString : res.ResString:=FP.Identifiers[0].AsString;
|
||||||
rtInteger : Res.ResInteger:=FP.Identifiers[0].AsInteger;
|
rtInteger : Res.ResInteger:=FP.Identifiers[0].AsInteger;
|
||||||
rtFloat : Res.ResFloat:=FP.Identifiers[0].AsFloat;
|
rtFloat : Res.ResFloat:=FP.Identifiers[0].AsFloat;
|
||||||
|
rtCurrency : Res.ResCurrency:=FP.Identifiers[0].AsCurrency;
|
||||||
rtDateTime : Res.ResDateTime:=FP.Identifiers[0].AsDateTime;
|
rtDateTime : Res.ResDateTime:=FP.Identifiers[0].AsDateTime;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -5027,6 +5133,7 @@ begin
|
|||||||
rtString : FP.Identifiers[0].AsString:=res.ResString;
|
rtString : FP.Identifiers[0].AsString:=res.ResString;
|
||||||
rtInteger : FP.Identifiers[0].AsInteger:=Res.ResInteger;
|
rtInteger : FP.Identifiers[0].AsInteger:=Res.ResInteger;
|
||||||
rtFloat : FP.Identifiers[0].AsFloat:=Res.ResFloat;
|
rtFloat : FP.Identifiers[0].AsFloat:=Res.ResFloat;
|
||||||
|
rtCurrency : FP.Identifiers[0].AsCurrency:=Res.ResCurrency;
|
||||||
rtDateTime : FP.Identifiers[0].AsDateTime:=Res.ResDateTime;
|
rtDateTime : FP.Identifiers[0].AsDateTime:=Res.ResDateTime;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -5119,6 +5226,24 @@ begin
|
|||||||
AssertException('No write access',EExprParser,@TryWrite);
|
AssertException('No write access',EExprParser,@TryWrite);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserFunctions.TestFunction30;
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : TFPExprIdentifierDef;
|
||||||
|
|
||||||
|
begin
|
||||||
|
I:=FP.Identifiers.AddFunction('EchoCurrency','C','C',@EchoCurrency);
|
||||||
|
AssertEquals('List is dirty',True,FP.Dirty);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
|
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
||||||
|
AssertSame('Result equals variable added',I,FP.Identifiers[0]);
|
||||||
|
AssertEquals('Function has correct resulttype',rtCurrency,I.ResultType);
|
||||||
|
AssertSame('Function has correct address',Pointer(@EchoCurrency),Pointer(I.OnGetFunctionValueCallBack));
|
||||||
|
FaccessAs:=rtCurrency;
|
||||||
|
AssertException('No read access',EExprParser,@TryRead);
|
||||||
|
AssertException('No write access',EExprParser,@TryWrite);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestParserFunctions.TestFunction6;
|
procedure TTestParserFunctions.TestFunction6;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
@ -5197,6 +5322,21 @@ begin
|
|||||||
// AssertSame('Function has correct address',Pointer(@EchoFloat),Pointer(I.OnGetFunctionValueCallBack));
|
// AssertSame('Function has correct address',Pointer(@EchoFloat),Pointer(I.OnGetFunctionValueCallBack));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserFunctions.TestFunction31;
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : TFPExprIdentifierDef;
|
||||||
|
|
||||||
|
begin
|
||||||
|
I:=FP.Identifiers.AddFunction('EchoCurrency','C','C',@DoEchoCurrency);
|
||||||
|
AssertEquals('List is dirty',True,FP.Dirty);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
|
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
||||||
|
AssertSame('Result equals variable added',I,FP.Identifiers[0]);
|
||||||
|
AssertEquals('Function has correct resulttype',rtCurrency,I.ResultType);
|
||||||
|
// AssertSame('Function has correct address',Pointer(@EchoFloat),Pointer(I.OnGetFunctionValueCallBack));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestParserFunctions.TestFunction11;
|
procedure TTestParserFunctions.TestFunction11;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
@ -5221,6 +5361,7 @@ Var
|
|||||||
begin
|
begin
|
||||||
D:=Date;
|
D:=Date;
|
||||||
I:=FP.Identifiers.AddFunction('Date','D','',@GetDate);
|
I:=FP.Identifiers.AddFunction('Date','D','',@GetDate);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='Date';
|
FP.Expression:='Date';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
@ -5237,7 +5378,9 @@ Var
|
|||||||
begin
|
begin
|
||||||
D:=Date;
|
D:=Date;
|
||||||
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
I:=FP.Identifiers.AddFunction('EchoDate','D','D',@EchoDate);
|
I:=FP.Identifiers.AddFunction('EchoDate','D','D',@EchoDate);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='EchoDate(a)';
|
FP.Expression:='EchoDate(a)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
@ -5248,11 +5391,10 @@ end;
|
|||||||
procedure TTestParserFunctions.TestFunction14;
|
procedure TTestParserFunctions.TestFunction14;
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoInteger','I','I',@EchoInteger);
|
I:=FP.Identifiers.AddFunction('EchoInteger','I','I',@EchoInteger);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='EchoInteger(13)';
|
FP.Expression:='EchoInteger(13)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
@ -5263,11 +5405,10 @@ end;
|
|||||||
procedure TTestParserFunctions.TestFunction15;
|
procedure TTestParserFunctions.TestFunction15;
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoBoolean','B','B',@EchoBoolean);
|
I:=FP.Identifiers.AddFunction('EchoBoolean','B','B',@EchoBoolean);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
FP.Expression:='EchoBoolean(True)';
|
FP.Expression:='EchoBoolean(True)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
@ -5278,11 +5419,10 @@ end;
|
|||||||
procedure TTestParserFunctions.TestFunction16;
|
procedure TTestParserFunctions.TestFunction16;
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoFloat','F','F',@EchoFloat);
|
I:=FP.Identifiers.AddFunction('EchoFloat','F','F',@EchoFloat);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
FP.Expression:='EchoFloat(1.234)';
|
FP.Expression:='EchoFloat(1.234)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
@ -5290,14 +5430,47 @@ begin
|
|||||||
AssertResult(1.234);
|
AssertResult(1.234);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestParserFunctions.TestFunction17;
|
procedure TTestParserFunctions.TestFunction32;
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : TFPExprIdentifierDef;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Note there will be an implicit conversion float-> currency as the const will be a float
|
||||||
|
I:=FP.Identifiers.AddFunction('EchoCurrency','C','C',@EchoCurrency);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
|
FP.Expression:='EchoCurrency(1.234)';
|
||||||
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
|
AssertResultType(rtCurrency);
|
||||||
|
AssertCurrencyResult(1.234);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserFunctions.TestFunction33;
|
||||||
|
Var
|
||||||
|
I : TFPExprIdentifierDef;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Note there will be no conversion
|
||||||
|
I:=FP.Identifiers.AddCurrencyVariable('a',1.234);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
|
I:=FP.Identifiers.AddFunction('EchoCurrency','C','C',@EchoCurrency);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
|
FP.Expression:='EchoCurrency(a)';
|
||||||
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
|
AssertResultType(rtCurrency);
|
||||||
|
AssertCurrencyResult(1.234);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestParserFunctions.TestFunction17;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoString','S','S',@EchoString);
|
I:=FP.Identifiers.AddFunction('EchoString','S','S',@EchoString);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
FP.Expression:='EchoString(''Aloha'')';
|
FP.Expression:='EchoString(''Aloha'')';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionCallBack, FP.ExprNode);
|
||||||
@ -5315,7 +5488,9 @@ Var
|
|||||||
begin
|
begin
|
||||||
D:=Date;
|
D:=Date;
|
||||||
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
I:=FP.Identifiers.AddDateTimeVariable('a',D);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
I:=FP.Identifiers.AddFunction('EchoDate','D','D',@DoEchoDate);
|
I:=FP.Identifiers.AddFunction('EchoDate','D','D',@DoEchoDate);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
FP.Expression:='EchoDate(a)';
|
FP.Expression:='EchoDate(a)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
||||||
@ -5326,11 +5501,10 @@ end;
|
|||||||
procedure TTestParserFunctions.TestFunction19;
|
procedure TTestParserFunctions.TestFunction19;
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoInteger','I','I',@DoEchoInteger);
|
I:=FP.Identifiers.AddFunction('EchoInteger','I','I',@DoEchoInteger);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
FP.Expression:='EchoInteger(13)';
|
FP.Expression:='EchoInteger(13)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
||||||
@ -5341,11 +5515,10 @@ end;
|
|||||||
procedure TTestParserFunctions.TestFunction20;
|
procedure TTestParserFunctions.TestFunction20;
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoBoolean','B','B',@DoEchoBoolean);
|
I:=FP.Identifiers.AddFunction('EchoBoolean','B','B',@DoEchoBoolean);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
FP.Expression:='EchoBoolean(True)';
|
FP.Expression:='EchoBoolean(True)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
||||||
@ -5356,11 +5529,10 @@ end;
|
|||||||
procedure TTestParserFunctions.TestFunction21;
|
procedure TTestParserFunctions.TestFunction21;
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoFloat','F','F',@DoEchoFloat);
|
I:=FP.Identifiers.AddFunction('EchoFloat','F','F',@DoEchoFloat);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
FP.Expression:='EchoFloat(1.234)';
|
FP.Expression:='EchoFloat(1.234)';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
||||||
@ -5371,11 +5543,10 @@ end;
|
|||||||
procedure TTestParserFunctions.TestFunction22;
|
procedure TTestParserFunctions.TestFunction22;
|
||||||
Var
|
Var
|
||||||
I : TFPExprIdentifierDef;
|
I : TFPExprIdentifierDef;
|
||||||
D : TDateTime;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
D:=Date;
|
|
||||||
I:=FP.Identifiers.AddFunction('EchoString','S','S',@DoEchoString);
|
I:=FP.Identifiers.AddFunction('EchoString','S','S',@DoEchoString);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
FP.Expression:='EchoString(''Aloha'')';
|
FP.Expression:='EchoString(''Aloha'')';
|
||||||
AssertNotNull('Have result node',FP.ExprNode);
|
AssertNotNull('Have result node',FP.ExprNode);
|
||||||
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
AssertNodeType('Constant expression',TFPFunctionEventHandler, FP.ExprNode);
|
||||||
@ -5392,6 +5563,7 @@ Var
|
|||||||
begin
|
begin
|
||||||
D:=Date;
|
D:=Date;
|
||||||
I:=FP.Identifiers.AddFunction('Date','D','',@DoGetDate);
|
I:=FP.Identifiers.AddFunction('Date','D','',@DoGetDate);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
AssertEquals('List is dirty',True,FP.Dirty);
|
AssertEquals('List is dirty',True,FP.Dirty);
|
||||||
AssertNotNull('Addvariable returns result',I);
|
AssertNotNull('Addvariable returns result',I);
|
||||||
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
||||||
@ -5411,8 +5583,8 @@ Var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddFunction('AddInteger','I','II',@DoAddInteger);
|
I:=FP.Identifiers.AddFunction('AddInteger','I','II',@DoAddInteger);
|
||||||
|
AssertNotNull('Have identifier',I);
|
||||||
AssertEquals('List is dirty',True,FP.Dirty);
|
AssertEquals('List is dirty',True,FP.Dirty);
|
||||||
AssertNotNull('Addvariable returns result',I);
|
|
||||||
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
||||||
AssertSame('Result equals variable added',I,FP.Identifiers[0]);
|
AssertSame('Result equals variable added',I,FP.Identifiers[0]);
|
||||||
AssertEquals('Function has correct resulttype',rtInteger,I.ResultType);
|
AssertEquals('Function has correct resulttype',rtInteger,I.ResultType);
|
||||||
@ -5431,7 +5603,7 @@ Var
|
|||||||
begin
|
begin
|
||||||
I:=FP.Identifiers.AddFunction('Delete','S','SII',@DoDeleteString);
|
I:=FP.Identifiers.AddFunction('Delete','S','SII',@DoDeleteString);
|
||||||
AssertEquals('List is dirty',True,FP.Dirty);
|
AssertEquals('List is dirty',True,FP.Dirty);
|
||||||
AssertNotNull('Addvariable returns result',I);
|
AssertNotNull('Have identifier',I);
|
||||||
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
AssertEquals('One variable added',1,FP.Identifiers.Count);
|
||||||
AssertSame('Result equals variable added',I,FP.Identifiers[0]);
|
AssertSame('Result equals variable added',I,FP.Identifiers[0]);
|
||||||
AssertEquals('Function has correct resulttype',rtString,I.ResultType);
|
AssertEquals('Function has correct resulttype',rtString,I.ResultType);
|
||||||
@ -5507,6 +5679,7 @@ Var
|
|||||||
begin
|
begin
|
||||||
// Test type mismatch
|
// Test type mismatch
|
||||||
I:=FP.Identifiers.AddFunction('AddInteger','I','II',@DoAddInteger);
|
I:=FP.Identifiers.AddFunction('AddInteger','I','II',@DoAddInteger);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
TestParser('AddInteger(3 and 2,''s'')');
|
TestParser('AddInteger(3 and 2,''s'')');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -5589,6 +5762,21 @@ begin
|
|||||||
AssertEquals('Variable has correct value',FloatToStr(1.23),I.Value);
|
AssertEquals('Variable has correct value',FloatToStr(1.23),I.Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestBuiltinsManager.TestVariable7;
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : TFPBuiltinExprIdentifierDef;
|
||||||
|
|
||||||
|
begin
|
||||||
|
I:=FM.AddCurrencyVariable(bcUser,'a',1.23);
|
||||||
|
AssertNotNull('Addvariable returns result',I);
|
||||||
|
AssertEquals('One variable added',1,FM.IdentifierCount);
|
||||||
|
AssertSame('Result equals variable added',I,FM.Identifiers[0]);
|
||||||
|
AssertEquals('Variable has correct category',ord(bcUser),Ord(I.Category));
|
||||||
|
AssertEquals('Variable has correct resulttype',rtCurrency,I.ResultType);
|
||||||
|
AssertEquals('Variable has correct value',CurrToStr(1.23),I.Value);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestBuiltinsManager.TestVariable5;
|
procedure TTestBuiltinsManager.TestVariable5;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
@ -5786,6 +5974,21 @@ begin
|
|||||||
AssertResult(AResult);
|
AssertResult(AResult);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestBuiltins.AssertAggregateCurrExpression(Const AExpression : String; AResult : Currency; AUpdateCount : integer);
|
||||||
|
|
||||||
|
begin
|
||||||
|
FP.BuiltIns:=AllBuiltIns;
|
||||||
|
SetExpression(AExpression);
|
||||||
|
AssertEquals('Has aggregate',True,FP.ExprNode.HasAggregate);
|
||||||
|
FP.InitAggregate;
|
||||||
|
While AUpdateCount>0 do
|
||||||
|
begin
|
||||||
|
FP.UpdateAggregate;
|
||||||
|
Dec(AUpdateCount);
|
||||||
|
end;
|
||||||
|
AssertCurrencyResult(AResult);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestBuiltins.TestRegister;
|
procedure TTestBuiltins.TestRegister;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -6314,9 +6517,21 @@ end;
|
|||||||
procedure TTestBuiltins.TestFunctionAggregateSum;
|
procedure TTestBuiltins.TestFunctionAggregateSum;
|
||||||
begin
|
begin
|
||||||
FP.Identifiers.AddIntegerVariable('S',2);
|
FP.Identifiers.AddIntegerVariable('S',2);
|
||||||
|
AssertAggregateExpression('sum(S)',10,5);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestBuiltins.TestFunctionAggregateSumFloat;
|
||||||
|
begin
|
||||||
|
FP.Identifiers.AddFloatVariable('S',2.0);
|
||||||
AssertAggregateExpression('sum(S)',10.0,5);
|
AssertAggregateExpression('sum(S)',10.0,5);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestBuiltins.TestFunctionAggregateSumCurrency;
|
||||||
|
begin
|
||||||
|
FP.Identifiers.AddCurrencyVariable('S',2.0);
|
||||||
|
AssertAggregateCurrExpression('sum(S)',Currency(10.0),5);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestBuiltins.TestFunctionAggregateCount;
|
procedure TTestBuiltins.TestFunctionAggregateCount;
|
||||||
begin
|
begin
|
||||||
AssertAggregateExpression('count',5,5);
|
AssertAggregateExpression('count',5,5);
|
||||||
@ -6796,7 +7011,7 @@ end;
|
|||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
RegisterTests([TTestExpressionScanner, TTestDestroyNode,
|
RegisterTests('ExprPars',[TTestExpressionScanner, TTestDestroyNode,
|
||||||
TTestConstExprNode,TTestNegateExprNode,
|
TTestConstExprNode,TTestNegateExprNode,
|
||||||
TTestBinaryAndNode,TTestBinaryOrNode,TTestBinaryXOrNode,
|
TTestBinaryAndNode,TTestBinaryOrNode,TTestBinaryXOrNode,
|
||||||
TTestNotNode,TTestEqualNode,TTestUnEqualNode,
|
TTestNotNode,TTestEqualNode,TTestUnEqualNode,
|
||||||
|
Loading…
Reference in New Issue
Block a user