* Support operators

git-svn-id: trunk@194 -
This commit is contained in:
daniel 2005-06-04 16:14:28 +00:00
parent cd01ab8935
commit 3ece6aa385
2 changed files with 73 additions and 72 deletions

View File

@ -89,7 +89,7 @@ type
function GetDeclaration(full : Boolean) : string; virtual; function GetDeclaration(full : Boolean) : string; virtual;
Visibility: TPasMemberVisibility; Visibility: TPasMemberVisibility;
property RefCount: LongWord read FRefCount; property RefCount: LongWord read FRefCount;
property Name: string read FName; property Name: string read FName write Fname;
property Parent: TPasElement read FParent; property Parent: TPasElement read FParent;
end; end;

View File

@ -47,36 +47,36 @@ type
protected protected
FPackage: TPasPackage; FPackage: TPasPackage;
public public
function CreateElement(AClass: TPTreeElement; const AName: String; function CreateElement(AClass: TPTreeElement; const AName: string;
AParent: TPasElement; const ASourceFilename: String; AParent: TPasElement; const ASourceFilename: string;
ASourceLinenumber: Integer): TPasElement; ASourceLinenumber: Integer): TPasElement;
function CreateElement(AClass: TPTreeElement; const AName: String; function CreateElement(AClass: TPTreeElement; const AName: string;
AParent: TPasElement; AVisibility: TPasMemberVisibility; AParent: TPasElement; AVisibility: TPasMemberVisibility;
const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement; const ASourceFilename: string; ASourceLinenumber: Integer): TPasElement;
virtual; abstract; virtual; abstract;
function CreateFunctionType(const AName: String; AParent: TPasElement; function CreateFunctionType(const AName,resultname: string; AParent: TPasElement;
UseParentAsResultParent: Boolean; const ASourceFilename: String; UseParentAsResultParent: Boolean; const ASourceFilename: string;
ASourceLinenumber: Integer): TPasFunctionType; ASourceLinenumber: Integer): TPasFunctionType;
function FindElement(const AName: String): TPasElement; virtual; abstract; function FindElement(const AName: string): TPasElement; virtual; abstract;
function FindModule(const AName: String): TPasModule; virtual; function FindModule(const AName: string): TPasModule; virtual;
property Package: TPasPackage read FPackage; property Package: TPasPackage read FPackage;
end; end;
EParserError = class(Exception) EParserError = class(Exception)
private private
FFilename: String; FFilename: string;
FRow, FColumn: Integer; FRow, FColumn: Integer;
public public
constructor Create(const AReason, AFilename: String; constructor Create(const AReason, AFilename: string;
ARow, AColumn: Integer); ARow, AColumn: Integer);
property Filename: String read FFilename; property Filename: string read FFilename;
property Row: Integer read FRow; property Row: Integer read FRow;
property Column: Integer read FColumn; property Column: Integer read FColumn;
end; end;
function ParseSource(AEngine: TPasTreeContainer; function ParseSource(AEngine: TPasTreeContainer;
const FPCCommandLine, OSTarget, CPUTarget: String): TPasModule; const FPCCommandLine, OSTarget, CPUTarget: string): TPasModule;
implementation implementation
@ -95,36 +95,36 @@ type
FScanner: TPascalScanner; FScanner: TPascalScanner;
FEngine: TPasTreeContainer; FEngine: TPasTreeContainer;
FCurToken: TToken; FCurToken: TToken;
FCurTokenString: String; FCurTokenString: string;
// UngetToken support: // UngetToken support:
FTokenBuffer: array[0..1] of TToken; FTokenBuffer: array[0..1] of TToken;
FTokenStringBuffer: array[0..1] of String; FTokenStringBuffer: array[0..1] of string;
FTokenBufferIndex, FTokenBufferSize: Integer; FTokenBufferIndex, FTokenBufferSize: Integer;
procedure ParseExc(const Msg: String); procedure ParseExc(const Msg: string);
protected protected
function CreateElement(AClass: TPTreeElement; const AName: String; function CreateElement(AClass: TPTreeElement; const AName: string;
AParent: TPasElement): TPasElement; AParent: TPasElement): TPasElement;
function CreateElement(AClass: TPTreeElement; const AName: String; function CreateElement(AClass: TPTreeElement; const AName: string;
AParent: TPasElement; AVisibility: TPasMemberVisibility): TPasElement; AParent: TPasElement; AVisibility: TPasMemberVisibility): TPasElement;
public public
constructor Create(AScanner: TPascalScanner; AFileResolver: TFileResolver; constructor Create(AScanner: TPascalScanner; AFileResolver: TFileResolver;
AEngine: TPasTreeContainer); AEngine: TPasTreeContainer);
function CurTokenName: String; function CurTokenName: string;
function CurTokenText: String; function CurTokenText: string;
procedure NextToken; procedure NextToken;
procedure UngetToken; procedure UngetToken;
procedure ExpectToken(tk: TToken); procedure ExpectToken(tk: TToken);
function ExpectIdentifier: String; function ExpectIdentifier: string;
function ParseType(Parent: TPasElement; Prefix : String): TPasType; function ParseType(Parent: TPasElement; Prefix : string): TPasType;
function ParseType(Parent: TPasElement): TPasType; function ParseType(Parent: TPasElement): TPasType;
function ParseComplexType: TPasType; function ParseComplexType: TPasType;
procedure ParseArrayType(Element: TPasArrayType); procedure ParseArrayType(Element: TPasArrayType);
function ParseExpression: String; function ParseExpression: string;
procedure AddProcOrFunction(ASection: TPasSection; AProc: TPasProcedure); procedure AddProcOrFunction(ASection: TPasSection; AProc: TPasProcedure);
function CheckIfOverloaded(AOwner: TPasClassType; function CheckIfOverloaded(AOwner: TPasClassType;
const AName: String): TPasElement; const AName: string): TPasElement;
procedure ParseMain(var Module: TPasModule); procedure ParseMain(var Module: TPasModule);
procedure ParseUnit(var Module: TPasModule); procedure ParseUnit(var Module: TPasModule);
@ -142,7 +142,7 @@ type
function ParseProcedureOrFunctionDecl(Parent: TPasElement; function ParseProcedureOrFunctionDecl(Parent: TPasElement;
proctype:Tproctype): TPasProcedure; proctype:Tproctype): TPasProcedure;
procedure ParseRecordDecl(Parent: TPasRecordType); procedure ParseRecordDecl(Parent: TPasRecordType);
function ParseClassDecl(Parent: TPasElement; const AClassName: String; function ParseClassDecl(Parent: TPasElement; const AClassName: string;
AObjKind: TPasObjKind): TPasType; AObjKind: TPasObjKind): TPasType;
procedure ParseProperty(Element:TPasElement); procedure ParseProperty(Element:TPasElement);
@ -151,21 +151,21 @@ type
property Engine: TPasTreeContainer read FEngine; property Engine: TPasTreeContainer read FEngine;
property CurToken: TToken read FCurToken; property CurToken: TToken read FCurToken;
property CurTokenString: String read FCurTokenString; property CurTokenString: string read FCurTokenString;
end; end;
function TPasTreeContainer.CreateElement(AClass: TPTreeElement; function TPasTreeContainer.CreateElement(AClass: TPTreeElement;
const AName: String; AParent: TPasElement; const ASourceFilename: String; const AName: string; AParent: TPasElement; const ASourceFilename: string;
ASourceLinenumber: Integer): TPasElement; ASourceLinenumber: Integer): TPasElement;
begin begin
Result := CreateElement(AClass, AName, AParent, visDefault, ASourceFilename, Result := CreateElement(AClass, AName, AParent, visDefault, ASourceFilename,
ASourceLinenumber); ASourceLinenumber);
end; end;
function TPasTreeContainer.CreateFunctionType(const AName: String; function TPasTreeContainer.CreateFunctionType(const AName,resultname: string;
AParent: TPasElement; UseParentAsResultParent: Boolean; AParent: TPasElement; UseParentAsResultParent: Boolean;
const ASourceFilename: String; ASourceLinenumber: Integer): TPasFunctionType; const ASourceFilename: string; ASourceLinenumber: Integer): TPasFunctionType;
var var
ResultParent: TPasElement; ResultParent: TPasElement;
begin begin
@ -178,16 +178,16 @@ begin
ResultParent := Result; ResultParent := Result;
TPasFunctionType(Result).ResultEl := TPasFunctionType(Result).ResultEl :=
TPasResultElement(CreateElement(TPasResultElement, 'Result', ResultParent, TPasResultElement(CreateElement(TPasResultElement, resultname, ResultParent,
ASourceFilename, ASourceLinenumber)); ASourceFilename, ASourceLinenumber));
end; end;
function TPasTreeContainer.FindModule(const AName: String): TPasModule; function TPasTreeContainer.FindModule(const AName: string): TPasModule;
begin begin
Result := nil; Result := nil;
end; end;
constructor EParserError.Create(const AReason, AFilename: String; constructor EParserError.Create(const AReason, AFilename: string;
ARow, AColumn: Integer); ARow, AColumn: Integer);
begin begin
inherited Create(AReason); inherited Create(AReason);
@ -196,7 +196,7 @@ begin
FColumn := AColumn; FColumn := AColumn;
end; end;
procedure TPasParser.ParseExc(const Msg: String); procedure TPasParser.ParseExc(const Msg: string);
begin begin
raise EParserError.Create(Format(SParserErrorAtToken, [Msg, CurTokenName]), raise EParserError.Create(Format(SParserErrorAtToken, [Msg, CurTokenName]),
Scanner.CurFilename, Scanner.CurRow, Scanner.CurColumn); Scanner.CurFilename, Scanner.CurRow, Scanner.CurColumn);
@ -211,7 +211,7 @@ begin
FEngine := AEngine; FEngine := AEngine;
end; end;
function TPasParser.CurTokenName: String; function TPasParser.CurTokenName: string;
begin begin
if CurToken = tkIdentifier then if CurToken = tkIdentifier then
Result := 'Identifier ' + Scanner.CurTokenString Result := 'Identifier ' + Scanner.CurTokenString
@ -219,7 +219,7 @@ begin
Result := TokenInfos[CurToken]; Result := TokenInfos[CurToken];
end; end;
function TPasParser.CurTokenText: String; function TPasParser.CurTokenText: string;
begin begin
case CurToken of case CurToken of
tkIdentifier, tkString, tkNumber, tkChar: tkIdentifier, tkString, tkNumber, tkChar:
@ -283,7 +283,7 @@ begin
ParseExc(Format(SParserExpectTokenError, [TokenInfos[tk]])); ParseExc(Format(SParserExpectTokenError, [TokenInfos[tk]]));
end; end;
function TPasParser.ExpectIdentifier: String; function TPasParser.ExpectIdentifier: string;
begin begin
ExpectToken(tkIdentifier); ExpectToken(tkIdentifier);
Result := CurTokenString; Result := CurTokenString;
@ -295,7 +295,7 @@ begin
Result:=ParseType(Parent,''); Result:=ParseType(Parent,'');
end; end;
function TPasParser.ParseType(Parent: TPasElement; Prefix : String): TPasType; function TPasParser.ParseType(Parent: TPasElement; Prefix : string): TPasType;
procedure ParseRange; procedure ParseRange;
begin begin
@ -311,7 +311,7 @@ function TPasParser.ParseType(Parent: TPasElement; Prefix : String): TPasType;
end; end;
var var
Name, s: String; Name, s: string;
EnumValue: TPasEnumValue; EnumValue: TPasEnumValue;
Ref: TPasElement; Ref: TPasElement;
begin begin
@ -341,7 +341,7 @@ begin
else if s = 'LONGWORD' then Name := 'LongWord' else if s = 'LONGWORD' then Name := 'LongWord'
else if s = 'SHORTINT' then Name := 'ShortInt' else if s = 'SHORTINT' then Name := 'ShortInt'
else if s = 'SMALLINT' then Name := 'SmallInt' else if s = 'SMALLINT' then Name := 'SmallInt'
else if s = 'STRING' then Name := 'String' else if s = 'string' then Name := 'string'
else if s = 'WORD' then Name := 'Word' else if s = 'WORD' then Name := 'Word'
else else
Ref := Engine.FindElement(Name); Ref := Engine.FindElement(Name);
@ -355,7 +355,7 @@ begin
Result := TPasUnresolvedTypeRef(CreateElement(TPasUnresolvedTypeRef, Name, nil)); Result := TPasUnresolvedTypeRef(CreateElement(TPasUnresolvedTypeRef, Name, nil));
// !!!: Doesn't make sense for resolved types // !!!: Doesn't make sense for resolved types
if Name = 'String' then if Name = 'string' then
begin begin
NextToken; NextToken;
if CurToken = tkSquaredBraceOpen then if CurToken = tkSquaredBraceOpen then
@ -429,7 +429,7 @@ begin
end; end;
tkFunction: tkFunction:
begin begin
Result := Engine.CreateFunctionType('', Parent, false, Result := Engine.CreateFunctionType('','result', Parent, false,
Scanner.CurFilename, Scanner.CurRow); Scanner.CurFilename, Scanner.CurRow);
try try
ParseProcedureOrFunctionHeader(Result,TPasFunctionType(Result), ParseProcedureOrFunctionHeader(Result,TPasFunctionType(Result),
@ -461,7 +461,7 @@ begin
end; end;
tkFunction: tkFunction:
begin begin
Result := Engine.CreateFunctionType('', nil, false, Scanner.CurFilename, Result := Engine.CreateFunctionType('','result', nil, false, Scanner.CurFilename,
Scanner.CurRow); Scanner.CurRow);
ParseProcedureOrFunctionHeader(Result, TPasFunctionType(Result), ParseProcedureOrFunctionHeader(Result, TPasFunctionType(Result),
pt_function, true); pt_function, true);
@ -479,7 +479,7 @@ end;
procedure TPasParser.ParseArrayType(Element: TPasArrayType); procedure TPasParser.ParseArrayType(Element: TPasArrayType);
Var Var
S : String; S : string;
begin begin
NextToken; NextToken;
@ -512,7 +512,7 @@ begin
end; end;
end; end;
function TPasParser.ParseExpression: String; function TPasParser.ParseExpression: string;
var var
BracketLevel: Integer; BracketLevel: Integer;
MayAppendSpace, AppendSpace, NextAppendSpace: Boolean; MayAppendSpace, AppendSpace, NextAppendSpace: Boolean;
@ -603,7 +603,7 @@ end;
// Returns the parent for an element which is to be created // Returns the parent for an element which is to be created
function TPasParser.CheckIfOverloaded(AOwner: TPasClassType; function TPasParser.CheckIfOverloaded(AOwner: TPasClassType;
const AName: String): TPasElement; const AName: string): TPasElement;
var var
i: Integer; i: Integer;
Member: TPasElement; Member: TPasElement;
@ -782,7 +782,7 @@ end;
// Starts after the "uses" token // Starts after the "uses" token
procedure TPasParser.ParseUsesList(ASection: TPasSection); procedure TPasParser.ParseUsesList(ASection: TPasSection);
var var
UnitName: String; UnitName: string;
Element: TPasElement; Element: TPasElement;
begin begin
while true do while true do
@ -843,7 +843,7 @@ end;
// Starts after the type name // Starts after the type name
function TPasParser.ParseTypeDecl(Parent: TPasElement): TPasType; function TPasParser.ParseTypeDecl(Parent: TPasElement): TPasType;
var var
TypeName: String; TypeName: string;
procedure ParseRange; procedure ParseRange;
begin begin
@ -861,7 +861,7 @@ var
var var
EnumValue: TPasEnumValue; EnumValue: TPasEnumValue;
Prefix : String; Prefix : string;
HadPackedModifier : Boolean; // 12/04/04 - Dave - Added HadPackedModifier : Boolean; // 12/04/04 - Dave - Added
begin begin
@ -962,7 +962,7 @@ begin
ParseRange; ParseRange;
end; end;
end; end;
{ _STRING, _FILE: { _string, _FILE:
begin begin
Result := TPasAliasType(CreateElement(TPasAliasType, TypeName, Parent)); Result := TPasAliasType(CreateElement(TPasAliasType, TypeName, Parent));
UngetToken; UngetToken;
@ -1038,7 +1038,7 @@ begin
end; end;
tkFunction: tkFunction:
begin begin
Result := Engine.CreateFunctionType(TypeName, Parent, false, Result := Engine.CreateFunctionType(TypeName, 'result', Parent, false,
Scanner.CurFilename, Scanner.CurRow); Scanner.CurFilename, Scanner.CurRow);
try try
ParseProcedureOrFunctionHeader(Result, TPasFunctionType(Result), ParseProcedureOrFunctionHeader(Result, TPasFunctionType(Result),
@ -1122,7 +1122,7 @@ procedure TPasParser.ParseVarDecl(Parent: TPasElement; List: TList);
var var
i: Integer; i: Integer;
VarType: TPasType; VarType: TPasType;
Value, S: String; Value, S: string;
M: string; M: string;
begin begin
while true do while true do
@ -1223,7 +1223,7 @@ procedure TPasParser.ParseArgList(Parent: TPasElement; Args: TList; EndToken: TT
var var
ArgNames: TStringList; ArgNames: TStringList;
IsUntyped: Boolean; IsUntyped: Boolean;
Name, Value: String; Name, Value: string;
i: Integer; i: Integer;
Arg: TPasArgument; Arg: TPasArgument;
Access: TArgumentAccess; Access: TArgumentAccess;
@ -1303,6 +1303,7 @@ end;
// will get the token after the final ";" as next token. // will get the token after the final ";" as next token.
procedure TPasParser.ParseProcedureOrFunctionHeader(Parent: TPasElement; procedure TPasParser.ParseProcedureOrFunctionHeader(Parent: TPasElement;
Element: TPasProcedureType; proctype:Tproctype; OfObjectPossible: Boolean); Element: TPasProcedureType; proctype:Tproctype; OfObjectPossible: Boolean);
begin begin
NextToken; NextToken;
case proctype of case proctype of
@ -1331,11 +1332,11 @@ begin
end; end;
pt_operator: pt_operator:
begin begin
if CurToken = tkBraceOpen then ParseArgList(Parent, Element.Args, tkBraceClose);
begin
ParseArgList(Parent, Element.Args, tkBraceClose); TPasFunctionType(Element).ResultEl.name := ExpectIdentifier;
ExpectToken(tkColon);
end else if CurToken <> tkColon then if CurToken <> tkColon then
ParseExc(SParserExpectedLBracketColon); ParseExc(SParserExpectedLBracketColon);
if Assigned(Element) then // !!! if Assigned(Element) then // !!!
TPasFunctionType(Element).ResultEl.ResultType := ParseType(Parent) TPasFunctionType(Element).ResultEl.ResultType := ParseType(Parent)
@ -1398,7 +1399,7 @@ end;
procedure TPasParser.ParseProperty(Element:TPasElement); procedure TPasParser.ParseProperty(Element:TPasElement);
function GetAccessorName: String; function GetAccessorName: string;
begin begin
ExpectIdentifier; ExpectIdentifier;
Result := CurTokenString; Result := CurTokenString;
@ -1519,14 +1520,14 @@ end;
function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement; function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
proctype: Tproctype): TPasProcedure; proctype: Tproctype): TPasProcedure;
var var
Name: String; Name: string;
begin begin
Name := ExpectIdentifier; Name := ExpectIdentifier;
case proctype of case proctype of
pt_function: pt_function:
begin begin
Result := TPasFunction(CreateElement(TPasFunction, Name, Parent)); Result := TPasFunction(CreateElement(TPasFunction, Name, Parent));
Result.ProcType := Engine.CreateFunctionType('', Result, true, Result.ProcType := Engine.CreateFunctionType('', 'result', Result, true,
Scanner.CurFilename, Scanner.CurRow); Scanner.CurFilename, Scanner.CurRow);
end; end;
pt_procedure: pt_procedure:
@ -1538,7 +1539,7 @@ begin
pt_operator: pt_operator:
begin begin
Result := TPasOperator(CreateElement(TPasOperator, Name, Parent)); Result := TPasOperator(CreateElement(TPasOperator, Name, Parent));
Result.ProcType := Engine.CreateFunctionType('', Result, true, Result.ProcType := Engine.CreateFunctionType('', '__INVALID__', Result, true,
Scanner.CurFilename, Scanner.CurRow); Scanner.CurFilename, Scanner.CurRow);
end; end;
end; end;
@ -1581,16 +1582,16 @@ end;
// Starts after the "class" token // Starts after the "class" token
function TPasParser.ParseClassDecl(Parent: TPasElement; function TPasParser.ParseClassDecl(Parent: TPasElement;
const AClassName: String; AObjKind: TPasObjKind): TPasType; const AClassName: string; AObjKind: TPasObjKind): TPasType;
var var
CurVisibility: TPasMemberVisibility; CurVisibility: TPasMemberVisibility;
pt: Tproctype; pt: Tproctype;
procedure ProcessMethod(const MethodTypeName: String; HasReturnValue: Boolean); procedure ProcessMethod(const MethodTypeName: string; HasReturnValue: Boolean);
var var
Owner: TPasElement; Owner: TPasElement;
Proc: TPasProcedure; Proc: TPasProcedure;
s: String; s: string;
begin begin
ExpectIdentifier; ExpectIdentifier;
Owner := CheckIfOverloaded(TPasClassType(Result), CurTokenString); Owner := CheckIfOverloaded(TPasClassType(Result), CurTokenString);
@ -1598,7 +1599,7 @@ var
begin begin
Proc := TPasFunction(CreateElement(TPasFunction, CurTokenString, Owner, Proc := TPasFunction(CreateElement(TPasFunction, CurTokenString, Owner,
CurVisibility)); CurVisibility));
Proc.ProcType := Engine.CreateFunctionType( '', Proc, true, Proc.ProcType := Engine.CreateFunctionType( '', 'result', Proc, true,
Scanner.CurFilename, Scanner.CurRow); Scanner.CurFilename, Scanner.CurRow);
end else end else
begin begin
@ -1669,7 +1670,7 @@ var
end; end;
var var
s, SourceFilename: String; s, SourceFilename: string;
i, SourceLinenumber: Integer; i, SourceLinenumber: Integer;
VarList: TList; VarList: TList;
Element: TPasElement; Element: TPasElement;
@ -1777,14 +1778,14 @@ begin
end; end;
end; end;
function TPasParser.CreateElement(AClass: TPTreeElement; const AName: String; function TPasParser.CreateElement(AClass: TPTreeElement; const AName: string;
AParent: TPasElement): TPasElement; AParent: TPasElement): TPasElement;
begin begin
Result := Engine.CreateElement(AClass, AName, AParent, Result := Engine.CreateElement(AClass, AName, AParent,
Scanner.CurFilename, Scanner.CurRow); Scanner.CurFilename, Scanner.CurRow);
end; end;
function TPasParser.CreateElement(AClass: TPTreeElement; const AName: String; function TPasParser.CreateElement(AClass: TPTreeElement; const AName: string;
AParent: TPasElement; AVisibility: TPasMemberVisibility): TPasElement; AParent: TPasElement; AVisibility: TPasMemberVisibility): TPasElement;
begin begin
Result := Engine.CreateElement(AClass, AName, AParent, AVisibility, Result := Engine.CreateElement(AClass, AName, AParent, AVisibility,
@ -1793,18 +1794,18 @@ end;
function ParseSource(AEngine: TPasTreeContainer; function ParseSource(AEngine: TPasTreeContainer;
const FPCCommandLine, OSTarget, CPUTarget: String): TPasModule; const FPCCommandLine, OSTarget, CPUTarget: string): TPasModule;
var var
FileResolver: TFileResolver; FileResolver: TFileResolver;
Parser: TPasParser; Parser: TPasParser;
Start, CurPos: PChar; Start, CurPos: PChar;
Filename: String; Filename: string;
Scanner: TPascalScanner; Scanner: TPascalScanner;
procedure ProcessCmdLinePart; procedure ProcessCmdLinePart;
var var
l: Integer; l: Integer;
s: String; s: string;
begin begin
l := CurPos - Start; l := CurPos - Start;
SetLength(s, l); SetLength(s, l);
@ -1829,7 +1830,7 @@ var
end; end;
var var
s: String; s: string;
begin begin
Result := nil; Result := nil;
FileResolver := nil; FileResolver := nil;