mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 09:29:26 +02:00
fcl-passrc: fixed parsing (expr).name()
git-svn-id: trunk@41225 -
This commit is contained in:
parent
bf1af93938
commit
9a878f99db
@ -13184,23 +13184,25 @@ begin
|
|||||||
Value:=nil;
|
Value:=nil;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
{$ifdef FPC_HAS_CPSTRING}
|
||||||
else if (bt=btAnsiString) or ((bt=btString) and (BaseTypeString=btAnsiString)) then
|
else if (bt=btAnsiString) or ((bt=btString) and (BaseTypeString=btAnsiString)) then
|
||||||
begin
|
begin
|
||||||
// ansistring(unicodestring)
|
// ansistring(unicodestring)
|
||||||
Result:=TResEvalString.CreateValue(
|
Result:=TResEvalString.CreateValue(
|
||||||
fExprEvaluator.GetRawByteString(TResEvalUTF16(Value).S,CP_ACP,Params));
|
fExprEvaluator.GetRawByteString(TResEvalUTF16(Value).S,CP_ACP,Params));
|
||||||
end
|
end
|
||||||
else if (bt=btUnicodeString) or ((bt=btString) and (BaseTypeString=btUnicodeString)) then
|
|
||||||
begin
|
|
||||||
// unicodestring(unicodestring)
|
|
||||||
Result:=Value;
|
|
||||||
Value:=nil;
|
|
||||||
end
|
|
||||||
else if bt=btRawByteString then
|
else if bt=btRawByteString then
|
||||||
begin
|
begin
|
||||||
// rawbytestring(unicodestring)
|
// rawbytestring(unicodestring)
|
||||||
Result:=TResEvalString.CreateValue(
|
Result:=TResEvalString.CreateValue(
|
||||||
fExprEvaluator.GetRawByteString(TResEvalUTF16(Value).S,CP_NONE,Params));
|
fExprEvaluator.GetRawByteString(TResEvalUTF16(Value).S,CP_NONE,Params));
|
||||||
|
end
|
||||||
|
{$endif}
|
||||||
|
else if (bt=btUnicodeString) or ((bt=btString) and (BaseTypeString=btUnicodeString)) then
|
||||||
|
begin
|
||||||
|
// unicodestring(unicodestring)
|
||||||
|
Result:=Value;
|
||||||
|
Value:=nil;
|
||||||
end;
|
end;
|
||||||
revkExternal:
|
revkExternal:
|
||||||
exit;
|
exit;
|
||||||
|
@ -2250,7 +2250,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
tkfalse, tktrue: Last:=CreateBoolConstExpr(AParent,pekBoolConst, CurToken=tktrue);
|
tkfalse, tktrue: Last:=CreateBoolConstExpr(AParent,pekBoolConst, CurToken=tktrue);
|
||||||
tknil: Last:=CreateNilExpr(AParent);
|
tknil: Last:=CreateNilExpr(AParent);
|
||||||
tkSquaredBraceOpen: Last:=ParseParams(AParent,pekSet);
|
tkSquaredBraceOpen:
|
||||||
|
begin
|
||||||
|
Last:=ParseParams(AParent,pekSet);
|
||||||
|
UngetToken;
|
||||||
|
end;
|
||||||
tkinherited:
|
tkinherited:
|
||||||
begin
|
begin
|
||||||
//inherited; inherited function
|
//inherited; inherited function
|
||||||
@ -2306,6 +2310,18 @@ begin
|
|||||||
end;
|
end;
|
||||||
Last:=CreatePrimitiveExpr(AParent,pekString, '^'+CurTokenText);
|
Last:=CreatePrimitiveExpr(AParent,pekString, '^'+CurTokenText);
|
||||||
end;
|
end;
|
||||||
|
tkBraceOpen:
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
Last:=DoParseExpression(AParent);
|
||||||
|
if not Assigned(Last) then
|
||||||
|
ParseExcSyntaxError;
|
||||||
|
if (CurToken<>tkBraceClose) then
|
||||||
|
begin
|
||||||
|
Last.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
||||||
|
CheckToken(tkBraceClose);
|
||||||
|
end;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
ParseExcExpectedIdentifier;
|
ParseExcExpectedIdentifier;
|
||||||
end;
|
end;
|
||||||
@ -2314,13 +2330,7 @@ begin
|
|||||||
ok:=false;
|
ok:=false;
|
||||||
ISE:=nil;
|
ISE:=nil;
|
||||||
try
|
try
|
||||||
if Last.Kind<>pekSet then NextToken;
|
NextToken;
|
||||||
if not (Last.Kind in [pekNumber,pekString,pekSet,pekIdent,pekSelf,pekNil]) then
|
|
||||||
begin
|
|
||||||
ok:=true;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Func:=Last;
|
Func:=Last;
|
||||||
repeat
|
repeat
|
||||||
case CurToken of
|
case CurToken of
|
||||||
@ -2509,8 +2519,6 @@ const
|
|||||||
Var
|
Var
|
||||||
AllowedBinaryOps : Set of TToken;
|
AllowedBinaryOps : Set of TToken;
|
||||||
SrcPos: TPasSourcePos;
|
SrcPos: TPasSourcePos;
|
||||||
ArrParams: TParamsExpr;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
AllowedBinaryOps:=BinaryOP;
|
AllowedBinaryOps:=BinaryOP;
|
||||||
if Not AllowEqual then
|
if Not AllowEqual then
|
||||||
@ -2536,62 +2544,12 @@ begin
|
|||||||
inc(PrefixCnt);
|
inc(PrefixCnt);
|
||||||
NextToken;
|
NextToken;
|
||||||
end;
|
end;
|
||||||
|
// parse operand
|
||||||
if (CurToken = tkBraceOpen) then
|
x:=ParseExprOperand(AParent);
|
||||||
begin
|
if not Assigned(x) then
|
||||||
NextToken;
|
ParseExcSyntaxError;
|
||||||
x:=DoParseExpression(AParent);
|
|
||||||
if not Assigned(x) then
|
|
||||||
ParseExcSyntaxError;
|
|
||||||
if (CurToken<>tkBraceClose) then
|
|
||||||
begin
|
|
||||||
x.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
||||||
CheckToken(tkBraceClose);
|
|
||||||
end;
|
|
||||||
NextToken;
|
|
||||||
repeat
|
|
||||||
case CurToken of
|
|
||||||
tkCaret:
|
|
||||||
begin
|
|
||||||
// for expressions like (ppdouble)^^;
|
|
||||||
x:=CreateUnaryExpr(AParent,x, TokenToExprOp(tkCaret));
|
|
||||||
NextToken;
|
|
||||||
end;
|
|
||||||
tkBraceOpen:
|
|
||||||
begin
|
|
||||||
// for expressions like (a+b)(0);
|
|
||||||
ArrParams:=ParseParams(AParent,pekFuncParams,False);
|
|
||||||
ArrParams.Value:=x;
|
|
||||||
x.Parent:=ArrParams;
|
|
||||||
x:=ArrParams;
|
|
||||||
end;
|
|
||||||
tkSquaredBraceOpen:
|
|
||||||
begin
|
|
||||||
// for expressions like (PChar(a)+10)[0];
|
|
||||||
ArrParams:=ParseParams(AParent,pekArrayParams,False);
|
|
||||||
ArrParams.Value:=x;
|
|
||||||
x.Parent:=ArrParams;
|
|
||||||
x:=ArrParams;
|
|
||||||
end;
|
|
||||||
tkDot:
|
|
||||||
begin
|
|
||||||
// for expressions like (TObject(m)).Free;
|
|
||||||
NextToken;
|
|
||||||
x:=CreateBinaryExpr(AParent,x, ParseExprOperand(AParent), TokenToExprOp(tkDot));
|
|
||||||
end
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
until false;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
x:=ParseExprOperand(AParent);
|
|
||||||
if not Assigned(x) then
|
|
||||||
ParseExcSyntaxError;
|
|
||||||
end;
|
|
||||||
ExpStack.Add(x);
|
ExpStack.Add(x);
|
||||||
|
// apply prefixes
|
||||||
for i:=1 to PrefixCnt do
|
for i:=1 to PrefixCnt do
|
||||||
begin
|
begin
|
||||||
TempOp:=PopOper(SrcPos);
|
TempOp:=PopOper(SrcPos);
|
||||||
@ -4254,17 +4212,8 @@ begin
|
|||||||
if (CurToken=tkAbsolute) then
|
if (CurToken=tkAbsolute) then
|
||||||
begin
|
begin
|
||||||
Result:=True;
|
Result:=True;
|
||||||
ExpectIdentifier;
|
|
||||||
Location:=CurTokenText;
|
|
||||||
AbsoluteExpr:=CreatePrimitiveExpr(Parent,pekIdent,CurTokenText);
|
|
||||||
NextToken;
|
NextToken;
|
||||||
While CurToken=tkDot do
|
Location:=ReadDottedIdentifier(Parent,AbsoluteExpr,true);
|
||||||
begin
|
|
||||||
ExpectIdentifier;
|
|
||||||
Location:=Location+'.'+CurTokenText;
|
|
||||||
AbsoluteExpr:=CreateBinaryExpr(Parent,AbsoluteExpr,CreatePrimitiveExpr(Parent,pekIdent,CurTokenText),eopSubIdent);
|
|
||||||
NextToken;
|
|
||||||
end;
|
|
||||||
UnGetToken;
|
UnGetToken;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -5212,20 +5161,9 @@ function TPasParser.ParseProperty(Parent: TPasElement; const AName: String;
|
|||||||
Param: TPasExpr;
|
Param: TPasExpr;
|
||||||
SrcPos: TPasSourcePos;
|
SrcPos: TPasSourcePos;
|
||||||
begin
|
begin
|
||||||
ExpectIdentifier;
|
NextToken;
|
||||||
Result := CurTokenString;
|
// read ident.subident...
|
||||||
Expr := CreatePrimitiveExpr(aParent,pekIdent,CurTokenString);
|
Result:=ReadDottedIdentifier(aParent,Expr,true);
|
||||||
|
|
||||||
// read .subident.subident...
|
|
||||||
repeat
|
|
||||||
NextToken;
|
|
||||||
if CurToken <> tkDot then break;
|
|
||||||
SrcPos:=CurTokenPos;
|
|
||||||
ExpectIdentifier;
|
|
||||||
Result := Result + '.' + CurTokenString;
|
|
||||||
AddToBinaryExprChain(Expr,CreatePrimitiveExpr(aParent,pekIdent,CurTokenString),
|
|
||||||
eopSubIdent,SrcPos);
|
|
||||||
until false;
|
|
||||||
|
|
||||||
// read optional array index
|
// read optional array index
|
||||||
if CurToken <> tkSquaredBraceOpen then
|
if CurToken <> tkSquaredBraceOpen then
|
||||||
|
@ -111,6 +111,7 @@ type
|
|||||||
Procedure TestADotBDotC;
|
Procedure TestADotBDotC;
|
||||||
Procedure TestADotBBracketC;
|
Procedure TestADotBBracketC;
|
||||||
Procedure TestSelfDotBBracketC;
|
Procedure TestSelfDotBBracketC;
|
||||||
|
Procedure TestAasBDotCBracketFuncParams;
|
||||||
Procedure TestRange;
|
Procedure TestRange;
|
||||||
Procedure TestBracketsTotal;
|
Procedure TestBracketsTotal;
|
||||||
Procedure TestBracketsLeft;
|
Procedure TestBracketsLeft;
|
||||||
@ -1289,6 +1290,32 @@ begin
|
|||||||
AssertExpression('first param c',p.Params[0],pekIdent,'c');
|
AssertExpression('first param c',p.Params[0],pekIdent,'c');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestExpressions.TestAasBDotCBracketFuncParams;
|
||||||
|
var
|
||||||
|
P: TParamsExpr;
|
||||||
|
B, AsExpr: TBinaryExpr;
|
||||||
|
begin
|
||||||
|
ParseExpression('(a as b).c(d)');
|
||||||
|
P:=TParamsExpr(AssertExpression('FuncParams',TheExpr,pekFuncParams,TParamsExpr));
|
||||||
|
AssertEquals('length(p.Params)',length(p.Params),1);
|
||||||
|
AssertExpression('first param d',p.Params[0],pekIdent,'d');
|
||||||
|
|
||||||
|
B:=TBinaryExpr(AssertExpression('Upper Binary identifier',P.Value,pekBinary,TBinaryExpr));
|
||||||
|
AssertEquals('dot c expr',eopSubIdent,B.OpCode);
|
||||||
|
TAssert.AssertSame('B.left.parent=B',B,B.left.Parent);
|
||||||
|
TAssert.AssertSame('B.right.parent=B',B,B.right.Parent);
|
||||||
|
|
||||||
|
AssertExpression('dot c',b.right,pekIdent,'c');
|
||||||
|
|
||||||
|
AsExpr:=TBinaryExpr(AssertExpression('lower binary identifier',B.left,pekBinary,TBinaryExpr));
|
||||||
|
AssertEquals('AS expr',eopAs,AsExpr.OpCode);
|
||||||
|
TAssert.AssertSame('AsExpr.left.parent=AsExpr',AsExpr,AsExpr.left.Parent);
|
||||||
|
TAssert.AssertSame('AsExpr.right.parent=AsExpr',AsExpr,AsExpr.right.Parent);
|
||||||
|
|
||||||
|
AssertExpression('left AS a',AsExpr.left,pekIdent,'a');
|
||||||
|
AssertExpression('right AS b',AsExpr.right,pekIdent,'b');
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
RegisterTest(TTestExpressions);
|
RegisterTest(TTestExpressions);
|
||||||
|
Loading…
Reference in New Issue
Block a user