mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-12 10:19:15 +02:00
codetools: added FindStartOfAtom
git-svn-id: trunk@20260 -
This commit is contained in:
parent
21c1fbbf04
commit
568ae66df6
@ -305,6 +305,7 @@ function ReadTilPascalBracketClose(const Source: string;
|
|||||||
var Position: integer; NestedComments: boolean = false): boolean;
|
var Position: integer; NestedComments: boolean = false): boolean;
|
||||||
function GetAtomLength(p: PChar; NestedComments: boolean): integer;
|
function GetAtomLength(p: PChar; NestedComments: boolean): integer;
|
||||||
function GetAtomString(p: PChar; NestedComments: boolean): string;
|
function GetAtomString(p: PChar; NestedComments: boolean): string;
|
||||||
|
function FindStartOfAtom(const Source: string; Position: integer): integer;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -2022,6 +2023,202 @@ begin
|
|||||||
System.Move(p^,Result[1],length(Result));
|
System.Move(p^,Result[1],length(Result));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function FindStartOfAtom(const Source: string; Position: integer): integer;
|
||||||
|
|
||||||
|
procedure ReadStringConstantBackward(var p: integer);
|
||||||
|
var PrePos: integer;
|
||||||
|
begin
|
||||||
|
while (p>1) do begin
|
||||||
|
case Source[p-1] of
|
||||||
|
'''':
|
||||||
|
begin
|
||||||
|
dec(p);
|
||||||
|
repeat
|
||||||
|
dec(p);
|
||||||
|
until (p<1) or (Source[p]='''');
|
||||||
|
end;
|
||||||
|
'0'..'9','A'..'Z','a'..'z':
|
||||||
|
begin
|
||||||
|
// test if char constant
|
||||||
|
PrePos:=p-1;
|
||||||
|
while (PrePos>1) and (IsHexNumberChar[Source[PrePos]]) do
|
||||||
|
dec(PrePos);
|
||||||
|
if (PrePos<1) then break;
|
||||||
|
if (Source[PrePos]='$') then begin
|
||||||
|
dec(PrePos);
|
||||||
|
if (PrePos<1) then break;
|
||||||
|
end;
|
||||||
|
if (Source[PrePos]='#') then
|
||||||
|
p:=PrePos
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
TNumberType = (ntDecimal, ntHexadecimal, ntBinary, ntIdentifier,
|
||||||
|
ntCharConstant, ntFloat, ntFloatWithExponent);
|
||||||
|
TNumberTypes = set of TNumberType;
|
||||||
|
|
||||||
|
const
|
||||||
|
AllNumberTypes: TNumberTypes = [ntDecimal, ntHexadecimal, ntBinary,
|
||||||
|
ntIdentifier, ntCharConstant, ntFloat, ntFloatWithExponent];
|
||||||
|
var
|
||||||
|
c: Char;
|
||||||
|
ForbiddenNumberTypes: TNumberTypes;
|
||||||
|
c2: Char;
|
||||||
|
begin
|
||||||
|
Result:=Position;
|
||||||
|
if (Result<1) then exit;
|
||||||
|
if Result>length(Source) then begin
|
||||||
|
Result:=length(Source);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
c:=Source[Result];
|
||||||
|
case c of
|
||||||
|
'_','A'..'Z','a'..'z':
|
||||||
|
begin
|
||||||
|
// identifier or keyword or hexnumber
|
||||||
|
while (Result>1) do begin
|
||||||
|
if (IsIdentChar[Source[Result-1]]) then
|
||||||
|
dec(Result)
|
||||||
|
else begin
|
||||||
|
case UpChars[Source[Result-1]] of
|
||||||
|
'@':
|
||||||
|
// assembler label
|
||||||
|
if (Result>2)
|
||||||
|
and (Source[Result-2]='@') then
|
||||||
|
dec(Result,2);
|
||||||
|
'$':
|
||||||
|
// hex number
|
||||||
|
dec(Result);
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
'''':
|
||||||
|
begin
|
||||||
|
inc(Result);
|
||||||
|
ReadStringConstantBackward(Result);
|
||||||
|
end;
|
||||||
|
'0'..'9':
|
||||||
|
begin
|
||||||
|
// could be a decimal number, an identifier, a hex number,
|
||||||
|
// a binary number, a char constant, a float, a float with exponent
|
||||||
|
ForbiddenNumberTypes:=[];
|
||||||
|
while true do begin
|
||||||
|
case UpChars[Source[Result]] of
|
||||||
|
'0'..'1':
|
||||||
|
;
|
||||||
|
'2'..'9':
|
||||||
|
ForbiddenNumberTypes:=ForbiddenNumberTypes+[ntBinary];
|
||||||
|
'A'..'D','F':
|
||||||
|
ForbiddenNumberTypes:=ForbiddenNumberTypes
|
||||||
|
+[ntBinary,ntDecimal,ntCharConstant,ntFloat,ntFloatWithExponent];
|
||||||
|
'E':
|
||||||
|
ForbiddenNumberTypes:=ForbiddenNumberTypes
|
||||||
|
+[ntBinary,ntDecimal,ntCharConstant,ntFloat];
|
||||||
|
'G'..'Z','_':
|
||||||
|
ForbiddenNumberTypes:=AllNumberTypes-[ntIdentifier];
|
||||||
|
'.':
|
||||||
|
begin
|
||||||
|
// could be the point of a float
|
||||||
|
if (ntFloat in ForbiddenNumberTypes)
|
||||||
|
or (Result<=1) or (Source[Result-1]='.') then begin
|
||||||
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
dec(Result);
|
||||||
|
// this was the part of a float after the point
|
||||||
|
// -> read decimal in front
|
||||||
|
ForbiddenNumberTypes:=AllNumberTypes-[ntDecimal];
|
||||||
|
end;
|
||||||
|
'+','-':
|
||||||
|
begin
|
||||||
|
// could be part of an exponent
|
||||||
|
if (ntFloatWithExponent in ForbiddenNumberTypes)
|
||||||
|
or (Result<=1)
|
||||||
|
or (not (Source[Result-1] in ['e','E']))
|
||||||
|
then begin
|
||||||
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
dec(Result);
|
||||||
|
// this was the exponent of a float -> read the float
|
||||||
|
ForbiddenNumberTypes:=AllNumberTypes-[ntFloat];
|
||||||
|
end;
|
||||||
|
'#': // char constant found
|
||||||
|
begin
|
||||||
|
if (ntCharConstant in ForbiddenNumberTypes) then
|
||||||
|
inc(Result);
|
||||||
|
ReadStringConstantBackward(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
'$':
|
||||||
|
begin
|
||||||
|
// hexadecimal number found
|
||||||
|
if (ntHexadecimal in ForbiddenNumberTypes) then
|
||||||
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
'%':
|
||||||
|
begin
|
||||||
|
// binary number found
|
||||||
|
if (ntBinary in ForbiddenNumberTypes) then
|
||||||
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
'@':
|
||||||
|
begin
|
||||||
|
if (Result=1) or (Source[Result-1]<>'@')
|
||||||
|
or (([ntIdentifier,ntDecimal]*ForbiddenNumberTypes)=[]) then
|
||||||
|
// atom start found
|
||||||
|
inc(Result)
|
||||||
|
else
|
||||||
|
// label found
|
||||||
|
dec(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if ForbiddenNumberTypes=AllNumberTypes then begin
|
||||||
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
if Result<=1 then break;
|
||||||
|
dec(Result);
|
||||||
|
end;
|
||||||
|
if IsIdentStartChar[Source[Result]] then begin
|
||||||
|
// it is an identifier
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
else
|
||||||
|
if Result>1 then begin
|
||||||
|
c2:=Source[Result-1];
|
||||||
|
// test for double char operators :=, +=, -=, /=, *=, <>, <=, >=, **, ><
|
||||||
|
if ((c2='=') and (IsEqualOperatorStartChar[c]))
|
||||||
|
or ((c='<') and (c2='>'))
|
||||||
|
or ((c='>') and (c2='<'))
|
||||||
|
or ((c='.') and (c2='.'))
|
||||||
|
or ((c='*') and (c2='*'))
|
||||||
|
or ((c='@') and (c2='@'))
|
||||||
|
then begin
|
||||||
|
dec(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function LineEndCount(const Txt: string;
|
function LineEndCount(const Txt: string;
|
||||||
out LengthOfLastLine: integer): integer;
|
out LengthOfLastLine: integer): integer;
|
||||||
begin
|
begin
|
||||||
|
@ -180,7 +180,8 @@ begin
|
|||||||
Code.LineColToPosition(Y,X,CodePos.P);
|
Code.LineColToPosition(Y,X,CodePos.P);
|
||||||
if (CodePos.P<1) or (CodePos.P>Code.SourceLength) then exit;
|
if (CodePos.P<1) or (CodePos.P>Code.SourceLength) then exit;
|
||||||
|
|
||||||
// move cursor to start of identifier (needed to find CodePos in cache)
|
// move cursor to start of atom (needed to find CodePos in cache)
|
||||||
|
|
||||||
while (CodePos.P>1) and (IsIdentChar[Code.Source[CodePos.P-1]]) do
|
while (CodePos.P>1) and (IsIdentChar[Code.Source[CodePos.P-1]]) do
|
||||||
dec(CodePos.P);
|
dec(CodePos.P);
|
||||||
if not IsIdentChar[Code.Source[CodePos.P]] then exit;
|
if not IsIdentChar[Code.Source[CodePos.P]] then exit;
|
||||||
|
@ -100,9 +100,9 @@ const
|
|||||||
ctnProperty = 50;
|
ctnProperty = 50;
|
||||||
ctnMethodMap = 51;
|
ctnMethodMap = 51;
|
||||||
|
|
||||||
ctnProcedure = 60;
|
ctnProcedure = 60; // childs: ctnProcedureHead, sections, ctnBeginBlock/ctnAsmBlock
|
||||||
ctnProcedureHead = 61;
|
ctnProcedureHead = 61; // childs: ctnParameterList, operator: ctnVarDefinition, operator/function: ctnIdentifier
|
||||||
ctnParameterList = 62;
|
ctnParameterList = 62; // childs: ctnVarDefinition
|
||||||
|
|
||||||
ctnIdentifier = 70;
|
ctnIdentifier = 70;
|
||||||
ctnRangedArrayType = 71;
|
ctnRangedArrayType = 71;
|
||||||
|
@ -1169,8 +1169,8 @@ end;
|
|||||||
|
|
||||||
procedure TCustomCodeTool.ReadPriorAtom;
|
procedure TCustomCodeTool.ReadPriorAtom;
|
||||||
var
|
var
|
||||||
CommentLvl, PrePos, OldPrePos: integer;
|
CommentLvl, PrePos, OldPrePos: integer;
|
||||||
IsStringConstant: boolean;
|
IsStringConstant: boolean;
|
||||||
|
|
||||||
procedure ReadStringConstantBackward;
|
procedure ReadStringConstantBackward;
|
||||||
var PrePos: integer;
|
var PrePos: integer;
|
||||||
|
Loading…
Reference in New Issue
Block a user