Patch from IvankoB on Yandex.Ru to add support for REINTRODUCE, DEPRECATED, STATIC, OVERRIDE, MESSAGE modifiers

git-svn-id: trunk@3172 -
This commit is contained in:
michael 2006-04-08 14:40:59 +00:00
parent a5a8741464
commit b3f6041d55
2 changed files with 204 additions and 93 deletions

View File

@ -346,7 +346,7 @@ type
function GetDeclaration(full: Boolean): string; override; function GetDeclaration(full: Boolean): string; override;
procedure GetModifiers(List: TStrings); procedure GetModifiers(List: TStrings);
IsVirtual, IsDynamic, IsAbstract, IsOverride, IsVirtual, IsDynamic, IsAbstract, IsOverride,
IsOverload, IsMessage: Boolean; IsOverload, IsMessage, isReintroduced, isStatic: Boolean;
end; end;
TPasFunction = class(TPasProcedure) TPasFunction = class(TPasProcedure)
@ -1374,6 +1374,8 @@ begin
DoAdd(IsOverride,' Override'); DoAdd(IsOverride,' Override');
DoAdd(IsAbstract,' Abstract'); DoAdd(IsAbstract,' Abstract');
DoAdd(IsOverload,' Overload'); DoAdd(IsOverload,' Overload');
DoAdd(IsReintroduced,' Reintroduce');
DoAdd(IsStatic,' Static');
DoAdd(IsMessage,' Message'); DoAdd(IsMessage,' Message');
end; end;

View File

