FpDebug: array-slice intrinsic, add mapping terminator "!"

This commit is contained in:
Martin 2024-07-27 22:16:47 +02:00
parent 21b35540cd
commit 8af587ec77
9 changed files with 1581 additions and 430 deletions

View File

@ -357,7 +357,7 @@ type
function DoGetResultValue(AParams: TFpPascalExpressionPartBracketArgumentList): TFpValue; override;
function ReturnsVariant: boolean; override;
public
constructor Create(AExpression: TFpPascalExpression; AStartChar: PChar; AnEndChar: PChar;
constructor Create(AnExpressionData: TFpPascalExpressionSharedData; AStartChar: PChar; AnEndChar: PChar;
ADisAssembler: TX86AsmDecoder);
destructor Destroy; override;
end;
@ -2479,7 +2479,7 @@ begin
then
exit;
ctx := Expression.Scope.LocationContext;
ctx := ExpressionData.Scope.LocationContext;
Addr := Arg.AsCardinal;
if Addr = 0 then begin
Result := Arg;
@ -2543,7 +2543,7 @@ begin
end;
CompVer := $030300;
Sym := Expression.Scope.SymbolAtAddress;
Sym := ExpressionData.Scope.SymbolAtAddress;
if (Sym <> nil) and (Sym is TFpSymbolDwarf) and (TFpSymbolDwarf(Sym).CompilationUnit <> nil)
then
CompVer := TFpDwarfFreePascalSymbolClassMap(TFpSymbolDwarf(Sym).CompilationUnit.DwarfSymbolClassMap).FCompilerVersion;
@ -2557,7 +2557,7 @@ begin
if R then begin
FChildClassCastType.ReleaseReference;
FChildClassCastType := Expression.GetDbgSymbolForIdentifier(AClassName);
FChildClassCastType := ExpressionData.GetDbgSymbolForIdentifier(AClassName);
if (FChildClassCastType = nil) or (FChildClassCastType.DbgSymbol = nil) or
(FChildClassCastType.DbgSymbol.SymbolType <> stType) or
(FChildClassCastType.DbgSymbol.Kind <> skClass)
@ -2578,11 +2578,12 @@ begin
Result := True;
end;
constructor TFpPascalExpressionPartIntrinsicIntfToObj.Create(AExpression: TFpPascalExpression;
AStartChar: PChar; AnEndChar: PChar; ADisAssembler: TX86AsmDecoder);
constructor TFpPascalExpressionPartIntrinsicIntfToObj.Create(
AnExpressionData: TFpPascalExpressionSharedData; AStartChar: PChar; AnEndChar: PChar;
ADisAssembler: TX86AsmDecoder);
begin
FDisAssembler := ADisAssembler;
inherited Create(AExpression, AStartChar, AnEndChar);
inherited Create(AnExpressionData, AStartChar, AnEndChar);
end;
destructor TFpPascalExpressionPartIntrinsicIntfToObj.Destroy;

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@ type
private
CurrentTestExprText: String;
CurrentTestExprObj: TTestFpPascalExpression;
FPrefix: TFpIntrinsicPrefix;
procedure CreateExpr(t: string; ExpValid: Boolean; SkipExpValid: Boolean = False);
published
procedure TestParser;
@ -44,7 +45,9 @@ begin
sc := TFpDbgSymbolScope.Create(ctx);
FreeAndNil(CurrentTestExprObj);
CurrentTestExprText := t;
CurrentTestExprObj := TTestFpPascalExpression.Create(CurrentTestExprText, sc);
CurrentTestExprObj := TTestFpPascalExpression.Create(CurrentTestExprText, sc, True);
CurrentTestExprObj.IntrinsicPrefix := FPrefix;
CurrentTestExprObj.Parse;
DebugLn(CurrentTestExprObj.DebugDump);
if not SkipExpValid then begin
s := ErrorHandler.ErrorAsString(CurrentTestExprObj.Error);
@ -70,12 +73,14 @@ procedure TTestPascalParser.TestParser;
end;
Procedure TestExpr(APart: TFpPascalExpressionPart; AClass: TFpPascalExpressionPartClass;
AText: String; AChildCount: Integer = -1);
AText: String; AChildCount: Integer = -1; AFullText: String = '');
begin
AssertNotNull(CurrentTestExprText+ ': IsAssigned', APart);
AssertTrue(CurrentTestExprText+': APart IS Class exp: '+AClass.ClassName+' was: '+APart.ClassName,
APart is AClass);
AssertEquals(CurrentTestExprText+': Text', AText, APart.GetText);
if AFullText <> '' then
AssertEquals(CurrentTestExprText+': FullText', AFullText, APart.GetFullText);
if AChildCount >=0 then begin
AssertTrue(CurrentTestExprText+': Is container ', APart is TFpPascalExpressionPartContainer);
AssertEquals(CurrentTestExprText+': childcount ', AChildCount, (APart as TFpPascalExpressionPartContainer).Count);
@ -83,12 +88,31 @@ procedure TTestPascalParser.TestParser;
end;
Procedure TestExpr(i: array of integer; AClass: TFpPascalExpressionPartClass;
AText: String; AChildCount: Integer = -1);
AText: String; AChildCount: Integer = -1; AFullText: String = '');
begin
TestExpr(GetChild(i), AClass, AText, AChildCount);
TestExpr(GetChild(i), AClass, AText, AChildCount, AFullText);
end;
Procedure TestSlOp(i: array of integer; AText: String);
var
APart: TFpPascalExpressionPart;
begin
APart := GetChild(i);
AssertNotNull(CurrentTestExprText+ ': IsAssigned', APart);
AssertTrue(CurrentTestExprText+': APart IS Class exp: TFpPascalExpressionPartOperatorArraySliceController was: '+APart.ClassName,
APart is TFpPascalExpressionPartOperatorArraySliceController);
AssertTrue(CurrentTestExprText+' text='+AText, strlcomp(APart.StartChar, PChar(AText), Length(AText) )=0);
AssertEquals(CurrentTestExprText+': childcount ', 1, (APart as TFpPascalExpressionPartContainer).Count);
end;
var
i, ip1: Integer;
s: String;
ip: Char;
begin
FPrefix := ipColon;
CurrentTestExprObj := nil;
try
CreateExpr('a', True);
@ -502,92 +526,471 @@ begin
CreateExpr('x * [a,]', False);
CreateExpr('a[1..2]', True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
for i := 0 to 3 do begin
s := StringOfChar('!', i);
CreateExpr('a[1..2]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
CreateExpr('a[1..2]+9', True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0], TFpPascalExpressionPartOperatorPlusMinus, '+', 2);
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,1], TFpPascalExpressionPartConstantNumber, '9', 0);
CreateExpr('a[1..2][3..4]', True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr('a[1..2]+9'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0], TFpPascalExpressionPartOperatorPlusMinus, '+', 2);
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,1], TFpPascalExpressionPartConstantNumber, '9', 0);
CreateExpr('a[1..2][3..4]+9', True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0,0], TFpPascalExpressionPartOperatorPlusMinus, '+', 2);
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
//
TestExpr([0,0,1], TFpPascalExpressionPartConstantNumber, '9', 0);
CreateExpr('a[b[1..2]..3]', True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertEquals('1..2', GetChild([]).GetFullText);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
//AssertEquals('b[1..2]..3', GetChild([0]).GetFullText);
AssertEquals('[1..2]..3', GetChild([0]).GetFullText);
//
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,1,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,0,1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,1,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '3', 0);
CreateExpr('a[1..2,3..4]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..4', strlcomp(GetChild([0]).StartChar, PChar('..4'), 3 )=0);
//
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 3);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,2], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..4');
TestExpr([0,0,2,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,2,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr('a[3..b[1..2]]', True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertEquals('1..2', GetChild([]).GetFullText);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertEquals('3..b[1..2]', GetChild([0]).GetFullText);
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
CreateExpr('a[1..2][3..4]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..4', strlcomp(GetChild([0]).StartChar, PChar('..4'), 3 )=0);
//
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..4');
TestExpr([0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,1,1,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,0,1,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,1,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr('a[1..2]![3..4]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..4', strlcomp(GetChild([]).StartChar, PChar('..4'), 3 )=0);
TestExpr([0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([0,0]).StartChar, PChar('..2'), 3 )=0);
//
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..4');
TestExpr([0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr('a[1..2][3..4]+9'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..4', strlcomp(GetChild([0]).StartChar, PChar('..4'), 3 )=0);
TestExpr([0,0], TFpPascalExpressionPartOperatorPlusMinus, '+', 2);
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..4');
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
//
TestExpr([0,0,1], TFpPascalExpressionPartConstantNumber, '9', 0);
CreateExpr('a[1..2][3..4]!+9'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0], TFpPascalExpressionPartOperatorPlusMinus, '+', 2);
TestExpr([0,0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..4', strlcomp(GetChild([0,0]).StartChar, PChar('..4'), 3 )=0);
//
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..4');
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
//
TestExpr([0,1], TFpPascalExpressionPartConstantNumber, '9', 0);
CreateExpr('a[1..2][3..4]!!+9'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorPlusMinus, '+', 2);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([0]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0,0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..4', strlcomp(GetChild([0,0]).StartChar, PChar('..4'), 3 )=0);
//
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..4');
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
//
TestExpr([1], TFpPascalExpressionPartConstantNumber, '9', 0);
CreateExpr('a[1..2]+b[3..4]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..4', strlcomp(GetChild([0]).StartChar, PChar('..4'), 3 )=0);
TestExpr([0,0], TFpPascalExpressionPartOperatorPlusMinus, '+', 2);
//
TestExpr([0,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,1,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..4');
TestExpr([0,0,1,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,1,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr('a[b[1..2]..3]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0], '..3');
//
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, 'b[1..2]..3');
TestExpr([0,0,1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,1,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,0,1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,1,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '3', 0);
CreateExpr('a[b[1..2]!..3]'+s, True); // Error when executing, but ...
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('..3', strlcomp(GetChild([]).StartChar, PChar('..3'), 3 )=0);
//
TestExpr([0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, 'b[1..2]!..3');
TestExpr([0,1,0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([0,1,0]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0,1,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,1,0,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,1,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,1,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,1,1], TFpPascalExpressionPartConstantNumber, '3', 0);
CreateExpr('a[3..b[1..2]]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0], '..b');
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..b[1..2]');
TestExpr([0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,1,1,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,0,1,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,0,1,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
CreateExpr('a[3..b[1..2]!]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('3..', strlcomp(GetChild([]).StartChar-1, PChar('3..'), 3 )=0);
TestExpr([0], TFpPascalExpressionPartBracketIndex, '[', 2, 'a[3..b[1..2]!]');
TestExpr([0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '3..b[1..2]');
TestExpr([0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,1,1], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
AssertTrue('1..2', strlcomp(GetChild([0,1,1]).StartChar, PChar('..2'), 3 )=0);
TestExpr([0,1,1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,1,1,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,1,1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,1,1,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,1,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
for ip1 := 0 to 1 do begin
ip := ':';
FPrefix := ipColon;
if ip1 = 1 then begin
ip := '!';
FPrefix := ipExclamation;
end;
CreateExpr(ip+'length(a[1..2])'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0], TFpPascalExpressionPartIntrinsic, 'length(', 0);
TestExpr([0,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,1,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2, '1..2');
TestExpr([0,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
CreateExpr(ip+'length(a[1..2]!)'+s, True);
TestExpr([], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0], TFpPascalExpressionPartIntrinsic, 'length(', 0);
TestExpr([1], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([1], '..2');
TestExpr([1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([1,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([1,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([1,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
CreateExpr(ip+'length(8+a[1..2])'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0], TFpPascalExpressionPartIntrinsic, 'length(', 0);
TestExpr([0,1], TFpPascalExpressionPartOperator, '+', 2);
TestExpr([0,1,0], TFpPascalExpressionPartConstantNumber, '8', 0);
TestExpr([0,1,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,1,1,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,1,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
CreateExpr(ip+'length(8+a[1..2]!)'+s, True);
TestExpr([], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0], TFpPascalExpressionPartIntrinsic, 'length(', 0);
TestExpr([1], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([1], '..2');
TestExpr([1,0], TFpPascalExpressionPartOperator, '+', 2);
TestExpr([1,0,0], TFpPascalExpressionPartConstantNumber, '8', 0);
TestExpr([1,0,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([1,0,1,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([1,0,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([1,0,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([1,0,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
CreateExpr(ip+'length(a[1..2])[3..4]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0], '..4');
TestExpr([0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0,0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0,0,0], TFpPascalExpressionPartIntrinsic, 'length(', 0);
TestExpr([0,0,0,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,1,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,0,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr(ip+'length(a[1..2]!)[3..4]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..4');
TestExpr([0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIntrinsic, 'length(', 0);
TestExpr([0,0,1], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0,0,1], '..2');
TestExpr([0,0,1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,1,0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,1,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,1,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr(ip+'length(a[1..2])![3..4]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..4');
TestExpr([0], TFpPascalExpressionPartBracketIndex, '[', 2);
//
TestExpr([0,0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0,0], '..2');
TestExpr([0,0,0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0,0,0], TFpPascalExpressionPartIntrinsic, 'length(', 0);
TestExpr([0,0,0,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,0,1,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,0,0,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,0,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,0,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
//
TestExpr([0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr(ip+'f_(a,b[1..2]:c[3..4])'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0], '..4');
TestExpr([0,0], TFpPascalExpressionPartBracketArgumentList, '(', 3);
TestExpr([0,0,0], TFpPascalExpressionPartIntrinsic, 'f_(', 0);
TestExpr([0,0,1], TFpPascalExpressionPartIdentifier, 'a', 0);
//TestExpr([0,0,2], TFpPascalExpressionPartOperatorColonAsSeparator, 'a', 0);
TestExpr([0,0,2,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,2,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,0,2,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,2,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,0,2,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,0,2,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,0,2,1,0], TFpPascalExpressionPartIdentifier, 'c', 0);
TestExpr([0,0,2,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,0,2,1,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,0,2,1,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr(ip+'f_(a,b[1..2]!:c[3..4])'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..4');
TestExpr([0], TFpPascalExpressionPartBracketArgumentList, '(', 3);
TestExpr([0,0], TFpPascalExpressionPartIntrinsic, 'f_(', 0);
TestExpr([0,1], TFpPascalExpressionPartIdentifier, 'a', 0);
//TestExpr([0,2], TFpPascalExpressionPartOperatorColonAsSeparator, 'a', 0);
TestExpr([0,2,0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0,2,0], '..2');
TestExpr([0,2,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,2,0,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,2,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,2,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,2,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,2,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,2,1,0], TFpPascalExpressionPartIdentifier, 'c', 0);
TestExpr([0,2,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,2,1,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,2,1,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr(ip+'f_(a,b[1..2]:c[3..4]!)'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([], '..2');
TestExpr([0], TFpPascalExpressionPartBracketArgumentList, '(', 3);
TestExpr([0,0], TFpPascalExpressionPartIntrinsic, 'f_(', 0);
TestExpr([0,1], TFpPascalExpressionPartIdentifier, 'a', 0);
//TestExpr([0,2], TFpPascalExpressionPartOperatorColonAsSeparator, 'a', 0);
TestExpr([0,2,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,2,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,2,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,2,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,2,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,2,1], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestSlOp([0,2,1], '..4');
TestExpr([0,2,1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,2,1,0,0], TFpPascalExpressionPartIdentifier, 'c', 0);
TestExpr([0,2,1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,2,1,0,1,0], TFpPascalExpressionPartConstantNumber, '3', 0);
TestExpr([0,2,1,0,1,1], TFpPascalExpressionPartConstantNumber, '4', 0);
CreateExpr('a ? b[1..2] : c'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0], TFpPascalExpressionPartOperatorQuestionMark, '?', 2);
TestExpr([0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartOperatorColon, ':', 2);
TestExpr([0,1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,1,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,1,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([0,1,1], TFpPascalExpressionPartIdentifier, 'c', 0);
CreateExpr('a ? b[1..2]! : c'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorQuestionMark, '?', 2);
TestExpr([0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([1], TFpPascalExpressionPartOperatorColon, ':', 2);
TestExpr([1,0], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([1,0,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([1,0,0,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([1,0,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([1,0,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([1,0,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
TestExpr([1,1], TFpPascalExpressionPartIdentifier, 'c', 0);
if s = '' then begin
CreateExpr('a ? b : c[1..2]'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([0], TFpPascalExpressionPartOperatorQuestionMark, '?', 2);
TestExpr([0,0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartOperatorColon, ':', 2);
TestExpr([0,1,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([0,1,1], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([0,1,1,0], TFpPascalExpressionPartIdentifier, 'c', 0);
TestExpr([0,1,1,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([0,1,1,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([0,1,1,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
end;
CreateExpr('a ? b : c[1..2]!'+s, True);
TestExpr([], TFpPascalExpressionPartOperatorQuestionMark, '?', 2);
TestExpr([0], TFpPascalExpressionPartIdentifier, 'a', 0);
TestExpr([1], TFpPascalExpressionPartOperatorColon, ':', 2);
TestExpr([1,0], TFpPascalExpressionPartIdentifier, 'b', 0);
TestExpr([1,1], TFpPascalExpressionPartOperatorArraySliceController, '..', 1);
TestExpr([1,1,0], TFpPascalExpressionPartBracketIndex, '[', 2);
TestExpr([1,1,0,0], TFpPascalExpressionPartIdentifier, 'c', 0);
TestExpr([1,1,0,1], TFpPascalExpressionPartOperatorArraySlice, '..', 2);
TestExpr([1,1,0,1,0], TFpPascalExpressionPartConstantNumber, '1', 0);
TestExpr([1,1,0,1,1], TFpPascalExpressionPartConstantNumber, '2', 0);
end;
end;
FPrefix := ipColon;
CreateExpr('a ? b : c', True);
TestExpr([], TFpPascalExpressionPartOperatorQuestionMark, '?', 2);
TestExpr([0], TFpPascalExpressionPartIdentifier, 'a', 0);
@ -721,6 +1124,7 @@ procedure TTestPascalParser.TestParserError;
var
s: String;
begin
FPrefix := ipColon;
// self test
s := ErrorHandler.ErrorAsString(CreateError(-1));
AssertFalse('self test format error msg', pos('Internal Error:', s) < 1);
@ -826,6 +1230,35 @@ begin
CreateExpr(':obj(1)', False);
CreateExpr(':obj(b)', False);
CreateExpr(':obj(b+1:3)', False);
CreateExpr('..', False);
CreateExpr('1..', False);
CreateExpr('..2', False);
CreateExpr('..]', False);
CreateExpr('1..]', False);
CreateExpr('..2]', False);
CreateExpr('a[..', False);
CreateExpr('a[1..', False);
CreateExpr('a[..2', False);
CreateExpr('a[..]', False);
CreateExpr('a[1..]', False);
CreateExpr('a[..2]', False);
CreateExpr('b[a[..]..1', False);
CreateExpr('b[a[1..]..1', False);
CreateExpr('b[a[..2]..1', False);
CreateExpr('a[..]..1', False);
CreateExpr('a[1..]..1', False);
CreateExpr('a[..2]..1', False);
CreateExpr('b[1..a[..]', False);
CreateExpr('b[1..a[1..]', False);
CreateExpr('b[1..a[..2]', False);
CreateExpr('!', False);
CreateExpr('-!', False);
CreateExpr('(!)', False);
CreateExpr('b[1..2]+!', False);
CreateExpr('b[1..2]+(!)', False);
end;

View File

@ -759,6 +759,8 @@ begin
finally
APasExpr.Free;
ExpressionScope.ReleaseReference;
if FDebugger.DbgController.CurrentProcess.GlobalCache <> nil then
FDebugger.DbgController.CurrentProcess.GlobalCache.Clear;
Queue(@DoCallback_DecRef);
end;
end;
@ -916,7 +918,7 @@ begin
ExprParamVal := AParams.Items[FoundIdx].ResultValue;
if (ExprParamVal = nil) then begin
DebugLn(FPDBG_FUNCCALL or DBG_WARNINGS, 'Internal error for arg %d ', [FoundIdx]);
AnError := AnExpressionPart.Expression.Error;
AnError := AnExpressionPart.ExpressionData.Error;
if not IsError(AnError) then
AnError := CreateError(fpErrAnyError, ['internal error, computing parameter']);
exit;
@ -1122,7 +1124,7 @@ begin
if (ALen = 3) and (strlicomp(AStart, pchar('i2o'), 3) = 0) and
(FDebugger.DbgController.CurrentProcess.Disassembler is TX86AsmDecoder)
then
Result := TFpPascalExpressionPartIntrinsicIntfToObj.Create(AnExpression,
Result := TFpPascalExpressionPartIntrinsicIntfToObj.Create(AnExpression.SharedData,
AStart, AStart+ALen,
TX86AsmDecoder(FDebugger.DbgController.CurrentProcess.Disassembler)
);
@ -1215,6 +1217,17 @@ begin
end;
end;
if FWatchValue <> nil then begin
if ResValue is TFpPasParserValueSlicedArray then begin
FWatchValue.SetSliceIndexPos(
TFpPasParserValueSlicedArray(ResValue).SliceBracketStartOffs,
TFpPasParserValueSlicedArray(ResValue).SliceBracketLength
);
end
else
FWatchValue.SetSliceIndexPos(-1,-1);
end;
if StopRequested then begin
if FWatchValue <> nil then
FWatchValue.Validity := ddsInvalid;

View File

@ -1,4 +1,4 @@
program intrinsic;
program WatchesIntrinsicPrg;
uses Classes;
type
@ -18,6 +18,10 @@ type
NextP: PFoo;
Dummy: TDummy;
Dummy2: TDummy2;
More: array [3..9] of TFoo;
More2: array [0..1,3..9] of TFoo;
MoreIdx: array [0..4] of Integer;
constructor Create(v: integer);
end;
var
@ -50,6 +54,18 @@ type
procedure Bar;
end;
{ TFoo }
constructor TFoo.Create(v: integer);
var
i: Integer;
begin
Value := v;
Dummy.a := 990+v;
Dummy2.a.a := 1990+v;
for i := 0 to 4 do MoreIdx[i] := i;
end;
procedure TIntf2.Foo; begin WriteLn(5); end;
procedure TIntf2.Bar; begin WriteLn(6); end;
procedure TIntf1.Foo; begin WriteLn(1); end;
@ -58,16 +74,17 @@ procedure TIntf1.Bar; begin WriteLn(2); end;
var
AnIntf1: IIntf1; AnIntf2: IIntf2;
AnObj1: TIntf1; AnObj2: TIntf2;
i: Integer;
begin
f1 := TFoo.Create; f1.Value := 1; f1.Dummy.a := 991; f1.Dummy2.a.a := 1991;
f2 := TFoo.Create; f2.Value := 2; f2.Dummy.a := 992; f2.Dummy2.a.a := 1992;
f3 := TFoo.Create; f3.Value := 3; f3.Dummy.a := 993; f3.Dummy2.a.a := 1993;
f4 := TFoo.Create; f4.Value := 4; f4.Dummy.a := 994; f4.Dummy2.a.a := 1994;
f5 := TFoo.Create; f5.Value := 5; f5.Dummy.a := 995; f5.Dummy2.a.a := 1995;
f6 := TFoo.Create; f6.Value := 6; f6.Dummy.a := 996; f6.Dummy2.a.a := 1996;
f7 := TFoo.Create; f7.Value := 7; f7.Dummy.a := 997; f7.Dummy2.a.a := 1997;
f8 := TFoo.Create; f8.Value := 8; f8.Dummy.a := 998; f8.Dummy2.a.a := 1998;
f1 := TFoo.Create(1);
f2 := TFoo.Create(2);
f3 := TFoo.Create(3);
f4 := TFoo.Create(4);
f5 := TFoo.Create(5);
f6 := TFoo.Create(6);
f7 := TFoo.Create(7);
f8 := TFoo.Create(8);
f1.Next := f2; f1.NextP := @f2;
f2.Next := f3; f2.NextP := @f3;
@ -91,6 +108,49 @@ begin
fa[5] := f3; f3.Idx := 0;
fa[0] := f4; f4.Idx := 0; // recurse self
f1.More[3] := nil;
f1.More[4] := TFoo.Create(100004);
f1.More[5] := TFoo.Create(100005);
f1.More[6] := TFoo.Create(100006);
f1.More[7] := TFoo.Create(100007);
f1.More[8] := f2;
f1.More[9] := f3;
f2.More[3] := f4;
f2.More[4] := TFoo.Create(200004);
f2.More[5] := TFoo.Create(200005);
f2.More[6] := TFoo.Create(200006);
f3.More[3] := TFoo.Create(300003);
f3.More[4] := TFoo.Create(300004);
f3.More[5] := TFoo.Create(300005);
f4.More[3] := TFoo.Create(400003);
f4.More[4] := TFoo.Create(400004);
for i := 0 to 1 do begin
f1.More2[i,3] := nil;
f1.More2[i,4] := TFoo.Create(100004+(i+1)*10000000);
f1.More2[i,5] := TFoo.Create(100005+(i+1)*10000000);
f1.More2[i,6] := TFoo.Create(100006+(i+1)*10000000);
f1.More2[i,7] := TFoo.Create(100007+(i+1)*10000000);
f1.More2[i,8] := f2;
f1.More2[i,9] := f3;
f2.More2[i,3] := f4;
f2.More2[i,4] := TFoo.Create(200004+(i+1)*10000000);
f2.More2[i,5] := TFoo.Create(200005+(i+1)*10000000);
f2.More2[i,6] := TFoo.Create(200006+(i+1)*10000000);
f3.More2[i,3] := TFoo.Create(300003+(i+1)*10000000);
f3.More2[i,4] := TFoo.Create(300004+(i+1)*10000000);
f3.More2[i,5] := TFoo.Create(300005+(i+1)*10000000);
f4.More2[i,3] := TFoo.Create(400003+(i+1)*10000000);
f4.More2[i,4] := TFoo.Create(400004+(i+1)*10000000);
end;
AnObj1 := TIntf1.Create; AnObj1.a := 123; AnObj1.b := 987; AnObj1.c := 551177;
AnObj2 := TIntf2.Create; AnObj2.x := 321; AnObj2.y := 789; AnObj2.c := 441188;
AnIntf1 := AnObj1;

View File

@ -2147,6 +2147,61 @@ begin
], 5)).IgnTypeName();
t.Add('flatten', ':flatten(f1, more[3..9]!, [array])', weArray([
weMatch('Value *:?=? ?1', skClass),
weMatch('Value *:?=? ?100004', skClass),
weMatch('Value *:?=? ?100005', skClass),
weMatch('Value *:?=? ?100006', skClass),
weMatch('Value *:?=? ?100007', skClass),
weMatch('Value *:?=? ?2', skClass),
weMatch('Value *:?=? ?4', skClass),
weMatch('Value *:?=? ?400003', skClass),
weMatch('Value *:?=? ?400004', skClass),
weMatch('Value *:?=? ?200004', skClass),
weMatch('Value *:?=? ?200005', skClass),
weMatch('Value *:?=? ?200006', skClass),
weMatch('Value *:?=? ?3', skClass),
weMatch('Value *:?=? ?300003', skClass),
weMatch('Value *:?=? ?300004', skClass),
weMatch('Value *:?=? ?300005', skClass)
], 16)).IgnTypeName();
t.Add('flatten', ':flatten(f2, more2[0..1][3..5]!!, moreidx[1..2]!, [array=2])', weArray([
weMatch('Value *:?=? ?2', skClass),
weMatch('Value *:?=? ?4', skClass), //[0,3]
weMatch('Value *:?=? ?10400003', skClass),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?10400004', skClass),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?20400003', skClass),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?20400004', skClass),
weInteger(1),weInteger(2),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?10200004', skClass), //[0,4]
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?10200005', skClass), //[0,5]
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?4', skClass), //[1,0]
weMatch('Value *:?=? ?10400003', skClass),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?10400004', skClass),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?20400003', skClass),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?20400004', skClass),
weInteger(1),weInteger(2),
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?20200004', skClass), //[1,4]
weInteger(1),weInteger(2),
weMatch('Value *:?=? ?20200005', skClass), //[1,5]
weInteger(1),weInteger(2),
weInteger(1),weInteger(2)
], 45)).IgnTypeName();
t.Add('i2o', ':i2o(AnIntf1)', weClass([
weInteger(123).N('a'), weInteger(987).N('b'), weInteger(551177).N('c') ], 'TIntf1'));
t.Add('i2o', ':i2o(AnIntf2)', weClass([

View File

@ -248,6 +248,7 @@ type
function GetValidity: TDebuggerDataState;
procedure SetTypeInfo(AValue: TDBGTypeBase); // Must not be used by MemDump
procedure SetValidity(AValue: TDebuggerDataState);
procedure SetSliceIndexPos(APos, ALen: Integer);
property EvaluateFlags: TWatcheEvaluateFlags read GetEvaluateFlags;
property FirstIndexOffs: Int64 read GetFirstIndexOffs;

View File

@ -36,10 +36,10 @@ type
FUpdateCount: Integer;
function GetIsUpdating: boolean; inline;
protected
procedure SetSliceIndexPos(APos, ALen: Integer); (* IDbgWatchValueIntf *)
procedure AddNotification(AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent);
procedure RemoveNotification(AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent);
procedure CallNotifications(AnEventType: TDbgDataRequestEventType; AnEventData: TDbgDataRequestEventData);
procedure BeginUpdate;
procedure EndUpdate;
procedure DoBeginUpdating; virtual;
@ -165,6 +165,11 @@ begin
Result := FUpdateCount > 0;
end;
procedure TDbgDataRequestTemplateBase.SetSliceIndexPos(APos, ALen: Integer);
begin
//
end;
procedure TDbgDataRequestTemplateBase.AddNotification(
AnEventType: TDbgDataRequestEventType; AnEvent: TDbgDataRequestEvent);
begin

View File

@ -593,6 +593,7 @@ type
FChildWatches: TIdeWatches;
FDisplayName: String;
FParentWatch: TIdeWatch;
FSliceIndexStartPos, FSliceIndexLen: Integer;
function GetChildWatch(ADispName, AnExpr: String): TIdeWatch;
function GetChildrenByNameAsArrayEntry(AName: Int64; DerefCount: Integer): TIdeWatch;
@ -770,6 +771,7 @@ type
function ResData: IDbgWatchDataIntf;
function GetDbgValConverter: ILazDbgValueConvertSelectorIntf;
function GetIntfEvaluateFlags: TWatcheEvaluateFlags;
procedure SetSliceIndexPos(APos, ALen: Integer);
function IDbgWatchValueIntf.GetEvaluateFlags = GetIntfEvaluateFlags;
private
FOnValidityChanged: TNotifyEvent;
@ -4147,6 +4149,13 @@ begin
Result := Result + [defMemDump];
end;
procedure TCurrentWatchValue.SetSliceIndexPos(APos, ALen: Integer);
begin
if Watch = nil then exit;
Watch.FSliceIndexStartPos := APos;
Watch.FSliceIndexLen := ALen;
end;
procedure TCurrentWatchValue.SetSnapShot(const AValue: TIdeWatchValue);
begin
assert((FSnapShot=nil) or (AValue=nil), 'TCurrentWatchValue already have snapshot');
@ -6845,10 +6854,21 @@ end;
function TIdeWatch.GetChildrenByNameAsArrayEntry(AName: Int64;
DerefCount: Integer): TIdeWatch;
var
s: String;
begin
Result := GetChildWatch(StringOfChar('^', DerefCount) + IntToStr(AName),
GetExpressionForArrayElement(Expression + StringOfChar('^', DerefCount), AName)
);
if FSliceIndexStartPos > 0 then begin
s := copy(Expression, 1, FSliceIndexStartPos-1) +
IntToStr(AName) +
copy(Expression, FSliceIndexStartPos+FSliceIndexLen, Length(Expression)) +
StringOfChar('^', DerefCount);
end
else
if FSliceIndexStartPos < 0 then
s := Expression + StringOfChar('^', DerefCount) + '[' + IntToStr(AName) + ']' // Do not replace any slice
else
s := GetExpressionForArrayElement(Expression + StringOfChar('^', DerefCount), AName);
Result := GetChildWatch(StringOfChar('^', DerefCount) + IntToStr(AName), s);
end;
function TIdeWatch.GetChildrenByNameAsField(AName, AClassName: String;