fpc/packages/fcl-passrc/tests/tcexprparser.pas
michael 2252b71ae9 * Some small fixes so sdo is parsed
git-svn-id: trunk@22210 -
2012-08-23 12:56:19 +00:00

911 lines
27 KiB
ObjectPascal

unit tcexprparser;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, fpcunit, testregistry, tcbaseparser, pastree;
type
{ TTestExpressions }
TTestExpressions= class(TTestParser)
private
FLeft: TPAsExpr;
FRight: TPAsExpr;
FTheExpr: TPasExpr;
FVariables : TStringList;
procedure AssertLeftPrecedence(AInnerLeft: Integer; AInnerOp: TExprOpCode;
AInnerRight: Integer; AOuterOp: TexprOpCode; AOuterRight: Integer);
procedure AssertRightPrecedence(AOuterLeft: Integer; AOuterOp: TExprOpCode;
AInnerLeft: Integer; AInnerOp: TexprOpCode; AInnerRight: Integer);
procedure DeclareVar(const AVarType: String; const AVarName: String = 'a');
protected
procedure SetUp; override;
procedure TearDown; override;
Procedure SetExpression(Const AExpression : String);
Procedure ParseExpression;
Procedure ParseExpression(Const AExpression : String);
Function AssertBinaryExpr(Const Msg : String; Op : TExprOpCode; Out ALeft,ARight : TPasExpr) : TBinaryExpr;
Function AssertBinaryExpr(Const Msg : String; AExpr : TPasExpr; Op : TExprOpCode; Out ALeft,ARight : TPasExpr) : TBinaryExpr;
Function AssertUnaryExpr(Const Msg : String; Op : TExprOpCode; Out AOperand : TPasExpr) : TUnaryExpr;
Function AssertUnaryExpr(Const Msg : String; AExpr: TPasExpr; Op : TExprOpCode; Out AOperand : TPasExpr) : TUnaryExpr;
Property TheExpr : TPasExpr read FTheExpr;
Property Theleft : TPAsExpr Read FLeft;
Property TheRight : TPAsExpr Read FRight;
published
{
TPasExprKind = (pekRange,
pekListOfExp, );
}
procedure TestPrimitiveInteger;
procedure TestPrimitiveIntegerHex;
procedure TestPrimitiveIntegerOctal;
procedure TestPrimitiveIntegerBinary;
procedure TestPrimitiveDouble;
procedure TestPrimitiveString;
procedure TestPrimitiveIdent;
procedure TestPrimitiveBooleanFalse;
procedure TestPrimitiveBooleanTrue;
procedure TestPrimitiveNil;
procedure TestPrimitiveSet;
procedure TestPrimitiveChar;
procedure TestPrimitiveControlChar;
procedure TestPrimitiveSetEmpty;
procedure TestPrimitiveSelf;
Procedure TestInherited;
Procedure TestInheritedFunction;
Procedure TestUnaryMinus;
Procedure TestUnaryMinusWhiteSpace;
Procedure TestUnaryAddress;
Procedure TestUnaryNot;
Procedure TestUnaryDeref;
Procedure TestBinaryAdd;
Procedure TestBinarySubtract;
Procedure TestBinaryMultiply;
Procedure TestBinaryDivision;
Procedure TestBinaryPower;
Procedure TestBinaryMod;
Procedure TestBinaryDiv;
procedure TestBinaryShl;
procedure TestBinaryShr;
Procedure TestBinarySymmetricalDifference;
Procedure TestBinaryAnd;
Procedure TestBinaryOr;
Procedure TestBinaryXOr;
Procedure TestBinaryIn;
Procedure TestBinaryIs;
Procedure TestBinaryAs;
Procedure TestBinaryEquals;
Procedure TestBinaryDiffers;
Procedure TestBinaryLessThan;
Procedure TestBinaryLessThanEqual;
Procedure TestBinaryLargerThan;
Procedure TestBinaryLargerThanEqual;
procedure TestBinaryFullIdent;
Procedure TestArrayElement;
Procedure TestArrayElement2Dims;
Procedure TestFunctionCall;
Procedure TestFunctionCall2args;
Procedure TestFunctionCallNoArgs;
Procedure TestRange;
Procedure TestBracketsTotal;
Procedure TestBracketsLeft;
Procedure TestBracketsRight;
Procedure TestPrecedenceLeftToRight;
Procedure TestPrecedenceLeftToRightMinus;
Procedure TestPrecedenceLeftToRightMultiply;
Procedure TestPrecedenceLeftToRightDivision;
Procedure TestPrecedenceLeftToRightPlusMinus;
Procedure TestPrecedenceLeftToRightMinusPlus;
Procedure TestPrecedenceLeftToRightMultiplyDivision;
Procedure TestPrecedenceLeftToRightDivisionMultiply;
Procedure TestPrecedencePlusMultiply;
Procedure TestPrecedencePlusDivide;
Procedure TestPrecedenceMinusMultiply;
Procedure TestPrecedenceMinusDivide;
Procedure TestPrecedencePlusOr;
Procedure TestPrecedenceAndOr;
Procedure TestPrecedenceAndNot;
Procedure TestPrecedencePlusAnd;
Procedure TestPrecedenceMinusOr;
Procedure TestPrecedenceMinusAnd;
Procedure TestPrecedenceMultiplyOr;
Procedure TestPrecedenceMultiplyAnd;
Procedure TestPrecedencePlusDiv;
Procedure TestPrecedencePlusMod;
Procedure TestPrecedenceMultiplyDiv;
Procedure TestPrecedenceDivMultiply;
Procedure TestTypeCast;
Procedure TestCreate;
end;
implementation
procedure TTestExpressions.DeclareVar(const AVarType: String;
const AVarName: String = 'a');
begin
FVariables.Add(AVarName+' : '+AVarType+';');
end;
procedure TTestExpressions.TestPrimitiveInteger;
begin
ParseExpression('1');
AssertExpression('Simple integer',theExpr,pekNumber,'1');
end;
procedure TTestExpressions.TestPrimitiveIntegerHex;
begin
ParseExpression('$FF');
AssertExpression('Simple integer',theExpr,pekNumber,'$FF');
end;
procedure TTestExpressions.TestPrimitiveIntegerOctal;
begin
ParseExpression('&777');
AssertExpression('Simple integer',theExpr,pekNumber,'&777');
end;
procedure TTestExpressions.TestPrimitiveIntegerBinary;
begin
ParseExpression('%10101010');
AssertExpression('Simple integer',theExpr,pekNumber,'%10101010');
end;
procedure TTestExpressions.TestPrimitiveDouble;
begin
ParseExpression('1.2');
AssertExpression('Simple double',theExpr,pekNumber,'1.2');
end;
procedure TTestExpressions.TestPrimitiveString;
begin
DeclareVar('string');
ParseExpression('''123''');
AssertExpression('Simple string',theExpr,pekString,'''123''');
end;
procedure TTestExpressions.TestPrimitiveIdent;
begin
DeclareVar('integer','a');
DeclareVar('integer','b');
ParseExpression('b');
AssertExpression('Simple identifier',theExpr,pekIdent,'b');
end;
procedure TTestExpressions.TestBinaryFullIdent;
begin
DeclareVar('integer','a');
DeclareVar('record x,y : integer; end','b');
ParseExpression('b.x');
AssertBinaryExpr('sub identifier',eopSubIdent,Fleft,FRight);
AssertExpression('Simple identifier',Theleft,pekIdent,'b');
AssertExpression('Simple identifier',Theright,pekIdent,'x');
end;
procedure TTestExpressions.TestArrayElement;
Var
P : TParamsExpr;
begin
DeclareVar('integer','a');
DeclareVar('array[1..2] of integer','b');
ParseExpression('b[1]');
P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekArrayParams,TParamsExpr));
AssertExpression('Name of array',P.Value,pekIdent,'b');
AssertEquals('One dimension',1,Length(p.params));
AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
end;
procedure TTestExpressions.TestArrayElement2Dims;
Var
P : TParamsExpr;
begin
DeclareVar('integer','a');
DeclareVar('array[1..2,1..2] of integer','b');
ParseExpression('b[1,2]');
P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekArrayParams,TParamsExpr));
AssertExpression('Name of array',P.Value,pekIdent,'b');
AssertEquals('Two dimensions',2,Length(p.params));
AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
AssertExpression('Simple identifier',p.params[1],pekNumber,'2');
end;
procedure TTestExpressions.TestFunctionCall;
Var
P : TParamsExpr;
begin
DeclareVar('integer','a');
ParseExpression('Random(10)');
P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
AssertExpression('Name of function',P.Value,pekIdent,'Random');
AssertEquals('1 argument',1,Length(p.params));
AssertExpression('Simple identifier',p.params[0],pekNumber,'10');
end;
procedure TTestExpressions.TestFunctionCall2args;
Var
P : TParamsExpr;
begin
DeclareVar('integer','a');
ParseExpression('Random(10,12)');
P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
AssertExpression('Name of function',P.Value,pekIdent,'Random');
AssertEquals('2 argument',2,Length(p.params));
AssertExpression('Simple identifier 1',p.params[0],pekNumber,'10');
AssertExpression('Simple identifier 2',p.params[1],pekNumber,'12');
end;
procedure TTestExpressions.TestFunctionCallNoArgs;
Var
P : TParamsExpr;
begin
DeclareVar('integer','a');
ParseExpression('Random()');
P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
AssertExpression('Name of function',P.Value,pekIdent,'Random');
AssertEquals('0 arguments',0,Length(p.params));
end;
procedure TTestExpressions.TestRange;
Var
B : TBinaryExpr;
begin
DeclareVar('boolean','a');
DeclareVar('byte','b');
ParseExpression('b in 0..10');
AssertBinaryExpr('Simple binary In',eopIn,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekIdent,'b');
B:=TBinaryExpr(AssertExpression('Right is range',TheRight,pekRange,TBinaryExpr));
AssertExpression('Left is 0',B.Left,pekNumber,'0');
AssertExpression('Right is 10',B.Right,pekNumber,'10');
end;
procedure TTestExpressions.TestBracketsTotal;
begin
DeclareVar('integer','a');
ParseExpression('(3+4)');
AssertBinaryExpr('simple binary add',eopAdd,FLeft,FRight);
AssertExpression('Inner Left is 3',TheLeft,pekNumber,'3');
AssertExpression('Inner Right is 4',TheRight,pekNumber,'4');
end;
procedure TTestExpressions.TestBracketsLeft;
begin
DeclareVar('integer','a');
ParseExpression('2*(3+4)');
AssertRightPrecedence(2,eopMultiply,3,eopAdd,4);
end;
procedure TTestExpressions.TestBracketsRight;
begin
DeclareVar('integer','a');
ParseExpression('(2*3)+4');
AssertLeftPrecedence(2,eopMultiply,3,eopAdd,4);
end;
procedure TTestExpressions.TestPrecedenceLeftToRight;
begin
ParseExpression('1+2+3');
AssertLeftPrecedence(1,eopAdd,2,eopAdd,3);
end;
procedure TTestExpressions.TestPrecedenceLeftToRightMinus;
begin
ParseExpression('1-2-3');
AssertLeftPrecedence(1,eopSubtract,2,eopSubtract,3);
end;
procedure TTestExpressions.TestPrecedenceLeftToRightMultiply;
begin
ParseExpression('1*2*3');
AssertLeftPrecedence(1,eopMultiply,2,eopMultiply,3);
end;
procedure TTestExpressions.TestPrecedenceLeftToRightDivision;
begin
ParseExpression('1/2/3');
AssertLeftPrecedence(1,eopDivide,2,eopDivide,3);
end;
procedure TTestExpressions.TestPrecedenceLeftToRightPlusMinus;
begin
ParseExpression('1+2-3');
AssertLeftPrecedence(1,eopAdd,2,eopSubtract,3);
end;
procedure TTestExpressions.TestPrecedenceLeftToRightMinusPlus;
begin
ParseExpression('1-2+3');
AssertLeftPrecedence(1,eopSubtract,2,eopAdd,3);
end;
procedure TTestExpressions.TestPrecedenceLeftToRightMultiplyDivision;
begin
ParseExpression('1*2/3');
AssertLeftPrecedence(1,eopMultiply,2,eopDivide,3);
end;
procedure TTestExpressions.TestPrecedenceLeftToRightDivisionMultiply;
begin
ParseExpression('1/2*3');
AssertLeftPrecedence(1,eopDivide,2,eopMultiply,3);
end;
procedure TTestExpressions.TestPrecedencePlusMultiply;
begin
ParseExpression('1+2*3');
AssertRightPrecedence(1,eopAdd,2,eopMultiply,3);
end;
procedure TTestExpressions.TestPrecedencePlusDivide;
begin
ParseExpression('1+2/3');
AssertRightPrecedence(1,eopAdd,2,eopDivide,3);
end;
procedure TTestExpressions.TestPrecedenceMinusMultiply;
begin
ParseExpression('1-2*3');
AssertRightPrecedence(1,eopsubtract,2,eopMultiply,3);
end;
procedure TTestExpressions.TestPrecedenceMinusDivide;
begin
ParseExpression('1-2/3');
AssertRightPrecedence(1,eopsubtract,2,eopDivide,3);
end;
procedure TTestExpressions.TestPrecedencePlusOr;
begin
ParseExpression('1 or 2 + 3');
AssertLeftPrecedence(1,eopor,2,eopAdd,3);
end;
procedure TTestExpressions.TestPrecedenceAndOr;
begin
ParseExpression('1 or 2 and 3');
AssertRightPrecedence(1,eopor,2,eopAnd,3);
end;
procedure TTestExpressions.TestPrecedenceAndNot;
begin
ParseExpression('Not 1 and 3');
AssertBinaryExpr('Simple binary and',eopAnd,FLeft,FRight);
AssertExpression('Outer right is 3',TheRight,pekNumber,'3');
AssertUnaryExpr('Left is Unary not ',TheLeft,eopNot,FRight);
AssertExpression('Inner Right is 1',TheRight,pekNumber,'1');
end;
procedure TTestExpressions.TestPrecedencePlusAnd;
begin
ParseExpression('1 + 2 and 3');
AssertRightPrecedence(1,eopAdd,2,eopAnd,3);
end;
procedure TTestExpressions.TestPrecedenceMinusOr;
begin
ParseExpression('1 or 2 - 3');
AssertLeftPrecedence(1,eopOr,2,eopSubtract,3);
end;
procedure TTestExpressions.TestPrecedenceMinusAnd;
begin
ParseExpression('1 - 2 and 3');
AssertRightPrecedence(1,eopSubtract,2,eopand,3);
end;
procedure TTestExpressions.TestPrecedenceMultiplyOr;
begin
ParseExpression('1 or 2 * 3');
AssertRightPrecedence(1,eopOr,2,eopMultiply,3);
end;
procedure TTestExpressions.TestPrecedenceMultiplyAnd;
begin
ParseExpression('1 * 2 and 3');
AssertLeftPrecedence(1,eopMultiply,2,eopAnd,3);
end;
procedure TTestExpressions.TestPrecedencePlusDiv;
begin
ParseExpression('1+2 div 3');
AssertRightPrecedence(1,eopAdd,2,eopDiv,3);
end;
procedure TTestExpressions.TestPrecedencePlusMod;
begin
ParseExpression('1+2 mod 3');
AssertRightPrecedence(1,eopAdd,2,eopMod,3);
end;
procedure TTestExpressions.AssertLeftPrecedence(AInnerLeft : Integer; AInnerOp : TExprOpCode; AInnerRight : Integer; AOuterOp : TexprOpCode; AOuterRight: Integer);
begin
AssertBinaryExpr('Outer expression',AOuterOp,FLeft,FRight);
AssertExpression('Outer right constant',TheRight,pekNumber,intToStr(AOuterRight));
AssertBinaryExpr('Inner (left) expression',TheLeft,AInnerOp,FLeft,FRight);
AssertExpression('Inner Left constant',TheLeft,pekNumber,IntToStr(AInnerLeft));
AssertExpression('Inner Right constant',TheRight,pekNumber,IntToStr(AInnerRight));
end;
procedure TTestExpressions.AssertRightPrecedence(AOuterLeft : Integer; AOuterOp : TExprOpCode; AInnerLeft : Integer; AInnerOp : TexprOpCode; AInnerRight: Integer);
begin
AssertBinaryExpr('Outer expression',AOuterOp,FLeft,FRight);
AssertExpression('Outer left constant',TheLeft,pekNumber,intToStr(AOuterLeft));
AssertBinaryExpr('Inner (right) expression',TheRight,AInnerOp,FLeft,FRight);
AssertExpression('Inner Left constant',TheLeft,pekNumber,IntToStr(AInnerLeft));
AssertExpression('Inner Right constant',TheRight,pekNumber,IntToStr(AInnerRight));
end;
procedure TTestExpressions.TestPrecedenceMultiplyDiv;
begin
ParseExpression('1 * 2 div 3');
AssertLeftPrecedence(1,eopMultiply,2,eopDiv,3);
end;
procedure TTestExpressions.TestPrecedenceDivMultiply;
begin
ParseExpression('1 div 2 * 3');
AssertLeftPrecedence(1,eopDiv,2,eopMultiply,3);
end;
procedure TTestExpressions.TestTypeCast;
begin
DeclareVar('TSDOBaseDataObjectClass');
ParseExpression('TSDOBaseDataObjectClass(Self.ClassType).Create');
end;
procedure TTestExpressions.TestCreate;
begin
DeclareVar('ESDOSerializationException');
ParseExpression('ESDOSerializationException.CreateFmt(SERR_InvalidDataTypeInContext,[IntToStr(Ord(AOwner^.DataType))])');
end;
procedure TTestExpressions.TestUnaryMinus;
begin
DeclareVar('integer','a');
DeclareVar('integer','b');
ParseExpression('-b');
AssertUnaryExpr('Simple minus unary',eopSubtract,FLeft);
AssertExpression('Simple identifier',theLeft,pekIdent,'b');
end;
procedure TTestExpressions.TestUnaryMinusWhiteSpace;
begin
DeclareVar('integer','a');
DeclareVar('integer','b');
ParseExpression('- b');
AssertUnaryExpr('Simple minus unary',eopSubtract,FLeft);
AssertExpression('Simple identifier',theLeft,pekIdent,'b');
end;
procedure TTestExpressions.TestUnaryAddress;
begin
DeclareVar('integer','a');
DeclareVar('integer','b');
ParseExpression('@b');
AssertUnaryExpr('Simple address unary',eopAddress,FLeft);
AssertExpression('Simple identifier',theLeft,pekIdent,'b');
end;
procedure TTestExpressions.TestUnaryNot;
begin
DeclareVar('boolean','a');
DeclareVar('boolean','b');
ParseExpression('not b');
AssertUnaryExpr('Simple address unary',eopNot,FLeft);
AssertExpression('Simple identifier',theLeft,pekIdent,'b');
end;
procedure TTestExpressions.TestUnaryDeref;
begin
DeclareVar('integer','a');
DeclareVar('pinteger','b');
ParseExpression('b^');
AssertUnaryExpr('Simple address unary',eopDeref,FLeft);
AssertExpression('Simple identifier',theLeft,pekIdent,'b');
end;
procedure TTestExpressions.TestBinaryAdd;
begin
ParseExpression('1+2');
AssertBinaryExpr('Simple binary add',eopAdd,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinarySubtract;
begin
ParseExpression('1-2');
AssertBinaryExpr('Simple binary subtract',eopSubtract,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinaryMultiply;
begin
ParseExpression('1*2');
AssertBinaryExpr('Simple binary multiply',eopMultiply,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinaryDivision;
begin
DeclareVar('double');
ParseExpression('1/2');
AssertBinaryExpr('Simple binary division',eopDivide,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinaryPower;
begin
DeclareVar('double');
ParseExpression('1**2');
AssertBinaryExpr('Simple binary power',eopPower,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinaryMod;
begin
ParseExpression('1 mod 2');
AssertBinaryExpr('Simple binary mod',eopMod,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinaryDiv;
begin
ParseExpression('1 div 2');
AssertBinaryExpr('Simple binary div',eopDiv,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinaryShl;
begin
ParseExpression('1 shl 2');
AssertBinaryExpr('Simple binary shl',eopShl,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinaryShr;
begin
ParseExpression('1 shr 2');
AssertBinaryExpr('Simple binary shr',eopShr,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is 2',TheRight,pekNumber,'2');
end;
procedure TTestExpressions.TestBinarySymmetricalDifference;
begin
DeclareVar('Set of Byte','a');
DeclareVar('Set of Byte','b');
DeclareVar('Set of Byte','c');
ParseExpression('b >< c');
AssertBinaryExpr('Simple binary smmetrical difference',eopSymmetricalDifference,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekident,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryAnd;
begin
DeclareVar('boolean','a');
DeclareVar('boolean','b');
DeclareVar('boolean','b');
ParseExpression('b and c');
AssertBinaryExpr('Simple binary and',eopAnd,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekIdent,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryOr;
begin
DeclareVar('boolean','a');
DeclareVar('boolean','b');
DeclareVar('boolean','b');
ParseExpression('b or c');
AssertBinaryExpr('Simple binary or',eopOr,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekIdent,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryXOr;
begin
DeclareVar('boolean','a');
DeclareVar('boolean','b');
DeclareVar('boolean','b');
ParseExpression('b xor c');
AssertBinaryExpr('Simple binary xor',eopxOr,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekIdent,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryIn;
begin
DeclareVar('boolean','a');
ParseExpression('1 in [1,2,3]');
AssertBinaryExpr('Simple binary In',eopIn,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekNumber,'1');
AssertExpression('Right is array set',TheRight,pekSet,TParamsExpr);
end;
procedure TTestExpressions.TestBinaryIs;
begin
DeclareVar('boolean','a');
DeclareVar('TObject','b');
ParseExpression('b is TObject');
AssertBinaryExpr('Simple binary Is',eopIs,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekident,'b');
AssertExpression('Right is TObject',TheRight,pekIdent,'TObject');
end;
procedure TTestExpressions.TestBinaryAs;
begin
DeclareVar('TObject','a');
DeclareVar('TObject','b');
ParseExpression('b as TObject');
AssertBinaryExpr('Simple binary As',eopAs,FLeft,FRight);
AssertExpression('Left is 1',TheLeft,pekident,'b');
AssertExpression('Right is TObject',TheRight,pekIdent,'TObject');
end;
procedure TTestExpressions.TestBinaryEquals;
begin
DeclareVar('boolean','a');
DeclareVar('integer','b');
DeclareVar('integer','c');
ParseExpression('b=c');
AssertBinaryExpr('Simple binary equals',eopEqual,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekident,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryDiffers;
begin
DeclareVar('boolean','a');
DeclareVar('integer','b');
DeclareVar('integer','c');
ParseExpression('b<>c');
AssertBinaryExpr('Simple binary differs',eopNotEqual,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekident,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryLessThan;
begin
DeclareVar('boolean','a');
DeclareVar('integer','b');
DeclareVar('integer','c');
ParseExpression('b<c');
AssertBinaryExpr('Simple binary less than',eopLessThan,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekident,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryLessThanEqual;
begin
DeclareVar('boolean','a');
DeclareVar('integer','b');
DeclareVar('integer','c');
ParseExpression('b<=c');
AssertBinaryExpr('Simple binary less than or equal',eopLessThanEqual,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekident,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryLargerThan;
begin
DeclareVar('boolean','a');
DeclareVar('integer','b');
DeclareVar('integer','c');
ParseExpression('b>c');
AssertBinaryExpr('Simple binary larger than ',eopGreaterThan,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekident,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestBinaryLargerThanEqual;
begin
DeclareVar('boolean','a');
DeclareVar('integer','b');
DeclareVar('integer','c');
ParseExpression('b>=c');
AssertBinaryExpr('Simple binary larger than or equal',eopGreaterThanEqual,FLeft,FRight);
AssertExpression('Left is b',TheLeft,pekident,'b');
AssertExpression('Right is c',TheRight,pekIdent,'c');
end;
procedure TTestExpressions.TestPrimitiveBooleanFalse;
begin
DeclareVar('boolean','a');
ParseExpression('False');
AssertExpression('Simple boolean',theExpr,pekBoolConst,TBoolConstExpr);
AssertEquals('Boolean false',False,TBoolConstExpr(TheExpr).Value);
end;
procedure TTestExpressions.TestPrimitiveBooleanTrue;
begin
DeclareVar('boolean','a');
ParseExpression('True');
AssertExpression('Simple boolean',theExpr,pekBoolConst,TBoolConstExpr);
AssertEquals('Boolean true',True,TBoolConstExpr(TheExpr).Value);
end;
procedure TTestExpressions.TestPrimitiveNil;
begin
DeclareVar('pointer','a');
ParseExpression('Nil');
AssertExpression('Nil expr',theExpr,pekNil,TNilExpr);
end;
procedure TTestExpressions.TestPrimitiveSet;
Var
P : TParamsExpr;
begin
DeclareVar('set of byte','a');
ParseExpression('[1,2,3]');
P:=TParamsExpr(AssertExpression('Set expr',theExpr,pekSet,TParamsExpr));
AssertEquals('Element count',3,Length(P.Params));
AssertExpression('Element 1 in set',P.Params[0],pekNumber,'1');
AssertExpression('Element 2 in set',P.Params[1],pekNumber,'2');
AssertExpression('Element 3 in set',P.Params[2],pekNumber,'3');
end;
procedure TTestExpressions.TestPrimitiveChar;
begin
DeclareVar('char');
ParseExpression('#32');
AssertExpression('Simple string',theExpr,pekString,'#32');
end;
procedure TTestExpressions.TestPrimitiveControlChar;
begin
DeclareVar('char');
ParseExpression('^M');
AssertExpression('Simple string',theExpr,pekString,'^M');
end;
procedure TTestExpressions.TestPrimitiveSetEmpty;
Var
P : TParamsExpr;
begin
DeclareVar('set of byte','a');
ParseExpression('[]');
P:=TParamsExpr(AssertExpression('Set expr',theExpr,pekSet,TParamsExpr));
AssertEquals('Element count',0,Length(P.Params));
end;
procedure TTestExpressions.TestPrimitiveSelf;
begin
DeclareVar('pointer','a');
ParseExpression('Self');
AssertExpression('Inherited expr',theExpr,pekSelf,TSelfExpr);
end;
procedure TTestExpressions.TestInherited;
begin
DeclareVar('pointer','a');
ParseExpression('inherited');
AssertExpression('Inherited expr',theExpr,pekInherited,TInheritedExpr);
end;
procedure TTestExpressions.TestInheritedFunction;
begin
DeclareVar('pointer','a');
ParseExpression('inherited myfunction');
AssertBinaryExpr('Inherited expr',eopNone,Fleft,FRight);
AssertExpression('Inherited expr',theleft,pekInherited,TInheritedExpr);
AssertExpression('Inherited expr',theright,pekIdent,'myfunction');
end;
procedure TTestExpressions.SetUp;
begin
Inherited;
FVariables:=TStringList.Create;
end;
procedure TTestExpressions.TearDown;
begin
FreeAndNil(FVariables);
Inherited;
end;
procedure TTestExpressions.SetExpression(const AExpression: String);
Var
I : Integer;
begin
StartProgram('afile');
if FVariables.Count=0 then
DeclareVar('integer');
Add('Var');
For I:=0 to FVariables.Count-1 do
Add(' '+Fvariables[I]);
Add('begin');
Add(' a:='+AExpression+';');
end;
procedure TTestExpressions.ParseExpression;
begin
ParseModule;
AssertEquals('Have program',TPasProgram,Module.ClassType);
AssertNotNull('Have program section',PasProgram.ProgramSection);
AssertNotNull('Have initialization section',PasProgram.InitializationSection);
AssertEquals('Have initialization statement',1,PasProgram.InitializationSection.Elements.Count);
AssertNotNull('Have initialization statement',PasProgram.InitializationSection.Elements[0]);
AssertEquals('Assignment statement',TPasImplAssign,TObject(PasProgram.InitializationSection.Elements[0]).ClassType);
FTheExpr:=TPasImplAssign(PasProgram.InitializationSection.Elements[0]).right;
AssertNotNull('Have assignment expression',FTheExpr);
end;
procedure TTestExpressions.ParseExpression(const AExpression: String);
begin
SetExpression(AExpression);
ParseExpression;
end;
function TTestExpressions.AssertBinaryExpr(const Msg: String; Op: TExprOpCode;
out ALeft, ARight: TPasExpr): TBinaryExpr;
begin
Result:=AssertBinaryExpr(Msg,TheExpr,Op,ALeft,ARight);
end;
function TTestExpressions.AssertBinaryExpr(const Msg: String; AExpr: TPasExpr;
Op: TExprOpCode; out ALeft, ARight: TPasExpr): TBinaryExpr;
begin
AssertExpression(Msg+' is binary',AExpr,pekBinary,TBinaryExpr);
Result:=AExpr as TBinaryExpr;
AssertEquals(Msg+' opcode OK',Op,Result.OpCode);
ALeft:=Result.Left;
ARight:=Result.Right;
AssertNotNull('Have left',ALeft);
AssertNotNull('Have right',ARight);
end;
function TTestExpressions.AssertUnaryExpr(const Msg: String; Op: TExprOpCode;
out AOperand : TPasExpr): TUnaryExpr;
begin
Result:=AssertUnaryExpr(Msg,TheExpr,OP,AOperand);
end;
function TTestExpressions.AssertUnaryExpr(const Msg: String; AExpr: TPasExpr;
Op: TExprOpCode; out AOperand: TPasExpr): TUnaryExpr;
begin
AssertExpression(Msg+' is unary',AExpr,pekUnary,TUnaryExpr);
Result:=AExpr as TUnaryExpr;
AssertEquals(Msg+' opcode OK',Op,Result.OpCode);
AOperand:=Result.Operand;
AssertNotNull('Have left',AOperand);
end;
initialization
RegisterTest(TTestExpressions);
end.