mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-24 09:49:20 +02:00
fcl-passrc: parser: mode objfpc: generic function name<>...
git-svn-id: trunk@41378 -
This commit is contained in:
parent
f7f1286e51
commit
97bbae538b
@ -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
|
||||
|
@ -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':
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user