fpc/packages/fcl-passrc/tests/tcstatements.pas
Mattias Gaertner 007f266ccf fcl-passrc: scanner: bool switch $goto
git-svn-id: trunk@41125 -
2019-01-29 19:08:16 +00:00

1815 lines
64 KiB
ObjectPascal

{
Examples:
./testpassrc --suite=TTestStatementParser.TestCallQualified2
}
unit tcstatements;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, fpcunit, pastree, pscanner, pparser,
tcbaseparser, testregistry;
Type
{ TTestStatementParser }
TTestStatementParser = Class(TTestParser)
private
FStatement: TPasImplBlock;
FVariables : TStrings;
procedure DoTestCallOtherFormat;
procedure TestCallFormat(FN: String; AddPrecision: Boolean; AddSecondParam: boolean = false);
Protected
Procedure SetUp; override;
Procedure TearDown; override;
procedure AddStatements(ASource : Array of string);
Procedure DeclareVar(Const AVarType : String; Const AVarName : String = 'A');
function TestStatement(ASource : string) : TPasImplElement;
function TestStatement(ASource : Array of string) : TPasImplElement;
Procedure ExpectParserError(Const Msg : string);
Procedure ExpectParserError(Const Msg : string; ASource : Array of string);
Function AssertStatement(Msg : String; AClass : TClass;AIndex : Integer = 0) : TPasImplBlock;
Property Statement: TPasImplBlock Read FStatement;
Published
Procedure TestEmpty;
Procedure TestEmptyStatement;
Procedure TestEmptyStatements;
Procedure TestBlock;
Procedure TestBlockComment;
Procedure TestBlock2Comments;
Procedure TestAssignment;
Procedure TestAssignmentAdd;
Procedure TestAssignmentMinus;
Procedure TestAssignmentMul;
Procedure TestAssignmentDivision;
Procedure TestAssignmentMissingSemicolonError;
Procedure TestCall;
Procedure TestCallComment;
Procedure TestCallQualified;
Procedure TestCallQualified2;
Procedure TestCallNoArgs;
Procedure TestCallOneArg;
procedure TestCallWriteFormat1;
procedure TestCallWriteFormat2;
procedure TestCallWriteFormat3;
procedure TestCallWriteFormat4;
procedure TestCallWritelnFormat1;
procedure TestCallWritelnFormat2;
procedure TestCallStrFormat1;
procedure TestCallStrFormat2;
procedure TestCallOtherFormat;
Procedure TestIf;
Procedure TestIfBlock;
Procedure TestIfAssignment;
Procedure TestIfElse;
Procedure TestIfElseBlock;
Procedure TestIfSemiColonElseError;
procedure TestIfforElseBlock;
procedure TestIfRaiseElseBlock;
procedure TestIfWithBlock;
Procedure TestNestedIf;
Procedure TestNestedIfElse;
Procedure TestWhile;
Procedure TestWhileBlock;
Procedure TestWhileNested;
Procedure TestRepeat;
Procedure TestRepeatBlock;
procedure TestRepeatBlockNosemicolon;
Procedure TestRepeatNested;
Procedure TestFor;
Procedure TestForIn;
Procedure TestForExpr;
Procedure TestForBlock;
procedure TestDowntoBlock;
Procedure TestForNested;
Procedure TestWith;
Procedure TestWithMultiple;
Procedure TestCaseEmpty;
Procedure TestCaseOneInteger;
Procedure TestCaseTwoIntegers;
Procedure TestCaseRange;
Procedure TestCaseRangeSeparate;
Procedure TestCase2Cases;
Procedure TestCaseBlock;
Procedure TestCaseElseBlockEmpty;
procedure TestCaseOtherwiseBlockEmpty;
Procedure TestCaseElseBlockAssignment;
Procedure TestCaseElseBlock2Assignments;
Procedure TestCaseIfCaseElse;
Procedure TestCaseIfElse;
Procedure TestCaseElseNoSemicolon;
Procedure TestRaise;
Procedure TestRaiseEmpty;
Procedure TestRaiseAt;
Procedure TestTryFinally;
Procedure TestTryFinallyEmpty;
Procedure TestTryFinallyNested;
procedure TestTryExcept;
procedure TestTryExceptNested;
procedure TestTryExceptEmpty;
Procedure TestTryExceptOn;
Procedure TestTryExceptOn2;
Procedure TestTryExceptOnElse;
Procedure TestTryExceptOnIfElse;
procedure TestTryExceptRaise;
Procedure TestAsm;
Procedure TestAsmBlock;
Procedure TestAsmBlockWithEndLabel;
Procedure TestAsmBlockInIfThen;
Procedure TestGotoInIfThen;
procedure TestAssignToAddress;
procedure TestFinalizationNoSemicolon;
procedure TestMacroComment;
Procedure TestPlatformIdentifier;
Procedure TestPlatformIdentifier2;
Procedure TestArgumentNameOn;
end;
implementation
{ TTestStatementParser }
procedure TTestStatementParser.SetUp;
begin
inherited SetUp;
FVariables:=TStringList.Create;
end;
procedure TTestStatementParser.TearDown;
begin
FreeAndNil(FVariables);
inherited TearDown;
end;
procedure TTestStatementParser.AddStatements(ASource: array of string);
Var
I :Integer;
begin
StartProgram(ExtractFileUnitName(MainFilename));
if FVariables.Count>0 then
begin
Add('Var');
For I:=0 to FVariables.Count-1 do
Add(' '+Fvariables[I]);
end;
Add('begin');
For I:=Low(ASource) to High(ASource) do
Add(' '+ASource[i]);
end;
procedure TTestStatementParser.DeclareVar(const AVarType: String;
const AVarName: String);
begin
FVariables.Add(AVarName+' : '+AVarType+';');
end;
function TTestStatementParser.TestStatement(ASource: string): TPasImplElement;
begin
Result:=TestStatement([ASource]);
end;
function TTestStatementParser.TestStatement(ASource: array of string
): TPasImplElement;
begin
Result:=Nil;
FStatement:=Nil;
AddStatements(ASource);
ParseModule;
AssertEquals('Have program',TPasProgram,Module.ClassType);
AssertNotNull('Have program section',PasProgram.ProgramSection);
AssertNotNull('Have initialization section',PasProgram.InitializationSection);
if (PasProgram.InitializationSection.Elements.Count>0) then
if TObject(PasProgram.InitializationSection.Elements[0]) is TPasImplBlock then
FStatement:=TPasImplBlock(PasProgram.InitializationSection.Elements[0]);
Result:=FStatement;
end;
procedure TTestStatementParser.ExpectParserError(const Msg: string);
begin
AssertException(Msg,EParserError,@ParseModule);
end;
procedure TTestStatementParser.ExpectParserError(const Msg: string;
ASource: array of string);
begin
AddStatements(ASource);
ExpectParserError(Msg);
end;
function TTestStatementParser.AssertStatement(Msg: String; AClass: TClass;
AIndex: Integer): TPasImplBlock;
begin
if not (AIndex<PasProgram.InitializationSection.Elements.Count) then
Fail(Msg+': No such statement : '+intTostr(AIndex));
AssertNotNull(Msg+' Have statement',PasProgram.InitializationSection.Elements[AIndex]);
AssertEquals(Msg+' statement class',AClass,TObject(PasProgram.InitializationSection.Elements[AIndex]).ClassType);
Result:=TObject(PasProgram.InitializationSection.Elements[AIndex]) as TPasImplBlock;
end;
procedure TTestStatementParser.TestEmpty;
begin
//TestStatement(';');
TestStatement('');
AssertEquals('No statements',0,PasProgram.InitializationSection.Elements.Count);
end;
procedure TTestStatementParser.TestEmptyStatement;
begin
TestStatement(';');
AssertEquals('0 statement',0,PasProgram.InitializationSection.Elements.Count);
end;
procedure TTestStatementParser.TestEmptyStatements;
begin
TestStatement(';;');
AssertEquals('0 statement',0,PasProgram.InitializationSection.Elements.Count);
end;
procedure TTestStatementParser.TestBlock;
Var
B : TPasImplBeginBlock;
begin
TestStatement(['begin','end']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertNotNull('Statement assigned',PasProgram.InitializationSection.Elements[0]);
AssertEquals('Block statement',TPasImplBeginBlock,Statement.ClassType);
B:= Statement as TPasImplBeginBlock;
AssertEquals('Empty block',0,B.Elements.Count);
end;
procedure TTestStatementParser.TestBlockComment;
Var
B : TPasImplBeginBlock;
begin
Engine.NeedComments:=True;
TestStatement(['{ This is a comment }','begin','end']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertNotNull('Statement assigned',PasProgram.InitializationSection.Elements[0]);
AssertEquals('Block statement',TPasImplBeginBlock,Statement.ClassType);
B:= Statement as TPasImplBeginBlock;
AssertEquals('Empty block',0,B.Elements.Count);
AssertEquals('No DocComment','',B.DocComment);
end;
procedure TTestStatementParser.TestBlock2Comments;
Var
B : TPasImplBeginBlock;
begin
Engine.NeedComments:=True;
TestStatement(['{ This is a comment }','// Another comment','begin','end']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertNotNull('Statement assigned',PasProgram.InitializationSection.Elements[0]);
AssertEquals('Block statement',TPasImplBeginBlock,Statement.ClassType);
B:= Statement as TPasImplBeginBlock;
AssertEquals('Empty block',0,B.Elements.Count);
AssertEquals('No DocComment','',B.DocComment);
end;
procedure TTestStatementParser.TestAssignment;
Var
A : TPasImplAssign;
begin
DeclareVar('integer');
TestStatement(['a:=1;']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
A:=Statement as TPasImplAssign;
AssertEquals('Normal assignment',akDefault,A.Kind);
AssertExpression('Right side is constant',A.Right,pekNumber,'1');
AssertExpression('Left side is variable',A.Left,pekIdent,'a');
end;
procedure TTestStatementParser.TestAssignmentAdd;
Var
A : TPasImplAssign;
begin
Parser.Scanner.Options:=[po_cassignments];
DeclareVar('integer');
TestStatement(['a+=1;']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
A:=Statement as TPasImplAssign;
AssertEquals('Add assignment',akAdd,A.Kind);
AssertExpression('Right side is constant',A.Right,pekNumber,'1');
AssertExpression('Left side is variable',A.Left,pekIdent,'a');
end;
procedure TTestStatementParser.TestAssignmentMinus;
Var
A : TPasImplAssign;
begin
Parser.Scanner.Options:=[po_cassignments];
DeclareVar('integer');
TestStatement(['a-=1;']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
A:=Statement as TPasImplAssign;
AssertEquals('Minus assignment',akMinus,A.Kind);
AssertExpression('Right side is constant',A.Right,pekNumber,'1');
AssertExpression('Left side is variable',A.Left,pekIdent,'a');
end;
procedure TTestStatementParser.TestAssignmentMul;
Var
A : TPasImplAssign;
begin
Parser.Scanner.Options:=[po_cassignments];
DeclareVar('integer');
TestStatement(['a*=1;']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
A:=Statement as TPasImplAssign;
AssertEquals('Mul assignment',akMul,A.Kind);
AssertExpression('Right side is constant',A.Right,pekNumber,'1');
AssertExpression('Left side is variable',A.Left,pekIdent,'a');
end;
procedure TTestStatementParser.TestAssignmentDivision;
Var
A : TPasImplAssign;
begin
Parser.Scanner.Options:=[po_cassignments];
DeclareVar('integer');
TestStatement(['a/=1;']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
A:=Statement as TPasImplAssign;
AssertEquals('Division assignment',akDivision,A.Kind);
AssertExpression('Right side is constant',A.Right,pekNumber,'1');
AssertExpression('Left side is variable',A.Left,pekIdent,'a');
end;
procedure TTestStatementParser.TestAssignmentMissingSemicolonError;
begin
DeclareVar('integer');
ExpectParserError('Semicolon expected, but "a" found',['a:=1','a:=2']);
end;
procedure TTestStatementParser.TestCall;
Var
S : TPasImplSimple;
begin
TestStatement('Doit;');
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
S:=Statement as TPasImplSimple;
AssertExpression('Doit call',S.Expr,pekIdent,'Doit');
end;
procedure TTestStatementParser.TestCallComment;
Var
S : TPasImplSimple;
begin
Engine.NeedComments:=True;
TestStatement(['//comment line','Doit;']);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
S:=Statement as TPasImplSimple;
AssertExpression('Doit call',S.Expr,pekIdent,'Doit');
AssertEquals('No DocComment','',S.DocComment);
end;
procedure TTestStatementParser.TestCallQualified;
Var
S : TPasImplSimple;
B : TBinaryExpr;
begin
TestStatement('Unita.Doit;');
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
S:=Statement as TPasImplSimple;
AssertExpression('Doit call',S.Expr,pekBinary,TBinaryExpr);
B:=S.Expr as TBinaryExpr;
TAssert.AssertSame('B.left.Parent=B',B,B.left.Parent);
TAssert.AssertSame('B.right.Parent=B',B,B.right.Parent);
AssertExpression('Unit name',B.Left,pekIdent,'Unita');
AssertExpression('Doit call',B.Right,pekIdent,'Doit');
end;
procedure TTestStatementParser.TestCallQualified2;
Var
S : TPasImplSimple;
B : TBinaryExpr;
begin
TestStatement('Unita.ClassB.Doit;');
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
S:=Statement as TPasImplSimple;
AssertExpression('Doit call',S.Expr,pekBinary,TBinaryExpr);
B:=S.Expr as TBinaryExpr;
AssertExpression('Doit call',B.Right,pekIdent,'Doit');
AssertExpression('First two parts of unit name',B.left,pekBinary,TBinaryExpr);
B:=B.left as TBinaryExpr;
AssertExpression('Unit name part 1',B.Left,pekIdent,'Unita');
AssertExpression('Unit name part 2',B.right,pekIdent,'ClassB');
end;
procedure TTestStatementParser.TestCallNoArgs;
Var
S : TPasImplSimple;
P : TParamsExpr;
begin
TestStatement('Doit();');
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
S:=Statement as TPasImplSimple;
AssertExpression('Doit call',S.Expr,pekFuncParams,TParamsExpr);
P:=S.Expr as TParamsExpr;
AssertExpression('Correct function call name',P.Value,pekIdent,'Doit');
AssertEquals('No params',0,Length(P.Params));
end;
procedure TTestStatementParser.TestCallOneArg;
Var
S : TPasImplSimple;
P : TParamsExpr;
begin
TestStatement('Doit(1);');
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
S:=Statement as TPasImplSimple;
AssertExpression('Doit call',S.Expr,pekFuncParams,TParamsExpr);
P:=S.Expr as TParamsExpr;
AssertExpression('Correct function call name',P.Value,pekIdent,'Doit');
AssertEquals('One param',1,Length(P.Params));
AssertExpression('Parameter is constant',P.Params[0],pekNumber,'1');
end;
procedure TTestStatementParser.TestCallFormat(FN: String;
AddPrecision: Boolean; AddSecondParam: boolean);
var
P : TParamsExpr;
procedure CheckParam(Index: integer; const aParamName: string);
begin
AssertExpression('Parameter['+IntToStr(Index)+'] is identifier',P.Params[Index],pekIdent,aParamName);
AssertExpression('Parameter['+IntToStr(Index)+'] has formatting constant 1' ,P.Params[Index].format1,pekNumber,'3');
if AddPrecision then
AssertExpression('Parameter['+IntToStr(Index)+'] has formatting constant 2',P.Params[Index].format2,pekNumber,'2');
end;
Var
S : TPasImplSimple;
N : String;
ArgCnt: Integer;
begin
N:=fn+'(a:3';
if AddPrecision then
N:=N+':2';
ArgCnt:=1;
if AddSecondParam then
begin
ArgCnt:=2;
N:=N+',b:3';
if AddPrecision then
N:=N+':2';
end;
N:=N+');';
TestStatement(N);
AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
S:=Statement as TPasImplSimple;
AssertExpression('Doit call',S.Expr,pekFuncParams,TParamsExpr);
P:=S.Expr as TParamsExpr;
AssertExpression('Correct function call name',P.Value,pekIdent,FN);
AssertEquals(IntToStr(ArgCnt)+' param',ArgCnt,Length(P.Params));
CheckParam(0,'a');
if AddSecondParam then
CheckParam(1,'b');
end;
procedure TTestStatementParser.TestCallWriteFormat1;
begin
TestCallFormat('write',False);
end;
procedure TTestStatementParser.TestCallWriteFormat2;
begin
TestCallFormat('write',True);
end;
procedure TTestStatementParser.TestCallWriteFormat3;
begin
TestCallFormat('write',false,true);
end;
procedure TTestStatementParser.TestCallWriteFormat4;
begin
TestCallFormat('write',true,true);
end;
procedure TTestStatementParser.TestCallWritelnFormat1;
begin
TestCallFormat('writeln',False);
end;
procedure TTestStatementParser.TestCallWritelnFormat2;
begin
TestCallFormat('writeln',True);
end;
procedure TTestStatementParser.TestCallStrFormat1;
begin
TestCallFormat('str',False);
end;
procedure TTestStatementParser.TestCallStrFormat2;
begin
TestCallFormat('str',True);
end;
procedure TTestStatementParser.DoTestCallOtherFormat;
begin
TestCallFormat('nono',False);
end;
procedure TTestStatementParser.TestCallOtherFormat;
begin
AssertException('Only Write(ln) and str allow format',EParserError,@DoTestCallOtherFormat);
end;
procedure TTestStatementParser.TestIf;
Var
I : TPasImplIfElse;
begin
DeclareVar('boolean');
TestStatement(['if a then',';']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertNull('No else',i.ElseBranch);
AssertNull('No if branch',I.IfBranch);
end;
procedure TTestStatementParser.TestIfBlock;
Var
I : TPasImplIfElse;
begin
DeclareVar('boolean');
TestStatement(['if a then',' begin',' end']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertNull('No else',i.ElseBranch);
AssertNotNull('if branch',I.IfBranch);
AssertEquals('begin end block',TPasImplBeginBlock,I.ifBranch.ClassType);
end;
procedure TTestStatementParser.TestIfAssignment;
Var
I : TPasImplIfElse;
begin
DeclareVar('boolean');
TestStatement(['if a then',' a:=False;']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertNull('No else',i.ElseBranch);
AssertNotNull('if branch',I.IfBranch);
AssertEquals('assignment statement',TPasImplAssign,I.ifBranch.ClassType);
end;
procedure TTestStatementParser.TestIfElse;
Var
I : TPasImplIfElse;
begin
DeclareVar('boolean');
TestStatement(['if a then',' begin',' end','else',';']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertNull('No else',i.ElseBranch);
AssertNotNull('if branch',I.IfBranch);
AssertEquals('begin end block',TPasImplBeginBlock,I.ifBranch.ClassType);
end;
procedure TTestStatementParser.TestIfElseBlock;
Var
I : TPasImplIfElse;
begin
DeclareVar('boolean');
TestStatement(['if a then',' begin',' end','else',' begin',' end']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertNotNull('if branch',I.IfBranch);
AssertEquals('begin end block',TPasImplBeginBlock,I.ifBranch.ClassType);
AssertNotNull('Else branch',i.ElseBranch);
AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
end;
procedure TTestStatementParser.TestIfforElseBlock;
Var
I : TPasImplIfElse;
begin
TestStatement(['if a then','for X := 1 downto 0 do Writeln(X)','else', 'for X := 0 to 1 do Writeln(X)']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertEquals('For statement',TPasImplForLoop,I.ifBranch.ClassType);
AssertEquals('For statement',TPasImplForLoop,I.ElseBranch.ClassType);
end;
procedure TTestStatementParser.TestIfRaiseElseBlock;
Var
I : TPasImplIfElse;
begin
TestStatement(['if a then','raise','else', 'for X := 0 to 1 do Writeln(X)']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertEquals('For statement',TPasImplRaise,I.ifBranch.ClassType);
AssertEquals('For statement',TPasImplForLoop,I.ElseBranch.ClassType);
end;
procedure TTestStatementParser.TestIfWithBlock;
Var
I : TPasImplIfElse;
begin
TestStatement(['if a then','with b do something','else', 'for X := 0 to 1 do Writeln(X)']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertEquals('For statement',TPasImplWithDo,I.ifBranch.ClassType);
AssertEquals('For statement',TPasImplForLoop,I.ElseBranch.ClassType);
end;
procedure TTestStatementParser.TestIfSemiColonElseError;
begin
DeclareVar('boolean');
ExpectParserError('No semicolon before else',['if a then',' begin',' end;','else',' begin',' end']);
end;
procedure TTestStatementParser.TestNestedIf;
Var
I : TPasImplIfElse;
begin
DeclareVar('boolean');
DeclareVar('boolean','b');
TestStatement(['if a then',' if b then',' begin',' end','else',' begin',' end']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertNotNull('if branch',I.IfBranch);
AssertNull('Else branch',i.ElseBranch);
AssertEquals('if in if branch',TPasImplIfElse,I.ifBranch.ClassType);
I:=I.Ifbranch as TPasImplIfElse;
AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
end;
procedure TTestStatementParser.TestNestedIfElse;
Var
I : TPasImplIfElse;
begin
DeclareVar('boolean');
TestStatement(['if a then',' if b then',' begin',' end',' else',' begin',' end','else',' begin','end']);
I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
AssertNotNull('if branch',I.IfBranch);
AssertNotNull('Else branch',i.ElseBranch);
AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
AssertEquals('if in if branch',TPasImplIfElse,I.ifBranch.ClassType);
I:=I.Ifbranch as TPasImplIfElse;
AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
end;
procedure TTestStatementParser.TestWhile;
Var
W : TPasImplWhileDo;
begin
DeclareVar('boolean');
TestStatement(['While a do ;']);
W:=AssertStatement('While statement',TPasImplWhileDo) as TPasImplWhileDo;
AssertExpression('While condition',W.ConditionExpr,pekIdent,'a');
AssertNull('Empty body',W.Body);
end;
procedure TTestStatementParser.TestWhileBlock;
Var
W : TPasImplWhileDo;
begin
DeclareVar('boolean');
TestStatement(['While a do',' begin',' end']);
W:=AssertStatement('While statement',TPasImplWhileDo) as TPasImplWhileDo;
AssertExpression('While condition',W.ConditionExpr,pekIdent,'a');
AssertNotNull('Have while body',W.Body);
AssertEquals('begin end block',TPasImplBeginBlock,W.Body.ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(W.Body).ELements.Count);
end;
procedure TTestStatementParser.TestWhileNested;
Var
W : TPasImplWhileDo;
begin
DeclareVar('boolean');
DeclareVar('boolean','b');
TestStatement(['While a do',' while b do',' begin',' end']);
W:=AssertStatement('While statement',TPasImplWhileDo) as TPasImplWhileDo;
AssertExpression('While condition',W.ConditionExpr,pekIdent,'a');
AssertNotNull('Have while body',W.Body);
AssertEquals('Nested while',TPasImplWhileDo,W.Body.ClassType);
W:=W.Body as TPasImplWhileDo;
AssertExpression('While condition',W.ConditionExpr,pekIdent,'b');
AssertNotNull('Have nested while body',W.Body);
AssertEquals('Nested begin end block',TPasImplBeginBlock,W.Body.ClassType);
AssertEquals('Empty nested block',0,TPasImplBeginBlock(W.Body).ELements.Count);
end;
procedure TTestStatementParser.TestRepeat;
Var
R : TPasImplRepeatUntil;
begin
DeclareVar('boolean');
TestStatement(['Repeat','Until a;']);
R:=AssertStatement('Repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
AssertEquals('Empty body',0,R.Elements.Count);
end;
procedure TTestStatementParser.TestRepeatBlock;
Var
R : TPasImplRepeatUntil;
begin
DeclareVar('boolean');
TestStatement(['Repeat','begin','end;','Until a;']);
R:=AssertStatement('repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
AssertEquals('Have statement',1,R.Elements.Count);
AssertEquals('begin end block',TPasImplBeginBlock,TObject(R.Elements[0]).ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(R.Elements[0]).ELements.Count);
end;
procedure TTestStatementParser.TestRepeatBlockNosemicolon;
Var
R : TPasImplRepeatUntil;
begin
DeclareVar('boolean');
TestStatement(['Repeat','begin','end','Until a;']);
R:=AssertStatement('repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
AssertEquals('Have statement',1,R.Elements.Count);
AssertEquals('begin end block',TPasImplBeginBlock,TObject(R.Elements[0]).ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(R.Elements[0]).ELements.Count);
end;
procedure TTestStatementParser.TestRepeatNested;
Var
R : TPasImplRepeatUntil;
begin
DeclareVar('boolean');
DeclareVar('boolean','b');
TestStatement(['Repeat','repeat','begin','end','until b','Until a;']);
R:=AssertStatement('repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
AssertEquals('Have statement',1,R.Elements.Count);
AssertEquals('Nested repeat',TPasImplRepeatUntil,TObject(R.Elements[0]).ClassType);
R:=TPasImplRepeatUntil(R.Elements[0]);
AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'b');
AssertEquals('Have statement',1,R.Elements.Count);
AssertEquals('begin end block',TPasImplBeginBlock,TObject(R.Elements[0]).ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(R.Elements[0]).ELements.Count);
end;
procedure TTestStatementParser.TestFor;
Var
F : TPasImplForLoop;
begin
DeclareVar('integer');
TestStatement(['For a:=1 to 10 do',';']);
F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
AssertExpression('Loop variable name',F.VariableName,pekIdent,'a');
AssertEquals('Loop type',ltNormal,F.Looptype);
AssertEquals('Up loop',False,F.Down);
AssertExpression('Start value',F.StartExpr,pekNumber,'1');
AssertExpression('End value',F.EndExpr,pekNumber,'10');
AssertNull('Empty body',F.Body);
end;
procedure TTestStatementParser.TestForIn;
Var
F : TPasImplForLoop;
begin
DeclareVar('integer');
TestStatement(['For a in SomeSet Do',';']);
F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
AssertExpression('Loop variable name',F.VariableName,pekIdent,'a');
AssertEquals('Loop type',ltIn,F.Looptype);
AssertEquals('In loop',False,F.Down);
AssertExpression('Start value',F.StartExpr,pekIdent,'SomeSet');
AssertNull('Loop type',F.EndExpr);
AssertNull('Empty body',F.Body);
end;
procedure TTestStatementParser.TestForExpr;
Var
F : TPasImplForLoop;
B : TBinaryExpr;
begin
DeclareVar('integer');
TestStatement(['For a:=1+1 to 5+5 do',';']);
F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
AssertExpression('Loop variable name',F.VariableName,pekIdent,'a');
AssertEquals('Up loop',False,F.Down);
AssertExpression('Start expression',F.StartExpr,pekBinary,TBinaryExpr);
B:=F.StartExpr as TBinaryExpr;
AssertExpression('Start value left',B.left,pekNumber,'1');
AssertExpression('Start value right',B.right,pekNumber,'1');
AssertExpression('Start expression',F.StartExpr,pekBinary,TBinaryExpr);
B:=F.EndExpr as TBinaryExpr;
AssertExpression('End value left',B.left,pekNumber,'5');
AssertExpression('End value right',B.right,pekNumber,'5');
AssertNull('Empty body',F.Body);
end;
procedure TTestStatementParser.TestForBlock;
Var
F : TPasImplForLoop;
begin
DeclareVar('integer');
TestStatement(['For a:=1 to 10 do','begin','end']);
F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
AssertExpression('Loop variable name',F.VariableName,pekIdent,'a');
AssertEquals('Up loop',False,F.Down);
AssertExpression('Start value',F.StartExpr,pekNumber,'1');
AssertExpression('End value',F.EndExpr,pekNumber,'10');
AssertNotNull('Have for body',F.Body);
AssertEquals('begin end block',TPasImplBeginBlock,F.Body.ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(F.Body).ELements.Count);
end;
procedure TTestStatementParser.TestDowntoBlock;
Var
F : TPasImplForLoop;
begin
DeclareVar('integer');
TestStatement(['For a:=10 downto 1 do','begin','end']);
F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
AssertExpression('Loop variable name',F.VariableName,pekIdent,'a');
AssertEquals('Down loop',True,F.Down);
AssertExpression('Start value',F.StartExpr,pekNumber,'10');
AssertExpression('End value',F.EndExpr,pekNumber,'1');
AssertNotNull('Have for body',F.Body);
AssertEquals('begin end block',TPasImplBeginBlock,F.Body.ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(F.Body).ELements.Count);
end;
procedure TTestStatementParser.TestForNested;
Var
F : TPasImplForLoop;
begin
DeclareVar('integer');
DeclareVar('integer','b');
TestStatement(['For a:=1 to 10 do','For b:=11 to 20 do','begin','end']);
F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
AssertExpression('Loop variable name',F.VariableName,pekIdent,'a');
AssertEquals('Up loop',False,F.Down);
AssertExpression('Start value',F.StartExpr,pekNumber,'1');
AssertExpression('End value',F.EndExpr,pekNumber,'10');
AssertNotNull('Have while body',F.Body);
AssertEquals('begin end block',TPasImplForLoop,F.Body.ClassType);
F:=F.Body as TPasImplForLoop;
AssertExpression('Loop variable name',F.VariableName,pekIdent,'b');
AssertEquals('Up loop',False,F.Down);
AssertExpression('Start value',F.StartExpr,pekNumber,'11');
AssertExpression('End value',F.EndExpr,pekNumber,'20');
AssertNotNull('Have for body',F.Body);
AssertEquals('begin end block',TPasImplBeginBlock,F.Body.ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(F.Body).ELements.Count);
end;
procedure TTestStatementParser.TestWith;
Var
W : TpasImplWithDo;
begin
DeclareVar('record X,Y : Integer; end');
TestStatement(['With a do','begin','end']);
W:=AssertStatement('For statement',TpasImplWithDo) as TpasImplWithDo;
AssertEquals('1 expression',1,W.Expressions.Count);
AssertExpression('With identifier',TPasExpr(W.Expressions[0]),pekIdent,'a');
AssertNotNull('Have with body',W.Body);
AssertEquals('begin end block',TPasImplBeginBlock,W.Body.ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(W.Body).ELements.Count);
end;
procedure TTestStatementParser.TestWithMultiple;
Var
W : TpasImplWithDo;
begin
DeclareVar('record X,Y : Integer; end');
DeclareVar('record W,Z : Integer; end','b');
TestStatement(['With a,b do','begin','end']);
W:=AssertStatement('For statement',TpasImplWithDo) as TpasImplWithDo;
AssertEquals('2 expressions',2,W.Expressions.Count);
AssertExpression('With identifier 1',TPasExpr(W.Expressions[0]),pekIdent,'a');
AssertExpression('With identifier 2',TPasExpr(W.Expressions[1]),pekIdent,'b');
AssertNotNull('Have with body',W.Body);
AssertEquals('begin end block',TPasImplBeginBlock,W.Body.ClassType);
AssertEquals('Empty block',0,TPasImplBeginBlock(W.Body).ELements.Count);
end;
procedure TTestStatementParser.TestCaseEmpty;
begin
DeclareVar('integer');
AddStatements(['case a of','end;']);
ExpectParserError('Empty case not allowed');
end;
procedure TTestStatementParser.TestCaseOneInteger;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : ;','end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertNull('No else branch',C.ElseBranch);
AssertEquals('One case label',1,C.Elements.Count);
AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('1 expression for case',1,S.Expressions.Count);
AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertEquals('Empty case label statement',0,S.Elements.Count);
AssertNull('Empty case label statement',S.Body);
end;
procedure TTestStatementParser.TestCaseTwoIntegers;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
begin
DeclareVar('integer');
TestStatement(['case a of','1,2 : ;','end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertNull('No else branch',C.ElseBranch);
AssertEquals('One case label',1,C.Elements.Count);
AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case',2,S.Expressions.Count);
AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertExpression('With identifier 2',TPasExpr(S.Expressions[1]),pekNumber,'2');
AssertEquals('Empty case label statement',0,S.Elements.Count);
AssertNull('Empty case label statement',S.Body);
end;
procedure TTestStatementParser.TestCaseRange;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
begin
DeclareVar('integer');
TestStatement(['case a of','1..3 : ;','end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertNull('No else branch',C.ElseBranch);
AssertEquals('One case label',1,C.Elements.Count);
AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('1 expression for case',1,S.Expressions.Count);
AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekRange,TBinaryExpr);
AssertEquals('Empty case label statement',0,S.Elements.Count);
AssertNull('Empty case label statement',S.Body);
end;
procedure TTestStatementParser.TestCaseRangeSeparate;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
begin
DeclareVar('integer');
TestStatement(['case a of','1..3,5 : ;','end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertNull('No else branch',C.ElseBranch);
AssertEquals('One case label',1,C.Elements.Count);
AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case',2,S.Expressions.Count);
AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekRange,TBinaryExpr);
AssertExpression('With identifier 2',TPasExpr(S.Expressions[1]),pekNumber,'5');
AssertEquals('Empty case label statement',0,S.Elements.Count);
AssertNull('Empty case label statement',S.Body);
end;
procedure TTestStatementParser.TestCase2Cases;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : ;','2 : ;','end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertNull('No else branch',C.ElseBranch);
AssertEquals('Two case labels',2,C.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
AssertExpression('Case 1 With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertEquals('Empty case label statement 1',0,S.Elements.Count);
AssertNull('Empty case label statement 1',S.Body);
// Two
AssertEquals('Correct case for case label 2',TPasImplCaseStatement,TPasElement(C.Elements[1]).ClassType);
S:=TPasImplCaseStatement(C.Elements[1]);
AssertEquals('2 expressions for case 2',1,S.Expressions.Count);
AssertExpression('Case 2 With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'2');
AssertEquals('Empty case label statement 2',0,S.Elements.Count);
AssertNull('Empty case label statement 2',S.Body);
end;
procedure TTestStatementParser.TestCaseBlock;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
B : TPasImplbeginBlock;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : begin end;','end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertNull('No else branch',C.ElseBranch);
AssertEquals('Two case labels',1,C.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertEquals('1 case label statement',1,S.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
B:=TPasImplbeginBlock(S.Elements[0]);
AssertEquals('0 statements in block',0,B.Elements.Count);
end;
procedure TTestStatementParser.TestCaseElseBlockEmpty;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
B : TPasImplbeginBlock;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : begin end;','else',' end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertEquals('Two case labels',2,C.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertEquals('1 case label statement',1,S.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
B:=TPasImplbeginBlock(S.Elements[0]);
AssertEquals('0 statements in block',0,B.Elements.Count);
AssertNotNull('Have else branch',C.ElseBranch);
AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
AssertEquals('Zero statements ',0,TPasImplCaseElse(C.ElseBranch).Elements.Count);
end;
procedure TTestStatementParser.TestCaseOtherwiseBlockEmpty;
Var
C : TPasImplCaseOf;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : begin end;','otherwise',' end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertNotNull('Have else branch',C.ElseBranch);
AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
AssertEquals('Zero statements ',0,TPasImplCaseElse(C.ElseBranch).Elements.Count);
end;
procedure TTestStatementParser.TestCaseElseBlockAssignment;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
B : TPasImplbeginBlock;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : begin end;','else','a:=1',' end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertEquals('Two case labels',2,C.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertEquals('1 case label statement',1,S.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
B:=TPasImplbeginBlock(S.Elements[0]);
AssertEquals('0 statements in block',0,B.Elements.Count);
AssertNotNull('Have else branch',C.ElseBranch);
AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
AssertEquals('1 statement in else branch ',1,TPasImplCaseElse(C.ElseBranch).Elements.Count);
end;
procedure TTestStatementParser.TestCaseElseBlock2Assignments;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
B : TPasImplbeginBlock;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : begin end;','else','a:=1;','a:=32;',' end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertEquals('Two case labels',2,C.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertEquals('1 case label statement',1,S.Elements.Count);
AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
B:=TPasImplbeginBlock(S.Elements[0]);
AssertEquals('0 statements in block',0,B.Elements.Count);
AssertNotNull('Have else branch',C.ElseBranch);
AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
AssertEquals('2 statements in else branch ',2,TPasImplCaseElse(C.ElseBranch).Elements.Count);
end;
procedure TTestStatementParser.TestCaseIfCaseElse;
Var
C : TPasImplCaseOf;
begin
DeclareVar('integer');
DeclareVar('boolean','b');
TestStatement(['case a of','1 : if b then',' begin end;','else',' end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertEquals('Two case labels',2,C.Elements.Count);
AssertNotNull('Have else branch',C.ElseBranch);
AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
AssertEquals('0 statement in else branch ',0,TPasImplCaseElse(C.ElseBranch).Elements.Count);
end;
procedure TTestStatementParser.TestCaseIfElse;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
begin
DeclareVar('integer');
DeclareVar('boolean','b');
TestStatement(['case a of','1 : if b then',' begin end','else','begin','end',' end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertEquals('Two case labels',1,C.Elements.Count);
AssertNull('Have no else branch',C.ElseBranch);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
AssertEquals('1 case label statement',1,S.Elements.Count);
AssertEquals('If statement in case label 1',TPasImplIfElse,TPasElement(S.Elements[0]).ClassType);
AssertNotNull('If statement has else block',TPasImplIfElse(S.Elements[0]).ElseBranch);
end;
procedure TTestStatementParser.TestCaseElseNoSemicolon;
Var
C : TPasImplCaseOf;
S : TPasImplCaseStatement;
begin
DeclareVar('integer');
TestStatement(['case a of','1 : dosomething;','2 : dosomethingmore','else','a:=1;','end;']);
C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
AssertNotNull('Have case expression',C.CaseExpr);
AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
AssertEquals('case label count',3,C.Elements.Count);
S:=TPasImplCaseStatement(C.Elements[0]);
AssertEquals('case 1',1,S.Expressions.Count);
AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
S:=TPasImplCaseStatement(C.Elements[1]);
AssertEquals('case 2',1,S.Expressions.Count);
AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'2');
AssertEquals('third is else',TPasImplCaseElse,TObject(C.Elements[2]).ClassType);
AssertNotNull('Have else branch',C.ElseBranch);
AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
AssertEquals('1 statements in else branch ',1,TPasImplCaseElse(C.ElseBranch).Elements.Count);
end;
procedure TTestStatementParser.TestRaise;
Var
R : TPasImplRaise;
begin
DeclareVar('Exception');
TestStatement('Raise A;');
R:=AssertStatement('Raise statement',TPasImplRaise) as TPasImplRaise;
AssertEquals(0,R.Elements.Count);
AssertNotNull(R.ExceptObject);
AssertNull(R.ExceptAddr);
AssertExpression('Expression object',R.ExceptObject,pekIdent,'A');
end;
procedure TTestStatementParser.TestRaiseEmpty;
Var
R : TPasImplRaise;
begin
TestStatement('Raise;');
R:=AssertStatement('Raise statement',TPasImplRaise) as TPasImplRaise;
AssertEquals(0,R.Elements.Count);
AssertNull(R.ExceptObject);
AssertNull(R.ExceptAddr);
end;
procedure TTestStatementParser.TestRaiseAt;
Var
R : TPasImplRaise;
begin
DeclareVar('Exception');
DeclareVar('Pointer','B');
TestStatement('Raise A at B;');
R:=AssertStatement('Raise statement',TPasImplRaise) as TPasImplRaise;
AssertEquals(0,R.Elements.Count);
AssertNotNull(R.ExceptObject);
AssertNotNull(R.ExceptAddr);
AssertExpression('Expression object',R.ExceptAddr,pekIdent,'B');
end;
procedure TTestStatementParser.TestTryFinally;
Var
T : TPasImplTry;
S : TPasImplSimple;
F : TPasImplTryFinally;
begin
TestStatement(['Try',' DoSomething;','finally',' DoSomethingElse','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
F:=TPasImplTryFinally(T.FinallyExcept);
AssertEquals(1,F.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(F.Elements[0]).ClassType);
S:=TPasImplSimple(F.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
end;
procedure TTestStatementParser.TestTryFinallyEmpty;
Var
T : TPasImplTry;
F : TPasImplTryFinally;
begin
TestStatement(['Try','finally','end;']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(0,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
F:=TPasImplTryFinally(T.FinallyExcept);
AssertEquals(0,F.Elements.Count);
end;
procedure TTestStatementParser.TestTryFinallyNested;
Var
T : TPasImplTry;
S : TPasImplSimple;
F : TPasImplTryFinally;
begin
TestStatement(['Try',' DoSomething1;',' Try',' DoSomething2;',' finally',' DoSomethingElse2',' end;','Finally',' DoSomethingElse1','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(2,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething1');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
F:=TPasImplTryFinally(T.FinallyExcept);
AssertEquals(1,F.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(F.Elements[0]).ClassType);
S:=TPasImplSimple(F.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse1');
// inner statement
AssertNotNull(T.Elements[1]);
AssertEquals('Nested try statement',TPasImplTry,TPasElement(T.Elements[1]).ClassType);
T:=TPasImplTry(T.Elements[1]);
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething2');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
F:=TPasImplTryFinally(T.FinallyExcept);
AssertEquals(1,F.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(F.Elements[0]).ClassType);
S:=TPasImplSimple(F.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse2');
end;
procedure TTestStatementParser.TestTryExcept;
Var
T : TPasImplTry;
S : TPasImplSimple;
E : TPasImplTryExcept;
begin
TestStatement(['Try',' DoSomething;','except',' DoSomethingElse','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(1,E.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(E.Elements[0]).ClassType);
S:=TPasImplSimple(E.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
end;
procedure TTestStatementParser.TestTryExceptNested;
Var
T : TPasImplTry;
S : TPasImplSimple;
E : TPasImplTryExcept;
begin
TestStatement(['Try',' DoSomething1;',' try',' DoSomething2;',' except',' DoSomethingElse2',' end','except',' DoSomethingElse1','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(2,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething1');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(1,E.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(E.Elements[0]).ClassType);
S:=TPasImplSimple(E.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse1');
AssertNotNull(T.Elements[1]);
AssertEquals('Simple statement',TPasImplTry,TPasElement(T.Elements[1]).ClassType);
T:=TPasImplTry(T.Elements[1]);
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement 2',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething2 call ',S.Expr,pekIdent,'DoSomething2');
AssertEquals('Simple statement2',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement2',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(1,E.Elements.Count);
AssertEquals('Simple statement2',TPasImplSimple,TPasElement(E.Elements[0]).ClassType);
S:=TPasImplSimple(E.Elements[0]);
AssertExpression('DoSomethingElse2 call',S.Expr,pekIdent,'DoSomethingElse2');
end;
procedure TTestStatementParser.TestTryExceptEmpty;
Var
T : TPasImplTry;
E : TPasImplTryExcept;
begin
TestStatement(['Try','except','end;']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(0,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(0,E.Elements.Count);
end;
procedure TTestStatementParser.TestTryExceptOn;
Var
T : TPasImplTry;
S : TPasImplSimple;
E : TPasImplTryExcept;
O : TPasImplExceptOn;
begin
TestStatement(['Try',' DoSomething;','except','On E : Exception do','DoSomethingElse;','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(1,E.Elements.Count);
AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
O:=TPasImplExceptOn(E.Elements[0]);
AssertEquals(1,O.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
AssertEquals('Exception Variable name','E',O.VariableName);
AssertEquals('Exception Type name','Exception',O.TypeName);
S:=TPasImplSimple(O.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
// AssertEquals('Variable name',
end;
procedure TTestStatementParser.TestTryExceptOn2;
Var
T : TPasImplTry;
S : TPasImplSimple;
E : TPasImplTryExcept;
O : TPasImplExceptOn;
begin
TestStatement(['Try',' DoSomething;','except',
'On E : Exception do','DoSomethingElse;',
'On Y : Exception2 do','DoSomethingElse2;',
'end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(2,E.Elements.Count);
// Exception handler 1
AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
O:=TPasImplExceptOn(E.Elements[0]);
AssertEquals(1,O.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
AssertEquals('Exception Variable name','E',O.VariableName);
AssertEquals('Exception Type name','Exception',O.TypeName);
S:=TPasImplSimple(O.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
// Exception handler 2
AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[1]).ClassType);
O:=TPasImplExceptOn(E.Elements[1]);
AssertEquals(1,O.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
AssertEquals('Exception Variable name','Y',O.VariableName);
AssertEquals('Exception Type name','Exception2',O.TypeName);
S:=TPasImplSimple(O.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse2');
end;
procedure TTestStatementParser.TestTryExceptOnElse;
Var
T : TPasImplTry;
S : TPasImplSimple;
E : TPasImplTryExcept;
O : TPasImplExceptOn;
EE : TPasImplTryExceptElse;
I : TPasImplIfElse;
begin
DeclareVar('Boolean','b');
// Check that Else belongs to Except, not to IF
TestStatement(['Try',' DoSomething;','except','On E : Exception do','if b then','DoSomethingElse;','else','DoSomethingMore;','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNotNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(1,E.Elements.Count);
AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
O:=TPasImplExceptOn(E.Elements[0]);
AssertEquals('Exception Variable name','E',O.VariableName);
AssertEquals('Exception Type name','Exception',O.TypeName);
AssertEquals(1,O.Elements.Count);
AssertEquals('Simple statement',TPasImplIfElse,TPasElement(O.Elements[0]).ClassType);
I:=TPasImplIfElse(O.Elements[0]);
AssertEquals(1,I.Elements.Count);
AssertNull('No else barcnh for if',I.ElseBranch);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(I.Elements[0]).ClassType);
S:=TPasImplSimple(I.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
AssertEquals('Except Else statement',TPasImplTryExceptElse,T.ElseBranch.ClassType);
EE:=TPasImplTryExceptElse(T.ElseBranch);
AssertEquals(1,EE.Elements.Count);
AssertNotNull(EE.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(EE.Elements[0]).ClassType);
S:=TPasImplSimple(EE.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomethingMore');
end;
procedure TTestStatementParser.TestTryExceptOnIfElse;
Var
T : TPasImplTry;
S : TPasImplSimple;
E : TPasImplTryExcept;
O : TPasImplExceptOn;
EE : TPasImplTryExceptElse;
begin
TestStatement(['Try',' DoSomething;','except','On E : Exception do','DoSomethingElse;','else','DoSomethingMore;','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNotNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(1,E.Elements.Count);
AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
O:=TPasImplExceptOn(E.Elements[0]);
AssertEquals('Exception Variable name','E',O.VariableName);
AssertEquals('Exception Type name','Exception',O.TypeName);
AssertEquals(1,O.Elements.Count);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
S:=TPasImplSimple(O.Elements[0]);
AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
AssertEquals('Except Else statement',TPasImplTryExceptElse,T.ElseBranch.ClassType);
EE:=TPasImplTryExceptElse(T.ElseBranch);
AssertEquals(1,EE.Elements.Count);
AssertNotNull(EE.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(EE.Elements[0]).ClassType);
S:=TPasImplSimple(EE.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomethingMore');
end;
procedure TTestStatementParser.TestTryExceptRaise;
Var
T : TPasImplTry;
S : TPasImplSimple;
E : TPasImplTryExcept;
begin
TestStatement(['Try',' DoSomething;','except',' raise','end']);
T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
AssertEquals(1,T.Elements.Count);
AssertNotNull(T.FinallyExcept);
AssertNull(T.ElseBranch);
AssertNotNull(T.Elements[0]);
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
S:=TPasImplSimple(T.Elements[0]);
AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
E:=TPasImplTryExcept(T.FinallyExcept);
AssertEquals(1,E.Elements.Count);
AssertEquals('Raise statement',TPasImplRaise,TPasElement(E.Elements[0]).ClassType);
end;
procedure TTestStatementParser.TestAsm;
Var
T : TPasImplAsmStatement;
begin
TestStatement(['asm',' mov eax,1','end;']);
T:=AssertStatement('Asm statement',TPasImplAsmStatement) as TPasImplAsmStatement;
AssertEquals('Asm tokens',4,T.Tokens.Count);
AssertEquals('token 1 ','mov',T.Tokens[0]);
AssertEquals('token 2 ','eax',T.Tokens[1]);
AssertEquals('token 3 ',',',T.Tokens[2]);
AssertEquals('token 4 ','1',T.Tokens[3]);
end;
procedure TTestStatementParser.TestAsmBlock;
begin
Source.Add('{$MODE DELPHI}');
Source.Add('function BitsHighest(X: Cardinal): Integer;');
Source.Add('asm');
Source.Add('end;');
Source.Add('begin');
Source.Add('end.');
ParseModule;
end;
procedure TTestStatementParser.TestAsmBlockWithEndLabel;
begin
Source.Add('{$MODE DELPHI}');
Source.Add('function BitsHighest(X: Cardinal): Integer;');
Source.Add('asm');
Source.Add(' MOV ECX, EAX');
Source.Add(' MOV EAX, -1');
Source.Add(' BSR EAX, ECX');
Source.Add(' JNZ @@End');
Source.Add(' MOV EAX, -1');
Source.Add('@@End:');
Source.Add('end;');
Source.Add('begin');
Source.Add('end.');
ParseModule;
end;
procedure TTestStatementParser.TestAsmBlockInIfThen;
begin
Source.Add('{$MODE DELPHI}');
Source.Add('function Get8087StatusWord(ClearExceptions: Boolean): Word;');
Source.Add(' begin');
Source.Add(' if ClearExceptions then');
Source.Add(' asm');
Source.Add(' end');
Source.Add(' else');
Source.Add(' asm');
Source.Add(' end;');
Source.Add(' end;');
Source.Add(' begin');
Source.Add(' end.');
ParseModule;
end;
procedure TTestStatementParser.TestAssignToAddress;
begin
AddStatements(['@Proc:=Nil']);
ParseModule;
end;
procedure TTestStatementParser.TestFinalizationNoSemicolon;
begin
Source.Add('unit afile;');
Source.Add('{$mode objfpc}');
Source.Add('interface');
Source.Add('implementation');
Source.Add('initialization');
Source.Add(' writeln(''qqq'')');
Source.Add('finalization');
Source.Add(' write(''rrr'')');
ParseModule;
end;
procedure TTestStatementParser.TestMacroComment;
begin
AddStatements(['{$MACRO ON}',
'{$DEFINE func := //}',
' calltest;',
' func (''1'',''2'',''3'');',
'CallTest2;'
]);
ParseModule;
end;
procedure TTestStatementParser.TestPlatformIdentifier;
begin
AddStatements(['write(platform);']);
ParseModule;
end;
procedure TTestStatementParser.TestPlatformIdentifier2;
begin
AddStatements(['write(libs+platform);']);
ParseModule;
end;
procedure TTestStatementParser.TestArgumentNameOn;
begin
Source.Add('function TryOn(const on: boolean): boolean;');
Source.Add(' begin');
Source.Add(' end;');
Source.Add(' begin');
Source.Add(' end.');
ParseModule;
end;
procedure TTestStatementParser.TestGotoInIfThen;
begin
AddStatements([
'{$goto on}',
'if expr then',
' dosomething',
' else if expr2 then',
' goto try_qword',
' else',
' dosomething;',
' try_qword:',
' dosomething;']);
ParseModule;
end;
initialization
RegisterTests([TTestStatementParser]);
end.