summaryrefslogtreecommitdiff
path: root/packages/fcl-passrc/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/fcl-passrc/src')
-rw-r--r--packages/fcl-passrc/src/pastree.pp60
-rw-r--r--packages/fcl-passrc/src/pparser.pp138
2 files changed, 168 insertions, 30 deletions
diff --git a/packages/fcl-passrc/src/pastree.pp b/packages/fcl-passrc/src/pastree.pp
index 027047e825..57e2d887dd 100644
--- a/packages/fcl-passrc/src/pastree.pp
+++ b/packages/fcl-passrc/src/pastree.pp
@@ -121,7 +121,7 @@ type
end;
TPasExprKind = (pekIdent, pekNumber, pekString, pekSet, pekNil, pekBoolConst, pekRange,
- pekUnary, pekBinary, pekFuncParams, pekArrayParams, pekListOfExp);
+ pekUnary, pekBinary, pekFuncParams, pekArrayParams, pekListOfExp, pekInherited, pekSelf);
TExprOpCode = (eopNone,
eopAdd,eopSubtract,eopMultiply,eopDivide, eopDiv,eopMod, eopPower,// arithmetic
@@ -178,6 +178,20 @@ type
function GetDeclaration(full : Boolean) : string; override;
end;
+ { TInheritedExpr }
+
+ TInheritedExpr = class(TPasExpr)
+ constructor Create(AParent : TPasElement); overload;
+ function GetDeclaration(full : Boolean) : string; override;
+ end;
+
+ { TSelfExpr }
+
+ TSelfExpr = class(TPasExpr)
+ constructor Create(AParent : TPasElement); overload;
+ function GetDeclaration(full : Boolean) : string; override;
+ end;
+
{ TParamsExpr }
TParamsExpr = class(TPasExpr)
@@ -454,6 +468,7 @@ type
AncestorType: TPasType; // TPasClassType or TPasUnresolvedTypeRef
IsPacked: Boolean; // 12/04/04 - Dave - Added
IsForward : Boolean;
+ IsShortDefinition: Boolean;//class(anchestor); without end
Members: TList; // array of TPasElement objects
InterfaceGUID : string; // 15/06/07 - Inoussa
@@ -1346,6 +1361,7 @@ constructor TPasClassType.Create(const AName: string; AParent: TPasElement);
begin
inherited Create(AName, AParent);
IsPacked := False; // 12/04/04 - Dave - Added
+ IsShortDefinition := False;
Members := TList.Create;
Modifiers := TStringList.Create;
ClassVars := TList.Create;
@@ -1388,7 +1404,7 @@ var
begin
for i := 0 to Args.Count - 1 do
TPasArgument(Args[i]).Release;
- Args.Free;
+ FreeAndNil(Args);
inherited Destroy;
end;
@@ -1726,12 +1742,14 @@ begin
Result:=TPasImplAssign.Create('', Self);
Result.left:=left;
Result.right:=right;
+ AddElement(Result);
end;
function TPasImplBlock.AddSimple(exp:TPasExpr):TPasImplSimple;
begin
Result:=TPasImplSimple.Create('', Self);
Result.expr:=exp;
+ AddElement(Result);
end;
function TPasImplBlock.CloseOnSemicolon: boolean;
@@ -2591,7 +2609,7 @@ Var
I : Integer;
begin
- For I:=0 to Length(Params) do
+ For I:=0 to High(Params) do
begin
If (Result<>'') then
Result:=Result+', ';
@@ -2629,7 +2647,7 @@ Function TRecordValues.GetDeclaration(Full : Boolean):AnsiString;
Var
I : Integer;
begin
- For I:=0 to Length(Fields) do
+ For I:=0 to High(Fields) do
begin
If Result='' then
Result:=Result+'; ';
@@ -2661,20 +2679,36 @@ begin
Fields[i].ValueExp:=Value;
end;
-{ TArrayValues }
+{ TNilExpr }
Function TNilExpr.GetDeclaration(Full :Boolean):AnsiString;
begin
Result:='Nil';
end;
+{ TInheritedExpr }
+
+Function TInheritedExpr.GetDeclaration(Full :Boolean):AnsiString;
+begin
+ Result:='Inherited';
+end;
+
+{ TSelfExpr }
+
+Function TSelfExpr.GetDeclaration(Full :Boolean):AnsiString;
+begin
+ Result:='Self';
+end;
+
+{ TArrayValues }
+
Function TArrayValues.GetDeclaration(Full: Boolean):AnsiString;
Var
I : Integer;
begin
- For I:=0 to Length(Values) do
+ For I:=0 to High(Values) do
begin
If Result='' then
Result:=Result+', ';
@@ -2712,6 +2746,20 @@ begin
inherited Create(AParent,pekNil, eopNone);
end;
+{ TInheritedExpr }
+
+constructor TInheritedExpr.Create(AParent : TPasElement);
+begin
+ inherited Create(AParent,pekInherited, eopNone);
+end;
+
+{ TSelfExpr }
+
+constructor TSelfExpr.Create(AParent : TPasElement);
+begin
+ inherited Create(AParent,pekSelf, eopNone);
+end;
+
{ TPasLabels }
constructor TPasLabels.Create(const AName:string;AParent:TPasElement);
diff --git a/packages/fcl-passrc/src/pparser.pp b/packages/fcl-passrc/src/pparser.pp
index 1490282ce1..6d2bb965c8 100644
--- a/packages/fcl-passrc/src/pparser.pp
+++ b/packages/fcl-passrc/src/pparser.pp
@@ -766,6 +766,40 @@ begin
tkfalse, tktrue: x:=TBoolConstExpr.Create(Aparent,pekBoolConst, CurToken=tktrue);
tknil: x:=TNilExpr.Create(Aparent);
tkSquaredBraceOpen: x:=ParseParams(AParent,pekSet);
+ tkinherited: begin
+ //inherited; inherited function
+ x:=TInheritedExpr.Create(AParent);
+ NextToken;
+ if (length(CurTokenText)>0) and (CurTokenText[1] in ['A'..'_']) then begin
+ b:=TBinaryExpr.Create(AParent,x, DoParseExpression(AParent), eopNone);
+ if not Assigned(b.right) then Exit; // error
+ x:=b;
+ UngetToken;
+ end
+ else UngetToken;
+ end;
+ tkself: begin
+ x:=TPrimitiveExpr.Create(AParent,pekString, CurTokenText); //function(self);
+ x:=TSelfExpr.Create(AParent);
+ NextToken;
+ if CurToken = tkDot then begin // self.Write(EscapeText(AText));
+ optk:=CurToken;
+ NextToken;
+ b:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(optk));
+ if not Assigned(b.right) then Exit; // error
+ x:=b;
+ end
+ else UngetToken;
+ end;
+ tkAt: begin
+ // P:=@function;
+ NextToken;
+ if (length(CurTokenText)=0) or not (CurTokenText[1] in ['A'..'_']) then begin
+ UngetToken;
+ ParseExc(SParserExpectedIdentifier);
+ end;
+ x:=TPrimitiveExpr.Create(AParent,pekString, '@'+CurTokenText);
+ end;
tkCaret: begin
// ^A..^_ characters. See #16341
NextToken;
@@ -2714,6 +2748,27 @@ begin
// empty then => add dummy command
CurBlock.AddCommand('');
end;
+ if TPasImplIfElse(CurBlock).ElseBranch<>nil then
+ begin
+ // this and the following 3 may solve TPasImplIfElse.AddElement BUG
+ // ifs without begin end
+ // if .. then
+ // if .. then
+ // else
+ // else
+ CloseBlock;
+ CloseStatement(false);
+ end;
+ end else if (CurBlock is TPasImplWhileDo) then
+ begin
+ //if .. then while .. do smt else ..
+ CloseBlock;
+ UngetToken;
+ end else if (CurBlock is TPasImplRaise) then
+ begin
+ //if .. then Raise Exception else ..
+ CloseBlock;
+ UngetToken;
end else if (CurBlock is TPasImplTryExcept) then
begin
CloseBlock;
@@ -2795,16 +2850,17 @@ begin
repeat
Expr:=ParseExpression(Parent);
//writeln(i,'CASE value="',Expr,'" Token=',CurTokenText);
- if CurBlock is TPasImplCaseStatement then
- TPasImplCaseStatement(CurBlock).Expressions.Add(Expr)
- else
- CurBlock:=TPasImplCaseOf(CurBlock).AddCase(Expr);
NextToken;
if CurToken=tkDotDot then
begin
Expr:=Expr+'..'+ParseExpression(Parent);
NextToken;
end;
+ // do not miss '..'
+ if CurBlock is TPasImplCaseStatement then
+ TPasImplCaseStatement(CurBlock).Expressions.Add(Expr)
+ else
+ CurBlock:=TPasImplCaseOf(CurBlock).AddCase(Expr);
//writeln(i,'CASE after value Token=',CurTokenText);
if CurToken=tkColon then break;
if CurToken<>tkComma then
@@ -2932,7 +2988,7 @@ begin
begin
// assign statement
NextToken;
- right:=ParseExpIdent(Parent);
+ right:=DoParseExpression(nil); // this may solve TPasImplWhileDo.AddElement BUG
CmdElem:=CurBlock.AddAssign(left, right);
UngetToken;
end;
@@ -2943,7 +2999,7 @@ begin
// label mark. todo: check mark identifier in the list of labels
CmdElem:=CurBlock.AddLabelMark(TPrimitiveExpr(left).Value);
left.Free;
- end
+ end;
else
// simple statement (function call)
CmdElem:=CurBlock.AddSimple(left);
@@ -3130,36 +3186,62 @@ function TPasParser.ParseClassDecl(Parent: TPasElement;
var
CurVisibility: TPasMemberVisibility;
- procedure ProcessMethod(const MethodTypeName: String; HasReturnValue: Boolean);
+ procedure ProcessMethod(ProcType: TProcType);
var
Owner: TPasElement;
Proc: TPasProcedure;
- s: String;
+ s,Name: String;
pt: TProcType;
+ HasReturnValue: Boolean;
+
begin
+ HasReturnValue:=false;
ExpectIdentifier;
- Owner := CheckIfOverloaded(TPasClassType(Result), CurTokenString);
- if HasReturnValue then
+ Name := CurTokenString;
+ Owner := CheckIfOverloaded(TPasClassType(Result), Name);
+ case ProcType of
+ ptFunction:
begin
- Proc := TPasFunction(CreateElement(TPasFunction, CurTokenString, Owner,
+ Proc := TPasFunction(CreateElement(TPasFunction, Name, Owner,
CurVisibility));
Proc.ProcType := Engine.CreateFunctionType('', 'Result', Proc, True,
Scanner.CurFilename, Scanner.CurRow);
- end else
+ HasReturnValue:=true;
+ end;
+ ptClassFunction:
begin
- // !!!: The following is more than ugly
- if MethodTypeName = 'constructor' then
- Proc := TPasConstructor(CreateElement(TPasConstructor, CurTokenString,
- Owner, CurVisibility))
- else if MethodTypeName = 'destructor' then
- Proc := TPasDestructor(CreateElement(TPasDestructor, CurTokenString,
- Owner, CurVisibility))
+ Proc := TPasClassFunction(CreateElement(TPasClassFunction, Name, Owner));
+ Proc.ProcType := Engine.CreateFunctionType('', 'Result', Proc, True,
+ Scanner.CurFilename, Scanner.CurRow);
+ HasReturnValue:=true;
+ end;
+ ptClassProcedure:
+ begin
+ Proc := TPasClassProcedure(CreateElement(TPasClassProcedure, Name, Owner));
+ Proc.ProcType := TPasProcedureType(CreateElement(TPasProcedureType, '',
+ Proc, CurVisibility));
+ end;
+ ptConstructor:
+ begin
+ Proc := TPasConstructor(CreateElement(TPasConstructor, Name,
+ Owner, CurVisibility));
+ Proc.ProcType := TPasProcedureType(CreateElement(TPasProcedureType, '',
+ Proc, CurVisibility));
+ end;
+ ptDestructor:
+ begin
+ Proc := TPasDestructor(CreateElement(TPasDestructor, Name,
+ Owner, CurVisibility));
+ Proc.ProcType := TPasProcedureType(CreateElement(TPasProcedureType, '',
+ Proc, CurVisibility));
+ end;
else
- Proc := TPasProcedure(CreateElement(TPasProcedure, CurTokenString,
+ Proc := TPasProcedure(CreateElement(TPasProcedure, Name,
Owner, CurVisibility));
Proc.ProcType := TPasProcedureType(CreateElement(TPasProcedureType, '',
Proc, CurVisibility));
end;
+
if Owner.ClassType = TPasOverloadedProc then
TPasOverloadedProc(Owner).Overloads.Add(Proc)
else
@@ -3302,6 +3384,8 @@ begin
end
else
TPasClassType(Result).isForward:=CurToken=tkSemicolon;
+ if CurToken = tkSemicolon then
+ TPasClassType(Result).IsShortDefinition:=true;
if CurToken <> tkSemicolon then
begin
@@ -3364,13 +3448,19 @@ begin
end;
tkProcedure:
- ProcessMethod('procedure', False);
+ ProcessMethod(ptProcedure);
tkFunction:
- ProcessMethod('function', True);
+ ProcessMethod(ptFunction);
tkConstructor:
- ProcessMethod('constructor', False);
+ ProcessMethod(ptConstructor);
tkDestructor:
- ProcessMethod('destructor', False);
+ ProcessMethod(ptDestructor);
+ tkclass:
+ begin
+ NextToken;
+ if CurToken = tkprocedure then ProcessMethod(ptClassProcedure)
+ else ProcessMethod(ptClassFunction);
+ end;
tkProperty:
begin
ExpectIdentifier;