|
@@ -0,0 +1,901 @@
|
|
|
|
+unit tcexprparser;
|
|
|
|
+
|
|
|
|
+{$mode objfpc}{$H+}
|
|
|
|
+
|
|
|
|
+interface
|
|
|
|
+
|
|
|
|
+uses
|
|
|
|
+ Classes, SysUtils, fpcunit, testutils, 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;
|
|
|
|
+ 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.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;
|
|
|
|
+Var
|
|
|
|
+ S : TSelfExpr;
|
|
|
|
+begin
|
|
|
|
+ DeclareVar('pointer','a');
|
|
|
|
+ ParseExpression('Self');
|
|
|
|
+ S:=TSelfExpr(AssertExpression('Inherited expr',theExpr,pekSelf,TSelfExpr));
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TTestExpressions.TestInherited;
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ I: TInheritedExpr;
|
|
|
|
+begin
|
|
|
|
+ DeclareVar('pointer','a');
|
|
|
|
+ ParseExpression('inherited');
|
|
|
|
+ I:=TInheritedExpr(AssertExpression('Inherited expr',theExpr,pekInherited,TInheritedExpr));
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TTestExpressions.TestInheritedFunction;
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ I: TInheritedExpr;
|
|
|
|
+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.
|
|
|
|
+
|