mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 12:19:18 +02:00
compiler: implement Inc, Dec class operators
- extend tok2node array to store inline function number for the case when nodetype = inlinen, add Inc, Dec operators to array - implement inline function support in isunaryoverloaded - check for operator overload if Inc, Dec is not used for standard types - extend test to check Inc,Dec operators git-svn-id: trunk@16629 -
This commit is contained in:
parent
d62ad56b74
commit
4531e1231b
@ -34,6 +34,7 @@ interface
|
|||||||
Ttok2nodeRec=record
|
Ttok2nodeRec=record
|
||||||
tok : ttoken;
|
tok : ttoken;
|
||||||
nod : tnodetype;
|
nod : tnodetype;
|
||||||
|
inr : integer; // inline number
|
||||||
op_overloading_supported : boolean;
|
op_overloading_supported : boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -94,33 +95,36 @@ interface
|
|||||||
ra_addr_taken);
|
ra_addr_taken);
|
||||||
tregableinfoflags = set of tregableinfoflag;
|
tregableinfoflags = set of tregableinfoflag;
|
||||||
|
|
||||||
|
{$i compinnr.inc}
|
||||||
const
|
const
|
||||||
tok2nodes=24;
|
tok2nodes=26;
|
||||||
tok2node:array[1..tok2nodes] of ttok2noderec=(
|
tok2node:array[1..tok2nodes] of ttok2noderec=(
|
||||||
(tok:_PLUS ;nod:addn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_PLUS ;nod:addn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_MINUS ;nod:subn;op_overloading_supported:true), { binary and unary overloading supported }
|
(tok:_MINUS ;nod:subn;inr:-1;op_overloading_supported:true), { binary and unary overloading supported }
|
||||||
(tok:_STAR ;nod:muln;op_overloading_supported:true), { binary overloading supported }
|
(tok:_STAR ;nod:muln;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_SLASH ;nod:slashn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_SLASH ;nod:slashn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_EQ ;nod:equaln;op_overloading_supported:true), { binary overloading supported }
|
(tok:_EQ ;nod:equaln;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_GT ;nod:gtn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_GT ;nod:gtn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_LT ;nod:ltn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_LT ;nod:ltn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_GTE ;nod:gten;op_overloading_supported:true), { binary overloading supported }
|
(tok:_GTE ;nod:gten;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_LTE ;nod:lten;op_overloading_supported:true), { binary overloading supported }
|
(tok:_LTE ;nod:lten;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_SYMDIF ;nod:symdifn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_SYMDIF ;nod:symdifn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_STARSTAR ;nod:starstarn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_STARSTAR ;nod:starstarn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_AS ;nod:asn;op_overloading_supported:false), { binary overloading NOT supported }
|
(tok:_OP_AS ;nod:asn;inr:-1;op_overloading_supported:false), { binary overloading NOT supported }
|
||||||
(tok:_OP_IN ;nod:inn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_IN ;nod:inn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_IS ;nod:isn;op_overloading_supported:false), { binary overloading NOT supported }
|
(tok:_OP_IS ;nod:isn;inr:-1;op_overloading_supported:false), { binary overloading NOT supported }
|
||||||
(tok:_OP_OR ;nod:orn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_OR ;nod:orn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_AND ;nod:andn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_AND ;nod:andn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_DIV ;nod:divn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_DIV ;nod:divn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_NOT ;nod:notn;op_overloading_supported:true), { unary overloading supported }
|
(tok:_OP_NOT ;nod:notn;inr:-1;op_overloading_supported:true), { unary overloading supported }
|
||||||
(tok:_OP_MOD ;nod:modn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_MOD ;nod:modn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_SHL ;nod:shln;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_SHL ;nod:shln;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_SHR ;nod:shrn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_SHR ;nod:shrn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_OP_XOR ;nod:xorn;op_overloading_supported:true), { binary overloading supported }
|
(tok:_OP_XOR ;nod:xorn;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
(tok:_ASSIGNMENT;nod:assignn;op_overloading_supported:true), { unary overloading supported }
|
(tok:_ASSIGNMENT;nod:assignn;inr:-1;op_overloading_supported:true), { unary overloading supported }
|
||||||
(tok:_NE ;nod:unequaln;op_overloading_supported:true) { binary overloading supported }
|
(tok:_NE ;nod:unequaln;inr:-1;op_overloading_supported:true), { binary overloading supported }
|
||||||
|
(tok:_OP_INC ;nod:inlinen;inr:in_inc_x;op_overloading_supported:true),{ unary overloading supported }
|
||||||
|
(tok:_OP_DEC ;nod:inlinen;inr:in_dec_x;op_overloading_supported:true) { unary overloading supported }
|
||||||
);
|
);
|
||||||
|
|
||||||
{ true, if we are parsing stuff which allows array constructors }
|
{ true, if we are parsing stuff which allows array constructors }
|
||||||
@ -331,13 +335,16 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function isunaryoperatoroverloadable(treetyp : tnodetype;ld : tdef) : boolean;
|
function isunaryoperatoroverloadable(treetyp:tnodetype;inlinenumber:integer;ld:tdef) : boolean;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
case treetyp of
|
case treetyp of
|
||||||
subn,
|
subn,
|
||||||
unaryminusn :
|
unaryminusn,
|
||||||
|
inlinen:
|
||||||
begin
|
begin
|
||||||
|
{ only Inc, Dec inline functions are supported for now, so skip check inlinenumber }
|
||||||
|
|
||||||
if (ld.typ in [orddef,enumdef,floatdef]) then
|
if (ld.typ in [orddef,enumdef,floatdef]) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
@ -440,9 +447,12 @@ implementation
|
|||||||
begin
|
begin
|
||||||
result:=
|
result:=
|
||||||
tok2node[i].op_overloading_supported and
|
tok2node[i].op_overloading_supported and
|
||||||
isunaryoperatoroverloadable(tok2node[i].nod,ld);
|
isunaryoperatoroverloadable(tok2node[i].nod,tok2node[i].inr,ld);
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
|
{ Inc, Dec operators are valid if only result type is the same as argument type }
|
||||||
|
if result and (optoken in [_OP_INC,_OP_DEC]) then
|
||||||
|
result:=pf.returndef=ld;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
2 : begin
|
2 : begin
|
||||||
@ -468,35 +478,57 @@ implementation
|
|||||||
operpd : tprocdef;
|
operpd : tprocdef;
|
||||||
ppn : tcallparanode;
|
ppn : tcallparanode;
|
||||||
candidates : tcallcandidates;
|
candidates : tcallcandidates;
|
||||||
cand_cnt : integer;
|
cand_cnt,
|
||||||
|
inlinenumber: integer;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
operpd:=nil;
|
operpd:=nil;
|
||||||
|
|
||||||
{ load easier access variables }
|
{ load easier access variables }
|
||||||
ld:=tunarynode(t).left.resultdef;
|
ld:=tunarynode(t).left.resultdef;
|
||||||
if not isunaryoperatoroverloadable(t.nodetype,ld) then
|
|
||||||
|
{ if we are dealing with inline function then get the function }
|
||||||
|
if t.nodetype=inlinen then
|
||||||
|
inlinenumber:=tinlinenode(t).inlinenumber
|
||||||
|
else
|
||||||
|
inlinenumber:=-1;
|
||||||
|
|
||||||
|
if not isunaryoperatoroverloadable(t.nodetype,inlinenumber,ld) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ operator overload is possible }
|
{ operator overload is possible }
|
||||||
result:=true;
|
result:=true;
|
||||||
|
|
||||||
|
optoken:=NOTOKEN;
|
||||||
case t.nodetype of
|
case t.nodetype of
|
||||||
notn:
|
notn:
|
||||||
optoken:=_OP_NOT;
|
optoken:=_OP_NOT;
|
||||||
unaryminusn:
|
unaryminusn:
|
||||||
optoken:=_MINUS;
|
optoken:=_MINUS;
|
||||||
else
|
inlinen:
|
||||||
begin
|
case inlinenumber of
|
||||||
CGMessage(parser_e_operator_not_overloaded);
|
in_inc_x:
|
||||||
t:=cnothingnode.create;
|
optoken:=_OP_INC;
|
||||||
exit;
|
in_dec_x:
|
||||||
|
optoken:=_OP_DEC;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
if (optoken=NOTOKEN) then
|
||||||
|
begin
|
||||||
|
CGMessage(parser_e_operator_not_overloaded);
|
||||||
|
t:=cnothingnode.create;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
{ generate parameter nodes }
|
{ generate parameter nodes }
|
||||||
ppn:=ccallparanode.create(tunarynode(t).left.getcopy,nil);
|
{ for inline nodes just copy existent callparanode }
|
||||||
ppn.get_paratype;
|
if (t.nodetype=inlinen) and (tinlinenode(t).left.nodetype=callparan) then
|
||||||
|
ppn:=tcallparanode(tinlinenode(t).left.getcopy)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
ppn:=ccallparanode.create(tunarynode(t).left.getcopy,nil);
|
||||||
|
ppn.get_paratype;
|
||||||
|
end;
|
||||||
candidates:=tcallcandidates.create_operator(optoken,ppn);
|
candidates:=tcallcandidates.create_operator(optoken,ppn);
|
||||||
|
|
||||||
{ stop when there are no operators found }
|
{ stop when there are no operators found }
|
||||||
|
@ -2348,7 +2348,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
CGMessagePos(left.fileinfo,type_e_ordinal_expr_expected);
|
begin
|
||||||
|
hp:=self;
|
||||||
|
if isunaryoverloaded(hp) then
|
||||||
|
begin
|
||||||
|
{ inc(rec) and dec(rec) assigns result value to argument }
|
||||||
|
result:=cassignmentnode.create(tcallparanode(left).left.getcopy,hp);
|
||||||
|
exit;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
CGMessagePos(left.fileinfo,type_e_ordinal_expr_expected);
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
CGMessagePos(fileinfo,type_e_mismatch);
|
CGMessagePos(fileinfo,type_e_mismatch);
|
||||||
|
@ -251,8 +251,8 @@ implementation
|
|||||||
t:=self;
|
t:=self;
|
||||||
if isbinaryoverloaded(t) then
|
if isbinaryoverloaded(t) then
|
||||||
begin
|
begin
|
||||||
result:=t;
|
result:=t;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if right.resultdef.typ<>setdef then
|
if right.resultdef.typ<>setdef then
|
||||||
|
@ -830,8 +830,8 @@ implementation
|
|||||||
// _EXPLICIT:optoken:=;
|
// _EXPLICIT:optoken:=;
|
||||||
_NEGATIVE:optoken:=_MINUS;
|
_NEGATIVE:optoken:=_MINUS;
|
||||||
// _POSITIVE:optoken:=_PLUS;
|
// _POSITIVE:optoken:=_PLUS;
|
||||||
// _INC:optoken:=;
|
_INC:optoken:=_OP_INC;
|
||||||
// _DEC:optoken:=;
|
_DEC:optoken:=_OP_DEC;
|
||||||
_LOGICALNOT:optoken:=_OP_NOT;
|
_LOGICALNOT:optoken:=_OP_NOT;
|
||||||
_IN:optoken:=_OP_IN;
|
_IN:optoken:=_OP_IN;
|
||||||
_EQUAL:optoken:=_EQ;
|
_EQUAL:optoken:=_EQ;
|
||||||
|
@ -290,7 +290,9 @@ interface
|
|||||||
{ _OP_SHR } 'shr',
|
{ _OP_SHR } 'shr',
|
||||||
{ _OP_XOR } 'xor',
|
{ _OP_XOR } 'xor',
|
||||||
{ _ASSIGNMENT } 'assign',
|
{ _ASSIGNMENT } 'assign',
|
||||||
{ _OP_ENUMERATOR } 'enumerator');
|
{ _OP_ENUMERATOR } 'enumerator',
|
||||||
|
{ _OP_INC } 'inc',
|
||||||
|
{ _OP_DEC } 'dec');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@ type
|
|||||||
_OP_XOR,
|
_OP_XOR,
|
||||||
_ASSIGNMENT,
|
_ASSIGNMENT,
|
||||||
_OP_ENUMERATOR,
|
_OP_ENUMERATOR,
|
||||||
|
_OP_INC,
|
||||||
|
_OP_DEC,
|
||||||
{ special chars }
|
{ special chars }
|
||||||
_CARET,
|
_CARET,
|
||||||
_LECKKLAMMER,
|
_LECKKLAMMER,
|
||||||
@ -296,7 +298,7 @@ const
|
|||||||
{ last operator which can be overloaded, the first_overloaded should
|
{ last operator which can be overloaded, the first_overloaded should
|
||||||
be declared directly after NOTOKEN }
|
be declared directly after NOTOKEN }
|
||||||
first_overloaded = succ(NOTOKEN);
|
first_overloaded = succ(NOTOKEN);
|
||||||
last_overloaded = _OP_ENUMERATOR;
|
last_overloaded = _OP_DEC;
|
||||||
|
|
||||||
type
|
type
|
||||||
tokenrec=record
|
tokenrec=record
|
||||||
@ -345,6 +347,8 @@ const
|
|||||||
(str:'xor' ;special:true ;keyword:m_none;op:NOTOKEN),
|
(str:'xor' ;special:true ;keyword:m_none;op:NOTOKEN),
|
||||||
(str:':=' ;special:true ;keyword:m_none;op:NOTOKEN),
|
(str:':=' ;special:true ;keyword:m_none;op:NOTOKEN),
|
||||||
(str:'enumerator' ;special:true ;keyword:m_none;op:NOTOKEN),
|
(str:'enumerator' ;special:true ;keyword:m_none;op:NOTOKEN),
|
||||||
|
(str:'++' ;special:true ;keyword:m_none;op:NOTOKEN),
|
||||||
|
(str:'--' ;special:true ;keyword:m_none;op:NOTOKEN),
|
||||||
{ Special chars }
|
{ Special chars }
|
||||||
(str:'^' ;special:true ;keyword:m_none;op:NOTOKEN),
|
(str:'^' ;special:true ;keyword:m_none;op:NOTOKEN),
|
||||||
(str:'[' ;special:true ;keyword:m_none;op:NOTOKEN),
|
(str:'[' ;special:true ;keyword:m_none;op:NOTOKEN),
|
||||||
|
@ -30,8 +30,8 @@ type
|
|||||||
class operator BitwiseOr(a, b: TFoo): TFoo;
|
class operator BitwiseOr(a, b: TFoo): TFoo;
|
||||||
class operator BitwiseAnd(a, b: TFoo): TFoo;
|
class operator BitwiseAnd(a, b: TFoo): TFoo;
|
||||||
class operator BitwiseXor(a, b: TFoo): TFoo;
|
class operator BitwiseXor(a, b: TFoo): TFoo;
|
||||||
// class operator Inc(a: TFoo): TFoo;
|
class operator Inc(a: TFoo): TFoo;
|
||||||
// class operator Dec(a: TFoo): TFoo;
|
class operator Dec(a: TFoo): TFoo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class operator TFoo.Equal(a, b: TFoo): Boolean;
|
class operator TFoo.Equal(a, b: TFoo): Boolean;
|
||||||
@ -144,6 +144,16 @@ begin
|
|||||||
Result.F := a.F xor b.F;
|
Result.F := a.F xor b.F;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class operator TFoo.Inc(a: TFoo): TFoo;
|
||||||
|
begin
|
||||||
|
Result.F := a.F + 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class operator TFoo.Dec(a: TFoo): TFoo;
|
||||||
|
begin
|
||||||
|
Result.F := a.F - 1;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
a, b: TFoo;
|
a, b: TFoo;
|
||||||
begin
|
begin
|
||||||
@ -197,5 +207,11 @@ begin
|
|||||||
if (a xor b).F <> (a.F xor b.F) then
|
if (a xor b).F <> (a.F xor b.F) then
|
||||||
halt(23);
|
halt(23);
|
||||||
}
|
}
|
||||||
|
inc(a);
|
||||||
|
if a.F <> 2 then
|
||||||
|
halt(24);
|
||||||
|
dec(b);
|
||||||
|
if b.F <> 1 then
|
||||||
|
halt(25);
|
||||||
WriteLn('ok');
|
WriteLn('ok');
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user