DelphiAST
DelphiAST copied to clipboard
Double @@ (for procedural variables) is not recorded:
This snippet:
unit Test;
interface
implementation
procedure TScriptlet.InitControlData;
begin
TControlData2(CControlData).FirstEventOfs := UIntPtr(@@FOnonscriptletevent) - UIntPtr(Self);
TControlData2(CControlData).FirstEventOfs := UIntPtr(@FOnonscriptletevent) - UIntPtr(Self);
end;
end.
Is recorded as:
<?xml version="1.0"?>
<UNIT line="1" col="1" name="PlusIsTest">
<INTERFACE begin_line="3" begin_col="1" end_line="5" end_col="1"/>
<IMPLEMENTATION begin_line="5" begin_col="1" end_line="13" end_col="1">
<METHOD begin_line="7" begin_col="1" end_line="13" end_col="1" kind="procedure">
<NAME line="7" col="11" name="TScriptlet.InitControlData">
<NAME line="7" col="11" name="TScriptlet"/>
<NAME line="7" col="22" name="InitControlData"/>
</NAME>
<STATEMENTS begin_line="8" begin_col="1" end_line="11" end_col="4" kind="begin">
<ASSIGN line="9" col="3">
<LHS line="9" col="3">
<DOT line="9" col="30">
<CALL line="9" col="3">
<IDENTIFIER line="9" col="3" name="TControlData2"/>
<EXPRESSIONS line="9" col="17">
<EXPRESSION line="9" col="17">
<IDENTIFIER line="9" col="17" name="CControlData"/>
</EXPRESSION>
</EXPRESSIONS>
</CALL>
<IDENTIFIER line="9" col="31" name="FirstEventOfs"/>
</DOT>
</LHS>
<RHS line="9" col="48">
<EXPRESSION line="9" col="48">
<SUB line="9" col="79">
<CALL line="9" col="48">
<IDENTIFIER line="9" col="48" name="UIntPtr"/>
<EXPRESSIONS line="9" col="56">
<EXPRESSION line="9" col="56"> //Incorrect, no ADDR nodes!
<IDENTIFIER line="9" col="58" name="FOnonscriptletevent"/>
</EXPRESSION>
</EXPRESSIONS>
</CALL>
<CALL line="9" col="48">
<IDENTIFIER line="9" col="81" name="UIntPtr"/>
<EXPRESSIONS line="9" col="89">
<EXPRESSION line="9" col="89">
<IDENTIFIER line="9" col="89" name="Self"/>
</EXPRESSION>
</EXPRESSIONS>
</CALL>
</SUB>
</EXPRESSION>
</RHS>
</ASSIGN>
<ASSIGN line="10" col="3">
<LHS line="10" col="3">
<DOT line="10" col="30">
<CALL line="10" col="3">
<IDENTIFIER line="10" col="3" name="TControlData2"/>
<EXPRESSIONS line="10" col="17">
<EXPRESSION line="10" col="17">
<IDENTIFIER line="10" col="17" name="CControlData"/>
</EXPRESSION>
</EXPRESSIONS>
</CALL>
<IDENTIFIER line="10" col="31" name="FirstEventOfs"/>
</DOT>
</LHS>
<RHS line="10" col="48">
<EXPRESSION line="10" col="48">
<SUB line="10" col="78">
<CALL line="10" col="48">
<IDENTIFIER line="10" col="48" name="UIntPtr"/>
<EXPRESSIONS line="10" col="56">
<EXPRESSION line="10" col="56">
<ADDR line="10" col="56"> ///Correct!
<IDENTIFIER line="10" col="57" name="FOnonscriptletevent"/>
</ADDR>
</EXPRESSION>
</EXPRESSIONS>
</CALL>
<CALL line="10" col="48">
<IDENTIFIER line="10" col="80" name="UIntPtr"/>
<EXPRESSIONS line="10" col="88">
<EXPRESSION line="10" col="88">
<IDENTIFIER line="10" col="88" name="Self"/>
</EXPRESSION>
</EXPRESSIONS>
</CALL>
</SUB>
</EXPRESSION>
</RHS>
</ASSIGN>
</STATEMENTS>
</METHOD>
</IMPLEMENTATION>
</UNIT>
The cast to UIntPtr in the first line with @@ is recorded as:
<CALL line="9" col="48">
<IDENTIFIER line="9" col="48" name="UIntPtr"/>
<EXPRESSIONS line="9" col="56">
<EXPRESSION line="9" col="56"> //Incorrect, no ADDR nodes!
<IDENTIFIER line="9" col="58" name="FOnonscriptletevent"/>
</EXPRESSION>
</EXPRESSIONS>
</CALL>
The <DOUBLEADDR> node is missing. There should be <DOUBLEADDR> node. (@@ is a distinct operator from @.)
The fix is to add @@ as an additional operator:
OperatorsInfo: array [0..28] of TOperatorInfo =
((Typ: ntAddr; Priority: 1; Kind: okUnary; AssocType: atRight),
(Typ: ntDoubleAddr; Priority: 1; Kind: okUnary; AssocType: atRight),
(Typ: ntDeref; Priority: 1; Kind: okUnary; AssocType: atLeft),
(Typ: ntGeneric; Priority: 1; Kind: okBinary; AssocType: atRight),
(Typ: ntIndexed; Priority: 1; Kind: okUnary; AssocType: atLeft),
....
procedure TPasSyntaxTreeBuilder.DoubleAddressOp;
begin
FStack.Push(ntDoubleAddr);
try
inherited;
finally
FStack.Pop;
end;
end;
procedure TmwSimplePasPar.VariableReference;
begin
case TokenID of
ptRoundOpen:
begin
RoundOpen;
Expression;
RoundClose;
VariableTail;
end;
ptSquareOpen:
begin
SetConstructor;
end;
ptAddressOp:
begin
AddressOp;
VariableReference;
end;
ptDoubleAddressOp:
begin
DoubleAddressOp;
VariableReference;
end;
ptInherited:
begin
InheritedVariableReference;
end;
else
variable;
end;
end;
procedure TmwSimplePasPar.DoubleAddressOp;
begin
Expected(ptDoubleAddressOp);
end;