fcl-passrc: parser: mode objfpc: generic function name<>...

git-svn-id: trunk@41378 -
This commit is contained in:
Mattias Gaertner 2019-02-18 23:08:46 +00:00
parent f7f1286e51
commit 97bbae538b
3 changed files with 63 additions and 15 deletions

View File

@ -450,7 +450,8 @@ type
procedure ParseProcBeginBlock(Parent: TProcedureBody);
procedure ParseProcAsmBlock(Parent: TProcedureBody);
// Function/Procedure declaration
function ParseProcedureOrFunctionDecl(Parent: TPasElement; ProcType: TProcType;AVisibility : TPasMemberVisibility = VisDefault): TPasProcedure;
function ParseProcedureOrFunctionDecl(Parent: TPasElement;
ProcType: TProcType; MustBeGeneric: boolean; AVisibility: TPasMemberVisibility = VisDefault): TPasProcedure;
procedure ParseArgList(Parent: TPasElement;
Args: TFPList; // list of TPasArgument
EndToken: TToken);
@ -2300,7 +2301,7 @@ begin
ProcType:=ptAnonymousFunction;
try
ProcExpr:=TProcedureExpr(CreateElement(TProcedureExpr,'',AParent,visPublic));
ProcExpr.Proc:=TPasAnonymousProcedure(ParseProcedureOrFunctionDecl(ProcExpr,ProcType));
ProcExpr.Proc:=TPasAnonymousProcedure(ParseProcedureOrFunctionDecl(ProcExpr,ProcType,false));
Result:=ProcExpr;
finally
if Result=nil then
@ -3413,7 +3414,7 @@ begin
SetBlock(declNone);
SaveComments;
pt:=GetProcTypeFromToken(CurToken);
AddProcOrFunction(Declarations, ParseProcedureOrFunctionDecl(Declarations, pt));
AddProcOrFunction(Declarations, ParseProcedureOrFunctionDecl(Declarations, pt, false));
end;
tkClass:
begin
@ -3423,7 +3424,7 @@ begin
If CurToken in [tkprocedure,tkFunction,tkConstructor,tkDestructor] then
begin
pt:=GetProcTypeFromToken(CurToken,True);
AddProcOrFunction(Declarations,ParseProcedureOrFunctionDecl(Declarations, pt));
AddProcOrFunction(Declarations,ParseProcedureOrFunctionDecl(Declarations, pt, false));
end
else
CheckToken(tkprocedure);
@ -3533,9 +3534,8 @@ begin
end;
end;
tkGeneric:
begin
if CurBlock <> declType then
ParseExcSyntaxError;
if CurBlock = declType then
begin
TypeName := ExpectIdentifier;
NamePos:=CurSourcePos;
List:=TFPList.Create;
@ -3593,7 +3593,41 @@ begin
TPasElement(List[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
List.Free;
end;
end;
end
else if CurBlock = declNone then
begin
if msDelphi in CurrentModeswitches then
ParseExcSyntaxError; // inconsistency, tkGeneric should be in Scanner.NonTokens
SetBlock(declNone);
SaveComments;
NextToken;
case CurToken of
tkclass:
begin
// generic class ...
NextToken;
if not (CurToken in [tkprocedure,tkfunction]) then
ParseExcSyntaxError;
// generic class procedure ...
pt:=GetProcTypeFromToken(CurToken,true);
AddProcOrFunction(Declarations, ParseProcedureOrFunctionDecl(Declarations, pt, true));
end;
tkprocedure,tkfunction:
begin
// generic procedure ...
SetBlock(declNone);
SaveComments;
pt:=GetProcTypeFromToken(CurToken);
AddProcOrFunction(Declarations, ParseProcedureOrFunctionDecl(Declarations, pt, true));
end;
else
ParseExcSyntaxError;
end;
end
else
begin
ParseExcSyntaxError;
end;
tkbegin:
begin
if Declarations is TProcedureBody then
@ -6112,7 +6146,8 @@ begin
end;
function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
ProcType: TProcType; AVisibility: TPasMemberVisibility): TPasProcedure;
ProcType: TProcType; MustBeGeneric: boolean; AVisibility: TPasMemberVisibility
): TPasProcedure;
function ExpectProcName: string;
@ -6124,13 +6159,15 @@ function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
Result:=ExpectIdentifier;
//writeln('ExpectProcName ',Parent.Classname);
if Parent is TImplementationSection then
begin
begin
NextToken;
repeat
if CurToken=tkDot then
Result:=Result+'.'+ExpectIdentifier
else if CurToken=tkLessThan then
begin // <> can be ignored, we read the list but discard its content
if (not MustBeGeneric) and not (msDelphi in CurrentModeswitches) then
ParseExcTokenError('('); // e.g. "generic" is missing in mode objfpc
UnGetToken;
L:=TFPList.Create;
Try
@ -6146,7 +6183,7 @@ function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
NextToken;
until false;
UngetToken;
end;
end;
end;
var
@ -6158,6 +6195,8 @@ begin
case ProcType of
ptOperator,ptClassOperator:
begin
if MustBeGeneric then
ParseExcTokenError('procedure');
NextToken;
IsTokenBased:=CurToken<>tkIdentifier;
if IsTokenBased then
@ -6169,7 +6208,11 @@ begin
Name:=OperatorNames[Ot];
end;
ptAnonymousProcedure,ptAnonymousFunction:
begin
Name:='';
if MustBeGeneric then
ParseExcTokenError('generic'); // inconsistency
end
else
Name:=ExpectProcName;
end;
@ -6376,7 +6419,7 @@ begin
if Not AllowMethods then
ParseExc(nErrRecordMethodsNotAllowed,SErrRecordMethodsNotAllowed);
ProcType:=GetProcTypeFromToken(CurToken,isClass);
Proc:=ParseProcedureOrFunctionDecl(ARec,ProcType,v);
Proc:=ParseProcedureOrFunctionDecl(ARec,ProcType,false,v);
if Proc.Parent is TPasOverloadedProc then
TPasOverloadedProc(Proc.Parent).Overloads.Add(Proc)
else
@ -6519,7 +6562,7 @@ var
ProcType: TProcType;
begin
ProcType:=GetProcTypeFromToken(CurToken,isClass);
Proc:=ParseProcedureOrFunctionDecl(AType,ProcType,AVisibility);
Proc:=ParseProcedureOrFunctionDecl(AType,ProcType,false,AVisibility);
if Proc.Parent is TPasOverloadedProc then
TPasOverloadedProc(Proc.Parent).Overloads.Add(Proc)
else

View File

@ -3400,9 +3400,15 @@ begin
'OBJFPC':
SetMode(msObjfpc,OBJFPCModeSwitches,true,bsObjFPCMode);
'DELPHI':
begin
SetMode(msDelphi,DelphiModeSwitches,true,bsDelphiMode,[bsPointerMath]);
SetNonToken(tkgeneric);
end;
'DELPHIUNICODE':
begin
SetMode(msDelphiUnicode,DelphiUnicodeModeSwitches,true,bsDelphiUnicodeMode,[bsPointerMath]);
SetNonToken(tkgeneric);
end;
'TP':
SetMode(msTP7,TPModeSwitches,false);
'MACPAS':

View File

@ -219,13 +219,12 @@ end;
procedure TTestGenerics.TestGenericFunction;
begin
exit; // ToDo
Add([
'generic function IfThen<T>(val:boolean;const iftrue:T; const iffalse:T) :T; inline; overload;',
'begin',
'end;',
'begin',
' IfThen<word>(true,2,3);',
' specialize IfThen<word>(true,2,3);',
'']);
ParseModule;
end;