@ -1421,16 +1421,41 @@ begin
{ El['calling-conv'] := 'cdecl';} { El['calling-conv'] := 'cdecl';}
ExpectToken(tkSemicolon); ExpectToken(tkSemicolon);
end end
else if (Tok='PASCAL') then
begin
{ El['calling-conv'] := 'pascal';}
ExpectToken(tkSemicolon);
end
else if (Tok='STDCALL') then else if (Tok='STDCALL') then
begin begin
{ El['calling-conv'] := 'stdcall';} { El['calling-conv'] := 'stdcall';}
ExpectToken(tkSemicolon); ExpectToken(tkSemicolon);
end end
else if (Tok='OLDFPCCALL') then
begin
{ El['calling-conv'] := 'oldfpccall';}
ExpectToken(tkSemicolon);
end
else if (Tok='EXTDECL') then
begin
{ El['calling-conv'] := 'extdecl';}
ExpectToken(tkSemicolon);
end
else if (Tok='REGISTER') then
begin
{ El['calling-conv'] := 'register';}
ExpectToken(tkSemicolon);
end
else if (Tok='COMPILERPROC') then else if (Tok='COMPILERPROC') then
begin begin
{ El['calling-conv'] := 'compilerproc';} { El['calling-conv'] := 'compilerproc';}
ExpectToken(tkSemicolon); ExpectToken(tkSemicolon);
end end
else if (Tok='VARARGS') then
begin
{ 'varargs': needs CDECL & EXTERNAL }
ExpectToken(tkSemicolon);
end
else if (tok='DEPRECATED') then else if (tok='DEPRECATED') then
begin begin
{ El['calling-conv'] := 'deprecated';} { El['calling-conv'] := 'deprecated';}
@ -1445,6 +1470,10 @@ begin
begin begin
ExpectToken(tkSemicolon); ExpectToken(tkSemicolon);
end end
else if (tok='ASSEMBLER') then
begin
ExpectToken(tkSemicolon);
end
else if (UpperCase(CurTokenString) = 'EXTERNAL') then else if (UpperCase(CurTokenString) = 'EXTERNAL') then
repeat repeat
NextToken; NextToken;
@ -1482,116 +1511,184 @@ procedure TPasParser.ParseProperty(Element:TPasElement);
begin begin
ExpectIdentifier; ExpectIdentifier;
Result := CurTokenString; Result := CurTokenString;
while True do
begin while True do begin
NextToken; NextToken;
if CurToken = tkDot then if CurToken = tkDot then begin
begin
ExpectIdentifier; ExpectIdentifier;
Result := Result + '.' + CurTokenString; Result := Result + '.' + CurTokenString;
end else end else
break; break;
end; end;
UngetToken;
if CurToken = tkSquaredBraceOpen then begin
Result := Result + '[';
NextToken;
if CurToken in [tkIdentifier, tkNumber] then begin
Result := Result + CurTokenString;
end;
ExpectToken(tkSquaredBraceClose);
Result := Result + ']';
end else
UngetToken;
// writeln(Result);
end; end;
begin begin
NextToken; NextToken;
// !!!: Parse array properties correctly // if array prop then parse [ arg1:type1;... ]
if CurToken = tkSquaredBraceOpen then if CurToken = tkSquaredBraceOpen then begin
begin // !!!: Parse array properties correctly
ParseArgList(Element, TPasProperty(Element).Args, tkSquaredBraceClose); ParseArgList(Element, TPasProperty(Element).Args, tkSquaredBraceClose);
NextToken; NextToken;
end; end;
if CurToken = tkColon then if CurToken = tkColon then begin
begin // if ":prop_data_type" if supplied then read it
// read property type // read property type
TPasProperty(Element).VarType := ParseType(Element); TPasProperty(Element).VarType := ParseType(Element);
NextToken; NextToken;
end; end;
if CurToken <> tkSemicolon then
begin if CurToken <> tkSemicolon then begin
// read 'index' access modifier // if indexed prop then read the index value
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'INDEX') then if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'INDEX') then
TPasProperty(Element).IndexValue := ParseExpression // read 'index' access modifier
else TPasProperty(Element).IndexValue := ParseExpression
UngetToken; else
NextToken; // not indexed prop will be recheck for another token
UngetToken;
NextToken;
end; end;
if CurToken <> tkSemicolon then
begin // if the accessors list is not finished
// read 'read' access modifier if CurToken <> tkSemicolon then begin
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'READ') then // read 'read' access modifier
TPasProperty(Element).ReadAccessorName := GetAccessorName if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'READ') then
else TPasProperty(Element).ReadAccessorName := GetAccessorName
UngetToken; else
NextToken; // not read accessor will be recheck for another token
UngetToken;
NextToken;
end; end;
if CurToken <> tkSemicolon then
begin // if the accessors list is not finished
// read 'write' access modifier if CurToken <> tkSemicolon then begin
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'WRITE') then // read 'write' access modifier
TPasProperty(Element).WriteAccessorName := GetAccessorName if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'WRITE') then
else TPasProperty(Element).WriteAccessorName := GetAccessorName
UngetToken; else
NextToken; // not write accessor will be recheck for another token
UngetToken;
NextToken;
end; end;
if CurToken <> tkSemicolon then
begin // if the specifiers list is not finished
// read 'stored' access modifier if CurToken <> tkSemicolon then begin
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'STORED') then // read 'stored' access modifier
begin if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'STORED') then begin
NextToken; NextToken;
if CurToken = tkTrue then if CurToken = tkTrue then
TPasProperty(Element).StoredAccessorName := 'True' TPasProperty(Element).StoredAccessorName := 'True'
else if CurToken = tkFalse then else if CurToken = tkFalse then
TPasProperty(Element).StoredAccessorName := 'False' TPasProperty(Element).StoredAccessorName := 'False'
else if CurToken = tkIdentifier then else if CurToken = tkIdentifier then
TPasProperty(Element).StoredAccessorName := CurTokenString TPasProperty(Element).StoredAccessorName := CurTokenString
else else
ParseExc(SParserSyntaxError); ParseExc(SParserSyntaxError);
end else
// not stored accessor will be recheck for another token
UngetToken;
NextToken;
end;
// if the specifiers list is not finished
if CurToken <> tkSemicolon then begin
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then
// read 'default' value modifier -> ParseExpression(DEFAULT <value>)
TPasProperty(Element).DefaultValue := ParseExpression
else
// not "default <value>" prop will be recheck for another token
UngetToken;
NextToken;
end;
// if the specifiers list is not finished
if CurToken <> tkSemicolon then begin
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'NODEFAULT') then begin
// read 'nodefault' modifier
TPasProperty(Element).IsNodefault:=true;
end;
// stop recheck for specifiers - start from next token
NextToken;
end;
// after NODEFAULT may be a ";"
if CurToken = tkSemicolon then begin
// read semicolon
NextToken;
end;
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then begin
// what is after DEFAULT token at the end
NextToken;
if CurToken = tkSemicolon then begin
// ";" then DEFAULT=prop
TPasProperty(Element).IsDefault := True;
UngetToken;
end else begin
// "!;" then a step back to get phrase "DEFAULT <value>"
UngetToken;
// DefaultValue -> ParseExpression(DEFAULT <value>) and stay on the <value>
TPasProperty(Element).DefaultValue := ParseExpression;
end;
//!! there may be DEPRECATED token
NextToken;
end;
// after DEFAULT may be a ";"
if CurToken = tkSemicolon then begin
// read semicolon
NextToken;
end;
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEPRECATED') then begin
// nothing to do on DEPRECATED - just to accept
// NextToken;
end else end else
UngetToken; UngetToken;;
NextToken;
//!! else
// not DEFAULT prop accessor will be recheck for another token
//!! UngetToken;
{
if CurToken = tkSemicolon then begin
// read semicolon
NextToken;
end; end;
if CurToken <> tkSemicolon then if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEPRECATED') then begin
begin // nothing to do - just to process
// read 'default' value modifier NextToken;
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then
TPasProperty(Element).DefaultValue := ParseExpression
else
UngetToken;
NextToken;
end; end;
if CurToken <> tkSemicolon then if CurToken = tkSemicolon then begin
begin // read semicolon
// read 'nodefault' modifier NextToken;
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'NODEFAULT') then
begin
TPasProperty(Element).IsNodefault:=true;
end; end;
NextToken; }
end;
if CurToken = tkSemicolon then
begin
// read semicolon
NextToken;
end;
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then
begin
NextToken;
if CurToken = tkSemicolon then
begin
TPasProperty(Element).IsDefault := True;
UngetToken;
end else
begin
UngetToken;
TPasProperty(Element).DefaultValue := ParseExpression;
end;
end else
UngetToken;
end; end;
@ -1782,19 +1879,31 @@ var
Proc.IsAbstract := True Proc.IsAbstract := True
else if s = 'OVERRIDE' then else if s = 'OVERRIDE' then
Proc.IsOverride := True Proc.IsOverride := True
else if s = 'REINTRODUCE' then
Proc.IsReintroduced := True
else if s = 'OVERLOAD' then else if s = 'OVERLOAD' then
Proc.IsOverload := True Proc.IsOverload := True
else if s = 'MESSAGE' then else if s = 'STATIC' then
begin Proc.IsStatic := True
else if s = 'MESSAGE' then begin
Proc.IsMessage := True; Proc.IsMessage := True;
repeat repeat
NextToken; NextToken;
until CurToken = tkSemicolon; until CurToken = tkSemicolon;
UngetToken; UngetToken;
end else if s = 'CDECL' then end
else if s = 'CDECL' then
{ El['calling-conv'] := 'cdecl';}
else if s = 'PASCAL' then
{ El['calling-conv'] := 'cdecl';} { El['calling-conv'] := 'cdecl';}
else if s = 'STDCALL' then else if s = 'STDCALL' then
{ El['calling-conv'] := 'stdcall';} { El['calling-conv'] := 'stdcall';}
else if s = 'OLDFPCCALL' then
{ El['calling-conv'] := 'oldfpccall';}
else if s = 'EXTDECL' then
{ El['calling-conv'] := 'extdecl';}
else if s = 'DEPRECATED' then
{ El['calling-conv'] := 'deprecated';}
else else
begin begin
UngetToken; UngetToken;