|
@@ -68,6 +68,10 @@ const
|
|
nParserArrayPropertiesCannotHaveDefaultValue = 2041;
|
|
nParserArrayPropertiesCannotHaveDefaultValue = 2041;
|
|
nParserDefaultPropertyMustBeArray = 2042;
|
|
nParserDefaultPropertyMustBeArray = 2042;
|
|
nParserUnknownProcedureType = 2043;
|
|
nParserUnknownProcedureType = 2043;
|
|
|
|
+ nParserGenericArray1Element = 2044;
|
|
|
|
+ nParserGenericClassOrArray = 2045;
|
|
|
|
+ nParserDuplicateIdentifier = 2046;
|
|
|
|
+
|
|
|
|
|
|
// resourcestring patterns of messages
|
|
// resourcestring patterns of messages
|
|
resourcestring
|
|
resourcestring
|
|
@@ -114,6 +118,9 @@ resourcestring
|
|
SParserArrayPropertiesCannotHaveDefaultValue = 'Array properties cannot have default value';
|
|
SParserArrayPropertiesCannotHaveDefaultValue = 'Array properties cannot have default value';
|
|
SParserDefaultPropertyMustBeArray = 'The default property must be an array property';
|
|
SParserDefaultPropertyMustBeArray = 'The default property must be an array property';
|
|
SParserUnknownProcedureType = 'Unknown procedure type "%d"';
|
|
SParserUnknownProcedureType = 'Unknown procedure type "%d"';
|
|
|
|
+ SParserGenericArray1Element = 'Generic arrays can have only 1 template element';
|
|
|
|
+ SParserGenericClassOrArray = 'Generic can only be used with classes or arrays';
|
|
|
|
+ SParserDuplicateIdentifier = 'Duplicate identifier "%s"';
|
|
|
|
|
|
type
|
|
type
|
|
TPasParserLogHandler = Procedure (Sender : TObject; Const Msg : String) of object;
|
|
TPasParserLogHandler = Procedure (Sender : TObject; Const Msg : String) of object;
|
|
@@ -237,8 +244,19 @@ type
|
|
Function TokenToExprOp (AToken : TToken) : TExprOpCode;
|
|
Function TokenToExprOp (AToken : TToken) : TExprOpCode;
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement): TPasElement;overload;
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement): TPasElement;overload;
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility): TPasElement;overload;
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility): TPasElement;overload;
|
|
|
|
+ function CreatePrimitiveExpr(AParent: TPasElement; AKind: TPasExprKind; const AValue: String): TPrimitiveExpr;
|
|
|
|
+ function CreateBoolConstExpr(AParent: TPasElement; AKind: TPasExprKind; const ABoolValue : Boolean): TBoolConstExpr;
|
|
|
|
+ function CreateBinaryExpr(AParent : TPasElement; xleft, xright: TPasExpr; AOpCode: TExprOpCode): TBinaryExpr;
|
|
|
|
+ procedure AddToBinaryExprChain(var ChainFirst, ChainLast: TPasExpr;
|
|
|
|
+ Element: TPasExpr; AOpCode: TExprOpCode);
|
|
|
|
+ function CreateUnaryExpr(AParent : TPasElement; AOperand: TPasExpr; AOpCode: TExprOpCode): TUnaryExpr;
|
|
|
|
+ function CreateArrayValues(AParent : TPasElement): TArrayValues;
|
|
function CreateFunctionType(const AName, AResultName: String; AParent: TPasElement;
|
|
function CreateFunctionType(const AName, AResultName: String; AParent: TPasElement;
|
|
UseParentAsResultParent: Boolean): TPasFunctionType;
|
|
UseParentAsResultParent: Boolean): TPasFunctionType;
|
|
|
|
+ function CreateInheritedExpr(AParent : TPasElement): TInheritedExpr;
|
|
|
|
+ function CreateSelfExpr(AParent : TPasElement): TSelfExpr;
|
|
|
|
+ function CreateNilExpr(AParent : TPasElement): TNilExpr;
|
|
|
|
+ function CreateRecordValues(AParent : TPasElement): TRecordValues;
|
|
Function IsCurTokenHint(out AHint : TPasMemberHint) : Boolean; overload;
|
|
Function IsCurTokenHint(out AHint : TPasMemberHint) : Boolean; overload;
|
|
Function IsCurTokenHint: Boolean; overload;
|
|
Function IsCurTokenHint: Boolean; overload;
|
|
Function TokenIsCallingConvention(S : String; out CC : TCallingConvention) : Boolean; virtual;
|
|
Function TokenIsCallingConvention(S : String; out CC : TCallingConvention) : Boolean; virtual;
|
|
@@ -250,6 +268,8 @@ type
|
|
function DoParseExpression(Aparent : TPaselement;InitExpr: TPasExpr=nil): TPasExpr;
|
|
function DoParseExpression(Aparent : TPaselement;InitExpr: TPasExpr=nil): TPasExpr;
|
|
function DoParseConstValueExpression(AParent : TPasElement): TPasExpr;
|
|
function DoParseConstValueExpression(AParent : TPasElement): TPasExpr;
|
|
function CheckPackMode: TPackMode;
|
|
function CheckPackMode: TPackMode;
|
|
|
|
+ function CheckUseUnit(ASection: TPasSection; AUnitName : string): TPasElement;
|
|
|
|
+ procedure CheckImplicitUsedUnits(ASection: TPasSection);
|
|
// Overload handling
|
|
// Overload handling
|
|
procedure AddProcOrFunction(Decs: TPasDeclarations; AProc: TPasProcedure);
|
|
procedure AddProcOrFunction(Decs: TPasDeclarations; AProc: TPasProcedure);
|
|
function CheckIfOverloaded(AParent: TPasElement; const AName: String): TPasElement;
|
|
function CheckIfOverloaded(AParent: TPasElement; const AName: String): TPasElement;
|
|
@@ -300,6 +320,7 @@ type
|
|
procedure ParseUnit(var Module: TPasModule);
|
|
procedure ParseUnit(var Module: TPasModule);
|
|
procedure ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
|
|
procedure ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
|
|
procedure ParseLibrary(var Module: TPasModule);
|
|
procedure ParseLibrary(var Module: TPasModule);
|
|
|
|
+ procedure ParseOptionalUsesList(ASection: TPasSection);
|
|
procedure ParseUsesList(ASection: TPasSection);
|
|
procedure ParseUsesList(ASection: TPasSection);
|
|
procedure ParseInterface;
|
|
procedure ParseInterface;
|
|
procedure ParseImplementation;
|
|
procedure ParseImplementation;
|
|
@@ -594,6 +615,7 @@ end;
|
|
|
|
|
|
function TPasTreeContainer.FindModule(const AName: String): TPasModule;
|
|
function TPasTreeContainer.FindModule(const AName: String): TPasModule;
|
|
begin
|
|
begin
|
|
|
|
+ if AName='' then ;
|
|
Result := nil;
|
|
Result := nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1019,7 +1041,7 @@ function TPasParser.ParseAliasType(Parent: TPasElement; const TypeName: String
|
|
begin
|
|
begin
|
|
Result := TPasTypeAliasType(CreateElement(TPasTypeAliasType, TypeName, Parent));
|
|
Result := TPasTypeAliasType(CreateElement(TPasTypeAliasType, TypeName, Parent));
|
|
try
|
|
try
|
|
- Result.DestType := ParseType(nil,'');
|
|
|
|
|
|
+ Result.DestType := ParseType(Result,'');
|
|
except
|
|
except
|
|
FreeAndNil(Result);
|
|
FreeAndNil(Result);
|
|
raise;
|
|
raise;
|
|
@@ -1032,7 +1054,7 @@ function TPasParser.ParsePointerType(Parent: TPasElement; const TypeName: String
|
|
begin
|
|
begin
|
|
Result := TPasPointerType(CreateElement(TPasPointerType, TypeName, Parent));
|
|
Result := TPasPointerType(CreateElement(TPasPointerType, TypeName, Parent));
|
|
Try
|
|
Try
|
|
- TPasPointerType(Result).DestType := ParseType(nil);
|
|
|
|
|
|
+ TPasPointerType(Result).DestType := ParseType(Result);
|
|
except
|
|
except
|
|
FreeAndNil(Result);
|
|
FreeAndNil(Result);
|
|
Raise;
|
|
Raise;
|
|
@@ -1201,7 +1223,7 @@ begin
|
|
until CurToken = tkSquaredBraceClose;
|
|
until CurToken = tkSquaredBraceClose;
|
|
Result.IndexRange:=S;
|
|
Result.IndexRange:=S;
|
|
ExpectToken(tkOf);
|
|
ExpectToken(tkOf);
|
|
- Result.ElType := ParseType(nil);
|
|
|
|
|
|
+ Result.ElType := ParseType(Result);
|
|
end;
|
|
end;
|
|
tkOf:
|
|
tkOf:
|
|
begin
|
|
begin
|
|
@@ -1210,7 +1232,7 @@ begin
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
UngetToken;
|
|
UngetToken;
|
|
- Result.ElType := ParseType(nil);
|
|
|
|
|
|
+ Result.ElType := ParseType(Result);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
else
|
|
@@ -1230,7 +1252,7 @@ begin
|
|
Result:=TPasFileType(CreateElement(TPasFileType, TypeName, Parent));
|
|
Result:=TPasFileType(CreateElement(TPasFileType, TypeName, Parent));
|
|
NextToken;
|
|
NextToken;
|
|
If CurToken=tkOf then
|
|
If CurToken=tkOf then
|
|
- Result.ElType := ParseType(nil)
|
|
|
|
|
|
+ Result.ElType := ParseType(Result)
|
|
else
|
|
else
|
|
ungettoken;
|
|
ungettoken;
|
|
end;
|
|
end;
|
|
@@ -1260,8 +1282,9 @@ begin
|
|
PClose:=tkBraceClose;
|
|
PClose:=tkBraceClose;
|
|
end;
|
|
end;
|
|
|
|
|
|
- params:=TParamsExpr.Create(AParent,paramskind);
|
|
|
|
|
|
+ params:=TParamsExpr(CreateElement(TParamsExpr,'',AParent));
|
|
try
|
|
try
|
|
|
|
+ params.Kind:=paramskind;
|
|
NextToken;
|
|
NextToken;
|
|
if not isEndOfExp then begin
|
|
if not isEndOfExp then begin
|
|
repeat
|
|
repeat
|
|
@@ -1326,55 +1349,55 @@ end;
|
|
|
|
|
|
function TPasParser.ParseExpIdent(AParent : TPasElement):TPasExpr;
|
|
function TPasParser.ParseExpIdent(AParent : TPasElement):TPasExpr;
|
|
var
|
|
var
|
|
- x : TPasExpr;
|
|
|
|
|
|
+ Last , Expr: TPasExpr;
|
|
prm : TParamsExpr;
|
|
prm : TParamsExpr;
|
|
- u : TUnaryExpr;
|
|
|
|
b : TBinaryExpr;
|
|
b : TBinaryExpr;
|
|
optk : TToken;
|
|
optk : TToken;
|
|
|
|
+ ok: Boolean;
|
|
begin
|
|
begin
|
|
Result:=nil;
|
|
Result:=nil;
|
|
case CurToken of
|
|
case CurToken of
|
|
- tkString: x:=TPrimitiveExpr.Create(AParent,pekString, CurTokenString);
|
|
|
|
- tkChar: x:=TPrimitiveExpr.Create(AParent,pekString, CurTokenText);
|
|
|
|
- tkNumber: x:=TPrimitiveExpr.Create(AParent,pekNumber, CurTokenString);
|
|
|
|
- tkIdentifier: x:=TPrimitiveExpr.Create(AParent,pekIdent, CurTokenText);
|
|
|
|
- tkfalse, tktrue: x:=TBoolConstExpr.Create(Aparent,pekBoolConst, CurToken=tktrue);
|
|
|
|
- tknil: x:=TNilExpr.Create(Aparent);
|
|
|
|
- tkSquaredBraceOpen: x:=ParseParams(AParent,pekSet);
|
|
|
|
|
|
+ tkString: Last:=CreatePrimitiveExpr(AParent,pekString,CurTokenString);
|
|
|
|
+ tkChar: Last:=CreatePrimitiveExpr(AParent,pekString, CurTokenText);
|
|
|
|
+ tkNumber: Last:=CreatePrimitiveExpr(AParent,pekNumber, CurTokenString);
|
|
|
|
+ tkIdentifier: Last:=CreatePrimitiveExpr(AParent,pekIdent, CurTokenText);
|
|
|
|
+ tkfalse, tktrue: Last:=CreateBoolConstExpr(Aparent,pekBoolConst, CurToken=tktrue);
|
|
|
|
+ tknil: Last:=CreateNilExpr(AParent);
|
|
|
|
+ tkSquaredBraceOpen: Last:=ParseParams(AParent,pekSet);
|
|
tkinherited:
|
|
tkinherited:
|
|
begin
|
|
begin
|
|
//inherited; inherited function
|
|
//inherited; inherited function
|
|
- x:=TInheritedExpr.Create(AParent);
|
|
|
|
|
|
+ Last:=CreateInheritedExpr(AParent);
|
|
NextToken;
|
|
NextToken;
|
|
if (CurToken=tkIdentifier) then
|
|
if (CurToken=tkIdentifier) then
|
|
begin
|
|
begin
|
|
- b:=TBinaryExpr.Create(AParent,x, DoParseExpression(AParent), eopNone);
|
|
|
|
|
|
+ b:=CreateBinaryExpr(AParent,Last, DoParseExpression(AParent), eopNone);
|
|
if not Assigned(b.right) then
|
|
if not Assigned(b.right) then
|
|
begin
|
|
begin
|
|
B.Free;
|
|
B.Free;
|
|
Exit; // error
|
|
Exit; // error
|
|
end;
|
|
end;
|
|
- x:=b;
|
|
|
|
|
|
+ Last:=b;
|
|
UngetToken;
|
|
UngetToken;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
UngetToken;
|
|
UngetToken;
|
|
end;
|
|
end;
|
|
tkself: begin
|
|
tkself: begin
|
|
- //x:=TPrimitiveExpr.Create(AParent,pekString, CurTokenText); //function(self);
|
|
|
|
- x:=TSelfExpr.Create(AParent);
|
|
|
|
|
|
+ //Last:=CreatePrimitiveExpr(AParent,pekString, CurTokenText); //function(self);
|
|
|
|
+ Last:=CreateSelfExpr(AParent);
|
|
NextToken;
|
|
NextToken;
|
|
if CurToken = tkDot then
|
|
if CurToken = tkDot then
|
|
begin // self.Write(EscapeText(AText));
|
|
begin // self.Write(EscapeText(AText));
|
|
optk:=CurToken;
|
|
optk:=CurToken;
|
|
NextToken;
|
|
NextToken;
|
|
- b:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(optk));
|
|
|
|
|
|
+ b:=CreateBinaryExpr(AParent,Last, ParseExpIdent(AParent), TokenToExprOp(optk));
|
|
if not Assigned(b.right) then
|
|
if not Assigned(b.right) then
|
|
begin
|
|
begin
|
|
B.Free;
|
|
B.Free;
|
|
Exit; // error
|
|
Exit; // error
|
|
end;
|
|
end;
|
|
- x:=b;
|
|
|
|
|
|
+ Last:=b;
|
|
end;
|
|
end;
|
|
UngetToken;
|
|
UngetToken;
|
|
end;
|
|
end;
|
|
@@ -1385,7 +1408,7 @@ begin
|
|
UngetToken;
|
|
UngetToken;
|
|
ParseExcExpectedIdentifier;
|
|
ParseExcExpectedIdentifier;
|
|
end;
|
|
end;
|
|
- x:=TPrimitiveExpr.Create(AParent,pekString, '@'+CurTokenText);
|
|
|
|
|
|
+ Last:=CreatePrimitiveExpr(AParent,pekString, '@'+CurTokenText);
|
|
end;
|
|
end;
|
|
tkCaret: begin
|
|
tkCaret: begin
|
|
// ^A..^_ characters. See #16341
|
|
// ^A..^_ characters. See #16341
|
|
@@ -1394,23 +1417,27 @@ begin
|
|
UngetToken;
|
|
UngetToken;
|
|
ParseExcExpectedIdentifier;
|
|
ParseExcExpectedIdentifier;
|
|
end;
|
|
end;
|
|
- x:=TPrimitiveExpr.Create(AParent,pekString, '^'+CurTokenText);
|
|
|
|
|
|
+ Last:=CreatePrimitiveExpr(AParent,pekString, '^'+CurTokenText);
|
|
end;
|
|
end;
|
|
else
|
|
else
|
|
ParseExcExpectedIdentifier;
|
|
ParseExcExpectedIdentifier;
|
|
end;
|
|
end;
|
|
|
|
|
|
- if x.Kind<>pekSet then NextToken;
|
|
|
|
|
|
+ Result:=Last;
|
|
|
|
+
|
|
|
|
+ if Last.Kind<>pekSet then NextToken;
|
|
|
|
|
|
|
|
+ ok:=false;
|
|
try
|
|
try
|
|
- if x.Kind=pekIdent then
|
|
|
|
|
|
+ if Last.Kind=pekIdent then
|
|
begin
|
|
begin
|
|
while CurToken in [tkDot] do
|
|
while CurToken in [tkDot] do
|
|
begin
|
|
begin
|
|
NextToken;
|
|
NextToken;
|
|
if CurToken=tkIdentifier then
|
|
if CurToken=tkIdentifier then
|
|
begin
|
|
begin
|
|
- b:=TBinaryExpr.Create(AParent,x, TPrimitiveExpr.Create(AParent,pekIdent, CurTokenText), eopSubIdent);
|
|
|
|
|
|
+ AddToBinaryExprChain(Result,Last,
|
|
|
|
+ CreatePrimitiveExpr(AParent,pekIdent, CurTokenText), eopSubIdent);
|
|
NextToken;
|
|
NextToken;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
@@ -1418,7 +1445,6 @@ begin
|
|
UngetToken;
|
|
UngetToken;
|
|
ParseExcExpectedIdentifier;
|
|
ParseExcExpectedIdentifier;
|
|
end;
|
|
end;
|
|
- x:=b;
|
|
|
|
end;
|
|
end;
|
|
while CurToken in [tkBraceOpen, tkSquaredBraceOpen, tkCaret] do
|
|
while CurToken in [tkBraceOpen, tkSquaredBraceOpen, tkCaret] do
|
|
case CurToken of
|
|
case CurToken of
|
|
@@ -1426,20 +1452,22 @@ begin
|
|
begin
|
|
begin
|
|
prm:=ParseParams(AParent,pekFuncParams);
|
|
prm:=ParseParams(AParent,pekFuncParams);
|
|
if not Assigned(prm) then Exit;
|
|
if not Assigned(prm) then Exit;
|
|
- prm.Value:=x;
|
|
|
|
- x:=prm;
|
|
|
|
|
|
+ prm.Value:=Last;
|
|
|
|
+ Result:=prm;
|
|
|
|
+ Last:=prm;
|
|
end;
|
|
end;
|
|
tkSquaredBraceOpen:
|
|
tkSquaredBraceOpen:
|
|
begin
|
|
begin
|
|
prm:=ParseParams(AParent,pekArrayParams);
|
|
prm:=ParseParams(AParent,pekArrayParams);
|
|
if not Assigned(prm) then Exit;
|
|
if not Assigned(prm) then Exit;
|
|
- prm.Value:=x;
|
|
|
|
- x:=prm;
|
|
|
|
|
|
+ prm.Value:=Last;
|
|
|
|
+ Result:=prm;
|
|
|
|
+ Last:=prm;
|
|
end;
|
|
end;
|
|
tkCaret:
|
|
tkCaret:
|
|
begin
|
|
begin
|
|
- u:=TUnaryExpr.Create(AParent,x, TokenToExprOp(CurToken));
|
|
|
|
- x:=u;
|
|
|
|
|
|
+ Result:=CreateUnaryExpr(AParent,Result,TokenToExprOp(CurToken));
|
|
|
|
+ Last:=Result;
|
|
NextToken;
|
|
NextToken;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -1448,19 +1476,16 @@ begin
|
|
begin
|
|
begin
|
|
optk:=CurToken;
|
|
optk:=CurToken;
|
|
NextToken;
|
|
NextToken;
|
|
- b:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(optk));
|
|
|
|
- if not Assigned(b.right) then
|
|
|
|
- begin
|
|
|
|
- b.free;
|
|
|
|
|
|
+ Expr:=ParseExpIdent(AParent);
|
|
|
|
+ if Expr=nil then
|
|
Exit; // error
|
|
Exit; // error
|
|
- end;
|
|
|
|
- x:=b;
|
|
|
|
|
|
+ AddToBinaryExprChain(Result,Last,Expr,TokenToExprOp(optk));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
-
|
|
|
|
- Result:=x;
|
|
|
|
|
|
+ ok:=true;
|
|
finally
|
|
finally
|
|
- if not Assigned(Result) then x.Free;
|
|
|
|
|
|
+ if not ok then
|
|
|
|
+ FreeAndNil(Result);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1537,9 +1562,12 @@ const
|
|
xright:=PopExp;
|
|
xright:=PopExp;
|
|
xleft:=PopExp;
|
|
xleft:=PopExp;
|
|
if t=tkDotDot then
|
|
if t=tkDotDot then
|
|
- bin := TBinaryExpr.CreateRange(AParent,xleft, xright)
|
|
|
|
|
|
+ begin
|
|
|
|
+ bin:=CreateBinaryExpr(Aparent,xleft,xright,eopNone);
|
|
|
|
+ bin.Kind:=pekRange;
|
|
|
|
+ end
|
|
else
|
|
else
|
|
- bin := TBinaryExpr.Create(AParent,xleft, xright, TokenToExprOp(t));
|
|
|
|
|
|
+ bin:=CreateBinaryExpr(AParent,xleft,xright,TokenToExprOp(t));
|
|
expstack.Add(bin);
|
|
expstack.Add(bin);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1590,7 +1618,7 @@ begin
|
|
begin
|
|
begin
|
|
NextToken;
|
|
NextToken;
|
|
// DumpCurToken('Here 2');
|
|
// DumpCurToken('Here 2');
|
|
- x:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(tkDot));
|
|
|
|
|
|
+ x:=CreateBinaryExpr(AParent,x, ParseExpIdent(AParent), TokenToExprOp(tkDot));
|
|
// DumpCurToken('Here 3');
|
|
// DumpCurToken('Here 3');
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1609,11 +1637,11 @@ begin
|
|
x:=popexp;
|
|
x:=popexp;
|
|
if (tempop=tkMinus) and (X.Kind=pekRange) then
|
|
if (tempop=tkMinus) and (X.Kind=pekRange) then
|
|
begin
|
|
begin
|
|
- TBinaryExpr(x).Left:=TUnaryExpr.Create(x, TBinaryExpr(X).left, eopSubtract);
|
|
|
|
|
|
+ TBinaryExpr(x).Left:=CreateUnaryExpr(x, TBinaryExpr(X).left, eopSubtract);
|
|
expstack.Add(x);
|
|
expstack.Add(x);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- expstack.Add( TUnaryExpr.Create(AParent, x, TokenToExprOp(tempop) ));
|
|
|
|
|
|
+ expstack.Add(CreateUnaryExpr(AParent, x, TokenToExprOp(tempop) ));
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
@@ -1697,7 +1725,7 @@ begin
|
|
case CurToken of
|
|
case CurToken of
|
|
tkComma: // array of values (a,b,c);
|
|
tkComma: // array of values (a,b,c);
|
|
begin
|
|
begin
|
|
- a:=TArrayValues.Create(AParent);
|
|
|
|
|
|
+ a:=CreateArrayValues(AParent);
|
|
a.AddValues(x);
|
|
a.AddValues(x);
|
|
repeat
|
|
repeat
|
|
NextToken;
|
|
NextToken;
|
|
@@ -1711,7 +1739,7 @@ begin
|
|
begin
|
|
begin
|
|
n:=GetExprIdent(x);
|
|
n:=GetExprIdent(x);
|
|
x.Free;
|
|
x.Free;
|
|
- r:=TRecordValues.Create(AParent);
|
|
|
|
|
|
+ r:=CreateRecordValues(AParent);
|
|
NextToken;
|
|
NextToken;
|
|
x:=DoParseConstValueExpression(AParent);
|
|
x:=DoParseConstValueExpression(AParent);
|
|
r.AddField(n, x);
|
|
r.AddField(n, x);
|
|
@@ -1757,7 +1785,7 @@ begin
|
|
Result:=TPasOverloadedProc(OldMember)
|
|
Result:=TPasOverloadedProc(OldMember)
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- Result:=TPasOverloadedProc.Create(AName, OldMember.Parent);
|
|
|
|
|
|
+ Result:=TPasOverloadedProc(CreateElement(TPasOverloadedProc, AName, OldMember.Parent));
|
|
Result.Visibility:=OldMember.Visibility;
|
|
Result.Visibility:=OldMember.Visibility;
|
|
Result.Overloads.Add(OldMember);
|
|
Result.Overloads.Add(OldMember);
|
|
Result.SourceFilename:=OldMember.SourceFilename;
|
|
Result.SourceFilename:=OldMember.SourceFilename;
|
|
@@ -1915,6 +1943,7 @@ begin
|
|
end;
|
|
end;
|
|
Section := TProgramSection(CreateElement(TProgramSection, '', CurModule));
|
|
Section := TProgramSection(CreateElement(TProgramSection, '', CurModule));
|
|
PP.ProgramSection := Section;
|
|
PP.ProgramSection := Section;
|
|
|
|
+ ParseOptionalUsesList(Section);
|
|
ParseDeclarations(Section);
|
|
ParseDeclarations(Section);
|
|
finally
|
|
finally
|
|
FCurModule:=nil;
|
|
FCurModule:=nil;
|
|
@@ -1942,12 +1971,25 @@ begin
|
|
ParseExcTokenError(';');
|
|
ParseExcTokenError(';');
|
|
Section := TLibrarySection(CreateElement(TLibrarySection, '', CurModule));
|
|
Section := TLibrarySection(CreateElement(TLibrarySection, '', CurModule));
|
|
PP.LibrarySection := Section;
|
|
PP.LibrarySection := Section;
|
|
|
|
+ ParseOptionalUsesList(Section);
|
|
ParseDeclarations(Section);
|
|
ParseDeclarations(Section);
|
|
finally
|
|
finally
|
|
FCurModule:=nil;
|
|
FCurModule:=nil;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPasParser.ParseOptionalUsesList(ASection: TPasSection);
|
|
|
|
+// checks if next token is Uses keyword and read uses list
|
|
|
|
+begin
|
|
|
|
+ NextToken;
|
|
|
|
+ if CurToken=tkuses then
|
|
|
|
+ ParseUsesList(ASection)
|
|
|
|
+ else begin
|
|
|
|
+ CheckImplicitUsedUnits(ASection);
|
|
|
|
+ UngetToken;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
// Starts after the "interface" token
|
|
// Starts after the "interface" token
|
|
procedure TPasParser.ParseInterface;
|
|
procedure TPasParser.ParseInterface;
|
|
var
|
|
var
|
|
@@ -1955,6 +1997,7 @@ var
|
|
begin
|
|
begin
|
|
Section := TInterfaceSection(CreateElement(TInterfaceSection, '', CurModule));
|
|
Section := TInterfaceSection(CreateElement(TInterfaceSection, '', CurModule));
|
|
CurModule.InterfaceSection := Section;
|
|
CurModule.InterfaceSection := Section;
|
|
|
|
+ ParseOptionalUsesList(Section);
|
|
ParseDeclarations(Section);
|
|
ParseDeclarations(Section);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1965,6 +2008,7 @@ var
|
|
begin
|
|
begin
|
|
Section := TImplementationSection(CreateElement(TImplementationSection, '', CurModule));
|
|
Section := TImplementationSection(CreateElement(TImplementationSection, '', CurModule));
|
|
CurModule.ImplementationSection := Section;
|
|
CurModule.ImplementationSection := Section;
|
|
|
|
+ ParseOptionalUsesList(Section);
|
|
ParseDeclarations(Section);
|
|
ParseDeclarations(Section);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2064,6 +2108,7 @@ var
|
|
ResStrEl: TPasResString;
|
|
ResStrEl: TPasResString;
|
|
TypeEl: TPasType;
|
|
TypeEl: TPasType;
|
|
ClassEl: TPasClassType;
|
|
ClassEl: TPasClassType;
|
|
|
|
+ ArrEl : TPasArrayType;
|
|
List: TFPList;
|
|
List: TFPList;
|
|
i,j: Integer;
|
|
i,j: Integer;
|
|
VarEl: TPasVariable;
|
|
VarEl: TPasVariable;
|
|
@@ -2112,8 +2157,10 @@ begin
|
|
break;
|
|
break;
|
|
end;
|
|
end;
|
|
tkUses:
|
|
tkUses:
|
|
- if Declarations is TPasSection then
|
|
|
|
- ParseUsesList(TPasSection(Declarations))
|
|
|
|
|
|
+ if Declarations.ClassType=TInterfaceSection then
|
|
|
|
+ ParseExcTokenError(TokenInfos[tkimplementation])
|
|
|
|
+ else if Declarations is TPasSection then
|
|
|
|
+ ParseExcTokenError(TokenInfos[tkend])
|
|
else
|
|
else
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
tkConst:
|
|
tkConst:
|
|
@@ -2255,21 +2302,44 @@ begin
|
|
if CurBlock <> declType then
|
|
if CurBlock <> declType then
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
TypeName := ExpectIdentifier;
|
|
TypeName := ExpectIdentifier;
|
|
- ClassEl := TPasClassType(Engine.CreateElement(TPasClassType,TypeName,Declarations, Scanner.CurFilename, Scanner.CurRow));
|
|
|
|
- ClassEl.ObjKind:=okGeneric;
|
|
|
|
|
|
+ List:=TFPList.Create;
|
|
try
|
|
try
|
|
- ReadGenericArguments(ClassEl.GenericTemplateTypes,ClassEl);
|
|
|
|
- Except
|
|
|
|
|
|
+ ReadGenericArguments(List,Nil);
|
|
|
|
+ ExpectToken(tkEqual);
|
|
|
|
+ NextToken;
|
|
|
|
+ Case CurToken of
|
|
|
|
+ tkClass :
|
|
|
|
+ begin
|
|
|
|
+ ClassEl := TPasClassType(Engine.CreateElement(TPasClassType,TypeName,Declarations, Scanner.CurFilename, Scanner.CurRow));
|
|
|
|
+ ClassEl.ObjKind:=okGeneric;
|
|
|
|
+ For I:=0 to List.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ TPasElement(List[i]).Parent:=ClassEl;
|
|
|
|
+ ClassEl.GenericTemplateTypes.Add(List[i]);
|
|
|
|
+ end;
|
|
|
|
+ NextToken;
|
|
|
|
+ DoParseClassType(ClassEl);
|
|
|
|
+ Declarations.Declarations.Add(ClassEl);
|
|
|
|
+ Declarations.Classes.Add(ClassEl);
|
|
|
|
+ CheckHint(classel,True);
|
|
|
|
+ end;
|
|
|
|
+ tkArray:
|
|
|
|
+ begin
|
|
|
|
+ if List.Count<>1 then
|
|
|
|
+ ParseExc(nParserGenericArray1Element,sParserGenericArray1Element);
|
|
|
|
+ ArrEl:=TPasArrayType(ParseArrayType(Declarations,TypeName,pmNone));
|
|
|
|
+ CheckHint(ArrEl,True);
|
|
|
|
+ ArrEl.ElType.Release;
|
|
|
|
+ ArrEl.elType:=TPasGenericTemplateType(List[0]);
|
|
|
|
+ Declarations.Declarations.Add(ArrEl);
|
|
|
|
+ Declarations.Types.Add(ArrEl);
|
|
|
|
+ end;
|
|
|
|
+ else
|
|
|
|
+ ParseExc(nParserGenericClassOrArray,SParserGenericClassOrArray);
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
List.Free;
|
|
List.Free;
|
|
- Raise;
|
|
|
|
end;
|
|
end;
|
|
- ExpectToken(tkEqual);
|
|
|
|
- ExpectToken(tkClass);
|
|
|
|
- NextToken;
|
|
|
|
- DoParseClassType(ClassEl);
|
|
|
|
- Declarations.Declarations.Add(ClassEl);
|
|
|
|
- Declarations.Classes.Add(ClassEl);
|
|
|
|
- CheckHint(classel,True);
|
|
|
|
end;
|
|
end;
|
|
tkbegin:
|
|
tkbegin:
|
|
begin
|
|
begin
|
|
@@ -2298,34 +2368,57 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-// Starts after the "uses" token
|
|
|
|
-procedure TPasParser.ParseUsesList(ASection: TPasSection);
|
|
|
|
|
|
+function TPasParser.CheckUseUnit(ASection: TPasSection; AUnitName: string
|
|
|
|
+ ): TPasElement;
|
|
|
|
|
|
- function CheckUnit(AUnitName : string):TPasElement;
|
|
|
|
|
|
+ procedure CheckDuplicateInUsesList(AUnitName : string; UsesList: TFPList);
|
|
|
|
+ var
|
|
|
|
+ i: Integer;
|
|
begin
|
|
begin
|
|
- result := Engine.FindModule(AUnitName); // should we resolve module here when "IN" filename is not known yet?
|
|
|
|
- if Assigned(result) then
|
|
|
|
- result.AddRef
|
|
|
|
- else
|
|
|
|
- Result := TPasType(CreateElement(TPasUnresolvedUnitRef, AUnitName,
|
|
|
|
- ASection));
|
|
|
|
- ASection.UsesList.Add(Result);
|
|
|
|
|
|
+ if UsesList=nil then exit;
|
|
|
|
+ for i:=0 to UsesList.Count-1 do
|
|
|
|
+ if CompareText(AUnitName,TPasModule(UsesList[i]).Name)=0 then
|
|
|
|
+ ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+begin
|
|
|
|
+ if CompareText(AUnitName,CurModule.Name)=0 then
|
|
|
|
+ ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
|
|
|
|
+ CheckDuplicateInUsesList(AUnitName,ASection.UsesList);
|
|
|
|
+ if ASection.ClassType=TImplementationSection then
|
|
|
|
+ CheckDuplicateInUsesList(AUnitName,CurModule.InterfaceSection.UsesList);
|
|
|
|
+
|
|
|
|
+ result := Engine.FindModule(AUnitName); // should we resolve module here when "IN" filename is not known yet?
|
|
|
|
+ if Assigned(result) then
|
|
|
|
+ result.AddRef
|
|
|
|
+ else
|
|
|
|
+ Result := TPasUnresolvedUnitRef(CreateElement(TPasUnresolvedUnitRef,
|
|
|
|
+ AUnitName, ASection));
|
|
|
|
+ ASection.UsesList.Add(Result);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasParser.CheckImplicitUsedUnits(ASection: TPasSection);
|
|
var
|
|
var
|
|
- AUnitName: String;
|
|
|
|
- Element: TPasElement;
|
|
|
|
i: Integer;
|
|
i: Integer;
|
|
begin
|
|
begin
|
|
- If not (Asection.ClassType=TImplementationSection) Then // interface,program,library,package
|
|
|
|
|
|
+ If not (ASection.ClassType=TImplementationSection) Then // interface,program,library,package
|
|
begin
|
|
begin
|
|
// load implicit units, like 'System'
|
|
// load implicit units, like 'System'
|
|
for i:=0 to ImplicitUses.Count-1 do
|
|
for i:=0 to ImplicitUses.Count-1 do
|
|
- CheckUnit(ImplicitUses[i]);
|
|
|
|
|
|
+ CheckUseUnit(ASection,ImplicitUses[i]);
|
|
end;
|
|
end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+// Starts after the "uses" token
|
|
|
|
+procedure TPasParser.ParseUsesList(ASection: TPasSection);
|
|
|
|
+var
|
|
|
|
+ AUnitName: String;
|
|
|
|
+ Element: TPasElement;
|
|
|
|
+begin
|
|
|
|
+ CheckImplicitUsedUnits(ASection);
|
|
|
|
|
|
Repeat
|
|
Repeat
|
|
- AUnitName := ExpectIdentifier;
|
|
|
|
|
|
+ AUnitName := ExpectIdentifier;
|
|
NextToken;
|
|
NextToken;
|
|
while CurToken = tkDot do
|
|
while CurToken = tkDot do
|
|
begin
|
|
begin
|
|
@@ -2333,7 +2426,7 @@ begin
|
|
AUnitName := AUnitName + '.' + CurTokenString;
|
|
AUnitName := AUnitName + '.' + CurTokenString;
|
|
NextToken;
|
|
NextToken;
|
|
end;
|
|
end;
|
|
- Element := CheckUnit(AUnitName);
|
|
|
|
|
|
+ Element := CheckUseUnit(ASection,AUnitName);
|
|
if (CurToken=tkin) then
|
|
if (CurToken=tkin) then
|
|
begin
|
|
begin
|
|
ExpectToken(tkString);
|
|
ExpectToken(tkString);
|
|
@@ -2357,7 +2450,7 @@ begin
|
|
try
|
|
try
|
|
NextToken;
|
|
NextToken;
|
|
if CurToken = tkColon then
|
|
if CurToken = tkColon then
|
|
- Result.VarType := ParseType(nil)
|
|
|
|
|
|
+ Result.VarType := ParseType(Result)
|
|
else
|
|
else
|
|
UngetToken;
|
|
UngetToken;
|
|
ExpectToken(tkEqual);
|
|
ExpectToken(tkEqual);
|
|
@@ -2468,7 +2561,7 @@ begin
|
|
Result := TPasClassType(Engine.CreateElement(TPasClassType, TypeName, Parent, Scanner.CurFilename, Scanner.CurRow));
|
|
Result := TPasClassType(Engine.CreateElement(TPasClassType, TypeName, Parent, Scanner.CurFilename, Scanner.CurRow));
|
|
try
|
|
try
|
|
Result.ObjKind := okSpecialize;
|
|
Result.ObjKind := okSpecialize;
|
|
- Result.AncestorType := ParseType(nil);
|
|
|
|
|
|
+ Result.AncestorType := ParseType(Result);
|
|
Result.IsShortDefinition:=True;
|
|
Result.IsShortDefinition:=True;
|
|
ReadGenericArguments(TPasClassType(Result).GenericTemplateTypes,Result);
|
|
ReadGenericArguments(TPasClassType(Result).GenericTemplateTypes,Result);
|
|
except
|
|
except
|
|
@@ -2619,10 +2712,7 @@ begin
|
|
if CurToken=tkComma then
|
|
if CurToken=tkComma then
|
|
ExpectIdentifier;
|
|
ExpectIdentifier;
|
|
Until (CurToken=tkColon);
|
|
Until (CurToken=tkColon);
|
|
- If Full then
|
|
|
|
- VarType := ParseComplexType(Nil)
|
|
|
|
- else
|
|
|
|
- VarType := ParseComplexType(Parent);
|
|
|
|
|
|
+ VarType := ParseComplexType(Parent);
|
|
Value:=Nil;
|
|
Value:=Nil;
|
|
H:=CheckHint(Nil,False);
|
|
H:=CheckHint(Nil,False);
|
|
If Full then
|
|
If Full then
|
|
@@ -2638,13 +2728,14 @@ begin
|
|
// Writeln(VarNames[i], AVisibility);
|
|
// Writeln(VarNames[i], AVisibility);
|
|
VarEl:=TPasVariable(CreateElement(TPasVariable,VarNames[i],Parent,AVisibility));
|
|
VarEl:=TPasVariable(CreateElement(TPasVariable,VarNames[i],Parent,AVisibility));
|
|
VarEl.VarType := VarType;
|
|
VarEl.VarType := VarType;
|
|
|
|
+ VarType.Parent := VarEl;
|
|
// Procedure declaration eats the hints.
|
|
// Procedure declaration eats the hints.
|
|
if Assigned(VarType) and (VarType is TPasprocedureType) then
|
|
if Assigned(VarType) and (VarType is TPasprocedureType) then
|
|
VarEl.Hints:=VarType.Hints
|
|
VarEl.Hints:=VarType.Hints
|
|
else
|
|
else
|
|
VarEl.Hints:=H;
|
|
VarEl.Hints:=H;
|
|
- Varel.Modifiers:=Mods;
|
|
|
|
- Varel.VarModifiers:=VarMods;
|
|
|
|
|
|
+ VarEl.Modifiers:=Mods;
|
|
|
|
+ VarEl.VarModifiers:=VarMods;
|
|
if (i=0) then
|
|
if (i=0) then
|
|
VarEl.Expr:=Value;
|
|
VarEl.Expr:=Value;
|
|
VarEl.AbsoluteLocation:=Loc;
|
|
VarEl.AbsoluteLocation:=Loc;
|
|
@@ -2737,7 +2828,7 @@ end;
|
|
procedure TPasParser.ParseArgList(Parent: TPasElement; Args: TFPList; EndToken: TToken);
|
|
procedure TPasParser.ParseArgList(Parent: TPasElement; Args: TFPList; EndToken: TToken);
|
|
var
|
|
var
|
|
ArgNames: TStringList;
|
|
ArgNames: TStringList;
|
|
- IsUntyped: Boolean;
|
|
|
|
|
|
+ IsUntyped, ok: Boolean;
|
|
Name : String;
|
|
Name : String;
|
|
Value : TPasExpr;
|
|
Value : TPasExpr;
|
|
i: Integer;
|
|
i: Integer;
|
|
@@ -2795,6 +2886,7 @@ begin
|
|
if not IsUntyped then
|
|
if not IsUntyped then
|
|
begin
|
|
begin
|
|
ArgType := ParseType(nil);
|
|
ArgType := ParseType(nil);
|
|
|
|
+ ok:=false;
|
|
try
|
|
try
|
|
NextToken;
|
|
NextToken;
|
|
if CurToken = tkEqual then
|
|
if CurToken = tkEqual then
|
|
@@ -2809,9 +2901,10 @@ begin
|
|
// After this, we're on ), which must be unget.
|
|
// After this, we're on ), which must be unget.
|
|
end;
|
|
end;
|
|
UngetToken;
|
|
UngetToken;
|
|
- except
|
|
|
|
- FreeAndNil(ArgType);
|
|
|
|
- Raise;
|
|
|
|
|
|
+ ok:=true;
|
|
|
|
+ finally
|
|
|
|
+ if not ok then
|
|
|
|
+ FreeAndNil(ArgType);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2820,8 +2913,12 @@ begin
|
|
Arg := TPasArgument(CreateElement(TPasArgument, ArgNames[i], Parent));
|
|
Arg := TPasArgument(CreateElement(TPasArgument, ArgNames[i], Parent));
|
|
Arg.Access := Access;
|
|
Arg.Access := Access;
|
|
Arg.ArgType := ArgType;
|
|
Arg.ArgType := ArgType;
|
|
- if (i > 0) and Assigned(ArgType) then
|
|
|
|
- ArgType.AddRef;
|
|
|
|
|
|
+ if Assigned(ArgType) then
|
|
|
|
+ begin
|
|
|
|
+ ArgType.Parent := Arg;
|
|
|
|
+ if (i > 0) then
|
|
|
|
+ ArgType.AddRef;
|
|
|
|
+ end;
|
|
Arg.ValueExpr := Value;
|
|
Arg.ValueExpr := Value;
|
|
Value:=Nil; // Only the first gets a value. OK, since Var A,B : Integer = 1 is not allowed.
|
|
Value:=Nil; // Only the first gets a value. OK, since Var A,B : Integer = 1 is not allowed.
|
|
Args.Add(Arg);
|
|
Args.Add(Arg);
|
|
@@ -3712,7 +3809,7 @@ begin
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
end;
|
|
end;
|
|
else
|
|
else
|
|
- left:=DoParseExpression(nil);
|
|
|
|
|
|
+ left:=DoParseExpression(Parent);
|
|
case CurToken of
|
|
case CurToken of
|
|
tkAssign,
|
|
tkAssign,
|
|
tkAssignPlus,
|
|
tkAssignPlus,
|
|
@@ -3723,8 +3820,10 @@ begin
|
|
// assign statement
|
|
// assign statement
|
|
Ak:=TokenToAssignKind(CurToken);
|
|
Ak:=TokenToAssignKind(CurToken);
|
|
NextToken;
|
|
NextToken;
|
|
- right:=DoParseExpression(nil); // this may solve TPasImplWhileDo.AddElement BUG
|
|
|
|
|
|
+ right:=DoParseExpression(Parent); // this may solve TPasImplWhileDo.AddElement BUG
|
|
el:=TPasImplAssign(CreateElement(TPasImplAssign,'',CurBlock));
|
|
el:=TPasImplAssign(CreateElement(TPasImplAssign,'',CurBlock));
|
|
|
|
+ left.Parent:=el;
|
|
|
|
+ right.Parent:=el;
|
|
TPasImplAssign(el).left:=Left;
|
|
TPasImplAssign(el).left:=Left;
|
|
TPasImplAssign(el).right:=Right;
|
|
TPasImplAssign(el).right:=Right;
|
|
TPasImplAssign(el).Kind:=ak;
|
|
TPasImplAssign(el).Kind:=ak;
|
|
@@ -4253,7 +4352,7 @@ begin
|
|
Atype.IsForward:=(CurToken=tkSemiColon);
|
|
Atype.IsForward:=(CurToken=tkSemiColon);
|
|
if (CurToken=tkBraceOpen) then
|
|
if (CurToken=tkBraceOpen) then
|
|
begin
|
|
begin
|
|
- AType.AncestorType := ParseType(nil);
|
|
|
|
|
|
+ AType.AncestorType := ParseType(AType);
|
|
while True do
|
|
while True do
|
|
begin
|
|
begin
|
|
NextToken;
|
|
NextToken;
|
|
@@ -4261,7 +4360,7 @@ begin
|
|
break;
|
|
break;
|
|
UngetToken;
|
|
UngetToken;
|
|
ExpectToken(tkComma);
|
|
ExpectToken(tkComma);
|
|
- Element:=ParseType(Nil); // search interface.
|
|
|
|
|
|
+ Element:=ParseType(AType); // search interface.
|
|
if assigned(element) then
|
|
if assigned(element) then
|
|
AType.Interfaces.add(element);
|
|
AType.Interfaces.add(element);
|
|
end;
|
|
end;
|
|
@@ -4272,7 +4371,7 @@ begin
|
|
begin
|
|
begin
|
|
if (CurToken<>tkFor) then
|
|
if (CurToken<>tkFor) then
|
|
ParseExcTokenError(TokenInfos[tkFor]);
|
|
ParseExcTokenError(TokenInfos[tkFor]);
|
|
- AType.HelperForType:=ParseType(Nil);
|
|
|
|
|
|
+ AType.HelperForType:=ParseType(AType);
|
|
NextToken;
|
|
NextToken;
|
|
end;
|
|
end;
|
|
if (AType.IsShortDefinition or AType.IsForward) then
|
|
if (AType.IsShortDefinition or AType.IsForward) then
|
|
@@ -4350,6 +4449,96 @@ begin
|
|
Scanner.CurFilename, Scanner.CurRow);
|
|
Scanner.CurFilename, Scanner.CurRow);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TPasParser.CreatePrimitiveExpr(AParent: TPasElement;
|
|
|
|
+ AKind: TPasExprKind; const AValue: String): TPrimitiveExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TPrimitiveExpr(CreateElement(TPrimitiveExpr,'',AParent));
|
|
|
|
+ Result.Kind:=AKind;
|
|
|
|
+ Result.Value:=AValue;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasParser.CreateBoolConstExpr(AParent: TPasElement;
|
|
|
|
+ AKind: TPasExprKind; const ABoolValue: Boolean): TBoolConstExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TBoolConstExpr(CreateElement(TBoolConstExpr,'',AParent));
|
|
|
|
+ Result.Kind:=AKind;
|
|
|
|
+ Result.Value:=ABoolValue;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasParser.CreateBinaryExpr(AParent: TPasElement; xleft,
|
|
|
|
+ xright: TPasExpr; AOpCode: TExprOpCode): TBinaryExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TBinaryExpr(CreateElement(TBinaryExpr,'',AParent));
|
|
|
|
+ Result.OpCode:=AOpCode;
|
|
|
|
+ Result.Kind:=pekBinary;
|
|
|
|
+ if xleft<>nil then
|
|
|
|
+ begin
|
|
|
|
+ Result.left:=xleft;
|
|
|
|
+ xleft.Parent:=Result;
|
|
|
|
+ end;
|
|
|
|
+ if xright<>nil then
|
|
|
|
+ begin
|
|
|
|
+ Result.right:=xright;
|
|
|
|
+ xright.Parent:=Result;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPasParser.AddToBinaryExprChain(var ChainFirst, ChainLast: TPasExpr;
|
|
|
|
+ Element: TPasExpr; AOpCode: TExprOpCode);
|
|
|
|
+
|
|
|
|
+ procedure RaiseInternal;
|
|
|
|
+ begin
|
|
|
|
+ raise Exception.Create('TBinaryExpr.AddToChain: internal error');
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+var
|
|
|
|
+ Last: TBinaryExpr;
|
|
|
|
+begin
|
|
|
|
+ if Element=nil then
|
|
|
|
+ exit
|
|
|
|
+ else if ChainFirst=nil then
|
|
|
|
+ begin
|
|
|
|
+ // empty chain => simply add element, no need to create TBinaryExpr
|
|
|
|
+ if (ChainLast<>nil) then
|
|
|
|
+ RaiseInternal;
|
|
|
|
+ ChainFirst:=Element;
|
|
|
|
+ ChainLast:=Element;
|
|
|
|
+ end
|
|
|
|
+ else if ChainLast is TBinaryExpr then
|
|
|
|
+ begin
|
|
|
|
+ // add a new TBinaryExpr at the end of the chain
|
|
|
|
+ Last:=TBinaryExpr(ChainLast);
|
|
|
|
+ if (Last.left=nil) or (Last.right=nil) then
|
|
|
|
+ // chain not yet full => inconsistency
|
|
|
|
+ RaiseInternal;
|
|
|
|
+ Last.right:=CreateBinaryExpr(Last,Last.right,Element,AOpCode);
|
|
|
|
+ ChainLast:=Last;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ // one element => create a TBinaryExpr with two elements
|
|
|
|
+ if ChainFirst<>ChainLast then
|
|
|
|
+ RaiseInternal;
|
|
|
|
+ ChainLast:=CreateBinaryExpr(ChainLast.Parent,ChainLast,Element,AOpCode);
|
|
|
|
+ ChainFirst:=ChainLast;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasParser.CreateUnaryExpr(AParent: TPasElement; AOperand: TPasExpr;
|
|
|
|
+ AOpCode: TExprOpCode): TUnaryExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TUnaryExpr(CreateElement(TUnaryExpr,'',AParent));
|
|
|
|
+ Result.Kind:=pekUnary;
|
|
|
|
+ Result.Operand:=AOperand;
|
|
|
|
+ Result.OpCode:=AOpCode;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasParser.CreateArrayValues(AParent: TPasElement): TArrayValues;
|
|
|
|
+begin
|
|
|
|
+ Result:=TArrayValues(CreateElement(TArrayValues,'',AParent));
|
|
|
|
+ Result.Kind:=pekListOfExp;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TPasParser.CreateFunctionType(const AName, AResultName: String;
|
|
function TPasParser.CreateFunctionType(const AName, AResultName: String;
|
|
AParent: TPasElement; UseParentAsResultParent: Boolean): TPasFunctionType;
|
|
AParent: TPasElement; UseParentAsResultParent: Boolean): TPasFunctionType;
|
|
begin
|
|
begin
|
|
@@ -4358,8 +4547,28 @@ begin
|
|
Scanner.CurFilename,Scanner.CurRow);
|
|
Scanner.CurFilename,Scanner.CurRow);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TPasParser.CreateInheritedExpr(AParent: TPasElement): TInheritedExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TInheritedExpr(CreateElement(TInheritedExpr,'',AParent));
|
|
|
|
+ Result.Kind:=pekInherited;
|
|
|
|
+end;
|
|
|
|
|
|
|
|
+function TPasParser.CreateSelfExpr(AParent: TPasElement): TSelfExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TSelfExpr(CreateElement(TSelfExpr,'Self',AParent));
|
|
|
|
+ Result.Kind:=pekSelf;
|
|
|
|
+end;
|
|
|
|
|
|
-initialization
|
|
|
|
|
|
+function TPasParser.CreateNilExpr(AParent: TPasElement): TNilExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TNilExpr(CreateElement(TNilExpr,'nil',AParent));
|
|
|
|
+ Result.Kind:=pekNil;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasParser.CreateRecordValues(AParent: TPasElement): TRecordValues;
|
|
|
|
+begin
|
|
|
|
+ Result:=TRecordValues(CreateElement(TRecordValues,'',AParent));
|
|
|
|
+ Result.Kind:=pekListOfExp;
|
|
|
|
+end;
|
|
|
|
|
|
end.
|
|
end.
|