|
@@ -299,7 +299,8 @@ type
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility; const ASrcPos: TPasSourcePos): TPasElement;overload;
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility; const ASrcPos: TPasSourcePos): TPasElement;overload;
|
|
function CreatePrimitiveExpr(AParent: TPasElement; AKind: TPasExprKind; const AValue: String): TPrimitiveExpr;
|
|
function CreatePrimitiveExpr(AParent: TPasElement; AKind: TPasExprKind; const AValue: String): TPrimitiveExpr;
|
|
function CreateBoolConstExpr(AParent: TPasElement; AKind: TPasExprKind; const ABoolValue : Boolean): TBoolConstExpr;
|
|
function CreateBoolConstExpr(AParent: TPasElement; AKind: TPasExprKind; const ABoolValue : Boolean): TBoolConstExpr;
|
|
- function CreateBinaryExpr(AParent : TPasElement; xleft, xright: TPasExpr; AOpCode: TExprOpCode): TBinaryExpr;
|
|
|
|
|
|
+ function CreateBinaryExpr(AParent : TPasElement; xleft, xright: TPasExpr; AOpCode: TExprOpCode): TBinaryExpr; overload;
|
|
|
|
+ function CreateBinaryExpr(AParent : TPasElement; xleft, xright: TPasExpr; AOpCode: TExprOpCode; const ASrcPos: TPasSourcePos): TBinaryExpr; overload;
|
|
procedure AddToBinaryExprChain(var ChainFirst: TPasExpr;
|
|
procedure AddToBinaryExprChain(var ChainFirst: TPasExpr;
|
|
Element: TPasExpr; AOpCode: TExprOpCode);
|
|
Element: TPasExpr; AOpCode: TExprOpCode);
|
|
procedure AddParamsToBinaryExprChain(var ChainFirst: TPasExpr;
|
|
procedure AddParamsToBinaryExprChain(var ChainFirst: TPasExpr;
|
|
@@ -307,7 +308,8 @@ type
|
|
{$IFDEF VerbosePasParser}
|
|
{$IFDEF VerbosePasParser}
|
|
procedure WriteBinaryExprChain(Prefix: string; First, Last: TPasExpr);
|
|
procedure WriteBinaryExprChain(Prefix: string; First, Last: TPasExpr);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
- function CreateUnaryExpr(AParent : TPasElement; AOperand: TPasExpr; AOpCode: TExprOpCode): TUnaryExpr;
|
|
|
|
|
|
+ function CreateUnaryExpr(AParent : TPasElement; AOperand: TPasExpr; AOpCode: TExprOpCode): TUnaryExpr; overload;
|
|
|
|
+ function CreateUnaryExpr(AParent : TPasElement; AOperand: TPasExpr; AOpCode: TExprOpCode; const ASrcPos: TPasSourcePos): TUnaryExpr; overload;
|
|
function CreateArrayValues(AParent : TPasElement): TArrayValues;
|
|
function CreateArrayValues(AParent : TPasElement): TArrayValues;
|
|
function CreateFunctionType(const AName, AResultName: String; AParent: TPasElement;
|
|
function CreateFunctionType(const AName, AResultName: String; AParent: TPasElement;
|
|
UseParentAsResultParent: Boolean; const NamePos: TPasSourcePos): TPasFunctionType;
|
|
UseParentAsResultParent: Boolean; const NamePos: TPasSourcePos): TPasFunctionType;
|
|
@@ -2190,14 +2192,20 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
function TPasParser.DoParseExpression(AParent : TPaselement;InitExpr: TPasExpr; AllowEqual : Boolean = True): TPasExpr;
|
|
function TPasParser.DoParseExpression(AParent : TPaselement;InitExpr: TPasExpr; AllowEqual : Boolean = True): TPasExpr;
|
|
|
|
+type
|
|
|
|
+ TOpStackItem = record
|
|
|
|
+ Token: TToken;
|
|
|
|
+ SrcPos: TPasSourcePos;
|
|
|
|
+ end;
|
|
|
|
+
|
|
var
|
|
var
|
|
- expstack : TFPList;
|
|
|
|
- opstack : array of TToken;
|
|
|
|
- opstackTop: integer;
|
|
|
|
- pcount : Integer;
|
|
|
|
|
|
+ ExpStack : TFPList;
|
|
|
|
+ OpStack : array of TOpStackItem;
|
|
|
|
+ OpStackTop: integer;
|
|
|
|
+ PrefixCnt : Integer;
|
|
x : TPasExpr;
|
|
x : TPasExpr;
|
|
i : Integer;
|
|
i : Integer;
|
|
- tempop : TToken;
|
|
|
|
|
|
+ TempOp : TToken;
|
|
NotBinary : Boolean;
|
|
NotBinary : Boolean;
|
|
|
|
|
|
const
|
|
const
|
|
@@ -2210,31 +2218,38 @@ const
|
|
|
|
|
|
function PopExp: TPasExpr; inline;
|
|
function PopExp: TPasExpr; inline;
|
|
begin
|
|
begin
|
|
- if expstack.Count>0 then begin
|
|
|
|
- Result:=TPasExpr(expstack[expstack.Count-1]);
|
|
|
|
- expstack.Delete(expstack.Count-1);
|
|
|
|
|
|
+ if ExpStack.Count>0 then begin
|
|
|
|
+ Result:=TPasExpr(ExpStack[ExpStack.Count-1]);
|
|
|
|
+ ExpStack.Delete(ExpStack.Count-1);
|
|
end else
|
|
end else
|
|
Result:=nil;
|
|
Result:=nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
- procedure PushOper(token: TToken); inline;
|
|
|
|
|
|
+ procedure PushOper(Token: TToken);
|
|
begin
|
|
begin
|
|
- inc(opstackTop);
|
|
|
|
- if opstackTop=length(opstack) then
|
|
|
|
- SetLength(opstack,length(opstack)*2+4);
|
|
|
|
- opstack[opstackTop]:=token;
|
|
|
|
|
|
+ inc(OpStackTop);
|
|
|
|
+ if OpStackTop=length(OpStack) then
|
|
|
|
+ SetLength(OpStack,length(OpStack)*2+4);
|
|
|
|
+ OpStack[OpStackTop].Token:=Token;
|
|
|
|
+ OpStack[OpStackTop].SrcPos:=CurTokenPos;
|
|
end;
|
|
end;
|
|
|
|
|
|
function PeekOper: TToken; inline;
|
|
function PeekOper: TToken; inline;
|
|
begin
|
|
begin
|
|
- if opstackTop>=0 then Result:=opstack[opstackTop]
|
|
|
|
|
|
+ if OpStackTop>=0 then Result:=OpStack[OpStackTop].Token
|
|
else Result:=tkEOF;
|
|
else Result:=tkEOF;
|
|
end;
|
|
end;
|
|
|
|
|
|
- function PopOper: TToken; inline;
|
|
|
|
|
|
+ function PopOper(out SrcPos: TPasSourcePos): TToken;
|
|
begin
|
|
begin
|
|
Result:=PeekOper;
|
|
Result:=PeekOper;
|
|
- if Result<>tkEOF then dec(opstackTop);
|
|
|
|
|
|
+ if Result=tkEOF then
|
|
|
|
+ SrcPos:=DefPasSourcePos
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ SrcPos:=OpStack[OpStackTop].SrcPos;
|
|
|
|
+ dec(OpStackTop);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure PopAndPushOperator;
|
|
procedure PopAndPushOperator;
|
|
@@ -2243,22 +2258,24 @@ const
|
|
xright : TPasExpr;
|
|
xright : TPasExpr;
|
|
xleft : TPasExpr;
|
|
xleft : TPasExpr;
|
|
bin : TBinaryExpr;
|
|
bin : TBinaryExpr;
|
|
|
|
+ SrcPos: TPasSourcePos;
|
|
begin
|
|
begin
|
|
- t:=PopOper;
|
|
|
|
|
|
+ t:=PopOper(SrcPos);
|
|
xright:=PopExp;
|
|
xright:=PopExp;
|
|
xleft:=PopExp;
|
|
xleft:=PopExp;
|
|
if t=tkDotDot then
|
|
if t=tkDotDot then
|
|
begin
|
|
begin
|
|
- bin:=CreateBinaryExpr(AParent,xleft,xright,eopNone);
|
|
|
|
|
|
+ bin:=CreateBinaryExpr(AParent,xleft,xright,eopNone,SrcPos);
|
|
bin.Kind:=pekRange;
|
|
bin.Kind:=pekRange;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- bin:=CreateBinaryExpr(AParent,xleft,xright,TokenToExprOp(t));
|
|
|
|
- expstack.Add(bin);
|
|
|
|
|
|
+ bin:=CreateBinaryExpr(AParent,xleft,xright,TokenToExprOp(t),SrcPos);
|
|
|
|
+ ExpStack.Add(bin);
|
|
end;
|
|
end;
|
|
|
|
|
|
Var
|
|
Var
|
|
AllowedBinaryOps : Set of TToken;
|
|
AllowedBinaryOps : Set of TToken;
|
|
|
|
+ SrcPos: TPasSourcePos;
|
|
|
|
|
|
begin
|
|
begin
|
|
AllowedBinaryOps:=BinaryOP;
|
|
AllowedBinaryOps:=BinaryOP;
|
|
@@ -2266,13 +2283,13 @@ begin
|
|
Exclude(AllowedBinaryOps,tkEqual);
|
|
Exclude(AllowedBinaryOps,tkEqual);
|
|
//DumpCurToken('Entry',iaIndent);
|
|
//DumpCurToken('Entry',iaIndent);
|
|
Result:=nil;
|
|
Result:=nil;
|
|
- expstack := TFPList.Create;
|
|
|
|
- SetLength(opstack,4);
|
|
|
|
- opstackTop:=-1;
|
|
|
|
|
|
+ ExpStack := TFPList.Create;
|
|
|
|
+ SetLength(OpStack,4);
|
|
|
|
+ OpStackTop:=-1;
|
|
try
|
|
try
|
|
repeat
|
|
repeat
|
|
NotBinary:=True;
|
|
NotBinary:=True;
|
|
- pcount:=0;
|
|
|
|
|
|
+ PrefixCnt:=0;
|
|
if not Assigned(InitExpr) then
|
|
if not Assigned(InitExpr) then
|
|
begin
|
|
begin
|
|
// the first part of the expression has been parsed externally.
|
|
// the first part of the expression has been parsed externally.
|
|
@@ -2291,7 +2308,7 @@ begin
|
|
while CurToken in PrefixSym do
|
|
while CurToken in PrefixSym do
|
|
begin
|
|
begin
|
|
PushOper(CurToken);
|
|
PushOper(CurToken);
|
|
- inc(pcount);
|
|
|
|
|
|
+ inc(PrefixCnt);
|
|
NextToken;
|
|
NextToken;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2311,6 +2328,7 @@ begin
|
|
x:=CreateUnaryExpr(AParent,x, TokenToExprOp(tkCaret));
|
|
x:=CreateUnaryExpr(AParent,x, TokenToExprOp(tkCaret));
|
|
NextToken;
|
|
NextToken;
|
|
end;
|
|
end;
|
|
|
|
+ // ToDo: move dot below []
|
|
// for expressions like (TObject(m)).Free;
|
|
// for expressions like (TObject(m)).Free;
|
|
if (x<>Nil) and (CurToken=tkDot) then
|
|
if (x<>Nil) and (CurToken=tkDot) then
|
|
begin
|
|
begin
|
|
@@ -2329,34 +2347,35 @@ begin
|
|
end;
|
|
end;
|
|
if not Assigned(x) then
|
|
if not Assigned(x) then
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
- expstack.Add(x);
|
|
|
|
|
|
+ ExpStack.Add(x);
|
|
|
|
|
|
- for i:=1 to pcount do
|
|
|
|
|
|
+ for i:=1 to PrefixCnt do
|
|
begin
|
|
begin
|
|
- tempop:=PopOper;
|
|
|
|
- x:=popexp;
|
|
|
|
- if (tempop=tkMinus) and (x.Kind=pekRange) then
|
|
|
|
|
|
+ TempOp:=PopOper(SrcPos);
|
|
|
|
+ x:=PopExp;
|
|
|
|
+ if (TempOp=tkMinus) and (x.Kind=pekRange) then
|
|
begin
|
|
begin
|
|
- TBinaryExpr(x).Left:=CreateUnaryExpr(x, TBinaryExpr(x).left, eopSubtract);
|
|
|
|
- expstack.Add(x);
|
|
|
|
|
|
+ TBinaryExpr(x).Left:=CreateUnaryExpr(x, TBinaryExpr(x).left,
|
|
|
|
+ eopSubtract, SrcPos);
|
|
|
|
+ ExpStack.Add(x);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- expstack.Add(CreateUnaryExpr(AParent, x, TokenToExprOp(tempop) ));
|
|
|
|
|
|
+ ExpStack.Add(CreateUnaryExpr(AParent, x, TokenToExprOp(TempOp), SrcPos));
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- expstack.Add(InitExpr);
|
|
|
|
|
|
+ ExpStack.Add(InitExpr);
|
|
InitExpr:=nil;
|
|
InitExpr:=nil;
|
|
end;
|
|
end;
|
|
if (CurToken in AllowedBinaryOPs) then
|
|
if (CurToken in AllowedBinaryOPs) then
|
|
begin
|
|
begin
|
|
// Adjusting order of the operations
|
|
// Adjusting order of the operations
|
|
NotBinary:=False;
|
|
NotBinary:=False;
|
|
- tempop:=PeekOper;
|
|
|
|
- while (opstackTop>=0) and (OpLevel(tempop)>=OpLevel(CurToken)) do begin
|
|
|
|
|
|
+ TempOp:=PeekOper;
|
|
|
|
+ while (OpStackTop>=0) and (OpLevel(TempOp)>=OpLevel(CurToken)) do begin
|
|
PopAndPushOperator;
|
|
PopAndPushOperator;
|
|
- tempop:=PeekOper;
|
|
|
|
|
|
+ TempOp:=PeekOper;
|
|
end;
|
|
end;
|
|
PushOper(CurToken);
|
|
PushOper(CurToken);
|
|
NextToken;
|
|
NextToken;
|
|
@@ -2366,14 +2385,14 @@ begin
|
|
|
|
|
|
if not NotBinary then ParseExcExpectedIdentifier;
|
|
if not NotBinary then ParseExcExpectedIdentifier;
|
|
|
|
|
|
- while opstackTop>=0 do PopAndPushOperator;
|
|
|
|
|
|
+ while OpStackTop>=0 do PopAndPushOperator;
|
|
|
|
|
|
- // only 1 expression should be on the stack, at the end of the correct expression
|
|
|
|
- if expstack.Count<>1 then
|
|
|
|
|
|
+ // only 1 expression should be on the OpStack, at the end of the correct expression
|
|
|
|
+ if ExpStack.Count<>1 then
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
- if expstack.Count=1 then
|
|
|
|
|
|
+ if ExpStack.Count=1 then
|
|
begin
|
|
begin
|
|
- Result:=TPasExpr(expstack[0]);
|
|
|
|
|
|
+ Result:=TPasExpr(ExpStack[0]);
|
|
Result.Parent:=AParent;
|
|
Result.Parent:=AParent;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2384,11 +2403,11 @@ begin
|
|
DumpCurtoken('Exiting (Result: "'+Result.GetDeclaration(true)+'") ',iaUndent);}
|
|
DumpCurtoken('Exiting (Result: "'+Result.GetDeclaration(true)+'") ',iaUndent);}
|
|
if not Assigned(Result) then begin
|
|
if not Assigned(Result) then begin
|
|
// expression error!
|
|
// expression error!
|
|
- for i:=0 to expstack.Count-1 do
|
|
|
|
- TPasExpr(expstack[i]).Release;
|
|
|
|
|
|
+ for i:=0 to ExpStack.Count-1 do
|
|
|
|
+ TPasExpr(ExpStack[i]).Release;
|
|
end;
|
|
end;
|
|
- SetLength(opstack,0);
|
|
|
|
- expstack.Free;
|
|
|
|
|
|
+ SetLength(OpStack,0);
|
|
|
|
+ ExpStack.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -6037,7 +6056,10 @@ function TPasParser.CreateElement(AClass: TPTreeElement; const AName: String;
|
|
AParent: TPasElement; AVisibility: TPasMemberVisibility;
|
|
AParent: TPasElement; AVisibility: TPasMemberVisibility;
|
|
const ASrcPos: TPasSourcePos): TPasElement;
|
|
const ASrcPos: TPasSourcePos): TPasElement;
|
|
begin
|
|
begin
|
|
- Result := Engine.CreateElement(AClass, AName, AParent, AVisibility, ASrcPos);
|
|
|
|
|
|
+ if (ASrcPos.Row=0) and (ASrcPos.FileName='') then
|
|
|
|
+ Result := Engine.CreateElement(AClass, AName, AParent, AVisibility, CurSourcePos)
|
|
|
|
+ else
|
|
|
|
+ Result := Engine.CreateElement(AClass, AName, AParent, AVisibility, ASrcPos);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TPasParser.CreatePrimitiveExpr(AParent: TPasElement;
|
|
function TPasParser.CreatePrimitiveExpr(AParent: TPasElement;
|
|
@@ -6059,7 +6081,14 @@ end;
|
|
function TPasParser.CreateBinaryExpr(AParent: TPasElement; xleft,
|
|
function TPasParser.CreateBinaryExpr(AParent: TPasElement; xleft,
|
|
xright: TPasExpr; AOpCode: TExprOpCode): TBinaryExpr;
|
|
xright: TPasExpr; AOpCode: TExprOpCode): TBinaryExpr;
|
|
begin
|
|
begin
|
|
- Result:=TBinaryExpr(CreateElement(TBinaryExpr,'',AParent));
|
|
|
|
|
|
+ Result:=CreateBinaryExpr(AParent,xleft,xright,AOpCode,CurSourcePos);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasParser.CreateBinaryExpr(AParent: TPasElement; xleft,
|
|
|
|
+ xright: TPasExpr; AOpCode: TExprOpCode; const ASrcPos: TPasSourcePos
|
|
|
|
+ ): TBinaryExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TBinaryExpr(CreateElement(TBinaryExpr,'',AParent,ASrcPos));
|
|
Result.OpCode:=AOpCode;
|
|
Result.OpCode:=AOpCode;
|
|
Result.Kind:=pekBinary;
|
|
Result.Kind:=pekBinary;
|
|
if xleft<>nil then
|
|
if xleft<>nil then
|
|
@@ -6187,7 +6216,13 @@ end;
|
|
function TPasParser.CreateUnaryExpr(AParent: TPasElement; AOperand: TPasExpr;
|
|
function TPasParser.CreateUnaryExpr(AParent: TPasElement; AOperand: TPasExpr;
|
|
AOpCode: TExprOpCode): TUnaryExpr;
|
|
AOpCode: TExprOpCode): TUnaryExpr;
|
|
begin
|
|
begin
|
|
- Result:=TUnaryExpr(CreateElement(TUnaryExpr,'',AParent,CurTokenPos));
|
|
|
|
|
|
+ Result:=CreateUnaryExpr(AParent,AOperand,AOpCode,CurTokenPos);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasParser.CreateUnaryExpr(AParent: TPasElement; AOperand: TPasExpr;
|
|
|
|
+ AOpCode: TExprOpCode; const ASrcPos: TPasSourcePos): TUnaryExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=TUnaryExpr(CreateElement(TUnaryExpr,'',AParent,ASrcPos));
|
|
Result.Kind:=pekUnary;
|
|
Result.Kind:=pekUnary;
|
|
Result.Operand:=AOperand;
|
|
Result.Operand:=AOperand;
|
|
Result.Operand.Parent:=Result;
|
|
Result.Operand.Parent:=Result;
|